Move sign, spend, account decode, etc to lib
This commit is contained in:
parent
b6cb79d81e
commit
10e3a0b1c3
189
src/hz.erl
189
src/hz.erl
@ -29,13 +29,13 @@
|
||||
-license("GPL-3.0-or-later").
|
||||
|
||||
% Get/Set admin functions.
|
||||
-export([network_id/0, network_id/1,
|
||||
chain_nodes/0, chain_nodes/1,
|
||||
-export([chain_nodes/0, chain_nodes/1,
|
||||
tls/0, tls/1,
|
||||
timeout/0, timeout/1]).
|
||||
|
||||
% Node JSON query interface functions
|
||||
-export([top_height/0, top_block/0,
|
||||
-export([network_id/0,
|
||||
top_height/0, top_block/0,
|
||||
kb_current/0, kb_current_hash/0, kb_current_height/0,
|
||||
kb_pending/0,
|
||||
kb_by_hash/1, kb_by_height/1,
|
||||
@ -71,6 +71,8 @@
|
||||
contract_call/6,
|
||||
contract_call/10,
|
||||
decode_bytearray_fate/1, decode_bytearray/2,
|
||||
spend/5, spend/10,
|
||||
sign_tx/2, sign_tx/3,
|
||||
verify_signature/3]).
|
||||
|
||||
|
||||
@ -225,17 +227,10 @@
|
||||
%% call data or perform other actions on chain that require a signature.
|
||||
|
||||
network_id() ->
|
||||
hz_man:network_id().
|
||||
|
||||
|
||||
-spec network_id(Identifier) -> ok | {error, Reason}
|
||||
when Identifier :: string() | none,
|
||||
Reason :: not_started.
|
||||
%% @doc
|
||||
%% Sets the network ID, or returns `not_started' if the service is not yet started.
|
||||
|
||||
network_id(Identifier) ->
|
||||
hz_man:network_id(Identifier).
|
||||
case status() of
|
||||
{ok, #{"network_id" := NetworkID}} -> {ok, NetworkID};
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
|
||||
-spec chain_nodes() -> [chain_node()].
|
||||
@ -2110,6 +2105,172 @@ encode_call_data2(ArgDef, Fun, Args) ->
|
||||
end.
|
||||
|
||||
|
||||
sign_tx(Unsigned, SecKey) ->
|
||||
case network_id() of
|
||||
{ok, NetworkID} -> sign_tx(Unsigned, SecKey, NetworkID);
|
||||
Error -> Error
|
||||
end.
|
||||
|
||||
sign_tx(Unsigned, SecKey, MNetworkID) ->
|
||||
UnsignedBin = unicode:characters_to_binary(Unsigned),
|
||||
NetworkID = unicode:characters_to_binary(MNetworkID),
|
||||
{ok, TX_Data} = gmser_api_encoder:safe_decode(transaction, UnsignedBin),
|
||||
{ok, Hash} = eblake2:blake2b(32, TX_Data),
|
||||
NetworkHash = <<NetworkID/binary, Hash/binary>>,
|
||||
Signature = ecu_eddsa:sign_detached(NetworkHash, SecKey),
|
||||
SigTxType = signed_tx,
|
||||
SigTxVsn = 1,
|
||||
SigTemplate =
|
||||
[{signatures, [binary]},
|
||||
{transaction, binary}],
|
||||
TX =
|
||||
[{signatures, [Signature]},
|
||||
{transaction, TX_Data}],
|
||||
SignedTX = gmser_chain_objects:serialize(SigTxType, SigTxVsn, SigTemplate, TX),
|
||||
gmser_api_encoder:encode(transaction, SignedTX).
|
||||
|
||||
|
||||
spend(SenderID, SecKey, ReceipientID, Amount, Payload) ->
|
||||
case status() of
|
||||
{ok, #{"top_block_height" := Height, "network_id" := NetworkID}} ->
|
||||
spend(SenderID, SecKey, ReceipientID, Amount, Payload, Height, NetworkID);
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
spend(SenderID, SecKey, RecipientID, Amount, Payload, Height, NetworkID) ->
|
||||
case next_nonce(SenderID) of
|
||||
{ok, Nonce} ->
|
||||
{ok, Height} = top_height(),
|
||||
TTL = Height + 262980,
|
||||
Gas = 20000,
|
||||
GasPrice = min_gas_price(),
|
||||
spend(SenderID,
|
||||
SecKey,
|
||||
RecipientID,
|
||||
Amount,
|
||||
GasPrice,
|
||||
Gas,
|
||||
TTL,
|
||||
Nonce,
|
||||
Payload,
|
||||
NetworkID);
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
|
||||
spend(SenderID,
|
||||
SecKey,
|
||||
RecipientID,
|
||||
Amount,
|
||||
GasPrice,
|
||||
Gas,
|
||||
TTL,
|
||||
Nonce,
|
||||
Payload,
|
||||
NetworkID) ->
|
||||
case decode_account_id(unicode:characters_to_binary(SenderID)) of
|
||||
{ok, DSenderID} ->
|
||||
spend2(gmser_id:create(account, DSenderID),
|
||||
SecKey,
|
||||
RecipientID,
|
||||
Amount,
|
||||
GasPrice,
|
||||
Gas,
|
||||
TTL,
|
||||
Nonce,
|
||||
Payload,
|
||||
NetworkID);
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
spend2(DSenderID,
|
||||
SecKey,
|
||||
RecipientID,
|
||||
Amount,
|
||||
GasPrice,
|
||||
Gas,
|
||||
TTL,
|
||||
Nonce,
|
||||
Payload,
|
||||
NetworkID) ->
|
||||
case decode_account_id(unicode:characters_to_binary(RecipientID)) of
|
||||
{ok, DRecipientID} ->
|
||||
spend3(DSenderID,
|
||||
SecKey,
|
||||
gmser_id:create(account, DRecipientID),
|
||||
Amount,
|
||||
GasPrice,
|
||||
Gas,
|
||||
TTL,
|
||||
Nonce,
|
||||
Payload,
|
||||
NetworkID);
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
|
||||
decode_account_id(S) when is_list(S) ->
|
||||
decode_account_id(list_to_binary(S));
|
||||
decode_account_id(B) ->
|
||||
try
|
||||
{account_pubkey, PK} = gmser_api_encoder:decode(B),
|
||||
{ok, PK}
|
||||
catch
|
||||
E:R -> {E, R}
|
||||
end.
|
||||
|
||||
|
||||
spend3(DSenderID,
|
||||
SecKey,
|
||||
DRecipientID,
|
||||
Amount,
|
||||
GasPrice,
|
||||
Gas,
|
||||
TTL,
|
||||
Nonce,
|
||||
Payload,
|
||||
MNetworkID) ->
|
||||
NetworkID = unicode:characters_to_binary(MNetworkID),
|
||||
Type = spend_tx,
|
||||
Vsn = 1,
|
||||
Fields =
|
||||
[{sender_id, DSenderID},
|
||||
{recipient_id, DRecipientID},
|
||||
{amount, Amount},
|
||||
{gas_price, GasPrice},
|
||||
{gas, Gas},
|
||||
{ttl, TTL},
|
||||
{nonce, Nonce},
|
||||
{payload, Payload}],
|
||||
Template =
|
||||
[{sender_id, id},
|
||||
{recipient_id, id},
|
||||
{amount, int},
|
||||
{gas_price, int},
|
||||
{gas, int},
|
||||
{ttl, int},
|
||||
{nonce, int},
|
||||
{payload, binary}],
|
||||
BinaryTX = gmser_chain_objects:serialize(Type, Vsn, Template, Fields),
|
||||
NetworkTX = <<NetworkID/binary, BinaryTX/binary>>,
|
||||
Signature = ecu_eddsa:sign_detached(NetworkTX, SecKey),
|
||||
SigTxType = signed_tx,
|
||||
SigTxVsn = 1,
|
||||
SigTemplate =
|
||||
[{signatures, [binary]},
|
||||
{transaction, binary}],
|
||||
TX_Data =
|
||||
[{signatures, [Signature]},
|
||||
{transaction, BinaryTX}],
|
||||
SignedTX = gmser_chain_objects:serialize(SigTxType, SigTxVsn, SigTemplate, TX_Data),
|
||||
Encoded = gmser_api_encoder:encode(transaction, SignedTX),
|
||||
hz:post_tx(Encoded).
|
||||
|
||||
|
||||
-spec verify_signature(Sig, Message, PubKey) -> Result
|
||||
when Sig :: binary(),
|
||||
Message :: iodata(),
|
||||
|
@ -16,8 +16,7 @@
|
||||
-license("MIT").
|
||||
|
||||
%% Admin functions
|
||||
-export([network_id/0, network_id/1,
|
||||
tls/0, tls/1,
|
||||
-export([tls/0, tls/1,
|
||||
chain_nodes/0, chain_nodes/1,
|
||||
timeout/0, timeout/1]).
|
||||
|
||||
@ -44,8 +43,7 @@
|
||||
req = none :: none | binary()}).
|
||||
|
||||
-record(s,
|
||||
{network_id = "gm_mainnet" :: string(),
|
||||
tls = false :: boolean(),
|
||||
{tls = false :: boolean(),
|
||||
chain_nodes = {[], []} :: {[hz:chain_node()], [hz:chain_node()]},
|
||||
sticky = none :: none | hz:chain_node(),
|
||||
fetchers = [] :: [#fetcher{}],
|
||||
@ -58,19 +56,6 @@
|
||||
|
||||
%%% Service Interface
|
||||
|
||||
-spec network_id() -> Name
|
||||
when Name :: hz:network_id().
|
||||
|
||||
network_id() ->
|
||||
gen_server:call(?MODULE, network_id).
|
||||
|
||||
|
||||
-spec network_id(Name) -> ok
|
||||
when Name :: hz:network_id().
|
||||
|
||||
network_id(Name) ->
|
||||
gen_server:cast(?MODULE, {network_id, Name}).
|
||||
|
||||
|
||||
-spec tls() -> boolean().
|
||||
|
||||
@ -163,8 +148,6 @@ init(none) ->
|
||||
handle_call({request, Request}, From, State) ->
|
||||
NewState = do_request(Request, From, State),
|
||||
{noreply, NewState};
|
||||
handle_call(network_id, _, State = #s{network_id = Name}) ->
|
||||
{reply, Name, State};
|
||||
handle_call(tls, _, State = #s{tls = TLS}) ->
|
||||
{reply, TLS, State};
|
||||
handle_call(chain_nodes, _, State = #s{chain_nodes = {Wait, Used}}) ->
|
||||
@ -177,8 +160,6 @@ handle_call(Unexpected, From, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
|
||||
handle_cast({network_id, Name}, State) ->
|
||||
{noreply, State#s{network_id = Name}};
|
||||
handle_cast({tls, Boolean}, State) ->
|
||||
NewState = do_tls(Boolean, State),
|
||||
{noreply, NewState};
|
||||
|
Loading…
x
Reference in New Issue
Block a user