aggregate token transfers

pull/2477/head
Ayrat Badykov 5 years ago
parent cb79fa59a5
commit 846b551f5b
No known key found for this signature in database
GPG Key ID: B44668E265E9396F
  1. 2
      apps/block_scout_web/lib/block_scout_web/templates/transaction/overview.html.eex
  2. 4
      apps/block_scout_web/lib/block_scout_web/views/tokens/helpers.ex
  3. 19
      apps/block_scout_web/lib/block_scout_web/views/transaction_view.ex
  4. 16
      apps/block_scout_web/test/block_scout_web/views/transaction_view_test.exs
  5. 5
      apps/explorer/test/support/factory.ex

@ -177,7 +177,7 @@
<div class="card-body card-body-flex-column-space-between"> <div class="card-body card-body-flex-column-space-between">
<h2 class="card-title balance-card-title"><%= token_type_name(type)%><%= gettext " Token Transfer" %></h2> <h2 class="card-title balance-card-title"><%= token_type_name(type)%><%= gettext " Token Transfer" %></h2>
<div class="text-right"> <div class="text-right">
<%= for transfer <- transaction_with_transfers.token_transfers do %> <%= for transfer <- aggregate_token_transfers(transaction_with_transfers.token_transfers) do %>
<h3 class="address-balance-text"> <h3 class="address-balance-text">
<%= token_transfer_amount(transfer) %> <%= token_transfer_amount(transfer) %>

@ -4,7 +4,7 @@ defmodule BlockScoutWeb.Tokens.Helpers do
""" """
alias BlockScoutWeb.{CurrencyHelpers} alias BlockScoutWeb.{CurrencyHelpers}
alias Explorer.Chain.{Address, Token, TokenTransfer} alias Explorer.Chain.{Address, Token}
@doc """ @doc """
Returns the token transfers' amount according to the token's type and decimals. Returns the token transfers' amount according to the token's type and decimals.
@ -16,7 +16,7 @@ defmodule BlockScoutWeb.Tokens.Helpers do
When the token's type is ERC-721, the function will return a string with the token_id that When the token's type is ERC-721, the function will return a string with the token_id that
represents the ERC-721 token since this kind of token doesn't have amount and decimals. represents the ERC-721 token since this kind of token doesn't have amount and decimals.
""" """
def token_transfer_amount(%TokenTransfer{token: token, amount: amount, token_id: token_id}) do def token_transfer_amount(%{token: token, amount: amount, token_id: token_id}) do
do_token_transfer_amount(token, amount, token_id) do_token_transfer_amount(token, amount, token_id)
end end

@ -39,6 +39,25 @@ defmodule BlockScoutWeb.TransactionView do
if type, do: {type, transaction_with_transfers} if type, do: {type, transaction_with_transfers}
end end
def aggregate_token_transfers(token_transfers) do
token_transfers
|> Enum.reduce(%{}, fn token_transfer, acc ->
new_entry = %{
token: token_transfer.token,
amount: token_transfer.amount,
token_id: token_transfer.token_id
}
existing_entry = Map.get(acc, token_transfer.token.contract_address_hash, %{new_entry | amount: Decimal.new(0)})
Map.put(acc, token_transfer.token.contract_address_hash, %{
new_entry
| amount: Decimal.add(new_entry.amount, existing_entry.amount)
})
end)
|> Enum.map(fn {_key, value} -> value end)
end
def token_type_name(type) do def token_type_name(type) do
case type do case type do
:erc20 -> gettext("ERC-20 ") :erc20 -> gettext("ERC-20 ")

@ -253,4 +253,20 @@ defmodule BlockScoutWeb.TransactionViewTest do
assert TransactionView.current_tab_name(logs_path) == "Logs" assert TransactionView.current_tab_name(logs_path) == "Logs"
end end
end end
describe "aggregate_token_transfers/1" do
test "aggregates token transfers" do
transaction =
:transaction
|> insert()
|> with_block()
token_transfer = insert(:token_transfer, transaction: transaction, amount: Decimal.new(1))
result = TransactionView.aggregate_token_transfers([token_transfer, token_transfer, token_transfer])
assert Enum.count(result) == 1
assert List.first(result).amount == Decimal.new(3)
end
end
end end

@ -413,7 +413,7 @@ defmodule Explorer.Factory do
contract_code = Map.fetch!(contract_code_info(), :bytecode) contract_code = Map.fetch!(contract_code_info(), :bytecode)
token_address = insert(:contract_address, contract_code: contract_code) token_address = insert(:contract_address, contract_code: contract_code)
insert(:token, contract_address: token_address) token = insert(:token, contract_address: token_address)
%TokenTransfer{ %TokenTransfer{
amount: Decimal.new(1), amount: Decimal.new(1),
@ -422,7 +422,8 @@ defmodule Explorer.Factory do
to_address: to_address, to_address: to_address,
token_contract_address: token_address, token_contract_address: token_address,
transaction: log.transaction, transaction: log.transaction,
log_index: log.index log_index: log.index,
token: token
} }
end end

Loading…
Cancel
Save