Add signature literals (#505)
* Add signature literals + handle system alias types * Add tests for signature literals + encode/decode * Add to CHANGELOG * Add in documentation * Additional documentation
This commit is contained in:
parent
31301911a2
commit
51bae61736
@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
- Support for OTP-27 - no changes in behavior.
|
- Support for OTP-27 - no changes in behavior.
|
||||||
|
- Signature literals `sg_...` - they have type `signature` (which is an alias for `bytes(64)`).
|
||||||
### Changed
|
### Changed
|
||||||
|
- System aliases are handled explicitly when converting to a Sophia value, this is only
|
||||||
|
observable for `signature` where a value of type `signature` is now represented as a
|
||||||
|
(new) signature literal.
|
||||||
### Removed
|
### Removed
|
||||||
### Fixed
|
### Fixed
|
||||||
- Allow self-qualification, i.e. referencing `X.foo` when in namespace `X`.
|
- Allow self-qualification, i.e. referencing `X.foo` when in namespace `X`.
|
||||||
|
@ -573,7 +573,7 @@ Sophia has the following types:
|
|||||||
| state | `state{ owner = Call.origin, magic_key = #a298105f }` |
|
| state | `state{ owner = Call.origin, magic_key = #a298105f }` |
|
||||||
| event | `EventX(0, "Hello")` |
|
| event | `EventX(0, "Hello")` |
|
||||||
| hash | `#000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f` |
|
| hash | `#000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f` |
|
||||||
| signature | `#000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f` |
|
| signature | `sg_MhibzTP1wWzGCTjtPFr1TiPqRJrrJqw7auvEuF5i3FdoALWqXLBDY6xxRRNUSPHK3EQTnTzF12EyspkxrSMxVHKsZeSMj`, `#000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f` |
|
||||||
| Chain.ttl | `FixedTTL(1050)`, `RelativeTTL(50)` |
|
| Chain.ttl | `FixedTTL(1050)`, `RelativeTTL(50)` |
|
||||||
| oracle('a, 'b) | `ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5` |
|
| oracle('a, 'b) | `ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5` |
|
||||||
| oracle_query('a, 'b) | `oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY` |
|
| oracle_query('a, 'b) | `oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY` |
|
||||||
|
@ -30,6 +30,7 @@ interface main using as for hiding
|
|||||||
- `ContractAddress` base58-encoded 32 byte contract address with `ct_` prefix
|
- `ContractAddress` base58-encoded 32 byte contract address with `ct_` prefix
|
||||||
- `OracleAddress` base58-encoded 32 byte oracle address with `ok_` prefix
|
- `OracleAddress` base58-encoded 32 byte oracle address with `ok_` prefix
|
||||||
- `OracleQueryId` base58-encoded 32 byte oracle query id with `oq_` prefix
|
- `OracleQueryId` base58-encoded 32 byte oracle query id with `oq_` prefix
|
||||||
|
- `Signature` base58-encoded 64 byte cryptographic signature with `sg_` prefix
|
||||||
|
|
||||||
Valid string escape codes are
|
Valid string escape codes are
|
||||||
|
|
||||||
@ -239,6 +240,7 @@ Expr ::= '(' LamArgs ')' '=>' Block(Stmt) // Anonymous function (x) => x +
|
|||||||
| Int | Bytes | String | Char // Literals 123, 0xff, #00abc123, "foo", '%'
|
| Int | Bytes | String | Char // Literals 123, 0xff, #00abc123, "foo", '%'
|
||||||
| AccountAddress | ContractAddress // Chain identifiers
|
| AccountAddress | ContractAddress // Chain identifiers
|
||||||
| OracleAddress | OracleQueryId // Chain identifiers
|
| OracleAddress | OracleQueryId // Chain identifiers
|
||||||
|
| Signature // Signature
|
||||||
| '???' // Hole expression 1 + ???
|
| '???' // Hole expression 1 + ???
|
||||||
|
|
||||||
Generator ::= Pattern '<-' Expr // Generator
|
Generator ::= Pattern '<-' Expr // Generator
|
||||||
|
@ -198,7 +198,8 @@ encode_expr({bytes, _, B}) ->
|
|||||||
<<N:Digits/unit:8>> = B,
|
<<N:Digits/unit:8>> = B,
|
||||||
list_to_binary(lists:flatten(io_lib:format("#~*.16.0b", [Digits*2, N])));
|
list_to_binary(lists:flatten(io_lib:format("#~*.16.0b", [Digits*2, N])));
|
||||||
encode_expr({Lit, _, L}) when Lit == oracle_pubkey; Lit == oracle_query_id;
|
encode_expr({Lit, _, L}) when Lit == oracle_pubkey; Lit == oracle_query_id;
|
||||||
Lit == contract_pubkey; Lit == account_pubkey ->
|
Lit == contract_pubkey; Lit == account_pubkey;
|
||||||
|
Lit == signature ->
|
||||||
aeser_api_encoder:encode(Lit, L);
|
aeser_api_encoder:encode(Lit, L);
|
||||||
encode_expr({app, _, {'-', _}, [{int, _, N}]}) ->
|
encode_expr({app, _, {'-', _}, [{int, _, N}]}) ->
|
||||||
encode_expr({int, [], -N});
|
encode_expr({int, [], -N});
|
||||||
|
@ -1935,6 +1935,8 @@ infer_expr(_Env, Body={bytes, As, Bin}) ->
|
|||||||
{typed, As, Body, {bytes_t, As, byte_size(Bin)}};
|
{typed, As, Body, {bytes_t, As, byte_size(Bin)}};
|
||||||
infer_expr(_Env, Body={account_pubkey, As, _}) ->
|
infer_expr(_Env, Body={account_pubkey, As, _}) ->
|
||||||
{typed, As, Body, {id, As, "address"}};
|
{typed, As, Body, {id, As, "address"}};
|
||||||
|
infer_expr(_Env, Body={signature, As, Bin}) when byte_size(Bin) == 64 ->
|
||||||
|
{typed, As, Body, {bytes_t, As, 64}};
|
||||||
infer_expr(_Env, Body={oracle_pubkey, As, _}) ->
|
infer_expr(_Env, Body={oracle_pubkey, As, _}) ->
|
||||||
Q = fresh_uvar(As),
|
Q = fresh_uvar(As),
|
||||||
R = fresh_uvar(As),
|
R = fresh_uvar(As),
|
||||||
@ -2173,6 +2175,8 @@ check_valid_const_expr({bytes, _, _}) ->
|
|||||||
true;
|
true;
|
||||||
check_valid_const_expr({account_pubkey, _, _}) ->
|
check_valid_const_expr({account_pubkey, _, _}) ->
|
||||||
true;
|
true;
|
||||||
|
check_valid_const_expr({signature, _, _}) ->
|
||||||
|
true;
|
||||||
check_valid_const_expr({oracle_pubkey, _, _}) ->
|
check_valid_const_expr({oracle_pubkey, _, _}) ->
|
||||||
true;
|
true;
|
||||||
check_valid_const_expr({oracle_query_id, _, _}) ->
|
check_valid_const_expr({oracle_query_id, _, _}) ->
|
||||||
@ -3060,7 +3064,8 @@ unfold_types_in_type(Env, {app_t, Ann, Id, Args}, Options) when ?is_type_id(Id)
|
|||||||
unfold_types_in_type(Env, Id, Options) when ?is_type_id(Id) ->
|
unfold_types_in_type(Env, Id, Options) when ?is_type_id(Id) ->
|
||||||
%% Like the case above, but for types without parameters.
|
%% Like the case above, but for types without parameters.
|
||||||
when_warning(warn_unused_typedefs, fun() -> used_typedef(Id, 0) end),
|
when_warning(warn_unused_typedefs, fun() -> used_typedef(Id, 0) end),
|
||||||
UnfoldRecords = proplists:get_value(unfold_record_types, Options, false),
|
UnfoldSysAlias = not proplists:get_value(not_unfold_system_alias_types, Options, false),
|
||||||
|
UnfoldRecords = proplists:get_value(unfold_record_types, Options, false),
|
||||||
UnfoldVariants = proplists:get_value(unfold_variant_types, Options, false),
|
UnfoldVariants = proplists:get_value(unfold_variant_types, Options, false),
|
||||||
case lookup_type(Env, Id) of
|
case lookup_type(Env, Id) of
|
||||||
{_, {_, {[], {record_t, Fields}}}} when UnfoldRecords ->
|
{_, {_, {[], {record_t, Fields}}}} when UnfoldRecords ->
|
||||||
@ -3068,7 +3073,12 @@ unfold_types_in_type(Env, Id, Options) when ?is_type_id(Id) ->
|
|||||||
{_, {_, {[], {variant_t, Constrs}}}} when UnfoldVariants ->
|
{_, {_, {[], {variant_t, Constrs}}}} when UnfoldVariants ->
|
||||||
{variant_t, unfold_types_in_type(Env, Constrs, Options)};
|
{variant_t, unfold_types_in_type(Env, Constrs, Options)};
|
||||||
{_, {_, {[], {alias_t, Type1}}}} ->
|
{_, {_, {[], {alias_t, Type1}}}} ->
|
||||||
unfold_types_in_type(Env, Type1, Options);
|
case aeso_syntax:get_ann(Type1) of
|
||||||
|
[{origin, system}] when not UnfoldSysAlias ->
|
||||||
|
Id;
|
||||||
|
_ ->
|
||||||
|
unfold_types_in_type(Env, Type1, Options)
|
||||||
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
%% Not a record type, or ill-formed record type
|
%% Not a record type, or ill-formed record type
|
||||||
Id
|
Id
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
| {contract_pubkey, binary()}
|
| {contract_pubkey, binary()}
|
||||||
| {oracle_pubkey, binary()}
|
| {oracle_pubkey, binary()}
|
||||||
| {oracle_query_id, binary()}
|
| {oracle_query_id, binary()}
|
||||||
|
| {signature, binary()}
|
||||||
| {bool, false | true}
|
| {bool, false | true}
|
||||||
| {contract_code, string()} %% for CREATE, by name
|
| {contract_code, string()} %% for CREATE, by name
|
||||||
| {typerep, ftype()}.
|
| {typerep, ftype()}.
|
||||||
@ -599,6 +600,7 @@ expr_to_fcode(_Env, _Type, {char, Ann, N}) -> {lit, to_fann(Ann), {in
|
|||||||
expr_to_fcode(_Env, _Type, {bool, Ann, B}) -> {lit, to_fann(Ann), {bool, B}};
|
expr_to_fcode(_Env, _Type, {bool, Ann, B}) -> {lit, to_fann(Ann), {bool, B}};
|
||||||
expr_to_fcode(_Env, _Type, {string, Ann, S}) -> {lit, to_fann(Ann), {string, S}};
|
expr_to_fcode(_Env, _Type, {string, Ann, S}) -> {lit, to_fann(Ann), {string, S}};
|
||||||
expr_to_fcode(_Env, _Type, {account_pubkey, Ann, K}) -> {lit, to_fann(Ann), {account_pubkey, K}};
|
expr_to_fcode(_Env, _Type, {account_pubkey, Ann, K}) -> {lit, to_fann(Ann), {account_pubkey, K}};
|
||||||
|
expr_to_fcode(_Env, _Type, {signature, Ann, K}) -> {lit, to_fann(Ann), {signature, K}};
|
||||||
expr_to_fcode(_Env, _Type, {contract_pubkey, Ann, K}) -> {lit, to_fann(Ann), {contract_pubkey, K}};
|
expr_to_fcode(_Env, _Type, {contract_pubkey, Ann, K}) -> {lit, to_fann(Ann), {contract_pubkey, K}};
|
||||||
expr_to_fcode(_Env, _Type, {oracle_pubkey, Ann, K}) -> {lit, to_fann(Ann), {oracle_pubkey, K}};
|
expr_to_fcode(_Env, _Type, {oracle_pubkey, Ann, K}) -> {lit, to_fann(Ann), {oracle_pubkey, K}};
|
||||||
expr_to_fcode(_Env, _Type, {oracle_query_id, Ann, K}) -> {lit, to_fann(Ann), {oracle_query_id, K}};
|
expr_to_fcode(_Env, _Type, {oracle_query_id, Ann, K}) -> {lit, to_fann(Ann), {oracle_query_id, K}};
|
||||||
|
@ -228,10 +228,13 @@ encode_value(Contract0, Type, Value, Options) ->
|
|||||||
decode_value(Contract0, Type, FateValue, Options) ->
|
decode_value(Contract0, Type, FateValue, Options) ->
|
||||||
case add_extra_call(Contract0, {type, Type}, Options) of
|
case add_extra_call(Contract0, {type, Type}, Options) of
|
||||||
{ok, CallName, Code} ->
|
{ok, CallName, Code} ->
|
||||||
#{ unfolded_typed_ast := TypedAst
|
#{ folded_typed_ast := TypedAst
|
||||||
, type_env := TypeEnv} = Code,
|
, type_env := TypeEnv} = Code,
|
||||||
{ok, _, Type0} = get_decode_type(CallName, TypedAst),
|
{ok, _, Type0} = get_decode_type(CallName, TypedAst),
|
||||||
Type1 = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
|
Type1 = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0,
|
||||||
|
[ unfold_record_types
|
||||||
|
, unfold_variant_types
|
||||||
|
, not_unfold_system_alias_types ]),
|
||||||
fate_data_to_sophia_value(Type0, Type1, FateValue);
|
fate_data_to_sophia_value(Type0, Type1, FateValue);
|
||||||
Err = {error, _} ->
|
Err = {error, _} ->
|
||||||
Err
|
Err
|
||||||
@ -272,7 +275,7 @@ insert_call_function(Ast, Code, Call, {type, Type}) ->
|
|||||||
[ Code,
|
[ Code,
|
||||||
"\n\n",
|
"\n\n",
|
||||||
lists:duplicate(Ind, " "),
|
lists:duplicate(Ind, " "),
|
||||||
"entrypoint ", Call, "(val : ", Type, ") = val\n"
|
"entrypoint ", Call, "(val : ", Type, ") : ", Type, " = val\n"
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-spec insert_init_function(string(), options()) -> string().
|
-spec insert_init_function(string(), options()) -> string().
|
||||||
@ -311,9 +314,12 @@ to_sophia_value(ContractString, FunName, ok, Data, Options0) ->
|
|||||||
Options = [no_code | Options0],
|
Options = [no_code | Options0],
|
||||||
try
|
try
|
||||||
Code = string_to_code(ContractString, Options),
|
Code = string_to_code(ContractString, Options),
|
||||||
#{ unfolded_typed_ast := TypedAst, type_env := TypeEnv} = Code,
|
#{ folded_typed_ast := TypedAst, type_env := TypeEnv} = Code,
|
||||||
{ok, _, Type0} = get_decode_type(FunName, TypedAst),
|
{ok, _, Type0} = get_decode_type(FunName, TypedAst),
|
||||||
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
|
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0,
|
||||||
|
[ unfold_record_types
|
||||||
|
, unfold_variant_types
|
||||||
|
, not_unfold_system_alias_types]),
|
||||||
|
|
||||||
fate_data_to_sophia_value(Type0, Type, Data)
|
fate_data_to_sophia_value(Type0, Type, Data)
|
||||||
catch
|
catch
|
||||||
@ -360,14 +366,17 @@ decode_calldata(ContractString, FunName, Calldata, Options0) ->
|
|||||||
Options = [no_code | Options0],
|
Options = [no_code | Options0],
|
||||||
try
|
try
|
||||||
Code = string_to_code(ContractString, Options),
|
Code = string_to_code(ContractString, Options),
|
||||||
#{ unfolded_typed_ast := TypedAst, type_env := TypeEnv} = Code,
|
#{ folded_typed_ast := TypedAst, type_env := TypeEnv} = Code,
|
||||||
|
|
||||||
{ok, Args, _} = get_decode_type(FunName, TypedAst),
|
{ok, Args, _} = get_decode_type(FunName, TypedAst),
|
||||||
GetType = fun({typed, _, _, T}) -> T; (T) -> T end,
|
GetType = fun({typed, _, _, T}) -> T; (T) -> T end,
|
||||||
ArgTypes = lists:map(GetType, Args),
|
ArgTypes = lists:map(GetType, Args),
|
||||||
Type0 = {tuple_t, [], ArgTypes},
|
Type0 = {tuple_t, [], ArgTypes},
|
||||||
%% user defined data types such as variants needed to match against
|
%% user defined data types such as variants needed to match against
|
||||||
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0, [unfold_record_types, unfold_variant_types]),
|
Type = aeso_ast_infer_types:unfold_types_in_type(TypeEnv, Type0,
|
||||||
|
[ unfold_record_types
|
||||||
|
, unfold_variant_types
|
||||||
|
, not_unfold_system_alias_types]),
|
||||||
case aeb_fate_abi:decode_calldata(FunName, Calldata) of
|
case aeb_fate_abi:decode_calldata(FunName, Calldata) of
|
||||||
{ok, FateArgs} ->
|
{ok, FateArgs} ->
|
||||||
try
|
try
|
||||||
|
@ -235,6 +235,7 @@ lit_to_fate(Env, L) ->
|
|||||||
{bytes, B} -> aeb_fate_data:make_bytes(B);
|
{bytes, B} -> aeb_fate_data:make_bytes(B);
|
||||||
{bool, B} -> aeb_fate_data:make_boolean(B);
|
{bool, B} -> aeb_fate_data:make_boolean(B);
|
||||||
{account_pubkey, K} -> aeb_fate_data:make_address(K);
|
{account_pubkey, K} -> aeb_fate_data:make_address(K);
|
||||||
|
{signature, S} -> aeb_fate_data:make_bytes(S);
|
||||||
{contract_pubkey, K} -> aeb_fate_data:make_contract(K);
|
{contract_pubkey, K} -> aeb_fate_data:make_contract(K);
|
||||||
{oracle_pubkey, K} -> aeb_fate_data:make_oracle(K);
|
{oracle_pubkey, K} -> aeb_fate_data:make_oracle(K);
|
||||||
{oracle_query_id, H} -> aeb_fate_data:make_oracle_query(H);
|
{oracle_query_id, H} -> aeb_fate_data:make_oracle_query(H);
|
||||||
|
@ -525,7 +525,7 @@ id_or_addr() ->
|
|||||||
?RULE(id(), parse_addr_literal(_1)).
|
?RULE(id(), parse_addr_literal(_1)).
|
||||||
|
|
||||||
parse_addr_literal(Id = {id, Ann, Name}) ->
|
parse_addr_literal(Id = {id, Ann, Name}) ->
|
||||||
case lists:member(lists:sublist(Name, 3), ["ak_", "ok_", "oq_", "ct_"]) of
|
case lists:member(lists:sublist(Name, 3), ["ak_", "ok_", "oq_", "ct_", "sg_"]) of
|
||||||
false -> Id;
|
false -> Id;
|
||||||
true ->
|
true ->
|
||||||
try aeser_api_encoder:decode(list_to_binary(Name)) of
|
try aeser_api_encoder:decode(list_to_binary(Name)) of
|
||||||
|
@ -387,7 +387,8 @@ expr_p(_, {Type, _, Bin})
|
|||||||
when Type == account_pubkey;
|
when Type == account_pubkey;
|
||||||
Type == contract_pubkey;
|
Type == contract_pubkey;
|
||||||
Type == oracle_pubkey;
|
Type == oracle_pubkey;
|
||||||
Type == oracle_query_id ->
|
Type == oracle_query_id;
|
||||||
|
Type == signature ->
|
||||||
text(binary_to_list(aeser_api_encoder:encode(Type, Bin)));
|
text(binary_to_list(aeser_api_encoder:encode(Type, Bin)));
|
||||||
expr_p(_, {string, _, <<>>}) -> text("\"\"");
|
expr_p(_, {string, _, <<>>}) -> text("\"\"");
|
||||||
expr_p(_, {string, _, S}) ->
|
expr_p(_, {string, _, S}) ->
|
||||||
|
@ -100,6 +100,7 @@
|
|||||||
| {contract_pubkey, ann(), binary()}
|
| {contract_pubkey, ann(), binary()}
|
||||||
| {oracle_pubkey, ann(), binary()}
|
| {oracle_pubkey, ann(), binary()}
|
||||||
| {oracle_query_id, ann(), binary()}
|
| {oracle_query_id, ann(), binary()}
|
||||||
|
| {signature, ann(), binary()}
|
||||||
| {string, ann(), binary()}
|
| {string, ann(), binary()}
|
||||||
| {char, ann(), integer()}.
|
| {char, ann(), integer()}.
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
|
|
||||||
-spec from_fate(aeso_syntax:type(), aeb_fate_data:fate_type()) -> aeso_syntax:expr().
|
-spec from_fate(aeso_syntax:type(), aeb_fate_data:fate_type()) -> aeso_syntax:expr().
|
||||||
from_fate({id, _, "address"}, ?FATE_ADDRESS(Bin)) -> {account_pubkey, [], Bin};
|
from_fate({id, _, "address"}, ?FATE_ADDRESS(Bin)) -> {account_pubkey, [], Bin};
|
||||||
|
from_fate({id, _, "signature"}, ?FATE_BYTES(Bin)) -> {signature, [], Bin};
|
||||||
|
from_fate({id, _, "hash"}, ?FATE_BYTES(Bin)) -> {bytes, [], Bin};
|
||||||
|
from_fate({id, _, "unit"}, ?FATE_UNIT) -> {tuple, [], []};
|
||||||
from_fate({app_t, _, {id, _, "oracle"}, _}, ?FATE_ORACLE(Bin)) -> {oracle_pubkey, [], Bin};
|
from_fate({app_t, _, {id, _, "oracle"}, _}, ?FATE_ORACLE(Bin)) -> {oracle_pubkey, [], Bin};
|
||||||
from_fate({app_t, _, {id, _, "oracle_query"}, _}, ?FATE_ORACLE_Q(Bin)) -> {oracle_query_id, [], Bin};
|
from_fate({app_t, _, {id, _, "oracle_query"}, _}, ?FATE_ORACLE_Q(Bin)) -> {oracle_query_id, [], Bin};
|
||||||
from_fate({con, _, _Name}, ?FATE_CONTRACT(Bin)) -> {contract_pubkey, [], Bin};
|
from_fate({con, _, _Name}, ?FATE_CONTRACT(Bin)) -> {contract_pubkey, [], Bin};
|
||||||
|
@ -117,6 +117,7 @@ compilable_contracts() ->
|
|||||||
{"funargs", "chain_base_tx", ["Chain.NameRevokeTx(#ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]},
|
{"funargs", "chain_base_tx", ["Chain.NameRevokeTx(#ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]},
|
||||||
{"funargs", "chain_base_tx", ["Chain.NameTransferTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, #ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]},
|
{"funargs", "chain_base_tx", ["Chain.NameTransferTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, #ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]},
|
||||||
{"funargs", "chain_base_tx", ["Chain.GAAttachTx"]},
|
{"funargs", "chain_base_tx", ["Chain.GAAttachTx"]},
|
||||||
|
{"funargs", "sig", ["sg_MhibzTP1wWzGCTjtPFr1TiPqRJrrJqw7auvEuF5i3FdoALWqXLBDY6xxRRNUSPHK3EQTnTzF12EyspkxrSMxVHKsZeSMj"]},
|
||||||
{"variant_types", "init", []},
|
{"variant_types", "init", []},
|
||||||
{"basic_auth", "init", []},
|
{"basic_auth", "init", []},
|
||||||
{"address_literals", "init", []},
|
{"address_literals", "init", []},
|
||||||
|
40
test/aeso_encode_decode_tests.erl
Normal file
40
test/aeso_encode_decode_tests.erl
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
-module(aeso_encode_decode_tests).
|
||||||
|
|
||||||
|
-compile([export_all, nowarn_export_all]).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
-define(EMPTY, "contract C =\n entrypoint f() = true").
|
||||||
|
|
||||||
|
encode_decode_test_() ->
|
||||||
|
[ {lists:flatten(io_lib:format("Testing encode-decode roundtrip for ~p : ~p", [Value, {EType, DType}])),
|
||||||
|
fun() ->
|
||||||
|
{ok, SerRes} = aeso_compiler:encode_value(?EMPTY, EType, Value, []),
|
||||||
|
{ok, Expr} = aeso_compiler:decode_value(?EMPTY, DType, SerRes, []),
|
||||||
|
Value2 = prettypr:format(aeso_pretty:expr(Expr)),
|
||||||
|
?assertEqual(Value, Value2)
|
||||||
|
end} || {Value, EType, DType} <- test_data() ].
|
||||||
|
|
||||||
|
test_data() ->
|
||||||
|
lists:map(fun({V, T}) -> {V, T, T};
|
||||||
|
({V, T1, T2}) -> {V, T1, T2} end, data()).
|
||||||
|
|
||||||
|
data() ->
|
||||||
|
[ {"42", "int"}
|
||||||
|
, {"- 42", "int"}
|
||||||
|
, {"true", "bool"}
|
||||||
|
, {"ak_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ", "address"}
|
||||||
|
, {"ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ", "C"}
|
||||||
|
, {"Some(42)", "option(int)"}
|
||||||
|
, {"None", "option(int)"}
|
||||||
|
, {"(true, 42)", "bool * int"}
|
||||||
|
, {"{[1] = true, [3] = false}", "map(int, bool)"}
|
||||||
|
, {"()", "unit"}
|
||||||
|
, {"#000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", "hash"}
|
||||||
|
, {"#000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f", "bytes(32)"}
|
||||||
|
, {"sg_MhibzTP1wWzGCTjtPFr1TiPqRJrrJqw7auvEuF5i3FdoALWqXLBDY6xxRRNUSPHK3EQTnTzF12EyspkxrSMxVHKsZeSMj", "signature"}
|
||||||
|
, {"sg_MhibzTP1wWzGCTjtPFr1TiPqRJrrJqw7auvEuF5i3FdoALWqXLBDY6xxRRNUSPHK3EQTnTzF12EyspkxrSMxVHKsZeSMj", "bytes(64)", "signature"}
|
||||||
|
, {"#0102030405060708090a0b0c0d0e0f101718192021222324252627282930313233343536373839401a1b1c1d1e1f202122232425262728293031323334353637", "bytes(64)"}
|
||||||
|
, {"#0102030405060708090a0b0c0d0e0f101718192021222324252627282930313233343536373839401a1b1c1d1e1f202122232425262728293031323334353637", "signature", "bytes(64)"}
|
||||||
|
].
|
||||||
|
|
@ -11,4 +11,5 @@ contract C =
|
|||||||
let i = Int.mulmod(a, b, h)
|
let i = Int.mulmod(a, b, h)
|
||||||
let j = Crypto.poseidon(i, a)
|
let j = Crypto.poseidon(i, a)
|
||||||
let k : bytes(32) = Address.to_bytes(Call.origin)
|
let k : bytes(32) = Address.to_bytes(Call.origin)
|
||||||
(a bor b band c bxor a << bnot b >> a, k)
|
let l = sg_MhibzTP1wWzGCTjtPFr1TiPqRJrrJqw7auvEuF5i3FdoALWqXLBDY6xxRRNUSPHK3EQTnTzF12EyspkxrSMxVHKsZeSMj
|
||||||
|
(a bor b band c bxor a << bnot b >> a, k, l)
|
||||||
|
@ -59,3 +59,5 @@ contract FunctionArguments =
|
|||||||
entrypoint chain_ga_meta_tx(tx : Chain.ga_meta_tx) = true
|
entrypoint chain_ga_meta_tx(tx : Chain.ga_meta_tx) = true
|
||||||
entrypoint chain_paying_for_tx(tx : Chain.paying_for_tx) = true
|
entrypoint chain_paying_for_tx(tx : Chain.paying_for_tx) = true
|
||||||
entrypoint chain_base_tx(tx : Chain.base_tx) = true
|
entrypoint chain_base_tx(tx : Chain.base_tx) = true
|
||||||
|
|
||||||
|
entrypoint sig(sg : signature) = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user