|
|
|
@ -1,12 +1,11 @@ |
|
|
|
|
defmodule BlockScoutWeb.TransactionView do |
|
|
|
|
use BlockScoutWeb, :view |
|
|
|
|
|
|
|
|
|
alias ABI.TypeDecoder |
|
|
|
|
alias BlockScoutWeb.{AddressView, BlockView, TabHelpers} |
|
|
|
|
alias Cldr.Number |
|
|
|
|
alias Explorer.Chain |
|
|
|
|
alias Explorer.Chain.Block.Reward |
|
|
|
|
alias Explorer.Chain.{Address, Block, InternalTransaction, TokenTransfer, Transaction, Wei} |
|
|
|
|
alias Explorer.Chain.{Address, Block, InternalTransaction, Transaction, Wei} |
|
|
|
|
alias Explorer.ExchangeRates.Token |
|
|
|
|
alias Timex.Duration |
|
|
|
|
|
|
|
|
@ -33,85 +32,10 @@ defmodule BlockScoutWeb.TransactionView do |
|
|
|
|
|
|
|
|
|
def value_transfer?(_), do: false |
|
|
|
|
|
|
|
|
|
def erc20_token_transfer( |
|
|
|
|
%Transaction{ |
|
|
|
|
status: :ok, |
|
|
|
|
created_contract_address_hash: nil, |
|
|
|
|
input: input, |
|
|
|
|
value: value |
|
|
|
|
}, |
|
|
|
|
token_transfers |
|
|
|
|
) do |
|
|
|
|
zero_wei = %Wei{value: Decimal.new(0)} |
|
|
|
|
|
|
|
|
|
case {to_string(input), value} do |
|
|
|
|
{unquote(TokenTransfer.transfer_function_signature()) <> params, ^zero_wei} -> |
|
|
|
|
types = [:address, {:uint, 256}] |
|
|
|
|
|
|
|
|
|
[address, value] = decode_params(params, types) |
|
|
|
|
|
|
|
|
|
decimal_value = Decimal.new(value) |
|
|
|
|
|
|
|
|
|
Enum.find(token_transfers, fn token_transfer -> |
|
|
|
|
token_transfer.to_address_hash.bytes == address && token_transfer.amount == decimal_value |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
_ -> |
|
|
|
|
nil |
|
|
|
|
end |
|
|
|
|
rescue |
|
|
|
|
_ -> nil |
|
|
|
|
def token_transfer_type(transaction) do |
|
|
|
|
Chain.transaction_token_transfer_type(transaction) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
def erc20_token_transfer(_, _) do |
|
|
|
|
nil |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
def erc721_token_transfer( |
|
|
|
|
%Transaction{ |
|
|
|
|
status: :ok, |
|
|
|
|
created_contract_address_hash: nil, |
|
|
|
|
input: input, |
|
|
|
|
value: value |
|
|
|
|
}, |
|
|
|
|
token_transfers |
|
|
|
|
) do |
|
|
|
|
zero_wei = %Wei{value: Decimal.new(0)} |
|
|
|
|
|
|
|
|
|
# https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721.sol#L35 |
|
|
|
|
{from_address, to_address} = |
|
|
|
|
case {to_string(input), value} do |
|
|
|
|
# transferFrom(address,address,uint256) |
|
|
|
|
{"0x23b872dd" <> params, ^zero_wei} -> |
|
|
|
|
types = [:address, :address, {:uint, 256}] |
|
|
|
|
[from_address, to_address, _value] = decode_params(params, types) |
|
|
|
|
{from_address, to_address} |
|
|
|
|
|
|
|
|
|
# safeTransferFrom(address,address,uint256) |
|
|
|
|
{"0x42842e0e" <> params, ^zero_wei} -> |
|
|
|
|
types = [:address, :address, {:uint, 256}] |
|
|
|
|
[from_address, to_address, _value] = decode_params(params, types) |
|
|
|
|
{from_address, to_address} |
|
|
|
|
|
|
|
|
|
# safeTransferFrom(address,address,uint256,bytes) |
|
|
|
|
{"0xb88d4fde" <> params, ^zero_wei} -> |
|
|
|
|
types = [:address, :address, {:uint, 256}, :bytes] |
|
|
|
|
[from_address, to_address, _value, _data] = decode_params(params, types) |
|
|
|
|
{from_address, to_address} |
|
|
|
|
|
|
|
|
|
_ -> |
|
|
|
|
nil |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
Enum.find(token_transfers, fn token_transfer -> |
|
|
|
|
token_transfer.from_address_hash.bytes == from_address && token_transfer.to_address_hash.bytes == to_address |
|
|
|
|
end) |
|
|
|
|
rescue |
|
|
|
|
_ -> nil |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
def erc721_token_transfer(_, _), do: nil |
|
|
|
|
|
|
|
|
|
def processing_time_duration(%Transaction{block: nil}) do |
|
|
|
|
:pending |
|
|
|
|
end |
|
|
|
@ -339,10 +263,4 @@ defmodule BlockScoutWeb.TransactionView do |
|
|
|
|
defp tab_name(["internal_transactions"]), do: gettext("Internal Transactions") |
|
|
|
|
defp tab_name(["logs"]), do: gettext("Logs") |
|
|
|
|
defp tab_name(["raw_trace"]), do: gettext("Raw Trace") |
|
|
|
|
|
|
|
|
|
defp decode_params(params, types) do |
|
|
|
|
params |
|
|
|
|
|> Base.decode16!(case: :mixed) |
|
|
|
|
|> TypeDecoder.decode_raw(types) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|