Change return type of contract_call/N

This commit is contained in:
Craig Everett
2022-10-15 00:06:05 +09:00
parent 5925b6dedb
commit 9b2aff77d3
+96 -28
View File
@@ -736,14 +736,16 @@ read_aci(Path) ->
end.
-spec contract_call(CallerID, Nonce, AACI, ConID, Fun, Args) -> CallTX
-spec contract_call(CallerID, Nonce, AACI, ConID, Fun, Args) -> Result
when CallerID :: binary(),
Nonce :: pos_integer(),
AACI :: map(),
ConID :: binary(),
Fun :: string(),
Args :: [string()],
CallTX :: binary().
Result :: {ok, CallTX} | {error, Reason},
CallTX :: binary(),
Reason :: term().
%% @doc
%% Form a contract call using hardcoded default values for `Gas', `GasPrice', `Fee',
%% and `Amount' to simplify the call (10 args is a bit much for normal calls!).
@@ -753,19 +755,19 @@ read_aci(Path) ->
%% For details on the meaning of these and other argument values see the doc comment
%% for contract_call/10.
contract_call(CallerID, Nonce, ACI, ConID, Fun, Args) ->
contract_call(CallerID, Nonce, AACI, ConID, Fun, Args) ->
Gas = 20000,
GasPrice = min_gas_price(),
Fee = 200000000000000,
Amount = 0,
contract_call(CallerID, Nonce,
Gas, GasPrice, Fee, Amount,
ACI, ConID, Fun, Args).
AACI, ConID, Fun, Args).
-spec contract_call(CallerID, Nonce,
Gas, GasPrice, Fee, Amount,
AACI, ConID, Fun, Args) -> CallTX
AACI, ConID, Fun, Args) -> Result
when CallerID :: binary(),
Nonce :: pos_integer(),
Gas :: pos_integer(),
@@ -776,7 +778,9 @@ contract_call(CallerID, Nonce, ACI, ConID, Fun, Args) ->
ConID :: binary(),
Fun :: string(),
Args :: [string()],
CallTX :: binary().
Result :: {ok, CallTX} | {error, Reason},
CallTX :: binary(),
Reason :: term().
%% @doc
%% Form a contract call using the supplied values.
%%
@@ -885,14 +889,33 @@ contract_call(CallerID, Nonce, ACI, ConID, Fun, Args) ->
%% if you do not already have a copy, and can check the spec of a function before
%% trying to form a contract call.
contract_call(CallerID, Nonce, Gas, GasPrice, Fee, Amount, ACI, ConID, Fun, Args) ->
{ok, CallData} = encode_call_data(ACI, Fun, Args),
contract_call(CallerID, Nonce, Gas, GP, Fee, Amount, AACI, ConID, Fun, Args) ->
case encode_call_data(AACI, Fun, Args) of
{ok, CD} -> contract_call2(CallerID, Nonce, Gas, GP, Fee, Amount, ConID, CD);
Error -> Error
end.
contract_call2(CallerID, Nonce, Gas, GasPrice, Fee, Amount, ConID, CallData) ->
try
{account_pubkey, PK} = aeser_api_encoder:decode(CallerID),
contract_call3(PK, Nonce, Gas, GasPrice, Fee, Amount, ConID, CallData)
catch
Error:Reason -> {Error, Reason}
end.
contract_call3(PK, Nonce, Gas, GasPrice, Fee, Amount, ConID, CallData) ->
try
{contract_pubkey, CK} = aeser_api_encoder:decode(ConID),
contract_call4(PK, Nonce, Gas, GasPrice, Fee, Amount, CK, CallData)
catch
Error:Reason -> {Error, Reason}
end.
contract_call4(PK, Nonce, Gas, GasPrice, Fee, Amount, CK, CallData) ->
ABI = 3,
TTL = 0,
CallVersion = 1,
Type = contract_call_tx,
{account_pubkey, PK} = aeser_api_encoder:decode(CallerID),
{contract_pubkey, CK} = aeser_api_encoder:decode(ConID),
Fields =
[{caller_id, {id, account, PK}},
{nonce, Nonce},
@@ -916,7 +939,11 @@ contract_call(CallerID, Nonce, Gas, GasPrice, Fee, Amount, ACI, ConID, Fun, Args
{gas_price, int},
{call_data, binary}],
TXB = aeser_chain_objects:serialize(Type, CallVersion, Template, Fields),
aeser_api_encoder:encode(transaction, TXB).
try
{ok, aeser_api_encoder:encode(transaction, TXB)}
catch
error:Reason -> {error, Reason}
end.
-spec prepare_contract(File) -> {ok, AACI} | {error, Reason}
@@ -929,7 +956,7 @@ contract_call(CallerID, Nonce, Gas, GasPrice, Fee, Amount, ACI, ConID, Fun, Args
prepare_contract(File) ->
case aeso_compiler:file(File, [{aci, json}]) of
{ok, #{aci := ACI}} -> prepare_aaci(ACI);
{ok, #{aci := ACI}} -> {ok, prepare_aaci(ACI)};
Error -> Error
end.
@@ -963,17 +990,39 @@ type(Name) -> binary_to_list(Name).
%type(#{<<"map">> := {K, V}} -> {map, type(K), type(V)};
%type(<<"string">>) -> string;
coerce({integer, S}) ->
list_to_integer(S);
coerce({address, S}) ->
{account_pubkey, Key} = aeser_api_encoder:decode(S),
{address, Key};
coerce({contract, S}) ->
aeser_api_encoder:decode(S);
coerce({bool, S}) ->
S;
coerce({_, S}) ->
S.
coerce({{ArgName, integer}, S}, {Good, Broken}) ->
try
N = list_to_integer(S),
{[N | Good], Broken}
catch
error:Reason -> {Good, [{ArgName, Reason} | Broken]}
end;
coerce({{ArgName, address}, S}, {Good, Broken}) ->
try
case aeser_api_encoder:decode(S) of
{account_pubkey, Key} -> {[{address, Key} | Good], Broken};
_ -> {Good, [{ArgName, bad_pubkey} | Broken]}
end
catch
error:Reason -> {Good, [{ArgName, Reason} | Broken]}
end;
coerce({{ArgName, contract}, S}, {Good, Broken}) ->
try
case aeser_api_encoder:decode(S) of
R = {contract_bytearray, _} -> {[R | Good], Broken};
_ -> {Good, [{ArgName, bad_contract} | Broken]}
end
catch
error:Reason -> {Good, [{ArgName, Reason} | Broken]}
end;
coerce({{_, bool}, true}, {Good, Broken}) ->
{[true | Good], Broken};
coerce({{_, bool}, false}, {Good, Broken}) ->
{[false | Good], Broken};
coerce({{ArgName, bool}, _}, {Good, Broken}) ->
{Good, [{ArgName, not_bool} | Broken]};
coerce({_, S}, {Good, Broken}) ->
{[S | Good], Broken}.
-spec min_gas_price() -> integer().
@@ -993,11 +1042,30 @@ min_gas_price() ->
1000000000.
encode_call_data({aaci, _Name, FunDefs}, Fun, Args) ->
ArgDef = maps:get(Fun, FunDefs),
Binding = lists:zip([element(2, D) || D <- ArgDef], Args),
Coerced = lists:map(fun coerce/1, Binding),
aeb_fate_abi:create_calldata(Fun, Coerced).
encode_call_data({aaci, _, FunDefs}, Fun, Args) ->
case maps:find(Fun, FunDefs) of
{ok, ArgDef} -> encode_call_data2(ArgDef, Fun, Args);
error -> {error, bad_fun_name}
end.
encode_call_data2(ArgDef, Fun, Args) ->
DefLength = length(ArgDef),
ArgLength = length(Args),
if
DefLength =:= ArgLength -> encode_call_data3(ArgDef, Fun, Args);
DefLength > ArgLength -> {error, too_few_args};
DefLength < ArgLength -> {error, too_many_args}
end.
encode_call_data3(ArgDef, Fun, Args) ->
Binding = lists:zip(ArgDef, Args),
case lists:foldl(fun coerce/2, {[], []}, Binding) of
{Coerced, []} ->
Reversed = lists:reverse(Coerced),
aeb_fate_abi:create_calldata(Fun, Reversed);
{_, Errors} ->
{error, {args, lists:reverse(Errors)}}
end.