Contract factories and bytecode introspection (#305)
* Support for CREATE, CLONE and BYTECODE_HASH * Add missing files * Pushed the clone example through the typechecker * CLONE compiles * Fix dependent type in CLONE * Bytecode hash fixes * Refactor * Refactor 2 * move some logic away * Fixed some error messages. Type inference of child contract still does some random shit\n(mistakes arguments with result type) * CREATE sometimes compiles and sometimes not * Fix some scoping/constraint issues * works, needs cleanup * cleanup * Fix some tests. Remove optimization of singleton tuples * Fix default argument for clone * Cleanup * CHANGELOG * Mention void type * Address review, fix some dialyzer errors * Please dialyzer * Fix failing tests * Write negative tests * Docs * TOC * missing 'the' * missing 'the' * missing 'the' * missing 'the' * mention pre-fund * format * pre-fund clarification * format * Grammar in docs
This commit is contained in:
@@ -190,7 +190,7 @@ parameterized_contract(ExtraCode, FunName, Types) ->
|
||||
lists:flatten(
|
||||
["contract Remote =\n"
|
||||
" entrypoint bla : () => unit\n\n"
|
||||
"contract Dummy =\n",
|
||||
"main contract Dummy =\n",
|
||||
ExtraCode, "\n",
|
||||
" type an_alias('a) = string * 'a\n"
|
||||
" record r = {x : an_alias(int), y : variant}\n"
|
||||
|
||||
+53
-44
@@ -22,7 +22,8 @@ test_cases(1) ->
|
||||
MapACI = #{contract =>
|
||||
#{name => <<"C">>,
|
||||
type_defs => [],
|
||||
payable => true,
|
||||
payable => true,
|
||||
kind => contract_main,
|
||||
functions =>
|
||||
[#{name => <<"a">>,
|
||||
arguments =>
|
||||
@@ -31,56 +32,57 @@ test_cases(1) ->
|
||||
returns => <<"int">>,
|
||||
stateful => true,
|
||||
payable => true}]}},
|
||||
DecACI = <<"payable contract C =\n"
|
||||
DecACI = <<"payable main contract C =\n"
|
||||
" payable entrypoint a : (int) => int\n">>,
|
||||
{Contract,MapACI,DecACI};
|
||||
|
||||
test_cases(2) ->
|
||||
Contract = <<"contract C =\n"
|
||||
Contract = <<"main contract C =\n"
|
||||
" type allan = int\n"
|
||||
" entrypoint a(i : allan) = i+1\n">>,
|
||||
MapACI = #{contract =>
|
||||
#{name => <<"C">>, payable => false,
|
||||
type_defs =>
|
||||
[#{name => <<"allan">>,
|
||||
typedef => <<"int">>,
|
||||
vars => []}],
|
||||
functions =>
|
||||
[#{arguments =>
|
||||
[#{name => <<"i">>,
|
||||
type => <<"C.allan">>}],
|
||||
name => <<"a">>,
|
||||
returns => <<"int">>,
|
||||
stateful => false,
|
||||
payable => false}]}},
|
||||
DecACI = <<"contract C =\n"
|
||||
#{name => <<"C">>, payable => false,
|
||||
kind => contract_main,
|
||||
type_defs =>
|
||||
[#{name => <<"allan">>,
|
||||
typedef => <<"int">>,
|
||||
vars => []}],
|
||||
functions =>
|
||||
[#{arguments =>
|
||||
[#{name => <<"i">>,
|
||||
type => <<"C.allan">>}],
|
||||
name => <<"a">>,
|
||||
returns => <<"int">>,
|
||||
stateful => false,
|
||||
payable => false}]}},
|
||||
DecACI = <<"main contract C =\n"
|
||||
" type allan = int\n"
|
||||
" entrypoint a : (C.allan) => int\n">>,
|
||||
{Contract,MapACI,DecACI};
|
||||
test_cases(3) ->
|
||||
Contract = <<"contract C =\n"
|
||||
Contract = <<"main contract C =\n"
|
||||
" type state = unit\n"
|
||||
" datatype event = SingleEventDefined\n"
|
||||
" datatype bert('a) = Bin('a)\n"
|
||||
" entrypoint a(i : bert(string)) = 1\n">>,
|
||||
" datatype bert('a) = Bin('a)\n"
|
||||
" entrypoint a(i : bert(string)) = 1\n">>,
|
||||
MapACI = #{contract =>
|
||||
#{functions =>
|
||||
[#{arguments =>
|
||||
[#{name => <<"i">>,
|
||||
type =>
|
||||
#{<<"C.bert">> => [<<"string">>]}}],
|
||||
name => <<"a">>,returns => <<"int">>,
|
||||
stateful => false, payable => false}],
|
||||
name => <<"C">>, payable => false,
|
||||
event => #{variant => [#{<<"SingleEventDefined">> => []}]},
|
||||
state => <<"unit">>,
|
||||
[#{arguments =>
|
||||
[#{name => <<"i">>,
|
||||
type =>
|
||||
#{<<"C.bert">> => [<<"string">>]}}],
|
||||
name => <<"a">>,returns => <<"int">>,
|
||||
stateful => false, payable => false}],
|
||||
name => <<"C">>, payable => false, kind => contract_main,
|
||||
event => #{variant => [#{<<"SingleEventDefined">> => []}]},
|
||||
state => <<"unit">>,
|
||||
type_defs =>
|
||||
[#{name => <<"bert">>,
|
||||
typedef =>
|
||||
#{variant =>
|
||||
[#{<<"Bin">> => [<<"'a">>]}]},
|
||||
vars => [#{name => <<"'a">>}]}]}},
|
||||
DecACI = <<"contract C =\n"
|
||||
[#{name => <<"bert">>,
|
||||
typedef =>
|
||||
#{variant =>
|
||||
[#{<<"Bin">> => [<<"'a">>]}]},
|
||||
vars => [#{name => <<"'a">>}]}]}},
|
||||
DecACI = <<"main contract C =\n"
|
||||
" type state = unit\n"
|
||||
" datatype event = SingleEventDefined\n"
|
||||
" datatype bert('a) = Bin('a)\n"
|
||||
@@ -101,17 +103,24 @@ aci_test_contract(Name) ->
|
||||
true -> [debug_mode];
|
||||
false -> []
|
||||
end ++ [{include, {file_system, [aeso_test_utils:contract_path()]}}],
|
||||
{ok, JSON} = aeso_aci:contract_interface(json, String, Opts),
|
||||
{ok, #{aci := JSON1}} = aeso_compiler:from_string(String, [{aci, json}, {backend, fate} | Opts]),
|
||||
?assertEqual(JSON, JSON1),
|
||||
JSON = case aeso_aci:contract_interface(json, String, Opts) of
|
||||
{ok, J} -> J;
|
||||
{error, ErrorStringJ} when is_binary(ErrorStringJ) -> error(ErrorStringJ);
|
||||
{error, ErrorJ} -> aeso_compiler_tests:print_and_throw(ErrorJ)
|
||||
end,
|
||||
case aeso_compiler:from_string(String, [{aci, json}, {backend, fate} | Opts]) of
|
||||
{ok, #{aci := JSON1}} ->
|
||||
?assertEqual(JSON, JSON1),
|
||||
io:format("JSON:\n~p\n", [JSON]),
|
||||
{ok, ContractStub} = aeso_aci:render_aci_json(JSON),
|
||||
|
||||
io:format("JSON:\n~p\n", [JSON]),
|
||||
{ok, ContractStub} = aeso_aci:render_aci_json(JSON),
|
||||
io:format("STUB:\n~s\n", [ContractStub]),
|
||||
check_stub(ContractStub, [{src_file, Name}]),
|
||||
|
||||
io:format("STUB:\n~s\n", [ContractStub]),
|
||||
check_stub(ContractStub, [{src_file, Name}]),
|
||||
|
||||
ok.
|
||||
ok;
|
||||
{error, ErrorString} when is_binary(ErrorString) -> error(ErrorString);
|
||||
{error, Error} -> aeso_compiler_tests:print_and_throw(Error)
|
||||
end.
|
||||
|
||||
check_stub(Stub, Options) ->
|
||||
try aeso_parser:string(binary_to_list(Stub), Options) of
|
||||
|
||||
@@ -59,8 +59,8 @@ calldata_aci_test_() ->
|
||||
end} || {ContractName, Fun, Args} <- compilable_contracts()].
|
||||
|
||||
parse_args(Fun, Args) ->
|
||||
[{contract, _, _, [{letfun, _, _, _, _, {app, _, _, AST}}]}] =
|
||||
aeso_parser:string("contract Temp = function foo() = " ++ Fun ++ "(" ++ string:join(Args, ", ") ++ ")"),
|
||||
[{contract_main, _, _, [{letfun, _, _, _, _, {app, _, _, AST}}]}] =
|
||||
aeso_parser:string("main contract Temp = function foo() = " ++ Fun ++ "(" ++ string:join(Args, ", ") ++ ")"),
|
||||
strip_ann(AST).
|
||||
|
||||
strip_ann(T) when is_tuple(T) ->
|
||||
|
||||
@@ -34,9 +34,7 @@ simple_compile_test_() ->
|
||||
#{fate_code := Code} when Backend == fate ->
|
||||
Code1 = aeb_fate_code:deserialize(aeb_fate_code:serialize(Code)),
|
||||
?assertMatch({X, X}, {Code1, Code});
|
||||
ErrBin ->
|
||||
io:format("\n~s", [ErrBin]),
|
||||
error(ErrBin)
|
||||
Error -> io:format("\n\n~p\n\n", [Error]), print_and_throw(Error)
|
||||
end
|
||||
end} || ContractName <- compilable_contracts(), Backend <- [aevm, fate],
|
||||
not lists:member(ContractName, not_compilable_on(Backend))] ++
|
||||
@@ -179,17 +177,16 @@ compilable_contracts() ->
|
||||
"lhs_matching",
|
||||
"more_strings",
|
||||
"protected_call",
|
||||
"hermetization_turnoff"
|
||||
"hermetization_turnoff",
|
||||
"multiple_contracts",
|
||||
"clone",
|
||||
"clone_simple",
|
||||
"create",
|
||||
"test" % Custom general-purpose test file. Keep it last on the list.
|
||||
].
|
||||
|
||||
not_compilable_on(fate) -> [];
|
||||
not_compilable_on(aevm) ->
|
||||
[ "stdlib_include", "manual_stdlib_include", "pairing_crypto"
|
||||
, "aens_update", "basic_auth_tx", "more_strings"
|
||||
, "unapplied_builtins", "bytes_to_x", "state_handling", "protected_call"
|
||||
, "hermetization_turnoff"
|
||||
|
||||
].
|
||||
not_compilable_on(aevm) -> compilable_contracts().
|
||||
|
||||
debug_mode_contracts() ->
|
||||
["hermetization_turnoff"].
|
||||
@@ -635,9 +632,9 @@ failing_contracts() ->
|
||||
<<?Pos(2, 1)
|
||||
"Cannot compile with this version of the compiler,\n"
|
||||
"because it does not satisfy the constraint ", Version/binary, " == 9.9.9">>])
|
||||
, ?TYPE_ERROR(multiple_contracts,
|
||||
, ?TYPE_ERROR(interface_with_defs,
|
||||
[<<?Pos(2, 3)
|
||||
"Only the main contract can contain defined functions or entrypoints.\n"
|
||||
"Contract interfaces cannot contain defined functions or entrypoints.\n"
|
||||
"Fix: replace the definition of 'foo' by a type signature.">>])
|
||||
, ?TYPE_ERROR(contract_as_namespace,
|
||||
[<<?Pos(5, 28)
|
||||
@@ -733,6 +730,39 @@ failing_contracts() ->
|
||||
, ?TYPE_ERROR(bad_state,
|
||||
[<<?Pos(4, 16)
|
||||
"Conflicting updates for field 'foo'">>])
|
||||
, ?TYPE_ERROR(factories_type_errors,
|
||||
[<<?Pos(10,18)
|
||||
"Chain.clone requires `ref` named argument of contract type.">>,
|
||||
<<?Pos(11,18)
|
||||
"Cannot unify (gas : int, value : int, protected : bool) => if(protected, option(void), void)\n and (gas : int, value : int, protected : bool, int, bool) => 'b\n"
|
||||
"when checking contract construction of type\n (gas : int, value : int, protected : bool) =>\n if(protected, option(void), void) (at line 11, column 18)\nagainst the expected type\n (gas : int, value : int, protected : bool, int, bool) => 'b">>,
|
||||
<<?Pos(12,37)
|
||||
"Cannot unify int\n and bool\n"
|
||||
"when checking named argument\n gas : int\nagainst inferred type\n bool">>,
|
||||
<<?Pos(13,18),
|
||||
"Kaboom is not implemented.\n"
|
||||
"when resolving arguments of variadic function\n Chain.create">>,
|
||||
<<?Pos(18,18)
|
||||
"Cannot unify (gas : int, value : int, protected : bool, int, bool) => if(protected, option(void), void)\n and (gas : int, value : int, protected : bool) => 'a\n"
|
||||
"when checking contract construction of type\n (gas : int, value : int, protected : bool, int, bool) =>\n if(protected, option(void), void) (at line 18, column 18)\nagainst the expected type\n (gas : int, value : int, protected : bool) => 'a">>,
|
||||
<<?Pos(19,42),
|
||||
"Named argument protected (at line 19, column 42) is not one of the expected named arguments\n - value : int">>,
|
||||
<<?Pos(20,42),
|
||||
"Cannot unify int\n and bool\n"
|
||||
"when checking named argument\n value : int\nagainst inferred type\n bool">>
|
||||
])
|
||||
, ?TYPE_ERROR(ambiguous_main,
|
||||
[<<?Pos(1,1)
|
||||
"Could not deduce the main contract. You can point it out manually with the `main` keyword.">>
|
||||
])
|
||||
, ?TYPE_ERROR(no_main_contract,
|
||||
[<<?Pos(0,0)
|
||||
"No contract defined.">>
|
||||
])
|
||||
, ?TYPE_ERROR(multiple_main_contracts,
|
||||
[<<?Pos(1,6)
|
||||
"Only one main contract can be defined.">>
|
||||
])
|
||||
].
|
||||
|
||||
-define(Path(File), "code_errors/" ??File).
|
||||
@@ -746,9 +776,7 @@ failing_contracts() ->
|
||||
{fate, ?Msg(File, Line, Col, ErrFATE)}]}).
|
||||
|
||||
failing_code_gen_contracts() ->
|
||||
[ ?SAME(last_declaration_must_be_contract, 1, 1,
|
||||
"Expected a contract as the last declaration instead of the namespace 'LastDeclarationIsNotAContract'")
|
||||
, ?SAME(missing_definition, 2, 14,
|
||||
[ ?SAME(missing_definition, 2, 14,
|
||||
"Missing definition of function 'foo'.")
|
||||
, ?AEVM(polymorphic_entrypoint, 2, 17,
|
||||
"The argument\n"
|
||||
@@ -846,6 +874,8 @@ failing_code_gen_contracts() ->
|
||||
"Invalid state type\n"
|
||||
" {f : (int) => int}\n"
|
||||
"The state cannot contain functions in the AEVM. Use FATE if you need this.")
|
||||
, ?FATE(child_with_decls, 2, 14,
|
||||
"Missing definition of function 'f'.")
|
||||
].
|
||||
|
||||
validation_test_() ->
|
||||
@@ -883,14 +913,26 @@ validation_fails() ->
|
||||
"Byte code contract is not payable, but source code contract is.">>]}].
|
||||
|
||||
validate(Contract1, Contract2) ->
|
||||
ByteCode = #{ fate_code := FCode } = compile(fate, Contract1),
|
||||
FCode1 = aeb_fate_code:serialize(aeb_fate_code:strip_init_function(FCode)),
|
||||
Source = aeso_test_utils:read_contract(Contract2),
|
||||
aeso_compiler:validate_byte_code(
|
||||
ByteCode#{ byte_code := FCode1 }, Source,
|
||||
case lists:member(Contract2, debug_mode_contracts()) of
|
||||
true -> [debug_mode];
|
||||
false -> []
|
||||
end ++
|
||||
[{backend, fate}, {include, {file_system, [aeso_test_utils:contract_path()]}}]).
|
||||
case compile(fate, Contract1) of
|
||||
ByteCode = #{ fate_code := FCode } ->
|
||||
FCode1 = aeb_fate_code:serialize(aeb_fate_code:strip_init_function(FCode)),
|
||||
Source = aeso_test_utils:read_contract(Contract2),
|
||||
aeso_compiler:validate_byte_code(
|
||||
ByteCode#{ byte_code := FCode1 }, Source,
|
||||
case lists:member(Contract2, debug_mode_contracts()) of
|
||||
true -> [debug_mode];
|
||||
false -> []
|
||||
end ++
|
||||
[{backend, fate}, {include, {file_system, [aeso_test_utils:contract_path()]}}]);
|
||||
Error -> print_and_throw(Error)
|
||||
end.
|
||||
|
||||
print_and_throw(Err) ->
|
||||
case Err of
|
||||
ErrBin when is_binary(ErrBin) ->
|
||||
io:format("\n~s", [ErrBin]),
|
||||
error(ErrBin);
|
||||
Errors ->
|
||||
io:format("Compilation error:\n~s", [string:join([aeso_errors:pp(E) || E <- Errors], "\n\n")]),
|
||||
error(compilation_error)
|
||||
end.
|
||||
|
||||
@@ -12,10 +12,10 @@ simple_contracts_test_() ->
|
||||
fun(_) -> ok end,
|
||||
[{"Parse a contract with an identity function.",
|
||||
fun() ->
|
||||
Text = "contract Identity =\n"
|
||||
Text = "main contract Identity =\n"
|
||||
" function id(x) = x\n",
|
||||
?assertMatch(
|
||||
[{contract, _, {con, _, "Identity"},
|
||||
[{contract_main, _, {con, _, "Identity"},
|
||||
[{letfun, _, {id, _, "id"}, [{id, _, "x"}], {id, _, "_"},
|
||||
{id, _, "x"}}]}], parse_string(Text)),
|
||||
ok
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract Identity =
|
||||
function main (x:int) = x
|
||||
function main_fun (x:int) = x
|
||||
|
||||
function __call() = 12
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
contract Remote =
|
||||
entrypoint main : (int) => unit
|
||||
contract interface Remote =
|
||||
entrypoint main_fun : (int) => unit
|
||||
|
||||
contract AddrChain =
|
||||
type o_type = oracle(string, map(string, int))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint foo : () => unit
|
||||
|
||||
contract AddressLiterals =
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
contract C =
|
||||
entrypoint f() = 123
|
||||
|
||||
contract D =
|
||||
entrypoint f() = 123
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint foo : () => unit
|
||||
|
||||
contract AddressLiterals =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint id : int => int
|
||||
|
||||
contract ProtectedCall =
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
function square(x) = x ^ 2
|
||||
contract Main =
|
||||
entrypoint main() = square(10)
|
||||
entrypoint main_fun() = square(10)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
contract interface HigherOrderState =
|
||||
entrypoint init : () => void
|
||||
entrypoint apply : int => int
|
||||
stateful entrypoint inc : int => unit
|
||||
|
||||
contract interface LowerDisorderAnarchy =
|
||||
entrypoint init : (int) => void
|
||||
|
||||
|
||||
main contract C =
|
||||
// both `s` and `l` should be of type `HigherOrderState` in this test
|
||||
stateful entrypoint run_clone(s : HigherOrderState, l : LowerDisorderAnarchy) : HigherOrderState =
|
||||
let s1 = Chain.clone(ref=s)
|
||||
let Some(s2) = Chain.clone(ref=s, protected=true)
|
||||
let None = Chain.clone(ref=s, protected=true, gas=1)
|
||||
let None = Chain.clone(ref=l, protected=true, 123) // since it should be HigherOrderState underneath
|
||||
let s3 = Chain.clone(ref=s1)
|
||||
require(s1.apply(2137) == 2137, "APPLY_S1_0")
|
||||
require(s2.apply(2137) == 2137, "APPLY_S2_0")
|
||||
require(s3.apply(2137) == 2137, "APPLY_S3_0")
|
||||
s1.inc(1)
|
||||
s2.inc(1)
|
||||
s1.inc(1)
|
||||
require(s1.apply(2137) == 2139, "APPLY_S1_2")
|
||||
require(s2.apply(2137) == 2138, "APPLY_S2_1")
|
||||
require(s3.apply(2137) == 2137, "APPLY_S3_0")
|
||||
s1
|
||||
@@ -0,0 +1,7 @@
|
||||
contract interface I =
|
||||
entrypoint init : () => void
|
||||
|
||||
contract C =
|
||||
stateful entrypoint f(i : I) =
|
||||
let Some(c1) = Chain.clone(ref=i, protected = true)
|
||||
2
|
||||
@@ -5,5 +5,5 @@ contract BadAENSresolve =
|
||||
function fail() : t(int) =
|
||||
AENS.resolve("foo.aet", "whatever")
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
contract C =
|
||||
entrypoint f : () => unit
|
||||
|
||||
main contract M =
|
||||
entrypoint f() = 123
|
||||
@@ -3,4 +3,4 @@ contract MapAsMapKey =
|
||||
|
||||
function foo(m) : t(int => int) = {[m] = 0}
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
@@ -2,4 +2,4 @@ contract HigherOrderQueryType =
|
||||
stateful function foo(o) : oracle_query(_, string ) =
|
||||
Oracle.query(o, (x) => x + 1, 100, RelativeTTL(100), RelativeTTL(100))
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
@@ -2,4 +2,4 @@ contract HigherOrderResponseType =
|
||||
stateful function foo(o, q : oracle_query(string, _)) =
|
||||
Oracle.respond(o, q, (x) => x + 1)
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
namespace LastDeclarationIsNotAContract =
|
||||
function add(x, y) = x + y
|
||||
@@ -1,3 +1,3 @@
|
||||
contract MissingDefinition =
|
||||
entrypoint foo : int => int
|
||||
entrypoint main() = foo(0)
|
||||
entrypoint main_fun() = foo(0)
|
||||
|
||||
@@ -3,5 +3,5 @@ contract PolymorphicAENSresolve =
|
||||
function fail() : option('a) =
|
||||
AENS.resolve("foo.aet", "whatever")
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ contract MapAsMapKey =
|
||||
|
||||
function foo(m) : t('a) = {[m] = 0}
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
@@ -2,4 +2,4 @@ contract PolymorphicQueryType =
|
||||
stateful function is_oracle(o) =
|
||||
Oracle.check(o)
|
||||
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
|
||||
@@ -2,4 +2,4 @@ contract PolymorphicResponseType =
|
||||
function is_oracle(o : oracle(string, 'r)) =
|
||||
Oracle.check(o)
|
||||
|
||||
entrypoint main(o : oracle(string, int)) = is_oracle(o)
|
||||
entrypoint main_fun(o : oracle(string, int)) = is_oracle(o)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint foo : int => int
|
||||
|
||||
contract UnappliedContractCall =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
contract UnappliedNamedArgBuiltin =
|
||||
// Allowed in FATE, but not AEVM
|
||||
stateful entrypoint main(s) =
|
||||
stateful entrypoint main_fun(s) =
|
||||
let reg = Oracle.register
|
||||
reg(signature = s, Contract.address, 100, RelativeTTL(100)) : oracle(int, int)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint up_to : (int) => list(int)
|
||||
entrypoint sum : (list(int)) => int
|
||||
entrypoint some_string : () => string
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
contract Foo =
|
||||
contract interface Foo =
|
||||
entrypoint foo : () => int
|
||||
|
||||
contract Fail =
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
contract IntegerAdder =
|
||||
entrypoint init() = ()
|
||||
entrypoint addIntegers(x, y) = x + y
|
||||
|
||||
contract IntegerAdderHolder =
|
||||
type state = IntegerAdder
|
||||
stateful entrypoint init() = Chain.create() : IntegerAdder
|
||||
entrypoint get() = state
|
||||
|
||||
contract IntegerAdderFactory =
|
||||
entrypoint init() = ()
|
||||
stateful entrypoint new() =
|
||||
let i = Chain.create() : IntegerAdderHolder
|
||||
i.get()
|
||||
|
||||
payable contract ValueAdder =
|
||||
entrypoint init() = ()
|
||||
stateful entrypoint addValue(x) =
|
||||
let integerAdderFactory = Chain.create()
|
||||
let adder = integerAdderFactory.new()
|
||||
adder.addIntegers(x, Contract.balance)
|
||||
|
||||
main contract EnterpriseContract =
|
||||
entrypoint init() = ()
|
||||
stateful payable entrypoint increaseByThree(x) =
|
||||
require(Call.value >= 3, "Price for addition = 3AEtto, insufficient funds")
|
||||
let threeAdder = Chain.create(value = 3)
|
||||
threeAdder.addValue(x)
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
// Testing primitives for accessing the block chain environment
|
||||
contract Interface =
|
||||
contract interface Interface =
|
||||
entrypoint contract_address : () => address
|
||||
entrypoint call_origin : () => address
|
||||
entrypoint call_caller : () => address
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint dummy : () => unit
|
||||
|
||||
contract Events =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// An implementation of the factorial function where each recursive
|
||||
// call is to another contract. Not the cheapest way to compute factorial.
|
||||
contract FactorialServer =
|
||||
contract interface FactorialServer =
|
||||
entrypoint fac : (int) => int
|
||||
|
||||
contract Factorial =
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
contract interface Kaboom =
|
||||
entrypoint init : () => void
|
||||
|
||||
contract Bakoom =
|
||||
type state = int
|
||||
entrypoint init(x, b) = if(b) x else 0
|
||||
|
||||
main contract Test =
|
||||
stateful entrypoint test(k : Kaboom) =
|
||||
let k_bad1 = Chain.clone() : Kaboom
|
||||
let k_bad2 = Chain.clone(ref=k, 123, true)
|
||||
let k_bad3 = Chain.clone(ref=k, gas=true)
|
||||
let k_bad4 = Chain.create() : Kaboom
|
||||
let k_gud1 = Chain.clone(ref=k)
|
||||
let Some(k_gud2) = Chain.clone(ref=k, protected=true)
|
||||
let Some(k_gud3) = Chain.clone(ref=k, value=10, protected=true, gas=123)
|
||||
|
||||
let b_bad1 = Chain.create() : Bakoom
|
||||
let b_bad2 = Chain.create(123, true, protected=true) : Bakoom
|
||||
let b_bad3 = Chain.create(123, true, value=true) : Bakoom
|
||||
let b_gud1 = Chain.create(123, true) : Bakoom
|
||||
let b_gud2 = Chain.create(123, true, value=100) : Bakoom
|
||||
|
||||
b_gud1
|
||||
@@ -1,3 +1,2 @@
|
||||
|
||||
contract Identity =
|
||||
entrypoint main (x:int) = x
|
||||
main contract Identity =
|
||||
entrypoint main_fun (x:int) = x
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
contract interface ContractOne =
|
||||
entrypoint foo() = "foo"
|
||||
|
||||
contract ContractTwo =
|
||||
entrypoint bar() = "bar"
|
||||
@@ -16,7 +16,7 @@ contract LHSMatching =
|
||||
let null(_ :: _) = false
|
||||
!null(xs)
|
||||
|
||||
entrypoint main() =
|
||||
entrypoint main_fun() =
|
||||
from_some(Some([0]))
|
||||
++ append([length([true]), 2, 3], [4, 5, 6])
|
||||
++ [7 | if (local_match([false]))]
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
contract MissingEventType =
|
||||
entrypoint main() =
|
||||
entrypoint main_fun() =
|
||||
Chain.event("MAIN")
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
contract ContractOne =
|
||||
entrypoint foo() = "foo"
|
||||
contract Child =
|
||||
entrypoint
|
||||
add2 : int => int
|
||||
add2(x) = x + 2
|
||||
|
||||
contract ContractTwo =
|
||||
entrypoint bar() = "bar"
|
||||
main contract Main =
|
||||
entrypoint add4(x, c : Child) = c.add2(x) + 2
|
||||
@@ -0,0 +1,5 @@
|
||||
main contract C =
|
||||
entrypoint f() = 123
|
||||
|
||||
main contract D =
|
||||
entrypoint f() = 123
|
||||
@@ -0,0 +1,2 @@
|
||||
contract interface C =
|
||||
entrypoint f : () => unit
|
||||
@@ -1,4 +1,4 @@
|
||||
contract C1 =
|
||||
contract interface C1 =
|
||||
entrypoint f : int
|
||||
|
||||
contract C =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
entrypoint id : int => int
|
||||
|
||||
contract ProtectedCall =
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
|
||||
contract Remote1 =
|
||||
entrypoint main : (int) => int
|
||||
contract interface Remote1 =
|
||||
entrypoint main_fun : (int) => int
|
||||
|
||||
contract Remote2 =
|
||||
contract interface Remote2 =
|
||||
entrypoint call : (Remote1, int) => int
|
||||
|
||||
contract Remote3 =
|
||||
contract interface Remote3 =
|
||||
entrypoint get : () => int
|
||||
entrypoint tick : () => unit
|
||||
|
||||
contract RemoteCall =
|
||||
|
||||
stateful entrypoint call(r : Remote1, x : int) : int =
|
||||
r.main(gas = 10000, value = 10, x)
|
||||
r.main_fun(gas = 10000, value = 10, x)
|
||||
|
||||
entrypoint staged_call(r1 : Remote1, r2 : Remote2, x : int) =
|
||||
r2.call(r1, x)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract SpendContract =
|
||||
contract interface SpendContract =
|
||||
entrypoint withdraw : (int) => int
|
||||
|
||||
contract SpendTest =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "String.aes"
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
record rstate = { i : int, s : string, m : map(int, int) }
|
||||
|
||||
entrypoint look_at : (rstate) => unit
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
stateful entrypoint remote_spend : (address, int) => unit
|
||||
entrypoint remote_pure : int => int
|
||||
|
||||
|
||||
+9
-99
@@ -1,102 +1,12 @@
|
||||
// This is a custom test file if you need to run a compiler without
|
||||
// changing aeso_compiler_tests.erl
|
||||
|
||||
contract Identity =
|
||||
// type xy = {x:int, y:int}
|
||||
// type xz = {x:int, z:int}
|
||||
// type yz = {y:int, z:int}
|
||||
record point = {x:int,y:int}
|
||||
record cp('a) = {color: string, p:'a}
|
||||
//type intpoint = point(int)
|
||||
// //if (x==42) 1 else (x*x)
|
||||
// }
|
||||
//let baz() = {age:3, name:(4:int)}
|
||||
//let foo(a,b,c) = c
|
||||
// let rec fac(n) = if((n:int)==0) 1 else (n*fac(n-1))
|
||||
// and main(x) = x::[x+1]
|
||||
// let lentr(l) = lent(0,l)
|
||||
// let rec len(l) =
|
||||
// switch(l) {
|
||||
// | [] => 0
|
||||
// | x::xs => 1+len(xs)
|
||||
// }
|
||||
// let lent(n,l) =
|
||||
// switch (l) {
|
||||
// | [] => n
|
||||
// | (x::xs) => lent(n+1,xs)
|
||||
// }
|
||||
// let rec app(a,b) =
|
||||
// switch(a) {
|
||||
// | [] => b
|
||||
// | (x::xs) => x::app(xs,b)
|
||||
// }
|
||||
// let rec revt(l,r) =
|
||||
// switch(l) {
|
||||
// | [] => r
|
||||
// | x::xs => revt(xs,x::r)
|
||||
// }
|
||||
// let rev(l) = revt(l,[])
|
||||
// let main(x:int) = {
|
||||
// switch(rev([1,2,3])) {
|
||||
// | h::_ => h
|
||||
// }
|
||||
// }
|
||||
//let fac(n:int) = {
|
||||
// if (n==0) 1 else (n*fac(n-1))
|
||||
//}
|
||||
//let main(x) = switch((12,34)) {
|
||||
//| (13,_) => x
|
||||
//| (_,a) => x+a
|
||||
// | y => y+1
|
||||
// }
|
||||
//let main(x) = ({y:0>1, x:x==0}:point(bool))
|
||||
//let main(x) = x
|
||||
//let main(x) = len(1::2::[])
|
||||
//let main(x) = ((x,x):list('a))
|
||||
// let main(x) = switch("a") {
|
||||
// | "b" => 0
|
||||
// | "a" => 1
|
||||
// | "c" => 2
|
||||
// }
|
||||
//let main(x) = x.color+1
|
||||
//let main(x) = switch(({x:x, y:x+1}:cp(int))) {
|
||||
// | {y:xx} => xx
|
||||
// }
|
||||
//let main(x) = {x:0, y:1, z:2}
|
||||
// let id(x) = x
|
||||
// let double(x) = x+x
|
||||
// let pair(x) = (1,2)
|
||||
// let unit(x) = ()
|
||||
// let tuples(x) = ((1,x),(2,3,4))
|
||||
// let singleton(x) = [x]
|
||||
// let rec seq(n) = if (n==0) [] else (app(seq(n-1),[n]))
|
||||
// let idString(s:string) = s
|
||||
// let pairString(s:string) = (s,s)
|
||||
// let revStrings(ss:list(string))=rev(ss)
|
||||
// let makePoint(x,y) = {x:x, y:y}
|
||||
// let getx(x) = x.x
|
||||
// let updatex(p,x) = p{x:x}
|
||||
// let quad(x) = {let y=x+x; let z=y+y; z;}
|
||||
// let noblock(x) = {x; x}
|
||||
// let unit(x) = ()
|
||||
// let foo(x) = switch (x) {
|
||||
// | y => y+1
|
||||
// }
|
||||
// let p(x) = {color:"blue", p:{x:x, y:x+1}}
|
||||
//let twice(f,x) = f(f(x))
|
||||
// let twice(f,x) = f(f(x))
|
||||
// let double(x) = x+x
|
||||
// let main(x) = twice((y=>y+y),x)
|
||||
// let rec map(f,xs) = switch(xs) {
|
||||
// | [] => []
|
||||
// | (x::ys) => f(x)::map(f,ys)
|
||||
// }
|
||||
// let id(x) = x
|
||||
// let main(xs) = map(double,xs)
|
||||
function z(f,x) = x
|
||||
function s(n) = (f,x)=>f(n(f,x))
|
||||
function add(m,n) = (f,x)=>m(f,n(f,x))
|
||||
include "List.aes"
|
||||
|
||||
entrypoint main() =
|
||||
let three=s(s(s(z)))
|
||||
add(three,three)
|
||||
(((i)=>i+1),0)
|
||||
contract IntegerHolder =
|
||||
type state = int
|
||||
entrypoint init(x) = x
|
||||
entrypoint get() = state
|
||||
|
||||
main contract Test =
|
||||
stateful entrypoint f(c) = Chain.clone(ref=c, 123)
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
contract Remote =
|
||||
contract interface Remote =
|
||||
|
||||
type themap = map(int, string)
|
||||
entrypoint foo : () => themap
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// Oracle.extend
|
||||
include "String.aes"
|
||||
contract UnappliedBuiltins =
|
||||
entrypoint main() = ()
|
||||
entrypoint main_fun() = ()
|
||||
type o = oracle(int, int)
|
||||
type t = list(int * string)
|
||||
type m = map(int, int)
|
||||
|
||||
Reference in New Issue
Block a user