|
|
|
@ -4,6 +4,7 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
using a custom tracer (`priv/js/ethereum_jsonrpc/geth/debug_traceTransaction/tracer.js`). |
|
|
|
|
""" |
|
|
|
|
import EthereumJSONRPC, only: [quantity_to_integer: 1] |
|
|
|
|
import EthereumJSONRPC.Transaction, only: [put_if_present: 3] |
|
|
|
|
|
|
|
|
|
@doc """ |
|
|
|
|
A call can call another another contract: |
|
|
|
@ -75,7 +76,9 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
from_address_hash: "0x8ec75ef3adf6c953775d0738e0e7bd60e647e5ef", |
|
|
|
|
to_address_hash: "0xaae465ad04b12e90c32291e59b65ca781c57e361", |
|
|
|
|
gas: 1225, |
|
|
|
|
gas_used: 1225, |
|
|
|
|
input: "0xa83627de", |
|
|
|
|
output: nil, |
|
|
|
|
value: 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -110,9 +113,11 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
from_address_hash: "0xaf7cf620c3df1b9ccbc640be903d5ea6cea7bc96", |
|
|
|
|
to_address_hash: "0x80629758f88b3f30b7f1244e4588444d6276eef0", |
|
|
|
|
input: "0x49b46d5d", |
|
|
|
|
output: nil, |
|
|
|
|
error: "stack limit reached 1024 (1024)", |
|
|
|
|
gas: 1445580, |
|
|
|
|
value: 0 |
|
|
|
|
gas_used: 1445580, |
|
|
|
|
value: 0, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
A contract creation: |
|
|
|
@ -179,6 +184,7 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
init: "0xf49e4745", |
|
|
|
|
error: "stack underflow (0 <=> 6)", |
|
|
|
|
gas: 540776, |
|
|
|
|
gas_used: 540776, |
|
|
|
|
value: 5287885714285715 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -254,8 +260,7 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
gas_used: 1040, |
|
|
|
|
input: "0x0f370699", |
|
|
|
|
output: "0x", |
|
|
|
|
value: 0, |
|
|
|
|
error: nil |
|
|
|
|
value: 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
A selfdestruct destroys the calling contract and sends any left over balance to the to address. |
|
|
|
@ -300,6 +305,8 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
Enum.into(call, %{}, &entry_to_elixir/1) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp entry_to_elixir({"error", nil} = entry), do: entry |
|
|
|
|
|
|
|
|
|
defp entry_to_elixir({key, value} = entry) |
|
|
|
|
when key in ~w(callType createdContractAddressHash createdContractCode error from init input output to transactionHash type) and |
|
|
|
|
is_binary(value), |
|
|
|
@ -318,40 +325,8 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
entry |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp elixir_to_internal_transaction_params(%{ |
|
|
|
|
"blockNumber" => block_number, |
|
|
|
|
"transactionIndex" => transaction_index, |
|
|
|
|
"transactionHash" => transaction_hash, |
|
|
|
|
"index" => index, |
|
|
|
|
"traceAddress" => trace_address, |
|
|
|
|
"type" => type, |
|
|
|
|
"callType" => call_type, |
|
|
|
|
"from" => from_address_hash, |
|
|
|
|
"to" => to_address_hash, |
|
|
|
|
"gas" => gas, |
|
|
|
|
"input" => input, |
|
|
|
|
"error" => error, |
|
|
|
|
"value" => value |
|
|
|
|
}) |
|
|
|
|
when type in ~w(call invalid) and call_type in ~w(call callcode delegatecall invalid) do |
|
|
|
|
defp elixir_to_internal_transaction_params( |
|
|
|
|
%{ |
|
|
|
|
block_number: block_number, |
|
|
|
|
transaction_index: transaction_index, |
|
|
|
|
transaction_hash: transaction_hash, |
|
|
|
|
index: index, |
|
|
|
|
trace_address: trace_address, |
|
|
|
|
type: "call", |
|
|
|
|
call_type: call_type, |
|
|
|
|
from_address_hash: from_address_hash, |
|
|
|
|
to_address_hash: to_address_hash, |
|
|
|
|
gas: gas, |
|
|
|
|
input: input, |
|
|
|
|
error: error, |
|
|
|
|
value: value |
|
|
|
|
} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp elixir_to_internal_transaction_params(%{ |
|
|
|
|
"blockNumber" => block_number, |
|
|
|
|
"transactionIndex" => transaction_index, |
|
|
|
|
"transactionHash" => transaction_hash, |
|
|
|
@ -364,10 +339,10 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
"gas" => gas, |
|
|
|
|
"gasUsed" => gas_used, |
|
|
|
|
"input" => input, |
|
|
|
|
"output" => output, |
|
|
|
|
"value" => value |
|
|
|
|
}) |
|
|
|
|
when type in ~w(call invalid) and call_type in ~w(call callcode delegatecall invalid) do |
|
|
|
|
} = params |
|
|
|
|
) |
|
|
|
|
when type in ~w(call invalid) and call_type in ~w(call callcode delegatecall staticcall invalid) do |
|
|
|
|
%{ |
|
|
|
|
block_number: block_number, |
|
|
|
|
transaction_index: transaction_index, |
|
|
|
@ -381,48 +356,16 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
gas: gas, |
|
|
|
|
gas_used: gas_used, |
|
|
|
|
input: input, |
|
|
|
|
output: output, |
|
|
|
|
output: params["output"], |
|
|
|
|
value: value |
|
|
|
|
} |
|
|
|
|
|> put_if_present(params, [ |
|
|
|
|
{"error", :error} |
|
|
|
|
]) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp elixir_to_internal_transaction_params( |
|
|
|
|
%{ |
|
|
|
|
"blockNumber" => block_number, |
|
|
|
|
"transactionIndex" => transaction_index, |
|
|
|
|
"transactionHash" => transaction_hash, |
|
|
|
|
"index" => index, |
|
|
|
|
"traceAddress" => trace_address, |
|
|
|
|
"type" => "call" = type, |
|
|
|
|
"callType" => "staticcall" = call_type, |
|
|
|
|
"from" => from_address_hash, |
|
|
|
|
"to" => to_address_hash, |
|
|
|
|
"input" => input, |
|
|
|
|
"gas" => gas, |
|
|
|
|
"gasUsed" => gas_used, |
|
|
|
|
"value" => 0 = value |
|
|
|
|
} = params |
|
|
|
|
) do |
|
|
|
|
%{ |
|
|
|
|
block_number: block_number, |
|
|
|
|
transaction_index: transaction_index, |
|
|
|
|
transaction_hash: transaction_hash, |
|
|
|
|
index: index, |
|
|
|
|
trace_address: trace_address, |
|
|
|
|
type: type, |
|
|
|
|
call_type: call_type, |
|
|
|
|
from_address_hash: from_address_hash, |
|
|
|
|
to_address_hash: to_address_hash, |
|
|
|
|
gas: gas, |
|
|
|
|
gas_used: gas_used, |
|
|
|
|
input: input, |
|
|
|
|
output: params["output"], |
|
|
|
|
value: value, |
|
|
|
|
error: params["error"] |
|
|
|
|
} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp elixir_to_internal_transaction_params(%{ |
|
|
|
|
"blockNumber" => block_number, |
|
|
|
|
"transactionIndex" => transaction_index, |
|
|
|
|
"transactionHash" => transaction_hash, |
|
|
|
@ -430,42 +373,12 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
"traceAddress" => trace_address, |
|
|
|
|
"type" => type, |
|
|
|
|
"from" => from_address_hash, |
|
|
|
|
"error" => error, |
|
|
|
|
"gas" => gas, |
|
|
|
|
"init" => init, |
|
|
|
|
"value" => value |
|
|
|
|
}) |
|
|
|
|
when type in ~w(create create2) do |
|
|
|
|
%{ |
|
|
|
|
block_number: block_number, |
|
|
|
|
transaction_index: transaction_index, |
|
|
|
|
transaction_hash: transaction_hash, |
|
|
|
|
index: index, |
|
|
|
|
trace_address: trace_address, |
|
|
|
|
type: type, |
|
|
|
|
from_address_hash: from_address_hash, |
|
|
|
|
gas: gas, |
|
|
|
|
error: error, |
|
|
|
|
init: init, |
|
|
|
|
value: value |
|
|
|
|
} |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp elixir_to_internal_transaction_params(%{ |
|
|
|
|
"blockNumber" => block_number, |
|
|
|
|
"transactionIndex" => transaction_index, |
|
|
|
|
"transactionHash" => transaction_hash, |
|
|
|
|
"index" => index, |
|
|
|
|
"traceAddress" => trace_address, |
|
|
|
|
"type" => type, |
|
|
|
|
"from" => from_address_hash, |
|
|
|
|
"createdContractAddressHash" => created_contract_address_hash, |
|
|
|
|
"gas" => gas, |
|
|
|
|
"gasUsed" => gas_used, |
|
|
|
|
"init" => init, |
|
|
|
|
"createdContractCode" => created_contract_code, |
|
|
|
|
"value" => value |
|
|
|
|
}) |
|
|
|
|
} = params |
|
|
|
|
) |
|
|
|
|
when type in ~w(create create2) do |
|
|
|
|
%{ |
|
|
|
|
block_number: block_number, |
|
|
|
@ -477,11 +390,14 @@ defmodule EthereumJSONRPC.Geth.Call do |
|
|
|
|
from_address_hash: from_address_hash, |
|
|
|
|
gas: gas, |
|
|
|
|
gas_used: gas_used, |
|
|
|
|
created_contract_address_hash: created_contract_address_hash, |
|
|
|
|
init: init, |
|
|
|
|
created_contract_code: created_contract_code, |
|
|
|
|
value: value |
|
|
|
|
} |
|
|
|
|
|> put_if_present(params, [ |
|
|
|
|
{"error", :error}, |
|
|
|
|
{"createdContractAddressHash", :created_contract_address_hash}, |
|
|
|
|
{"createdContractCode", :created_contract_code} |
|
|
|
|
]) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
defp elixir_to_internal_transaction_params(%{ |
|
|
|
|