Refactoring

pull/3013/head
Victor Baranov 5 years ago
parent 77ec071ef7
commit 6de9ab29b1
  1. 2
      apps/block_scout_web/lib/block_scout_web/controllers/transaction_raw_trace_controller.ex
  2. 155
      apps/ethereum_jsonrpc/lib/ethereum_jsonrpc/parity.ex
  3. 40
      apps/ethereum_jsonrpc/test/ethereum_jsonrpc/parity_test.exs
  4. 129
      apps/explorer/lib/explorer/chain.ex
  5. 6
      apps/explorer/test/explorer/chain/import/runner/blocks_test.exs
  6. 111
      apps/explorer/test/explorer/chain_test.exs

@ -36,7 +36,7 @@ defmodule BlockScoutWeb.TransactionRawTraceController do
internal_transactions
else
{:ok, first_trace_params} =
Keyword.fetch!(json_rpc_named_arguments, :variant).fetch_first_trace(
Chain.fetch_first_trace(
[
%{
block_hash: transaction.block_hash,

@ -8,10 +8,6 @@ defmodule EthereumJSONRPC.Parity do
alias EthereumJSONRPC.Parity.{FetchedBeneficiaries, Traces}
alias EthereumJSONRPC.{Transaction, Transactions}
alias Explorer.Chain
alias Explorer.Chain.{Data, Wei}
alias Explorer.Chain.InternalTransaction.{CallType, Type}
@behaviour EthereumJSONRPC.Variant
@impl EthereumJSONRPC.Variant
@ -53,6 +49,24 @@ defmodule EthereumJSONRPC.Parity do
end
end
@impl EthereumJSONRPC.Variant
def fetch_first_trace(transactions_params, json_rpc_named_arguments) when is_list(transactions_params) do
id_to_params = id_to_params(transactions_params)
with {:ok, responses} <-
id_to_params
|> trace_replay_transaction_requests()
|> json_rpc(json_rpc_named_arguments) do
{:ok, [first_trace]} = trace_replay_transaction_responses_to_first_trace_params(responses, id_to_params)
%{block_hash: block_hash} =
transactions_params
|> Enum.at(0)
{:ok, [%{first_trace: first_trace, block_hash: block_hash, json_rpc_named_arguments: json_rpc_named_arguments}]}
end
end
@doc """
Fetches the pending transactions from the Parity node.
@ -172,138 +186,7 @@ defmodule EthereumJSONRPC.Parity do
request(%{id: id, method: "trace_replayBlockTransactions", params: [integer_to_quantity(block_number), ["trace"]]})
end
@doc """
Fetches the first trace from the Parity trace URL.
"""
@impl EthereumJSONRPC.Variant
def fetch_first_trace(transactions_params, json_rpc_named_arguments) when is_list(transactions_params) do
id_to_params = id_to_params(transactions_params)
with {:ok, responses} <-
id_to_params
|> trace_replay_transaction_requests()
|> json_rpc(json_rpc_named_arguments) do
{:ok, [first_trace]} = trace_replay_transaction_responses_to_first_trace_params(responses, id_to_params)
%{block_hash: block_hash} =
transactions_params
|> Enum.at(0)
{:ok, to_address_hash} =
if Map.has_key?(first_trace, :to_address_hash) do
Chain.string_to_address_hash(first_trace.to_address_hash)
else
{:ok, nil}
end
{:ok, from_address_hash} = Chain.string_to_address_hash(first_trace.from_address_hash)
{:ok, created_contract_address_hash} =
if Map.has_key?(first_trace, :created_contract_address_hash) do
Chain.string_to_address_hash(first_trace.created_contract_address_hash)
else
{:ok, nil}
end
{:ok, transaction_hash} = Chain.string_to_transaction_hash(first_trace.transaction_hash)
{:ok, call_type} =
if Map.has_key?(first_trace, :call_type) do
CallType.load(first_trace.call_type)
else
{:ok, nil}
end
{:ok, type} = Type.load(first_trace.type)
{:ok, input} =
if Map.has_key?(first_trace, :input) do
Data.cast(first_trace.input)
else
{:ok, nil}
end
{:ok, output} =
if Map.has_key?(first_trace, :output) do
Data.cast(first_trace.output)
else
{:ok, nil}
end
{:ok, created_contract_code} =
if Map.has_key?(first_trace, :created_contract_code) do
Data.cast(first_trace.created_contract_code)
else
{:ok, nil}
end
{:ok, init} =
if Map.has_key?(first_trace, :init) do
Data.cast(first_trace.init)
else
{:ok, nil}
end
block_index =
get_block_index(%{
transaction_index: first_trace.transaction_index,
transaction_hash: first_trace.transaction_hash,
block_number: first_trace.block_number,
json_rpc_named_arguments: json_rpc_named_arguments
})
value = %Wei{value: Decimal.new(first_trace.value)}
first_trace_formatted =
first_trace
|> Map.merge(%{
block_index: block_index,
block_hash: block_hash,
call_type: call_type,
to_address_hash: to_address_hash,
created_contract_address_hash: created_contract_address_hash,
from_address_hash: from_address_hash,
input: input,
output: output,
created_contract_code: created_contract_code,
init: init,
transaction_hash: transaction_hash,
type: type,
value: value
})
{:ok, [first_trace_formatted]}
end
end
defp get_block_index(%{
transaction_index: transaction_index,
transaction_hash: transaction_hash,
block_number: block_number,
json_rpc_named_arguments: json_rpc_named_arguments
}) do
if transaction_index == 0 do
0
else
{:ok, traces} = fetch_block_internal_transactions([block_number], json_rpc_named_arguments)
sorted_traces =
traces
|> Enum.sort_by(&{&1.transaction_index, &1.index})
|> Enum.with_index()
{_, block_index} =
sorted_traces
|> Enum.find(fn {trace, _} ->
trace.transaction_index == transaction_index &&
trace.transaction_hash == transaction_hash
end)
block_index
end
end
defp trace_replay_transaction_responses_to_first_trace_params(responses, id_to_params)
def trace_replay_transaction_responses_to_first_trace_params(responses, id_to_params)
when is_list(responses) and is_map(id_to_params) do
with {:ok, traces} <- trace_replay_transaction_responses_to_first_trace(responses, id_to_params) do
params =

@ -6,9 +6,6 @@ defmodule EthereumJSONRPC.ParityTest do
import Mox
alias EthereumJSONRPC.FetchedBeneficiaries
alias Explorer.Chain
alias Explorer.Chain.Data
alias Explorer.Chain.InternalTransaction.Type
setup :verify_on_exit!
@ -107,8 +104,8 @@ defmodule EthereumJSONRPC.ParityTest do
end
end
describe "fetch_first_trace/1" do
test "with all valid block_numbers returns {:ok, first_trace_params}", %{
describe "fetch_first_trace/2" do
test "returns {:ok, first_trace_params}", %{
json_rpc_named_arguments: json_rpc_named_arguments
} do
from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca"
@ -131,7 +128,6 @@ defmodule EthereumJSONRPC.ParityTest do
transaction_hash = "0x0fa6f723216dba694337f9bb37d8870725655bdf2573526a39454685659e39b1"
transaction_index = 0
type = "create"
call_type = "create"
if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do
expect(EthereumJSONRPC.Mox, :json_rpc, fn _json, _options ->
@ -168,13 +164,6 @@ defmodule EthereumJSONRPC.ParityTest do
end)
end
{:ok, to_address_hash_bytes} = Chain.string_to_address_hash(created_contract_address_hash)
{:ok, from_address_hash_bytes} = Chain.string_to_address_hash(from_address_hash)
{:ok, created_contract_code_bytes} = Data.cast(created_contract_code)
{:ok, init_bytes} = Data.cast(init)
{:ok, transaction_hash_bytes} = Chain.string_to_transaction_hash(transaction_hash)
{:ok, type_bytes} = Type.load(type)
assert EthereumJSONRPC.Parity.fetch_first_trace(
[
%{
@ -187,22 +176,31 @@ defmodule EthereumJSONRPC.ParityTest do
json_rpc_named_arguments
) == {
:ok,
[
%{
block_index: 0,
block_hash: block_hash,
created_contract_address_hash: to_address_hash_bytes,
created_contract_code: created_contract_code_bytes,
from_address_hash: from_address_hash_bytes,
first_trace: %{
block_number: block_number,
created_contract_address_hash: created_contract_address_hash,
created_contract_code: created_contract_code,
from_address_hash: from_address_hash,
gas: gas,
gas_used: gas_used,
index: index,
init: init_bytes,
init: init,
trace_address: trace_address,
transaction_hash: transaction_hash_bytes,
type: type_bytes,
transaction_hash: transaction_hash,
type: type,
value: value,
transaction_index: transaction_index
},
block_hash: block_hash,
json_rpc_named_arguments: [
transport: EthereumJSONRPC.Mox,
transport_options: [],
variant: EthereumJSONRPC.Parity
]
}
]
}
end
end

@ -21,12 +21,14 @@ defmodule Explorer.Chain do
where: 3
]
import EthereumJSONRPC, only: [integer_to_quantity: 1]
import EthereumJSONRPC, only: [integer_to_quantity: 1, fetch_block_internal_transactions: 2]
alias ABI.TypeDecoder
alias Ecto.Adapters.SQL
alias Ecto.{Changeset, Multi}
alias Explorer.Chain
alias Explorer.Chain.{
Address,
Address.CoinBalance,
@ -63,6 +65,7 @@ defmodule Explorer.Chain do
}
alias Explorer.Chain.Import.Runner
alias Explorer.Chain.InternalTransaction.{CallType, Type}
alias Explorer.Counters.{AddressesCounter, AddressesWithBalanceCounter}
alias Explorer.Market.MarketHistoryCache
alias Explorer.{PagingOptions, Repo}
@ -4051,4 +4054,128 @@ defmodule Explorer.Chain do
defp boolean_to_check_result(true), do: :ok
defp boolean_to_check_result(false), do: :not_found
@doc """
Fetches the first trace from the Parity trace URL.
"""
def fetch_first_trace(transactions_params, json_rpc_named_arguments) do
{:ok, [%{first_trace: first_trace, block_hash: block_hash, json_rpc_named_arguments: json_rpc_named_arguments}]} =
EthereumJSONRPC.fetch_first_trace(transactions_params, json_rpc_named_arguments)
format_tx_first_trace(first_trace, block_hash, json_rpc_named_arguments)
end
defp format_tx_first_trace(first_trace, block_hash, json_rpc_named_arguments) do
{:ok, to_address_hash} =
if Map.has_key?(first_trace, :to_address_hash) do
Chain.string_to_address_hash(first_trace.to_address_hash)
else
{:ok, nil}
end
{:ok, from_address_hash} = Chain.string_to_address_hash(first_trace.from_address_hash)
{:ok, created_contract_address_hash} =
if Map.has_key?(first_trace, :created_contract_address_hash) do
Chain.string_to_address_hash(first_trace.created_contract_address_hash)
else
{:ok, nil}
end
{:ok, transaction_hash} = Chain.string_to_transaction_hash(first_trace.transaction_hash)
{:ok, call_type} =
if Map.has_key?(first_trace, :call_type) do
CallType.load(first_trace.call_type)
else
{:ok, nil}
end
{:ok, type} = Type.load(first_trace.type)
{:ok, input} =
if Map.has_key?(first_trace, :input) do
Data.cast(first_trace.input)
else
{:ok, nil}
end
{:ok, output} =
if Map.has_key?(first_trace, :output) do
Data.cast(first_trace.output)
else
{:ok, nil}
end
{:ok, created_contract_code} =
if Map.has_key?(first_trace, :created_contract_code) do
Data.cast(first_trace.created_contract_code)
else
{:ok, nil}
end
{:ok, init} =
if Map.has_key?(first_trace, :init) do
Data.cast(first_trace.init)
else
{:ok, nil}
end
block_index =
get_block_index(%{
transaction_index: first_trace.transaction_index,
transaction_hash: first_trace.transaction_hash,
block_number: first_trace.block_number,
json_rpc_named_arguments: json_rpc_named_arguments
})
value = %Wei{value: Decimal.new(first_trace.value)}
first_trace_formatted =
first_trace
|> Map.merge(%{
block_index: block_index,
block_hash: block_hash,
call_type: call_type,
to_address_hash: to_address_hash,
created_contract_address_hash: created_contract_address_hash,
from_address_hash: from_address_hash,
input: input,
output: output,
created_contract_code: created_contract_code,
init: init,
transaction_hash: transaction_hash,
type: type,
value: value
})
{:ok, [first_trace_formatted]}
end
defp get_block_index(%{
transaction_index: transaction_index,
transaction_hash: transaction_hash,
block_number: block_number,
json_rpc_named_arguments: json_rpc_named_arguments
}) do
if transaction_index == 0 do
0
else
{:ok, traces} = fetch_block_internal_transactions([block_number], json_rpc_named_arguments)
sorted_traces =
traces
|> Enum.sort_by(&{&1.transaction_index, &1.index})
|> Enum.with_index()
{_, block_index} =
sorted_traces
|> Enum.find(fn {trace, _} ->
trace.transaction_index == transaction_index &&
trace.transaction_hash == transaction_hash
end)
block_index
end
end
end

@ -7,7 +7,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
alias Ecto.Multi
alias Explorer.Chain.Import.Runner.{Blocks, Transactions}
alias Explorer.Chain.{Address, Block, Transaction, TokenTransfer}
alias Explorer.Chain.{Address, Block, Transaction}
alias Explorer.{Chain, Repo}
describe "run/1" do
@ -312,7 +312,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
end
test "removes duplicate blocks (by hash) before inserting",
%{consensus_block: %{number: _, hash: block_hash, miner_hash: miner_hash}, options: options} do
%{consensus_block: %{number: _, hash: _block_hash, miner_hash: miner_hash}, options: options} do
new_block = params_for(:block, miner_hash: miner_hash, consensus: true)
%Ecto.Changeset{valid?: true, changes: block_changes} = Block.changeset(%Block{}, new_block)
@ -322,7 +322,7 @@ defmodule Explorer.Chain.Import.Runner.BlocksTest do
|> Blocks.run([block_changes, block_changes], options)
|> Repo.transaction()
assert {:ok, %{blocks: [%{hash: block_hash, consensus: true}]}} = result
assert {:ok, %{blocks: [%{hash: _block_hash, consensus: true}]}} = result
end
end

@ -5,6 +5,7 @@ defmodule Explorer.ChainTest do
require Ecto.Query
import Ecto.Query
import EthereumJSONRPC, only: [integer_to_quantity: 1]
import Explorer.Factory
import Mox
@ -26,6 +27,9 @@ defmodule Explorer.ChainTest do
Wei
}
alias Explorer.Chain
alias Explorer.Chain.InternalTransaction.Type
alias Explorer.Chain.Supply.ProofOfAuthority
alias Explorer.Counters.AddressesWithBalanceCounter
alias Explorer.Counters.AddressesCounter
@ -4875,4 +4879,111 @@ defmodule Explorer.ChainTest do
assert third.delta == Decimal.new(1)
end
end
describe "fetch_first_trace/2" do
test "fetched first trace", %{
json_rpc_named_arguments: json_rpc_named_arguments
} do
from_address_hash = "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca"
gas = 4_533_872
init =
"0x6060604052341561000f57600080fd5b60405160208061071a83398101604052808051906020019091905050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506003600160006001600281111561007e57fe5b60ff1660ff168152602001908152602001600020819055506002600160006002808111156100a857fe5b60ff1660ff168152602001908152602001600020819055505061064a806100d06000396000f30060606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063247b3210146100935780632ffdfc8a146100bc57806374294144146100f6578063ae4b1b5b14610125578063bf7370d11461017a578063d1104cb2146101a3578063eecd1079146101f8578063fcff021c14610221575b600080fd5b341561009e57600080fd5b6100a661024a565b6040518082815260200191505060405180910390f35b34156100c757600080fd5b6100e0600480803560ff16906020019091905050610253565b6040518082815260200191505060405180910390f35b341561010157600080fd5b610123600480803590602001909190803560ff16906020019091905050610276565b005b341561013057600080fd5b61013861037a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561018557600080fd5b61018d61039f565b6040518082815260200191505060405180910390f35b34156101ae57600080fd5b6101b66104d9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561020357600080fd5b61020b610588565b6040518082815260200191505060405180910390f35b341561022c57600080fd5b6102346105bd565b6040518082815260200191505060405180910390f35b600060c8905090565b6000600160008360ff1660ff168152602001908152602001600020549050919050565b61027e6104d9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102b757600080fd5b60008160ff161115156102c957600080fd5b6002808111156102d557fe5b60ff168160ff16111515156102e957600080fd5b6000821180156103125750600160008260ff1660ff168152602001908152602001600020548214155b151561031d57600080fd5b81600160008360ff1660ff168152602001908152602001600020819055508060ff167fe868bbbdd6cd2efcd9ba6e0129d43c349b0645524aba13f8a43bfc7c5ffb0889836040518082815260200191505060405180910390a25050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b8414c46000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561042f57600080fd5b6102c65a03f1151561044057600080fd5b5050506040518051905090508073ffffffffffffffffffffffffffffffffffffffff16630eaba26a6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156104b857600080fd5b6102c65a03f115156104c957600080fd5b5050506040518051905091505090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3b3fff16000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561056857600080fd5b6102c65a03f1151561057957600080fd5b50505060405180519050905090565b60006105b860016105aa600261059c61039f565b6105e590919063ffffffff16565b61060090919063ffffffff16565b905090565b60006105e06105ca61039f565b6105d261024a565b6105e590919063ffffffff16565b905090565b60008082848115156105f357fe5b0490508091505092915050565b600080828401905083811015151561061457fe5b80915050929150505600a165627a7a723058206b7eef2a57eb659d5e77e45ab5bc074e99c6a841921038cdb931e119c6aac46c0029000000000000000000000000862d67cb0773ee3f8ce7ea89b328ffea861ab3ef"
value = 0
block_number = 39
block_hash = "0x74c72ccabcb98b7ebbd7b31de938212b7e8814a002263b6569564e944d88f51f"
index = 0
created_contract_address_hash = "0x1e0eaa06d02f965be2dfe0bc9ff52b2d82133461"
created_contract_code =
"0x60606040526004361061008e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063247b3210146100935780632ffdfc8a146100bc57806374294144146100f6578063ae4b1b5b14610125578063bf7370d11461017a578063d1104cb2146101a3578063eecd1079146101f8578063fcff021c14610221575b600080fd5b341561009e57600080fd5b6100a661024a565b6040518082815260200191505060405180910390f35b34156100c757600080fd5b6100e0600480803560ff16906020019091905050610253565b6040518082815260200191505060405180910390f35b341561010157600080fd5b610123600480803590602001909190803560ff16906020019091905050610276565b005b341561013057600080fd5b61013861037a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561018557600080fd5b61018d61039f565b6040518082815260200191505060405180910390f35b34156101ae57600080fd5b6101b66104d9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561020357600080fd5b61020b610588565b6040518082815260200191505060405180910390f35b341561022c57600080fd5b6102346105bd565b6040518082815260200191505060405180910390f35b600060c8905090565b6000600160008360ff1660ff168152602001908152602001600020549050919050565b61027e6104d9565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102b757600080fd5b60008160ff161115156102c957600080fd5b6002808111156102d557fe5b60ff168160ff16111515156102e957600080fd5b6000821180156103125750600160008260ff1660ff168152602001908152602001600020548214155b151561031d57600080fd5b81600160008360ff1660ff168152602001908152602001600020819055508060ff167fe868bbbdd6cd2efcd9ba6e0129d43c349b0645524aba13f8a43bfc7c5ffb0889836040518082815260200191505060405180910390a25050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638b8414c46000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561042f57600080fd5b6102c65a03f1151561044057600080fd5b5050506040518051905090508073ffffffffffffffffffffffffffffffffffffffff16630eaba26a6000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156104b857600080fd5b6102c65a03f115156104c957600080fd5b5050506040518051905091505090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3b3fff16000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b151561056857600080fd5b6102c65a03f1151561057957600080fd5b50505060405180519050905090565b60006105b860016105aa600261059c61039f565b6105e590919063ffffffff16565b61060090919063ffffffff16565b905090565b60006105e06105ca61039f565b6105d261024a565b6105e590919063ffffffff16565b905090565b60008082848115156105f357fe5b0490508091505092915050565b600080828401905083811015151561061457fe5b80915050929150505600a165627a7a723058206b7eef2a57eb659d5e77e45ab5bc074e99c6a841921038cdb931e119c6aac46c0029"
gas_used = 382_953
trace_address = []
transaction_hash = "0x0fa6f723216dba694337f9bb37d8870725655bdf2573526a39454685659e39b1"
transaction_index = 0
type = "create"
if json_rpc_named_arguments[:transport] == EthereumJSONRPC.Mox do
expect(EthereumJSONRPC.Mox, :json_rpc, fn _json, _options ->
{:ok,
[
%{
id: 0,
result: %{
"output" => "0x",
"stateDiff" => nil,
"trace" => [
%{
"action" => %{
"from" => from_address_hash,
"gas" => integer_to_quantity(gas),
"init" => init,
"value" => integer_to_quantity(value)
},
"blockNumber" => block_number,
"index" => index,
"result" => %{
"address" => created_contract_address_hash,
"code" => created_contract_code,
"gasUsed" => integer_to_quantity(gas_used)
},
"traceAddress" => trace_address,
"type" => type
}
],
"transactionHash" => transaction_hash
}
}
]}
end)
end
{:ok, created_contract_address_hash_bytes} = Chain.string_to_address_hash(created_contract_address_hash)
{:ok, from_address_hash_bytes} = Chain.string_to_address_hash(from_address_hash)
{:ok, created_contract_code_bytes} = Data.cast(created_contract_code)
{:ok, init_bytes} = Data.cast(init)
{:ok, transaction_hash_bytes} = Chain.string_to_transaction_hash(transaction_hash)
{:ok, type_bytes} = Type.load(type)
value_wei = %Wei{value: Decimal.new(value)}
assert Chain.fetch_first_trace(
[
%{
hash_data: transaction_hash,
block_hash: block_hash,
block_number: block_number,
transaction_index: transaction_index
}
],
json_rpc_named_arguments
) == {
:ok,
[
%{
block_index: 0,
block_number: block_number,
block_hash: block_hash,
call_type: nil,
created_contract_address_hash: created_contract_address_hash_bytes,
created_contract_code: created_contract_code_bytes,
from_address_hash: from_address_hash_bytes,
gas: gas,
gas_used: gas_used,
index: index,
init: init_bytes,
input: nil,
output: nil,
to_address_hash: nil,
trace_address: trace_address,
transaction_hash: transaction_hash_bytes,
type: type_bytes,
value: value_wei,
transaction_index: transaction_index
}
]
}
end
end
end

Loading…
Cancel
Save