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").
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
% Get/Set admin functions.
|
% Get/Set admin functions.
|
||||||
-export([network_id/0, network_id/1,
|
-export([chain_nodes/0, chain_nodes/1,
|
||||||
chain_nodes/0, chain_nodes/1,
|
|
||||||
tls/0, tls/1,
|
tls/0, tls/1,
|
||||||
timeout/0, timeout/1]).
|
timeout/0, timeout/1]).
|
||||||
|
|
||||||
% Node JSON query interface functions
|
% 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_current/0, kb_current_hash/0, kb_current_height/0,
|
||||||
kb_pending/0,
|
kb_pending/0,
|
||||||
kb_by_hash/1, kb_by_height/1,
|
kb_by_hash/1, kb_by_height/1,
|
||||||
@ -71,6 +71,8 @@
|
|||||||
contract_call/6,
|
contract_call/6,
|
||||||
contract_call/10,
|
contract_call/10,
|
||||||
decode_bytearray_fate/1, decode_bytearray/2,
|
decode_bytearray_fate/1, decode_bytearray/2,
|
||||||
|
spend/5, spend/10,
|
||||||
|
sign_tx/2, sign_tx/3,
|
||||||
verify_signature/3]).
|
verify_signature/3]).
|
||||||
|
|
||||||
|
|
||||||
@ -225,17 +227,10 @@
|
|||||||
%% call data or perform other actions on chain that require a signature.
|
%% call data or perform other actions on chain that require a signature.
|
||||||
|
|
||||||
network_id() ->
|
network_id() ->
|
||||||
hz_man:network_id().
|
case status() of
|
||||||
|
{ok, #{"network_id" := NetworkID}} -> {ok, NetworkID};
|
||||||
|
Error -> Error
|
||||||
-spec network_id(Identifier) -> ok | {error, Reason}
|
end.
|
||||||
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).
|
|
||||||
|
|
||||||
|
|
||||||
-spec chain_nodes() -> [chain_node()].
|
-spec chain_nodes() -> [chain_node()].
|
||||||
@ -2110,6 +2105,172 @@ encode_call_data2(ArgDef, Fun, Args) ->
|
|||||||
end.
|
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
|
-spec verify_signature(Sig, Message, PubKey) -> Result
|
||||||
when Sig :: binary(),
|
when Sig :: binary(),
|
||||||
Message :: iodata(),
|
Message :: iodata(),
|
||||||
|
@ -16,8 +16,7 @@
|
|||||||
-license("MIT").
|
-license("MIT").
|
||||||
|
|
||||||
%% Admin functions
|
%% Admin functions
|
||||||
-export([network_id/0, network_id/1,
|
-export([tls/0, tls/1,
|
||||||
tls/0, tls/1,
|
|
||||||
chain_nodes/0, chain_nodes/1,
|
chain_nodes/0, chain_nodes/1,
|
||||||
timeout/0, timeout/1]).
|
timeout/0, timeout/1]).
|
||||||
|
|
||||||
@ -44,8 +43,7 @@
|
|||||||
req = none :: none | binary()}).
|
req = none :: none | binary()}).
|
||||||
|
|
||||||
-record(s,
|
-record(s,
|
||||||
{network_id = "gm_mainnet" :: string(),
|
{tls = false :: boolean(),
|
||||||
tls = false :: boolean(),
|
|
||||||
chain_nodes = {[], []} :: {[hz:chain_node()], [hz:chain_node()]},
|
chain_nodes = {[], []} :: {[hz:chain_node()], [hz:chain_node()]},
|
||||||
sticky = none :: none | hz:chain_node(),
|
sticky = none :: none | hz:chain_node(),
|
||||||
fetchers = [] :: [#fetcher{}],
|
fetchers = [] :: [#fetcher{}],
|
||||||
@ -58,19 +56,6 @@
|
|||||||
|
|
||||||
%%% Service Interface
|
%%% 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().
|
-spec tls() -> boolean().
|
||||||
|
|
||||||
@ -163,8 +148,6 @@ init(none) ->
|
|||||||
handle_call({request, Request}, From, State) ->
|
handle_call({request, Request}, From, State) ->
|
||||||
NewState = do_request(Request, From, State),
|
NewState = do_request(Request, From, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
handle_call(network_id, _, State = #s{network_id = Name}) ->
|
|
||||||
{reply, Name, State};
|
|
||||||
handle_call(tls, _, State = #s{tls = TLS}) ->
|
handle_call(tls, _, State = #s{tls = TLS}) ->
|
||||||
{reply, TLS, State};
|
{reply, TLS, State};
|
||||||
handle_call(chain_nodes, _, State = #s{chain_nodes = {Wait, Used}}) ->
|
handle_call(chain_nodes, _, State = #s{chain_nodes = {Wait, Used}}) ->
|
||||||
@ -177,8 +160,6 @@ handle_call(Unexpected, From, State) ->
|
|||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
|
|
||||||
handle_cast({network_id, Name}, State) ->
|
|
||||||
{noreply, State#s{network_id = Name}};
|
|
||||||
handle_cast({tls, Boolean}, State) ->
|
handle_cast({tls, Boolean}, State) ->
|
||||||
NewState = do_tls(Boolean, State),
|
NewState = do_tls(Boolean, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user