From 9abeb21eee1dd2c0af33118e1bde0bf45266232e Mon Sep 17 00:00:00 2001 From: Erik Stenman Date: Mon, 25 Mar 2019 17:57:12 +0100 Subject: [PATCH] Pt 164601244 add hash and signature type (#22) * Add hash, signature and object types. * Add serilaize/deserialize test for new types. * Document new types. * Use aeserialization for base58c encoding/decoding. --- README.md | 30 ++++- include/aeb_fate_data.hrl | 68 +++++++---- src/aeb_fate_asm.erl | 140 +++++++++++----------- src/aeb_fate_asm_scan.template | 49 ++++---- src/aeb_fate_data.erl | 175 +++++++++++++++++----------- src/aeb_fate_encoding.erl | 161 +++++++++++++++++++++---- src/aeb_fate_generate_ops.erl | 4 +- test/aeb_serialize_test.erl | 5 + test/asm_code/all_instructions.fate | 8 +- test/asm_code/immediates.fate | 2 +- 10 files changed, 430 insertions(+), 212 deletions(-) diff --git a/README.md b/README.md index 1472bf1..41ecff0 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ or start with stack followed by an integer `stack1` `a` -Immediate values can be of 9 types: +Immediate values can be of 11 types: 1. Integers as decimals: {Digits} or -{Digits} `42` @@ -57,8 +57,24 @@ Immediate values can be of 9 types: And integers as Hexadecimals:: 0x{Hexdigits} `0x0deadbeef0` -2. addresses, a base58 encoded string starting with # followed by a number of base58chars - `#nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` +2. Chain Objects. These are all addresses to different types of chain objects. + Each address is a 256 bits number encoded in base58 with checksum + with a prefix of "@" plus a type prefix followed by "_". + +2a. Account Address: a base58c encoded number starting with @ak_ followed by a number of base58chars + '@ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` + +2b. Contract address: @ct_{base58char}+ + `@ct_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` + +2c. Oracle address: @ok_{base58char}+ + `@ok_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` + +2d. Name address: @nm_{base58char}+ + `@nm_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` + +2e. Channel address: @ch_{base58char}+ + `@ch_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv` 3. Boolean true or false `true` @@ -88,6 +104,12 @@ Immediate values can be of 9 types: 9. Variants: (| Size | Tag | ( Elements ) |) `(| 42 | 12 | ( "foo", 12) |)` +10. Hashes: #{base64char}+ + `#AQIDCioLFQ==` + +11. Signatures: $sg_{base58char}+ + + Where Digits: [0123456789] @@ -96,6 +118,8 @@ Hexdigits: [0123456789abcdef] base58char: [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz] +base64char: [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789+/=] + Characters: any printable ascii character 0..255 (except " no quoting yet) Key: any value except for a map diff --git a/include/aeb_fate_data.hrl b/include/aeb_fate_data.hrl index 424c9b1..d82c43c 100644 --- a/include/aeb_fate_data.hrl +++ b/include/aeb_fate_data.hrl @@ -1,23 +1,35 @@ --define(FATE_INTEGER_T, integer()). --define(FATE_BYTE_T, 0..255). --define(FATE_BOOLEAN_T, true | false). --define(FATE_NIL_T, []). --define(FATE_LIST_T, list()). --define(FATE_UNIT_T, {tuple, {}}). --define(FATE_MAP_T, #{ fate_type() => fate_type() }). --define(FATE_STRING_T, binary()). --define(FATE_ADDRESS_T, {address, <<_:256>>}). --define(FATE_VARIANT_T, {variant, ?FATE_BYTE_T, ?FATE_BYTE_T, tuple()}). --define(FATE_VOID_T, void). --define(FATE_TUPLE_T, {tuple, tuple()}). --define(FATE_BITS_T, {bits, integer()}). +-define(FATE_INTEGER_T, integer()). +-define(FATE_BYTE_T, 0..255). +-define(FATE_BOOLEAN_T, true | false). +-define(FATE_NIL_T, []). +-define(FATE_LIST_T, list()). +-define(FATE_UNIT_T, {tuple, {}}). +-define(FATE_MAP_T, #{ fate_type() => fate_type() }). +-define(FATE_STRING_T, binary()). +-define(FATE_ADDRESS_T, {address, <<_:256>>}). +-define(FATE_HASH_T, {hash, binary()}). +-define(FATE_SIGNATURE_T, {signature, binary()}). +-define(FATE_CONTRACT_T, {contract, <<_:256>>}). +-define(FATE_ORACLE_T, {oracle, <<_:256>>}). +-define(FATE_NAME_T, {name, <<_:256>>}). +-define(FATE_CHANNEL_T, {channel, <<_:256>>}). +-define(FATE_VARIANT_T, {variant, ?FATE_BYTE_T, ?FATE_BYTE_T, tuple()}). +-define(FATE_VOID_T, void). +-define(FATE_TUPLE_T, {tuple, tuple()}). +-define(FATE_BITS_T, {bits, integer()}). --define(IS_FATE_INTEGER(X), is_integer(X)). --define(IS_FATE_LIST(X), (is_list(X))). --define(IS_FATE_STRING(X), (is_binary(X))). --define(IS_FATE_MAP(X), (is_map(X))). --define(IS_FATE_TUPLE(X), (is_tuple(X) andalso (tuple == element(1, X) andalso is_tuple(element(2, X))))). +-define(IS_FATE_INTEGER(X), (is_integer(X))). +-define(IS_FATE_LIST(X), (is_list(X))). +-define(IS_FATE_STRING(X), (is_binary(X))). +-define(IS_FATE_MAP(X), (is_map(X))). +-define(IS_FATE_TUPLE(X), (is_tuple(X) andalso (tuple == element(1, X) andalso is_tuple(element(2, X))))). -define(IS_FATE_ADDRESS(X), (is_tuple(X) andalso (address == element(1, X) andalso is_binary(element(2, X))))). +-define(IS_FATE_HASH(X), (is_tuple(X) andalso (hash == element(1, X) andalso is_binary(element(2, X))))). +-define(IS_FATE_SIGNATURE(X), (is_tuple(X) andalso (signature == element(1, X) andalso is_binary(element(2, X))))). +-define(IS_FATE_CONTRACT(X), (is_tuple(X) andalso (contract == element(1, X) andalso is_binary(element(2, X))))). +-define(IS_FATE_ORACLE(X), (is_tuple(X) andalso (oracle == element(1, X) andalso is_binary(element(2, X))))). +-define(IS_FATE_NAME(X), (is_tuple(X) andalso (name == element(1, X) andalso is_binary(element(2, X))))). +-define(IS_FATE_CHANNEL(X), (is_tuple(X) andalso (channel == element(1, X) andalso is_binary(element(2, X))))). -define(IS_FATE_BITS(X), (is_tuple(X) andalso (bits == element(1, X) andalso is_integer(element(2, X))))). -define(IS_FATE_VARIANT(X), (is_tuple(X) andalso @@ -28,16 +40,28 @@ ))). -define(IS_FATE_BOOLEAN(X), is_boolean(X)). --define(FATE_UNIT, {tuple, {}}). --define(FATE_TUPLE(T), {tuple, T}). --define(FATE_ADDRESS(A), {address, A}). --define(FATE_BITS(B), {bits, B}). +-define(FATE_UNIT, {tuple, {}}). +-define(FATE_TUPLE(T), {tuple, T}). +-define(FATE_ADDRESS(A), {address, A}). +-define(FATE_HASH(X), {hash, X}). +-define(FATE_SIGNATURE(S), {signature, S}). +-define(FATE_CONTRACT(X), {contract, X}). +-define(FATE_ORACLE(X), {oracle, X}). +-define(FATE_NAME(X), {name, X}). +-define(FATE_CHANNEL(X), {channel, X}). +-define(FATE_BITS(B), {bits, B}). -define(FATE_INTEGER_VALUE(X), (X)). -define(FATE_LIST_VALUE(X), (X)). -define(FATE_STRING_VALUE(X), (X)). -define(FATE_ADDRESS_VALUE(X), (element(2, X))). +-define(FATE_HASH_VALUE(X), (element(2, X))). +-define(FATE_SIGNATURE_VALUE(X), (element(2, X))). +-define(FATE_CONTRACT_VALUE(X), (element(2, X))). +-define(FATE_ORACLE_VALUE(X), (element(2, X))). +-define(FATE_NAME_VALUE(X), (element(2, X))). +-define(FATE_CHANNEL_VALUE(X), (element(2, X))). -define(FATE_MAP_VALUE(X), (X)). -define(FATE_MAP_SIZE(X), (map_size(X))). -define(FATE_STRING_SIZE(X), (byte_size(X))). diff --git a/src/aeb_fate_asm.erl b/src/aeb_fate_asm.erl index 645eb48..708dea5 100644 --- a/src/aeb_fate_asm.erl +++ b/src/aeb_fate_asm.erl @@ -34,15 +34,17 @@ %%% stack1 %%% a %%% -%%% Immediate values can be of 9 types: +%%% Immediate values can be of 11 types: %%% 1a. Integers as decimals: {Digits} or -{Digits} %%% 42 %%% -2374683271468723648732648736498712634876147 %%% 1b. Integers as Hexadecimals:: 0x{Hexdigits} %%% 0x0deadbeef0 -%%% 2. addresses, a base58 encoded string starting with #{base58char} -%%% followed by up to 64 hex chars -%%% #00000deadbeef +%%% 2a. account addresses, a base58c encoded string prefixed with @ak_ +%%% 2b. contract address: @ct_{base58char}+ +%%% 2c. oracle address: @ok_{base58char}+ +%%% 2d. name address: @nm_{base58char}+ +%%% 2e. channel address: @ch_{base58char}+ %%% 3. Boolean true or false %%% true %%% false @@ -64,10 +66,14 @@ %%% (1, "foo") %%% 9. Variants: (| Size | Tag | ( Elements ) |) %%% (| 42 | 12 | ( "foo", 12) |) +%%% 10. Hashes: #{base64char}+ +%%% #AQIDCioLFQ== +%%% 11. Signatures: $sg_{base58char}+ %%% %%% Where Digits: [0123456789] %%% Hexdigits: [0123456789abcdef] %%% base58char: [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz] +%%% base64char: [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789+/=] %%% Characters any printable ascii character 0..255 (except " no quoting yet) %%% Key: any value except for a map %%% Bits: 01 or space @@ -708,49 +714,16 @@ serialize_data(_, Data) -> aeb_fate_encoding:serialize(Data). serialize_signature({Args, RetType}) -> - [serialize_type({tuple, Args}) | - serialize_type(RetType)]. + [aeb_fate_encoding:serialize_type({tuple, Args}) | + aeb_fate_encoding:serialize_type(RetType)]. deserialize_signature(Binary) -> - {{tuple, Args}, Rest} = deserialize_type(Binary), - {RetType, Rest2} = deserialize_type(Rest), + {{tuple, Args}, Rest} = aeb_fate_encoding:deserialize_type(Binary), + {RetType, Rest2} = aeb_fate_encoding:deserialize_type(Rest), {{Args, RetType}, Rest2}. -deserialize_type(<<0, Rest/binary>>) -> {integer, Rest}; -deserialize_type(<<1, Rest/binary>>) -> {boolean, Rest}; -deserialize_type(<<2, Rest/binary>>) -> - {T, Rest2} = deserialize_type(Rest), - {{list, T}, Rest2}; -deserialize_type(<<3, N, Rest/binary>>) -> - {Ts, Rest2} = deserialize_types(N, Rest, []), - {{tuple, Ts}, Rest2}; -deserialize_type(<<4, Rest/binary>>) -> {address, Rest}; -deserialize_type(<<5, Rest/binary>>) -> {bits, Rest}; -deserialize_type(<<6, Rest/binary>>) -> - {K, Rest2} = deserialize_type(Rest), - {V, Rest3} = deserialize_type(Rest2), - {{map, K, V}, Rest3}; -deserialize_type(<<7, Rest/binary>>) -> - {string, Rest}; -deserialize_type(<<8, Size, Rest/binary>>) -> - {Variants, Rest2} = deserialize_variants(Size, Rest, []), - {{variant, Variants}, Rest2}. - -deserialize_variants(0, Rest, Variants) -> - {lists:reverse(Variants), Rest}; -deserialize_variants(N, Rest, Variants) -> - {T, Rest2} = deserialize_type(Rest), - deserialize_variants(N-1, Rest2, [T|Variants]). - - - -deserialize_types(0, Binary, Acc) -> - {lists:reverse(Acc), Binary}; -deserialize_types(N, Binary, Acc) -> - {T, Rest} = deserialize_type(Binary), - deserialize_types(N-1, Rest, [T | Acc]). to_hexstring(ByteList) -> @@ -786,10 +759,41 @@ to_bytecode([{string,_line, String}|Rest], Address, Env, Code, Opts) -> to_bytecode(Rest, Address, Env, [{immediate, aeb_fate_data:make_string(String)}|Code], Opts); -to_bytecode([{address,_line, Value}|Rest], Address, Env, Code, Opts) -> +to_bytecode([{object,_line, {address, Value}}|Rest], + Address, Env, Code, Opts) -> to_bytecode(Rest, Address, Env, [{immediate, aeb_fate_data:make_address(Value)}|Code], Opts); +to_bytecode([{object,_line, {contract, Value}}|Rest], + Address, Env, Code, Opts) -> + to_bytecode(Rest, Address, Env, + [{immediate, aeb_fate_data:make_contract(Value)}|Code], + Opts); +to_bytecode([{object,_line, {oracle, Value}}|Rest], + Address, Env, Code, Opts) -> + to_bytecode(Rest, Address, Env, + [{immediate, aeb_fate_data:make_oracle(Value)}|Code], + Opts); +to_bytecode([{object,_line, {name, Value}}|Rest], + Address, Env, Code, Opts) -> + to_bytecode(Rest, Address, Env, + [{immediate, aeb_fate_data:make_name(Value)}|Code], + Opts); +to_bytecode([{object,_line, {channel, Value}}|Rest], + Address, Env, Code, Opts) -> + to_bytecode(Rest, Address, Env, + [{immediate, aeb_fate_data:make_contract(Value)}|Code], + Opts); +to_bytecode([{hash,_line, Value}|Rest], + Address, Env, Code, Opts) -> + to_bytecode(Rest, Address, Env, + [{immediate, aeb_fate_data:make_hash(Value)}|Code], + Opts); +to_bytecode([{signature,_line, {signature, Value}}|Rest], + Address, Env, Code, Opts) -> + to_bytecode(Rest, Address, Env, + [{immediate, aeb_fate_data:make_signature(Value)}|Code], + Opts); to_bytecode([{id,_line, ID}|Rest], Address, Env, Code, Opts) -> {Hash, Env2} = insert_symbol(ID, Env), to_bytecode(Rest, Address, Env2, [{immediate, Hash}|Code], Opts); @@ -878,7 +882,6 @@ parse_variant([{start_variant,_line} parse_value([{int,_line, Int} | Rest]) -> {Int, Rest}; parse_value([{boolean,_line, Bool} | Rest]) -> {Bool, Rest}; -parse_value([{hash,_line, Hash} | Rest]) -> {Hash, Rest}; parse_value([{'{',_line} | Rest]) -> parse_map(Rest); parse_value([{'[',_line} | Rest]) -> parse_list(Rest); parse_value([{'(',_line} | Rest]) -> @@ -892,8 +895,20 @@ parse_value([{start_variant,_line}|_] = Tokens) -> {Variant, Rest}; parse_value([{string,_line, String} | Rest]) -> {aeb_fate_data:make_string(String), Rest}; -parse_value([{address,_line, Address} | Rest]) -> - {aeb_fate_data:make_address(Address), Rest}. +parse_value([{address,_line, {address, Address}} | Rest]) -> + {aeb_fate_data:make_address(Address), Rest}; +parse_value([{address,_line, {contract, Address}} | Rest]) -> + {aeb_fate_data:make_contract(Address), Rest}; +parse_value([{address,_line, {oracle, Address}} | Rest]) -> + {aeb_fate_data:make_oracle(Address), Rest}; +parse_value([{address,_line, {name, Address}} | Rest]) -> + {aeb_fate_data:make_name(Address), Rest}; +parse_value([{address,_line, {channel, Address}} | Rest]) -> + {aeb_fate_data:make_channel(Address), Rest}; +parse_value([{hash,_line, Hash} | Rest]) -> + {aeb_fate_data:make_hash(Hash), Rest}; +parse_value([{signature,_line, Hash} | Rest]) -> + {aeb_fate_data:make_signature(Hash), Rest}. to_fun_def([{id, _, Name}, {'(', _} | Rest]) -> {ArgsType, [{'to', _} | Rest2]} = to_arg_types(Rest), @@ -913,11 +928,17 @@ to_arg_types(Tokens) -> %% Type handling -to_type([{id, _, "integer"} | Rest]) -> {integer, Rest}; -to_type([{id, _, "boolean"} | Rest]) -> {boolean, Rest}; -to_type([{id, _, "string"} | Rest]) -> {string, Rest}; -to_type([{id, _, "address"} | Rest]) -> {address, Rest}; -to_type([{id, _, "bits"} | Rest]) -> {bits, Rest}; +to_type([{id, _, "integer"} | Rest]) -> {integer, Rest}; +to_type([{id, _, "boolean"} | Rest]) -> {boolean, Rest}; +to_type([{id, _, "string"} | Rest]) -> {string, Rest}; +to_type([{id, _, "address"} | Rest]) -> {address, Rest}; +to_type([{id, _, "contract"} | Rest]) -> {contract, Rest}; +to_type([{id, _, "oracle"} | Rest]) -> {oracle, Rest}; +to_type([{id, _, "name"} | Rest]) -> {name, Rest}; +to_type([{id, _, "channel"} | Rest]) -> {channel, Rest}; +to_type([{id, _, "hash"} | Rest]) -> {hash, Rest}; +to_type([{id, _, "signature"} | Rest]) -> {signature, Rest}; +to_type([{id, _, "bits"} | Rest]) -> {bits, Rest}; to_type([{'{', _}, {id, _, "list"}, {',', _} | Rest]) -> %% TODO: Error handling {ListType, [{'}', _}| Rest2]} = to_type(Rest), @@ -951,25 +972,6 @@ to_list_of_types(Tokens) -> {[Type], Rest} end. --spec serialize_type(aeb_fate_data:fate_type_type()) -> [byte()]. -serialize_type(integer) -> [0]; -serialize_type(boolean) -> [1]; -serialize_type({list, T}) -> [2 | serialize_type(T)]; -serialize_type({tuple, Ts}) -> - case length(Ts) of - N when N =< 255 -> - [3, N | [serialize_type(T) || T <- Ts]] - end; -serialize_type(address) -> [4]; -serialize_type(bits) -> [5]; -serialize_type({map, K, V}) -> [6 | serialize_type(K) ++ serialize_type(V)]; -serialize_type(string) -> [7]; -serialize_type({variant, ListOfVariants}) -> - Size = length(ListOfVariants), - if Size < 256 -> - [8, Size | [serialize_type(T) || T <- ListOfVariants]] - end. - %% ------------------------------------------------------------------- %% Helper functions diff --git a/src/aeb_fate_asm_scan.template b/src/aeb_fate_asm_scan.template index 1fa686a..b5da2b7 100644 --- a/src/aeb_fate_asm_scan.template +++ b/src/aeb_fate_asm_scan.template @@ -4,7 +4,7 @@ %%% @doc %%% Handling FATE code. %%% @end -###REPLACEWITHNOTE### +%%% ###REPLACEWITHNOTE### %%%------------------------------------------------------------------- Definitions. @@ -13,9 +13,12 @@ HEXDIGIT = [0-9a-fA-F] LOWER = [a-z_] UPPER = [A-Z] BASE58 = [123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz] +BASE64 = [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy0123456789+/=] INT = {DIGIT}+ HEX = 0x{HEXDIGIT}+ -HASH = #{BASE58}+ +OBJECT = @[a-z][a-z]_{BASE58}+ +HASH = #{BASE64}+ +SIG = \$\sg_{BASE58}+ WS = [\000-\s] ID = {LOWER}[a-zA-Z0-9_]* STRING = "[^"]*" @@ -30,10 +33,16 @@ a{INT} : {token, {stack, TokenLine, parse_acc(TokenChars)}}. true : {token, {boolean, TokenLine, true}}. false : {token, {boolean, TokenLine, false}}. -###REPLACEWITHOPTOKENS### +%% ###REPLACEWITHOPTOKENS### FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. +{HASH} : + {token, {hash, TokenLine, parse_hash(TokenChars)}}. +{SIG} : + {token, {signature, TokenLine, parse_object(TokenChars)}}. +{OBJECT} : + {token, {object, TokenLine, parse_object(TokenChars)}}. {ID} : {token, {id, TokenLine, TokenChars}}. {HEX} : @@ -42,8 +51,6 @@ FUNCTION : {token, {function, TokenLine, 'FUNCTION' }}. {token, {int, TokenLine, parse_int(TokenChars)}}. -{INT} : {token, {int, TokenLine, parse_int(TokenChars)}}. -{HASH} : - {token, {address, TokenLine, parse_hash(TokenChars)}}. {STRING} : {token, {string, TokenLine, list_to_binary(TokenChars)}}. {BITS} : @@ -102,7 +109,17 @@ parse_acc("a" ++ N) -> list_to_integer(N). parse_hash("#" ++ Chars) -> - base58_to_address(Chars). + base64:decode(Chars). + +parse_object([_|Chars]) -> + case aeser_api_encoder:decode(list_to_binary(Chars)) of + {account_pubkey, Bin} -> {address, Bin}; + {contract_pubkey, Bin} -> {contract, Bin}; + {oracle_pubkey, Bin} -> {oracle, Bin}; + {name, Bin} -> {name, Bin}; + {channel, Bin} -> {channel, Bin}; + {signature, Bin} -> {signature, Bin} + end. scan(S) -> string(S). @@ -120,23 +137,3 @@ bits([$> |_Rest], Acc) -> Acc; bits([$0 | Rest], Acc) -> bits(Rest, Acc bsl 1); bits([$1 | Rest], Acc) -> bits(Rest, (Acc bsl 1) bor 1); bits([$ | Rest], Acc) -> bits(Rest, Acc). - -char_to_base58(C) -> - binary:at(<<0,1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,9,10,11,12,13,14,15,16,0,17, - 18,19,20,21,0,22,23,24,25,26,27,28,29,30,31,32,0,0,0,0,0,0, - 33,34,35,36,37,38,39,40,41,42,43,0,44,45,46,47,48,49,50,51, - 52,53,54,55,56,57>>, C-$1). - -base58_to_integer(C, []) -> C; -base58_to_integer(C, [X | Xs]) -> - base58_to_integer(C * 58 + char_to_base58(X), Xs). - -base58_to_integer([]) -> error; -base58_to_integer([Char]) -> char_to_base58(Char); -base58_to_integer([Char | Str]) -> - base58_to_integer(char_to_base58(Char), Str). - -base58_to_address(Base58) -> - I = base58_to_integer(Base58), - Bin = <>, - Bin. \ No newline at end of file diff --git a/src/aeb_fate_data.erl b/src/aeb_fate_data.erl index e2308ea..83aa247 100644 --- a/src/aeb_fate_data.erl +++ b/src/aeb_fate_data.erl @@ -4,18 +4,22 @@ -module(aeb_fate_data). --type fate_integer() :: ?FATE_INTEGER_T. --type fate_boolean() :: ?FATE_BOOLEAN_T. --type fate_nil() :: ?FATE_NIL_T. --type fate_list() :: ?FATE_LIST_T. --type fate_unit() :: ?FATE_UNIT_T. --type fate_map() :: ?FATE_MAP_T. --type fate_string() :: ?FATE_STRING_T. --type fate_address() :: ?FATE_ADDRESS_T. - --type fate_variant() :: ?FATE_VARIANT_T. - --type fate_tuple() :: ?FATE_TUPLE_T. +-type fate_integer() :: ?FATE_INTEGER_T. +-type fate_boolean() :: ?FATE_BOOLEAN_T. +-type fate_nil() :: ?FATE_NIL_T. +-type fate_list() :: ?FATE_LIST_T. +-type fate_unit() :: ?FATE_UNIT_T. +-type fate_map() :: ?FATE_MAP_T. +-type fate_string() :: ?FATE_STRING_T. +-type fate_address() :: ?FATE_ADDRESS_T. +-type fate_hash() :: ?FATE_HASH_T. +-type fate_contract() :: ?FATE_CONTRACT_T. +-type fate_oracle() :: ?FATE_ORACLE_T. +-type fate_name() :: ?FATE_NAME_T. +-type fate_channel() :: ?FATE_CHANNEL_T. +-type fate_signature() :: ?FATE_SIGNATURE_T. +-type fate_variant() :: ?FATE_VARIANT_T. +-type fate_tuple() :: ?FATE_TUPLE_T. -type fate_type_type() :: integer | boolean @@ -23,6 +27,12 @@ | {map, fate_type(), fate_type()} | {tuple, [fate_type()]} | address + | hash + | signature + | contract + | oracle + | name + | channel | bits | {variant, integer()}. @@ -36,6 +46,12 @@ | fate_tuple() | fate_string() | fate_address() + | fate_hash() + | fate_signature() + | fate_contract() + | fate_oracle() + | fate_name() + | fate_channel() | fate_variant() | fate_map() | fate_type_type(). @@ -49,6 +65,12 @@ , fate_tuple/0 , fate_string/0 , fate_address/0 + , fate_hash/0 + , fate_signature/0 + , fate_contract/0 + , fate_oracle/0 + , fate_name/0 + , fate_channel/0 , fate_variant/0 , fate_map/0 , fate_type_type/0 @@ -62,6 +84,12 @@ , make_string/1 , make_map/1 , make_address/1 + , make_hash/1 + , make_signature/1 + , make_contract/1 + , make_oracle/1 + , make_name/1 + , make_channel/1 , make_bits/1 , make_unit/0 , tuple_to_list/1 @@ -71,19 +99,26 @@ -export([format/1]). -make_integer(I) when is_integer(I) -> ?MAKE_FATE_INTEGER(I). + make_boolean(true) -> ?FATE_TRUE; make_boolean(false) -> ?FATE_FALSE. -make_list([]) -> ?FATE_NIL; -make_list(L) -> ?MAKE_FATE_LIST(L). -make_string(S) when is_list(S) -> +make_list([]) -> ?FATE_NIL; +make_list(L) -> ?MAKE_FATE_LIST(L). +make_unit() -> ?FATE_UNIT. +make_tuple(T) -> ?FATE_TUPLE(T). +make_map(M) -> ?MAKE_FATE_MAP(M). +make_address(X) -> ?FATE_ADDRESS(X). +make_hash(X) -> ?FATE_HASH(X). +make_signature(X) -> ?FATE_SIGNATURE(X). +make_contract(X) -> ?FATE_CONTRACT(X). +make_oracle(X) -> ?FATE_ORACLE(X). +make_name(X) -> ?FATE_NAME(X). +make_channel(X) -> ?FATE_CHANNEL(X). +make_integer(I) when is_integer(I) -> ?MAKE_FATE_INTEGER(I). +make_bits(I) when is_integer(I) -> ?FATE_BITS(I). +make_string(S) when is_list(S) -> ?FATE_STRING(list_to_binary(lists:flatten(S))); -make_string(S) when is_binary(S) -> ?FATE_STRING(S). -make_unit() -> ?FATE_UNIT. -make_tuple(T) -> ?FATE_TUPLE(T). -make_map(M) -> ?MAKE_FATE_MAP(M). -make_address(A) -> ?FATE_ADDRESS(A). -make_bits(I) when is_integer(I) -> ?FATE_BITS(I). +make_string(S) when is_binary(S) -> ?FATE_STRING(S). make_variant(Size, Tag, Values) when is_integer(Size), is_integer(Tag) , 0 =< Size @@ -102,7 +137,29 @@ encode({bits, Term}) when is_integer(Term) -> make_bits(Term); %% TODO: check that each byte is in base58 encode({address, B}) when is_binary(B) -> make_address(B); encode({address, I}) when is_integer(I) -> B = <>, make_address(B); -encode({address, S}) when is_list(S) -> make_address(base58_to_address(S)); +encode({address, S}) when is_list(S) -> + make_address(encode_address(account_pubkey, S)); +encode({hash, H}) when is_binary(H) -> make_hash(H); +encode({hash, H}) when is_list(H) -> make_hash(base64:decode(H)); +encode({signature, S}) when is_binary(S) -> make_signature(S); +encode({signature, S}) when is_list(S) -> + make_signature(encode_address(signature, S)); +encode({contract, B}) when is_binary(B) -> make_contract(B); +encode({contract, I}) when is_integer(I) -> B = <>, make_contract(B); +encode({contract, S}) when is_list(S) -> + make_contract(encode_address(contract_pubkey, S)); +encode({oracle, B}) when is_binary(B) -> make_oracle(B); +encode({oracle, I}) when is_integer(I) -> B = <>, make_oracle(B); +encode({oracle, S}) when is_list(S) -> + make_oracle(encode_address(oracle_pubkey, S)); +encode({name, B}) when is_binary(B) -> make_name(B); +encode({name, I}) when is_integer(I) -> B = <>, make_name(B); +encode({name, S}) when is_list(S) -> + make_name(encode_address(name, S)); +encode({channel, B}) when is_binary(B) -> make_channel(B); +encode({channel, I}) when is_integer(I) -> B = <>, make_channel(B); +encode({channel, S}) when is_list(S) -> + make_channel(encode_address(channel, S)); encode({variant, Size, Tag, Values}) -> make_variant(Size, Tag, Values); encode(Term) when is_integer(Term) -> make_integer(Term); encode(Term) when is_boolean(Term) -> make_boolean(Term); @@ -120,8 +177,14 @@ decode(?FATE_TRUE) -> true; decode(?FATE_FALSE) -> false; decode(L) when ?IS_FATE_LIST(L) -> [decode(E) || E <- L]; decode(?FATE_ADDRESS(<>)) -> {address, Address}; -decode(?FATE_BITS(Bits)) -> {bits, Bits}; -decode(?FATE_TUPLE(T)) -> erlang:list_to_tuple([decode(E) || E <- T]); +decode(?FATE_HASH(H)) -> {hash, H}; +decode(?FATE_SIGNATURE(S)) -> {signature, S}; +decode(?FATE_CONTRACT(X)) -> {contract, X}; +decode(?FATE_ORACLE(X)) -> {oracle, X}; +decode(?FATE_NAME(X)) -> {name, X}; +decode(?FATE_CHANNEL(X)) -> {channel, X}; +decode(?FATE_BITS(Bits)) -> {bits, Bits}; +decode(?FATE_TUPLE(T)) -> erlang:list_to_tuple([decode(E) || E <- T]); decode(?FATE_VARIANT(Size, Tag, Values)) -> {variant, Size, Tag, Values}; decode(S) when ?IS_FATE_STRING(S) -> binary_to_list(S); decode(M) when ?IS_FATE_MAP(M) -> @@ -148,7 +211,19 @@ format(?FATE_VARIANT(Size, Tag, T)) -> " |)"]; format(M) when ?IS_FATE_MAP(M) -> ["{ ", format_kvs(maps:to_list(?FATE_MAP_VALUE(M))), " }"]; -format(?FATE_ADDRESS(Address)) -> ["#", address_to_base58(Address)]; +format(?FATE_HASH(X)) -> ["#", base64:encode(X)]; +format(?FATE_ADDRESS(X)) -> + ["@", aeser_api_encoder:encode(account_pubkey, X)]; +format(?FATE_SIGNATURE(X)) -> + ["$", aeser_api_encoder:encode(signature, X)]; +format(?FATE_CONTRACT(X)) -> + ["@", aeser_api_encoder:encode(contract_pubkey, X)]; +format(?FATE_ORACLE(X)) -> + ["@", aeser_api_encoder:encode(oracle_pubkey, X)]; +format(?FATE_NAME(X)) -> + ["@", aeser_api_encoder:encode(name, X)]; +format(?FATE_CHANNEL(X)) -> + ["@", aeser_api_encoder:encode(channel, X)]; format(V) -> exit({not_a_fate_type, V}). format_bits(0, Acc) -> Acc; @@ -167,42 +242,12 @@ format_list(List) -> format_kvs(List) -> lists:join(", ", [ [format(K), " => ", format(V)] || {K, V} <- List]). - -%% -- Local base 58 library - -base58char(Char) -> - binary:at(<<"123456789ABCDEFGHJKLMNPQRSTUVWXYZ" - "abcdefghijkmnopqrstuvwxyz">>, Char). -char_to_base58(C) -> - binary:at(<<0,1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,9,10,11,12,13,14,15,16,0,17, - 18,19,20,21,0,22,23,24,25,26,27,28,29,30,31,32,0,0,0,0,0,0, - 33,34,35,36,37,38,39,40,41,42,43,0,44,45,46,47,48,49,50,51, - 52,53,54,55,56,57>>, C-$1). - -base58_to_integer(C, []) -> C; -base58_to_integer(C, [X | Xs]) -> - base58_to_integer(C * 58 + char_to_base58(X), Xs). - -base58_to_integer([]) -> error; -base58_to_integer([Char]) -> char_to_base58(Char); -base58_to_integer([Char | Str]) -> - base58_to_integer(char_to_base58(Char), Str). - -base58_to_address(Base58) -> - I = base58_to_integer(Base58), - Bin = <>, - Bin. - -address_to_base58(<>) -> - integer_to_base58(A). - -integer_to_base58(0) -> <<"1">>; -integer_to_base58(Integer) -> - Base58String = integer_to_base58(Integer, []), - list_to_binary(Base58String). - -integer_to_base58(0, Acc) -> Acc; -integer_to_base58(Integer, Acc) -> - Quot = Integer div 58, - Rem = Integer rem 58, - integer_to_base58(Quot, [base58char(Rem)|Acc]). +encode_address(Type, S) when is_list(S) -> + B = list_to_binary(S), + try aeser_api_encoder:decode(B) of + {Type, Encoding} -> + Encoding; + _ -> erlang:error({bad_address_encoding, Type, S}) + catch _:_ -> + erlang:error({bad_address_encoding, Type, S}) + end. diff --git a/src/aeb_fate_encoding.erl b/src/aeb_fate_encoding.erl index d0e5c12..7b68826 100644 --- a/src/aeb_fate_encoding.erl +++ b/src/aeb_fate_encoding.erl @@ -37,7 +37,9 @@ -export([ deserialize/1 , deserialize_one/1 + , deserialize_type/1 , serialize/1 + , serialize_type/1 ]). -include("aeb_fate_data.hrl"). @@ -47,38 +49,62 @@ -define(SMALL_INT , 2#0). %% sxxxxxx 0 - 6 bit integer with sign bit %% 1 Set below --define(LONG_STRING , 2#00000001). %% 000000 01 - RLP encoded array, size >= 64 --define(SHORT_STRING , 2#01). %% xxxxxx 01 - [bytes], 0 < xxxxxx:size < 64 +-define(LONG_STRING , 2#00000001). %% 000000 01 | RLP encoded array - when size >= 64 +-define(SHORT_STRING , 2#01). %% xxxxxx 01 | [bytes] - when 0 < xxxxxx:size < 64 %% 11 Set below --define(SHORT_LIST , 2#0011). %% xxxx 0011 - [encoded elements], 0 < length < 16 -%% xxxx 0111 - FREE (For typedefs in future) --define(LONG_TUPLE , 2#00001011). %% 0000 1011 - RLP encoded (size - 16) + [encoded elements], --define(SHORT_TUPLE , 2#1011). %% xxxx 1011 - [encoded elements], 0 < size < 16 +-define(SHORT_LIST , 2#0011). %% xxxx 0011 | [encoded elements] when 0 < length < 16 +%% xxxx 0111 +-define(TYPE_INTEGER , 2#00000111). %% 0000 0111 - Integer typedef +-define(TYPE_BOOLEAN , 2#00010111). %% 0001 0111 - Boolean typedef +-define(TYPE_LIST , 2#00100111). %% 0010 0111 | Type +-define(TYPE_TUPLE , 2#00110111). %% 0011 0111 | Size | [Element Types] +-define(TYPE_OBJECT , 2#01000111). %% 0100 0111 | ObjectType +-define(TYPE_BITS , 2#01010111). %% 0101 0111 - Bits typedef +-define(TYPE_MAP , 2#01100111). %% 0110 0111 | Type | Type +-define(TYPE_STRING , 2#01110111). %% 0111 0111 - string typedef +-define(TYPE_VARIANT , 2#10000111). %% 1000 0111 | Size | [Type] + %% 1001 0111 + %% 1010 0111 + %% 1011 0111 + %% 1100 0111 + %% 1101 0111 + %% 1110 0111 + %% 1111 0111 +-define(LONG_TUPLE , 2#00001011). %% 0000 1011 | RLP encoded (size - 16) | [encoded elements], +-define(SHORT_TUPLE , 2#1011). %% xxxx 1011 | [encoded elements] when 0 < size < 16 %% 1111 Set below --define(LONG_LIST , 2#00011111). %% 0001 1111 - RLP encoded (length - 16) + [Elements] --define(MAP , 2#00101111). %% 0010 1111 - RLP encoded size + [encoded key, encoded value] +-define(LONG_LIST , 2#00011111). %% 0001 1111 | RLP encoded (length - 16) | [encoded lements] +-define(MAP , 2#00101111). %% 0010 1111 | RLP encoded size | [encoded key, encoded value] -define(EMPTY_TUPLE , 2#00111111). %% 0011 1111 --define(POS_BITS , 2#01001111). %% 0100 1111 - RLP encoded integer (to be interpreted as bitfield) +-define(POS_BITS , 2#01001111). %% 0100 1111 | RLP encoded integer (to be interpreted as bitfield) -define(EMPTY_STRING , 2#01011111). %% 0101 1111 --define(POS_BIG_INT , 2#01101111). %% 0110 1111 - RLP encoded (integer - 64) +-define(POS_BIG_INT , 2#01101111). %% 0110 1111 | RLP encoded (integer - 64) -define(FALSE , 2#01111111). %% 0111 1111 %% %% 1000 1111 - FREE (Possibly for bytecode in the future.) --define(ADDRESS , 2#10011111). %% 1001 1111 - [32 bytes] --define(VARIANT , 2#10101111). %% 1010 1111 - encoded size + encoded tag + encoded values +-define(OBJECT , 2#10011111). %% 1001 1111 | ObjectType | RLP encoded Array +-define(VARIANT , 2#10101111). %% 1010 1111 | encoded size | encoded tag | [encoded values] -define(NIL , 2#10111111). %% 1011 1111 - Empty list --define(NEG_BITS , 2#11001111). %% 1100 1111 - RLP encoded integer (infinite 1:s bitfield) +-define(NEG_BITS , 2#11001111). %% 1100 1111 | RLP encoded integer (infinite 1:s bitfield) -define(EMPTY_MAP , 2#11011111). %% 1101 1111 --define(NEG_BIG_INT , 2#11101111). %% 1110 1111 - RLP encoded (integer - 64) +-define(NEG_BIG_INT , 2#11101111). %% 1110 1111 | RLP encoded (integer - 64) -define(TRUE , 2#11111111). %% 1111 1111 --define(SHORT_TUPLE_SIZE, 16). --define(SHORT_LIST_SIZE , 16). --define(SMALL_INT_SIZE , 64). +-define(SHORT_TUPLE_SIZE, 16). +-define(SHORT_LIST_SIZE, 16). +-define(SMALL_INT_SIZE, 64). -define(SHORT_STRING_SIZE, 64). -define(POS_SIGN, 0). -define(NEG_SIGN, 1). +%% Object types +-define(OTYPE_ADDRESS, 0). +-define(OTYPE_HASH, 1). +-define(OTYPE_SIGNATURE, 2). +-define(OTYPE_CONTRACT, 3). +-define(OTYPE_ORACLE, 4). +-define(OTYPE_NAME, 5). +-define(OTYPE_CHANNEL, 6). %% -------------------------------------------------- %% Serialize @@ -106,7 +132,19 @@ serialize(String) when ?IS_FATE_STRING(String), Bytes = ?FATE_STRING_VALUE(String), <>; serialize(?FATE_ADDRESS(Address)) when is_binary(Address) -> - <>; + <>; +serialize(?FATE_HASH(Address)) when is_binary(Address) -> + <>; +serialize(?FATE_SIGNATURE(Address)) when is_binary(Address) -> + <>; +serialize(?FATE_CONTRACT(Address)) when is_binary(Address) -> + <>; +serialize(?FATE_ORACLE(Address)) when is_binary(Address) -> + <>; +serialize(?FATE_NAME(Address)) when is_binary(Address) -> + <>; +serialize(?FATE_CHANNEL(Address)) when is_binary(Address) -> + <>; serialize(?FATE_TUPLE(T)) when size(T) > 0 -> S = size(T), L = tuple_to_list(T), @@ -142,6 +180,79 @@ serialize(?FATE_VARIANT(Size, Tag, Values)) when 0 < Size, Size < 256, (serialize(?FATE_TUPLE(Values)))/binary >>. +%% ----------------------------------------------------- + +-spec serialize_type(aeb_fate_data:fate_type_type()) -> [byte()]. +serialize_type(integer) -> [?TYPE_INTEGER]; +serialize_type(boolean) -> [?TYPE_BOOLEAN]; +serialize_type({list, T}) -> [?TYPE_LIST | serialize_type(T)]; +serialize_type({tuple, Ts}) -> + case length(Ts) of + N when N =< 255 -> + [?TYPE_TUPLE, N | [serialize_type(T) || T <- Ts]] + end; +serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS]; +serialize_type(hash) -> [?TYPE_OBJECT, ?OTYPE_HASH]; +serialize_type(signature) -> [?TYPE_OBJECT, ?OTYPE_SIGNATURE]; +serialize_type(contract) -> [?TYPE_OBJECT, ?OTYPE_CONTRACT]; +serialize_type(oracle) -> [?TYPE_OBJECT, ?OTYPE_ORACLE]; +serialize_type(name) -> [?TYPE_OBJECT, ?OTYPE_NAME]; +serialize_type(channel) -> [?TYPE_OBJECT, ?OTYPE_CHANNEL]; +serialize_type(bits) -> [?TYPE_BITS]; +serialize_type({map, K, V}) -> [?TYPE_MAP + | serialize_type(K) ++ serialize_type(V)]; +serialize_type(string) -> [?TYPE_STRING]; +serialize_type({variant, ListOfVariants}) -> + Size = length(ListOfVariants), + if Size < 256 -> + [?TYPE_VARIANT, Size | [serialize_type(T) || T <- ListOfVariants]] + end. + + +-spec deserialize_type(binary()) -> {aeb_fate_data:fate_type_type(), binary()}. +deserialize_type(<>) -> {integer, Rest}; +deserialize_type(<>) -> {boolean, Rest}; +deserialize_type(<>) -> + {T, Rest2} = deserialize_type(Rest), + {{list, T}, Rest2}; +deserialize_type(<>) -> + {Ts, Rest2} = deserialize_types(N, Rest, []), + {{tuple, Ts}, Rest2}; +deserialize_type(<>) -> + case ObjectType of + ?OTYPE_ADDRESS -> {address, Rest}; + ?OTYPE_HASH -> {hash, Rest}; + ?OTYPE_SIGNATURE -> {signature, Rest}; + ?OTYPE_CONTRACT -> {contract, Rest}; + ?OTYPE_ORACLE -> {oracle, Rest}; + ?OTYPE_NAME -> {name, Rest}; + ?OTYPE_CHANNEL -> {channel, Rest} + end; +deserialize_type(<>) -> {bits, Rest}; +deserialize_type(<>) -> + {K, Rest2} = deserialize_type(Rest), + {V, Rest3} = deserialize_type(Rest2), + {{map, K, V}, Rest3}; +deserialize_type(<>) -> + {string, Rest}; +deserialize_type(<>) -> + {Variants, Rest2} = deserialize_variants(Size, Rest, []), + {{variant, Variants}, Rest2}. + +deserialize_variants(0, Rest, Variants) -> + {lists:reverse(Variants), Rest}; +deserialize_variants(N, Rest, Variants) -> + {T, Rest2} = deserialize_type(Rest), + deserialize_variants(N-1, Rest2, [T|Variants]). + + + +deserialize_types(0, Binary, Acc) -> + {lists:reverse(Acc), Binary}; +deserialize_types(N, Binary, Acc) -> + {T, Rest} = deserialize_type(Binary), + deserialize_types(N-1, Rest, [T | Acc]). + %% ----------------------------------------------------- @@ -205,9 +316,19 @@ deserialize2(<>) -> String = binary:part(Rest, 0, S), Rest2 = binary:part(Rest, byte_size(Rest), - (byte_size(Rest) - S)), {?MAKE_FATE_STRING(String), Rest2}; -deserialize2(<>) -> +deserialize2(<>) -> {A, Rest2} = aeser_rlp:decode_one(Rest), - {?FATE_ADDRESS(A), Rest2}; + Val = + case ObjectType of + ?OTYPE_ADDRESS -> ?FATE_ADDRESS(A); + ?OTYPE_HASH -> ?FATE_HASH(A); + ?OTYPE_SIGNATURE -> ?FATE_SIGNATURE(A); + ?OTYPE_CONTRACT -> ?FATE_CONTRACT(A); + ?OTYPE_ORACLE -> ?FATE_ORACLE(A); + ?OTYPE_NAME -> ?FATE_NAME(A); + ?OTYPE_CHANNEL -> ?FATE_CHANNEL(A) + end, + {Val, Rest2}; deserialize2(<>) -> {?FATE_TRUE, Rest}; deserialize2(<>) -> diff --git a/src/aeb_fate_generate_ops.erl b/src/aeb_fate_generate_ops.erl index 524b795..2988191 100644 --- a/src/aeb_fate_generate_ops.erl +++ b/src/aeb_fate_generate_ops.erl @@ -393,9 +393,9 @@ gen_token(#{opname := OpName}) -> io_lib:format("~-28s: {token, {mnemonic, TokenLine, ~w}}.\n", [Name, OpName]). -insert_tokens_in_template(<<"###REPLACEWITHOPTOKENS###", Rest/binary >>, Tokens) -> +insert_tokens_in_template(<<"%% ###REPLACEWITHOPTOKENS###", Rest/binary >>, Tokens) -> [Tokens, Rest]; -insert_tokens_in_template(<<"###REPLACEWITHNOTE###", Rest/binary >>, Tokens) -> +insert_tokens_in_template(<<"%%% ###REPLACEWITHNOTE###", Rest/binary >>, Tokens) -> [ "%%%\n" "%%% === === N O T E : This file is generated do not edit. === ===\n" diff --git a/test/aeb_serialize_test.erl b/test/aeb_serialize_test.erl index 778a2f9..ec8e88a 100644 --- a/test/aeb_serialize_test.erl +++ b/test/aeb_serialize_test.erl @@ -47,6 +47,11 @@ sources() -> [aeb_fate_data:make_integer(0), aeb_fate_data:make_integer(1), True, False, Unit, Nil, EmptyString, EmptyMap, + aeb_fate_data:make_hash(<<1,2,3,4,5>>), + aeb_fate_data:make_signature(<<1,2,3,4,5>>), + aeb_fate_data:make_contract(<<1,2,3,4,5>>), + aeb_fate_data:make_name(<<1,2,3,4,5>>), + aeb_fate_data:make_channel(<<1,2,3,4,5>>), aeb_fate_data:make_list([True]), aeb_fate_data:make_address( <<0,1,2,3,4,5,6,7,8,9, diff --git a/test/asm_code/all_instructions.fate b/test/asm_code/all_instructions.fate index 51d0d29..e585471 100644 --- a/test/asm_code/all_instructions.fate +++ b/test/asm_code/all_instructions.fate @@ -24,7 +24,7 @@ FUNCTION foo () : {tuple, []} SWITCH_V3 var4 0x1d61723dd 79 7 - SWITCH_VN #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv [1, 2, 3] + SWITCH_VN arg0 [1, 2, 3] PUSH var80 @@ -112,7 +112,7 @@ FUNCTION foo () : {tuple, []} ADDR_TO_STR a arg216 - STR_REVERSE a174 #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv + STR_REVERSE a174 @ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv INT_TO_ADDR arg127 var207 @@ -180,11 +180,11 @@ FUNCTION foo () : {tuple, []} LOG3 arg255 arg15 arg211 var139 arg44 - LOG4 #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv a247 a 9 a38 a + LOG4 @ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv a247 a 9 a38 a DEACTIVATE - SPEND #nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv var136 + SPEND @ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv var136 ORACLE_REGISTER arg29 48 ((| 5 | 2 | (1, "foo", ()) |)) arg65 { <> => false} <> diff --git a/test/asm_code/immediates.fate b/test/asm_code/immediates.fate index 3efcc1a..d0b6445 100644 --- a/test/asm_code/immediates.fate +++ b/test/asm_code/immediates.fate @@ -66,7 +66,7 @@ FUNCTION tuple() : {tuple, [integer, boolean, string, {tuple, [integer, integer] FUNCTION address() : address - RETURNR #deadbeef + RETURNR @ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv ;; Option(integer) = NONE | SOME(integer) FUNCTION variant_none() : {variant, [{tuple, []}, {tuple, [integer]}]}