Blockchain explorer for Ethereum based network and a tool for inspecting and analyzing EVM based blockchains.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
blockscout/lib/explorer/forms/transaction_form.ex

98 lines
2.7 KiB

defmodule Explorer.TransactionForm do
@moduledoc "Format a Block and a Transaction for display."
import Ecto.Query
import ExplorerWeb.Gettext
alias Cldr.Number
alias Explorer.Block
alias Explorer.Receipt
alias Explorer.Repo
def build(transaction) do
block = (Ecto.assoc_loaded?(transaction.block) && transaction.block) || nil
receipt = Ecto.assoc_loaded?(transaction.receipt) && transaction.receipt
status = status(transaction, receipt || Receipt.null())
%{
block_number: block |> block_number,
age: block |> block_age,
formatted_age: block |> format_age,
formatted_timestamp: block |> format_timestamp,
cumulative_gas_used: block |> cumulative_gas_used,
to_address_hash: transaction |> to_address_hash,
from_address_hash: transaction |> from_address_hash,
confirmations: block |> confirmations,
status: status,
formatted_status: status |> format_status,
first_seen: transaction |> first_seen,
last_seen: transaction |> last_seen
}
end
def build_and_merge(transaction) do
Map.merge(transaction, build(transaction))
end
def block_number(block) do
(block && block.number) || ""
end
def block_age(block) do
(block && block.timestamp |> Timex.from_now()) || gettext("Pending")
end
def format_age(block) do
(block && "#{block_age(block)} (#{format_timestamp(block)})") || gettext("Pending")
end
def format_timestamp(block) do
(block && block.timestamp |> Timex.format!("%b-%d-%Y %H:%M:%S %p %Z", :strftime)) ||
gettext("Pending")
end
def cumulative_gas_used(block) do
(block && block.gas_used |> Number.to_string!()) || gettext("Pending")
end
def to_address_hash(transaction) do
(transaction.to_address && transaction.to_address.hash) || nil
end
def from_address_hash(transaction) do
(transaction.to_address && transaction.from_address.hash) || nil
end
def confirmations(block) do
query = from(block in Block, select: max(block.number))
(block && Repo.one(query) - block.number) || 0
end
def status(transaction, receipt) do
%{
0 => %{true => :out_of_gas, false => :failed},
1 => %{true => :success, false => :success}
}
|> Map.get(receipt.status, %{true: :pending, false: :pending})
|> Map.get(receipt.gas_used == transaction.gas)
end
def format_status(status) do
%{
out_of_gas: gettext("Out of Gas"),
failed: gettext("Failed"),
success: gettext("Success"),
pending: gettext("Pending")
}
|> Map.fetch!(status)
end
def first_seen(transaction) do
transaction.inserted_at |> Timex.from_now()
end
def last_seen(transaction) do
transaction.updated_at |> Timex.from_now()
end
end