diff --git a/src/aeb_fate_abi.erl b/src/aeb_fate_abi.erl index 91f05b2..bd6d305 100644 --- a/src/aeb_fate_abi.erl +++ b/src/aeb_fate_abi.erl @@ -9,7 +9,12 @@ %%%------------------------------------------------------------------- -module(aeb_fate_abi). --export([ create_calldata/2 ]). +-export([ create_calldata/2 + , get_function_hash_from_calldata/1 + , get_function_name_from_function_hash/2 + , get_function_type_from_function_hash/2 ]). + +-include("../include/aeb_fate_data.hrl"). %%%=================================================================== %%% API @@ -21,3 +26,37 @@ create_calldata(FunName, Args) -> {ok, aeb_fate_encoding:serialize( aeb_fate_data:make_tuple({FunctionId, aeb_fate_data:make_tuple(list_to_tuple(Args))}))}. + +-spec get_function_name_from_function_hash(binary(), aeb_fate_code:fcode()) -> + {ok, term()} | {error, term()}. +get_function_name_from_function_hash(<>, FateCode) -> + get_function_name_from_function_hash(SymbolHash, FateCode); +get_function_name_from_function_hash(SymbolHash = <<_:4/binary>>, FateCode) -> + Symbols = aeb_fate_code:symbols(FateCode), + case maps:get(SymbolHash, Symbols, undefined) of + undefined -> {error, no_function_matching_function_hash}; + Function -> {ok, Function} + end. + +-spec get_function_hash_from_calldata(binary()) -> + {ok, binary()} | {error, term()}. +get_function_hash_from_calldata(CallData) -> + try ?FATE_TUPLE_ELEMENTS(aeb_fate_encoding:deserialize(CallData)) of + [FunHash, _Args] -> {ok, FunHash}; + _ -> {error, bad_calldata} + catch _:_ -> + {error, bad_calldata} + end. + +-spec get_function_type_from_function_hash(binary(), aeb_fate_code:fcode()) -> + {ok, term()} | {error, term()}. +get_function_type_from_function_hash(<>, FateCode) -> + get_function_type_from_function_hash(SymbolHash, FateCode); +get_function_type_from_function_hash(SymbolHash, FateCode) -> + Functions = aeb_fate_code:functions(FateCode), + case maps:get(SymbolHash, Functions, undefined) of + undefined -> + {error, no_function_matching_function_hash}; + {{ArgTypes, RetType}, _Code} -> + {ok, ArgTypes, RetType} + end. diff --git a/src/aeb_fate_code.erl b/src/aeb_fate_code.erl index a60858b..5d010bc 100644 --- a/src/aeb_fate_code.erl +++ b/src/aeb_fate_code.erl @@ -27,7 +27,7 @@ -include("../include/aeb_fate_data.hrl"). -ifdef(EQC). --export([update_annotations/2 +-export([ update_annotations/2 , update_functions/2 , update_symbols/2]). -endif. @@ -39,6 +39,9 @@ -define(HASH_BYTES, 32). +-type fcode() :: #fcode{}. +-export_type([fcode/0]). + %%%=================================================================== %%% API %%%=================================================================== diff --git a/src/aeb_fate_generate_ops.erl b/src/aeb_fate_generate_ops.erl index 757ecb2..1458a34 100644 --- a/src/aeb_fate_generate_ops.erl +++ b/src/aeb_fate_generate_ops.erl @@ -166,6 +166,7 @@ ops_defs() -> , { 'ECVERIFY_SECP256K1', 16#73, false, 1300, [a,a,a,a], ecverify_secp256k1, {hash, signature, signature}, boolean, "Arg0 := ecverify_secp256k1(Hash, PubKey, Signature)"} , { 'CONTRACT_TO_ADDRESS', 16#74, false, 3, [a,a], contract_to_address, {contract}, address, "Arg0 := Arg1 - A no-op type conversion"} + , { 'AUTH_TX_HASH', 16#75, false, 3, [a], auth_tx_hash, {}, variant, "If in GA authentication context return Some(TxHash) otherwise None."} , { 'DEACTIVATE', 16#fa, false, 3, [], deactivate, {}, none, "Mark the current contract for deactivation."} , { 'ABORT', 16#fb, true, 3, [a], abort, {string}, none, "Abort execution (dont use all gas) with error message in Arg0."} diff --git a/test/asm_code/all_instructions.fate b/test/asm_code/all_instructions.fate index d40dbbb..0516967 100644 --- a/test/asm_code/all_instructions.fate +++ b/test/asm_code/all_instructions.fate @@ -243,3 +243,7 @@ FUNCTION foo () : {tuple, []} BALANCE_OTHER a arg0 SETELEMENT a 2 (1, "two", 3) 2 + + AUTH_TX_HASH + + CONTRACT_TO_ADDRESS @ct_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv