Add require builtin

This commit is contained in:
Ulf Norell 2019-06-14 10:27:07 +02:00
parent 5628cf90b8
commit 17a1fd8095
14 changed files with 19 additions and 30 deletions

View File

@ -380,7 +380,8 @@ global_env() ->
{"RelativeTTL", Fun1(Int, TTL)},
{"FixedTTL", Fun1(Int, TTL)},
%% Abort
{"abort", Fun1(String, A)}])
{"abort", Fun1(String, A)},
{"require", Fun([Bool, String], A)}])
, types = MkDefs(
[{"int", 0}, {"bool", 0}, {"char", 0}, {"string", 0}, {"address", 0},
{"hash", {[], {alias_t, Bytes(32)}}},

View File

@ -170,7 +170,7 @@ builtins() ->
MkName = fun(NS, Fun) ->
list_to_atom(string:to_lower(string:join(NS ++ [Fun], "_")))
end,
Scopes = [{[], [{"abort", 1}]},
Scopes = [{[], [{"abort", 1}, {"require", 2}]},
{["Chain"], [{"spend", 2}, {"balance", 1}, {"block_hash", 1}, {"coinbase", none},
{"timestamp", none}, {"block_height", none}, {"difficulty", none},
{"gas_limit", none}]},
@ -765,6 +765,8 @@ op_builtins() ->
bits_difference, int_to_str, address_to_str, crypto_ecverify,
crypto_ecverify_secp256k1, crypto_sha3, crypto_sha256, crypto_blake2b].
builtin_to_fcode(require, [Cond, Msg]) ->
make_if(Cond, {tuple, []}, {builtin, abort, [Msg]});
builtin_to_fcode(map_delete, [Key, Map]) ->
{op, map_delete, [Map, Key]};
builtin_to_fcode(map_member, [Key, Map]) ->

View File

@ -174,6 +174,8 @@ ast_body({qid, _, [Con, "put"]}, #{ contract_name := Con }) ->
%% Abort
ast_body(?id_app("abort", [String], _, _), Icode) ->
builtin_call(abort, [ast_body(String, Icode)]);
ast_body(?id_app("require", [Bool, String], _, _), Icode) ->
builtin_call(require, [ast_body(Bool, Icode), ast_body(String, Icode)]);
%% Authentication
ast_body({qid, _, ["Auth", "tx_hash"]}, _Icode) ->

View File

@ -45,6 +45,7 @@ builtin_deps1({baseX_int, X}) -> [{baseX_int_pad, X}];
builtin_deps1({baseX_int_pad, X}) -> [{baseX_int_encode, X}];
builtin_deps1({baseX_int_encode, X}) -> [{baseX_int_encode_, X}, {baseX_tab, X}, {baseX_digits, X}];
builtin_deps1(string_reverse) -> [string_reverse_];
builtin_deps1(require) -> [abort];
builtin_deps1(_) -> [].
dep_closure(Deps) ->
@ -131,6 +132,7 @@ builtin_function(BF) ->
case BF of
{event, EventT} -> bfun(BF, builtin_event(EventT));
abort -> bfun(BF, builtin_abort());
require -> bfun(BF, builtin_require());
{map_lookup, Type} -> bfun(BF, builtin_map_lookup(Type));
map_put -> bfun(BF, builtin_map_put());
map_delete -> bfun(BF, builtin_map_delete());
@ -201,6 +203,11 @@ builtin_abort() ->
A(?REVERT)]}, %% Stack: 0,Ptr
{tuple,[]}}.
builtin_require() ->
{[{"c", word}, {"msg", string}],
{ifte, ?V(c), {tuple, []}, ?call(abort, [?V(msg)])},
{tuple, []}}.
%% Map primitives
builtin_map_lookup(Type) ->
Ret = aeso_icode:option_typerep(Type),

View File

@ -104,10 +104,10 @@ contract AEProof =
proofsByOwner : map(address, array(uint)) }
function notarize(document:string, comment:string, ipfsHash:hash) =
let _ = require(aetoken.balanceOf(caller()) > 0)
let _ = require(aetoken.balanceOf(caller()) > 0, "false")
let proofHash: uint = calculateHash(document)
let proof : proof = Map.get_(proofHash, state().proofs)
let _ = require(proof.owner == #0)
let _ = require(proof.owner == #0, "false")
let proof' : proof = proof { owner = caller()
, timestamp = block().timestamp
, proofBlock = block().height
@ -124,12 +124,12 @@ contract AEProof =
function getProof(document) : proof =
let calcHash = calculateHash(document)
let proof = Map.get_(calcHash, state().proofs)
let _ = require(proof.owner != #0)
let _ = require(proof.owner != #0, "false")
proof
function getProofByHash(hash: uint) : proof =
let proof = Map.get_(hash, state().proofs)
let _ = require(proof.owner != #0)
let _ = require(proof.owner != #0, "false")
proof
@ -141,5 +141,3 @@ contract AEProof =
function getProofsByOwner(owner: address): array(uint) =
Map.get(owner, state())
function require(x : bool) : unit = if(x) () else abort("false")

View File

@ -15,5 +15,3 @@ contract BasicAuth =
function to_sign(h : hash, n : int) =
Crypto.blake2b((h, n))
private function require(b : bool, err : string) =
if(!b) abort(err)

View File

@ -14,5 +14,3 @@ contract BitcoinAuth =
function to_sign(h : hash, n : int) : hash =
Crypto.blake2b((h, n))
private function require(b : bool, err : string) =
if(!b) abort(err)

View File

@ -15,9 +15,6 @@ contract DutchAuction =
Chain.spend(to, amount)
total - amount
private function require(b : bool, err : string) =
if(!b) abort(err)
// TTL set by user on posting contract, typically (start - end ) div dec
public function init(beneficiary, start, decrease) : state =
require(start > 0 && decrease > 0, "bad args")

View File

@ -77,9 +77,6 @@ contract ERC20Token =
put( state{approval_log = e :: state.approval_log })
e
private function require(b : bool, err : string) =
if(!b) abort(err)
private function sub(_a : int, _b : int) : int =
require(_b =< _a, "Error")
_a - _b

View File

@ -12,9 +12,6 @@ contract FundMe =
deadline : int,
goal : int }
private function require(b : bool, err : string) =
if(!b) abort(err)
private stateful function spend(args : spend_args) =
Chain.spend(args.recipient, args.amount)

View File

@ -108,5 +108,3 @@ contract Oracles =
Oracle.respond(o, q, Answer(question, "magic", 1337), signature = sig)
Oracle.get_answer(o, q)
private function require(b : bool, err : string) =
if(!b) abort(err)

View File

@ -20,5 +20,3 @@ contract OraclesGas =
Oracle.respond(o, q, answer)
()
private function require(b : bool, err : string) =
if(!b) abort(err)

View File

@ -33,5 +33,3 @@ contract Oracles =
q : query_id) : option(answer_t) =
Oracle.get_answer(o, q)
private function require(b : bool, err : string) =
if(!b) abort(err)

View File

@ -9,8 +9,6 @@ contract VariantTypes =
function init() = Stopped
function require(b) = if(!b) abort("required")
stateful function start(bal : int) =
switch(state)
Stopped => put(Started({owner = Call.caller, balance = bal, color = Grey(0)}))
@ -18,7 +16,7 @@ contract VariantTypes =
stateful function stop() =
switch(state)
Started(st) =>
require(Call.caller == st.owner)
require(Call.caller == st.owner, "required")
put(Stopped)
st.balance