From 74a7ae1a6e3d12f921cd9ca138d9de553197bc91 Mon Sep 17 00:00:00 2001 From: LiAohua Date: Wed, 3 Jan 2024 08:12:18 +0800 Subject: [PATCH] update --- .swp | Bin 12288 -> 0 bytes lib/components/transaction.ex | 109 ++++++++++++++++++++++++++++++++++ lib/components/verifier.ex | 3 +- lib/utils/type_translator.ex | 7 +++ mix.exs | 3 + 5 files changed, 121 insertions(+), 1 deletion(-) delete mode 100644 .swp create mode 100644 lib/components/transaction.ex diff --git a/.swp b/.swp deleted file mode 100644 index a60f871474e292634716f120cf4095f3aa001cb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI%%SyvQ6oBEWu3Rbl0#(;7lQeD8r6{P2c%v0}VUn4W(rQ~1(#ytIaq9#5J|;EY zNY|FYe_-Y?hk-Nm!7M^T`F!iwyG<$bI4Y*!cu9qLpG2eOdfHUC=ci(yHol4)ufw-t zb3BREc>7kW2q3UCfrEa_w$@Mm{Oq)Ta@^n9Nob4!0tg_000IagfB*vjFOW`a;v;Xn zSGL|SbL~$qmm~xbKmY**5I_I{1Q0*~0R#}Jpn%dsEDnYE%t!J6fAjtSov*((^$OmL zBO`zS0tg_000IagfB*srAW$U%OXiUzvADi6t6-Up3rCr;NOv{eEwkNyFR>m6)9PM>X7|D*O#Sb1zG=Bg9 diff --git a/lib/components/transaction.ex b/lib/components/transaction.ex new file mode 100644 index 0000000..b1652b0 --- /dev/null +++ b/lib/components/transaction.ex @@ -0,0 +1,109 @@ +defmodule Components.Transaction do + alias Ethereumex.HttpClient + defstruct from: <<>>, to: <<>>, gas_price: 0, gas_limit: 0, value: 0, init: <<>>, data: <<>> + + @base_recovery_id_eip_155 35 + + def send(chain_id, priv_key, tx, nonce, others) do + items = prepare_items(tx, nonce, others) + + # Refer to EIP-155, we SHOULD hash nine rlp encoded elements: + # (nonce, gasprice, startgas, to, value, data, chainid, 0, 0) + hashed_tx = hash(items ++ [encode_unsigned(chain_id), <<>>, <<>>]) + {v, r, s} = sign(hashed_tx, priv_key, chain_id) + signature = [ + encode_unsigned(v), + encode_unsigned(r), + encode_unsigned(s) + ] + + raw_tx = + (items ++ signature) + |> ExRLP.encode(encoding: :hex) + HttpClient.eth_send_raw_transaction("0x" <> raw_tx, others) + end + + def send(chain_id, priv_key, tx, others) do + items = prepare_items(tx, others) + + # Refer to EIP-155, we SHOULD hash nine rlp encoded elements: + # (nonce, gasprice, startgas, to, value, data, chainid, 0, 0) + hashed_tx = hash(items ++ [encode_unsigned(chain_id), <<>>, <<>>]) + {v, r, s} = sign(hashed_tx, priv_key, chain_id) + signature = [ + encode_unsigned(v), + encode_unsigned(r), + encode_unsigned(s) + ] + + raw_tx = + (items ++ signature) + |> ExRLP.encode(encoding: :hex) + HttpClient.eth_send_raw_transaction("0x" <> raw_tx, others) + end + + def get_gas(contract_address, behaviour, payloads, others) do + transaction = %{ + "to" => contract_address, + "data" => TypeTranslator.get_data(behaviour, payloads) + } + + {:ok, gas_limit} = HttpClient.eth_estimate_gas(transaction, others) + {:ok, gas_price} = HttpClient.eth_gas_price(others) + + { + TypeTranslator.hex_to_int(gas_limit), + TypeTranslator.hex_to_int(gas_price) + } + end + + defp prepare_items(tx, nonce, _others) do + + [ + encode_unsigned(nonce), + encode_unsigned(tx.gas_price), + encode_unsigned(tx.gas_limit), + tx.to |> String.replace("0x", "") |> Base.decode16!(case: :mixed), + encode_unsigned(tx.value || 0), + if(tx.to == <<>>, do: <<>>, else: tx.data) + ] + end + + defp prepare_items(tx, others) do + nonce = get_nonce(tx.from, others) + + [ + encode_unsigned(nonce), + encode_unsigned(tx.gas_price), + encode_unsigned(tx.gas_limit), + tx.to |> String.replace("0x", "") |> Base.decode16!(case: :mixed), + encode_unsigned(tx.value || 0), + if(tx.to == <<>>, do: <<>>, else: tx.data) + ] + end + + defp hash(items) do + items + |> ExRLP.encode(encoding: :binary) + |> ExKeccak.hash_256() + end + + defp sign(hashed_tx, priv_key, chain_id) do + {:ok, {<>, recovery_id}} = + ExSecp256k1.sign_compact(hashed_tx, priv_key) + + # Refer to EIP-155 + recovery_id = chain_id * 2 + @base_recovery_id_eip_155 + recovery_id + + {recovery_id, r, s} + end + + def get_nonce(wallet_address, others) do + {:ok, hex} = HttpClient.eth_get_transaction_count(wallet_address, "latest", others) + + TypeTranslator.hex_to_int(hex) + end + + defp encode_unsigned(0), do: <<>> + defp encode_unsigned(number), do: :binary.encode_unsigned(number) +end \ No newline at end of file diff --git a/lib/components/verifier.ex b/lib/components/verifier.ex index c91ec89..1644e0d 100644 --- a/lib/components/verifier.ex +++ b/lib/components/verifier.ex @@ -103,6 +103,7 @@ defmodule Components.Verifier do defp verify_signature(hash, signature) do {r, s, v} = destructure_sig(signature) - :libsecp256k1.ecdsa_recover_compact(hash, r <> s, :uncompressed, v) + # :libsecp256k1.ecdsa_recover_compact(hash, r <> s, :uncompressed, v) + ExSecp256k1.recover_compact(hash, r <> s, v) end end diff --git a/lib/utils/type_translator.ex b/lib/utils/type_translator.ex index d24e79c..1ed575b 100644 --- a/lib/utils/type_translator.ex +++ b/lib/utils/type_translator.ex @@ -1,4 +1,11 @@ defmodule TypeTranslator do + @doc """ + TODO: impl the cases. + iex(34)> ABI.encode("buy(uint256,uint256)", [13721, 10000000000000000]) + iex(33)> ABI.decode("buy(uint256,uint256)", "d6febde80000000000000000000000000000000000000000000000000000000000003599000000000000000000000000000000000000000000000000002386f26fc10000" |> Base.decode16!(case: :lower)) +[97245039436039886927109785377494219820477888259653562449568703439859083116544, + 369917428219973928622626114008996352472975258621679195013222636231821042] + """ def str_to_module(class, mod_name) do "Elixir.TaiShangWorldGenerator.#{class}.#{mod_name}" diff --git a/mix.exs b/mix.exs index 7e78b29..8f37ecf 100644 --- a/mix.exs +++ b/mix.exs @@ -111,6 +111,9 @@ defmodule TaiShangMicroFaasSystem.MixProject do # graphql client {:neuron, "~> 5.1.0"}, + # decimal + {:decimal, "~> 2.0"} + ] end