use new method in view

pull/2093/head
Ayrat Badykov 6 years ago
parent f7868aac80
commit 26232bfb39
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 29
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  2. 88
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  3. 24
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  4. 16
      apps/explorer/lib/explorer/chain.ex

@ -169,39 +169,22 @@
</div>
</div>
<%= cond do %>
<% erc20_token_transfer = assigns[:token_transfers] && erc20_token_transfer(@transaction, @token_transfers) -> %>
<%= case token_transfer_type(@transaction) do %>
<% {type, token_transfer} -> %>
<div class="col-md-12 col-lg-4 d-flex flex-column flex-md-row flex-lg-column pl-0">
<!-- Value -->
<div class="card card-background-1 flex-grow-1">
<div class="card-body card-body-flex-column-space-between">
<h2 class="card-title balance-card-title"><%= gettext "ERC-20" %> <%= gettext "Token Transfer" %></h2>
<h2 class="card-title balance-card-title"><%= if type == :erc20, do: gettext("ERC-20"), else: gettext("ERC-721")%><%= gettext " Token Transfer" %></h2>
<div class="text-right">
<h3 class="address-balance-text">
<%= token_transfer_amount(erc20_token_transfer) %>
<%= link(token_symbol(erc20_token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, erc20_token_transfer.token.contract_address_hash)) %>
</h3>
</div>
</div>
</div>
<% erc721_token_transfer = assigns[:token_transfers] && erc721_token_transfer(@transaction, @token_transfers) -> %>
<div class="col-md-12 col-lg-4 d-flex flex-column flex-md-row flex-lg-column">
<!-- Value -->
<div class="card card-primary flex-grow-1">
<div class="card-body">
<h2 class="card-title text-white"><%= gettext "ERC-721" %> <%= gettext "Token Transfer" %></h2>
<div class="text-right">
<h3 class="text-white">
<span class="col-12 col-md-7 ml-3 ml-sm-0">
<%= token_transfer_amount(erc721_token_transfer) %>
<%= link(token_symbol(erc721_token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, erc721_token_transfer.token.contract_address_hash)) %>
</span>
<%= token_transfer_amount(token_transfer) %>
<%= link(token_symbol(token_transfer.token), to: token_path(BlockScoutWeb.Endpoint, :show, token_transfer.token.contract_address_hash)) %>
</h3>
</div>
</div>
</div>
<% true -> %>
<% _ -> %>
<div class="col-md-12 col-lg-4 d-flex flex-column flex-md-row flex-lg-column pl-0-md">
<!-- Value -->
<div class="card card-background-1 flex-grow-1">

@ -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

@ -47,30 +47,6 @@ defmodule BlockScoutWeb.TransactionViewTest do
end
end
describe "erc721_token_transfer/2" do
test "finds token transfer" do
from_address_hash = "0x7a30272c902563b712245696f0a81c5a0e45ddc8"
to_address_hash = "0xb544cead8b660aae9f2e37450f7be2ffbc501793"
from_address = insert(:address, hash: from_address_hash)
to_address = insert(:address, hash: to_address_hash)
block = insert(:block)
transaction =
insert(:transaction,
input:
"0x23b872dd0000000000000000000000007a30272c902563b712245696f0a81c5a0e45ddc8000000000000000000000000b544cead8b660aae9f2e37450f7be2ffbc5017930000000000000000000000000000000000000000000000000000000000000002",
value: Decimal.new(0),
created_contract_address_hash: nil
)
|> with_block(block, status: :ok)
token_transfer =
insert(:token_transfer, from_address: from_address, to_address: to_address, transaction: transaction)
assert TransactionView.erc721_token_transfer(transaction, [token_transfer]) == token_transfer
end
end
describe "processing_time_duration/2" do
test "returns :pending if the transaction has no block" do
transaction = build(:transaction, block: nil)

@ -2833,10 +2833,7 @@ defmodule Explorer.Chain do
) do
zero_wei = %Wei{value: Decimal.new(0)}
transaction =
if Ecto.assoc_loaded?(transaction.token_transfers),
do: transaction,
else: Repo.preload(transaction, :token_transfers)
transaction = Repo.preload(transaction, token_transfers: :token)
# https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC721/ERC721.sol#L35
case {to_string(input), value} do
@ -2890,17 +2887,16 @@ defmodule Explorer.Chain do
end
defp find_erc721_or_erc20_token_transfer(token_transfers, {address, decimal_value}) do
IO.inspect({address, decimal_value})
token_transfer =
Enum.find(token_transfers, fn token_transfer ->
token_transfer.to_address_hash.bytes == address && token_transfer.amount == decimal_value
token_transfer.to_address_hash.bytes == address &&
(token_transfer.amount == decimal_value || token_transfer.token_id)
end)
if token_transfer do
case token_from_address_hash(token_transfer.token_contract_address_hash) do
{:ok, %Token{type: "ERC-20"}} -> {:erc20, token_transfer}
{:ok, %Token{type: "ERC-721"}} -> {:erc721, token_transfer}
case token_transfer.token do
%Token{type: "ERC-20"} -> {:erc20, token_transfer}
%Token{type: "ERC-721"} -> {:erc721, token_transfer}
_ -> nil
end
end

Loading…
Cancel
Save