0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ネイティブトークンの収入と支出を監視

Posted at

はじめに(Introduction)

Ethereumなど、EVM互換ブロックチェーンのネイティブトークンに対して、秘密鍵をもつアカウント(以下、EOA)のネイティブトークンに対する収入と支出を監視しようとした場合、案外複雑な手順が必要なので説明したいと思います。

輸入と支出トークン(In Out Token)

ネイティブトークンの収入と支出には以下の2つが考えられます。

  • EOA ⇒ EOA
  • EOA ⇒ コントラクトアカウント(CA) ⇒ EOA

トランザクションをノードに送付するには秘密鍵が必要な為、EOAからの送付となります。

支出トークン(Out Token)

ネイティブトークンの支出を見てみます。

手順として、まずはトランザクションデータを取得します。
トランザクションデータの取得には、単体であればeth_getTransactionByHasheth_getTransactionByBlockNumberAndIndexeth_getTransactionByBlockHashAndIndexなどから、複数であればeth_getBlockByHasheth_getBlockByNumberhydratedオプションを true にすることで取得できます。
以下がトランザクションデータのデータ構造となります。
※:トランザクションの形式により項目が増える場合もあります。

field type description
blockHash DATA
32バイト
このトランザクションが組み込まれていたブロックのハッシュ
保留中の場合はnull
blockNumber QUANTITY このトランザクションが組み込まれていたブロックの番号
保留中の場合はnull
from DATA
20バイト
送信者のアドレス
gas QUANTITY 送信者が提供するガス
gasPrice QUANTITY 送信者が指定したガス価格(wei単位)
hash DATA、32バイト トランザクションのハッシュ
input DATA トランザクションと共に送信されるデータ
nonce QUANTITY 送信者がこのトランザクションより前に送信したトランザクションの数
to DATA
20バイト
受信者のアドレス
コントラクト作成時のトランザクションはnull
transactionIndex QUANTITY ブロック内のトランザクションのインデックスの位置(整数)
保留中の場合はnull
value QUANTITY 送金された価値(wei単位)
v QUANTITY ECDSAのリカバリID
r QUANTITY ECDSA署名 r
s QUANTITY ECDSA署名 s

fromが対象のEOAであった場合、支出していることになります。

支出を計算する前に、このトランザクションレシートを取得します。
トランザクションレシートの取得方法は、eth_getTransactionReceipt を利用します。
以下がトランザクションレシートのデータ構造となります。

field type description
transactionHash DATA
32バイト
トランザクションのハッシュ
transactionIndex QUANTITY ブロック内のトランザクションのインデックスの位置(整数)
blockHash DATA
32バイト
このトランザクションが組み込まれていたブロックのハッシュ
blockNumber QUANTITY このトランザクションが組み込まれていたブロックの番号
from DATA
20バイト
送信者のアドレス
to DATA
20バイト
受信者のアドレス
コントラクト作成時のトランザクションはnull
cumulativeGasUsed QUANTITY ブロック内でこのトランザクションの実行時に使用されたガスの総量
effectiveGasPrice QUANTITY ガスユニットごとに支払われるベースフィーとチップの合計
gasUsed QUANTITY この特定のトランザクションのみで使用されたガスの量
contractAddress DATA
20バイト
コントラクト作成のトランザクションの場合は、作成されたコントラクト
logs Array このトランザクションが生成したログオブジェクトの配列
logsBloom DATA
256バイト
関連ログを迅速に取得するためのライトクライアント用のブルームフィルター
type QUANTITY トランザクションタイプの整数、0x0でレガシートランザクション、 0x1でアクセスリストタイプ、0x2で動的手数料
status QUANTITY 1(成功)、または 0(失敗)

このデータから、statusを参照します。

1(成功) の場合

支出は、トランザクションデータから以下の式で求めることができます。

$ \mathrm{Out} = \mathrm{value} + \mathrm{gas} \times \mathrm{gasPrice} $

0(失敗) の場合

支出の値は、トランザクションデータから以下の式で求めることができます。

$ \mathrm{Out} = \mathrm{gas} \times \mathrm{gasPrice} $

収入トークン(In Token)

支出と同等に、トランザクションデータとトランザクションレシートを取得します。

以下の2つの場合でも収入の可能性はあります。

  • トランザクションデータの to が対象のEOAでない
  • トランザクションデータの value0x0

トランザクションレシートの statusを参照します。

  • 0(失敗) の場合
    ネイティブトークンの収入はありません。

  • 1(成功) の場合
    ここからまた分岐します。
    トランザクションデータの to を参照します。

    • to が対象のEOAだった場合
      トランザクションデータの value が収入の値となります。
    • to が対象のEOAでない場合
      インターナルトランザクションを調べる必要があります。
      Gethの場合、debug_traceTransaction を利用してインターナルトランザクションを取得します。
      パラメータは、トランザクションハッシュと callTracer({ tracer: 'callTracer' }) になります。
      • call(サブcallが存在)を検索
        • toが対象のEOAだった場合
          callvalue が収入の値となります。

以下がcallのデータ構造となります。

field type description
type string CALL または CREATE
from string アドレス
to string アドレス
value string 16進数でエンコードされた価値転送量(value transfer)
gas string call 用に提供された 16 進数でエンコードされたガス(gas)
gasUsed string call 中に使用された 16 進数でエンコードされたガス
input string call データ
output string リターンデータ
error string エラー(ある場合)
revertReason string Solidity の「revert」理由(ある場合)
calls []callframe サブcallのリスト

インターナルトランザクション(Internal Transaction)

インターナルトランザクションの仕様を探したところ、イーサリアム仮想マシン(EVM)のドキュメントに記載されていました。

The calldata
calldata 領域は、スマート コントラクト トランザクションの一部としてトランザクションに送信されるデータです。
たとえば、コントラクトを作成する場合、calldata は新しいコントラクトのコンストラクター コードになります。
calldata は不変であり、CALLDATALOAD、CALLDATASIZE、および CALLDATACOPY 命令を使用して読み取ることができます。
コントラクトが xCALL 命令を実行すると、内部トランザクション(internal transaction)も作成されることに注意してください。
その結果、xCALL を実行すると、新しいコンテキストに calldata 領域が存在します。

まとめ(Conclusion)

EOAからの支出に関しては比較的簡単に見つけることが出来ます。
EOAへの収入に関しては、かなり複雑な手順が必要となります。
これは、コントラクトからEOAへの支出がEOAからの場合とコントラクトからの場合がある為です。
コントラクト内での呼び出しはインターナルトランザクションとして作成される為、これらをトレースする必要があります。

参考(References)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?