コンテンツにスキップ

ガスとストレージ手数料

Aptosブロックチェーン上でのトランザクション実行には処理手数料が必要です。現在、この手数料は2つのコンポーネントで構成されています:

  1. 実行とIOコスト
  • これは、トランザクションの処理やメインネットの分散ネットワーク全体での検証済みレコードの伝播など、一時的な計算リソースの使用をカバーします。
  • これはガスユニットで測定され、その価格はネットワークの負荷に応じて変動する可能性があります。これにより、ネットワークが忙しくない時に実行とIOコストを低く抑えることができます。
  • ガスのこの部分は、トランザクションの実行時に永続的に焼却されます。
  1. ストレージ手数料
  • これは、分散ブロックチェーンストレージに検証済みレコードを永続的に保存するコストをカバーします。
  • これは固定APT価格で測定されるため、ガスユニット価格がネットワークの一時的な負荷で変動しても、永続ストレージコストは安定したままです。
  • ストレージ手数料は、割り当てられたストレージスロットが削除されると返金される可能性があります。現在、ネットワークは状態ストレージスロットの生涯にわたって支払われたストレージ手数料の全額を返金するように設定されています。
  • システム実装をシンプルに保つため、ガスのこの部分は焼却され、返金時に再鋳造されます。

トランザクションは、その動作に応じてシンプルで安価なものから複雑なものまで様々です。Aptosブロックチェーンでは、ガスユニットは計算やストレージへのアクセスなど、一時的なリソースの消費の基本単位を表します。後者は、そのような操作の長期ストレージ側面と混同すべきではありません。それは別途ストレージ手数料でカバーされるからです。

ガス手数料の種類と利用可能な最適化の詳細については、How Base Gas Worksを参照してください。

Aptosフレームワークリリース1.7以降、手数料請求と返金の内訳は、0x1::transaction_fee::FeeStatement構造体で表現されるモジュールイベントとして出力されます。

#[event]
/// トランザクションの手数料請求と返金の内訳。
/// 構造は以下の通り:
///
/// - 正味請求または返金(明細書には含まれない)
/// - 総請求額:total_charge_gas_units、オンチェーンの`TransactionInfo`の`gas_used`と一致。
/// これは以下のサブアイテムの合計です。内部と外部のガスユニット間、およびネイティブトークンと
/// ガスユニット間の変換で精度損失の可能性があるため、数値が正確に一致しない可能性があります。
/// この数値が最終的な請求額で、内訳は単に情報提供のためです。
/// - 実行のガス請求(CPU時間):`execution_gas_units`
/// - IOのガス請求(ストレージランダムアクセス):`io_gas_units`
/// - ストレージ手数料請求(ストレージ空間):`storage_fee_octas`、
/// `total_charge_gas_unit`に含まれるため、この数値はトランザクションでユーザーが
/// 指定した`gas_unit_price`に従ってガスユニットに変換されます。
/// - ストレージ削除返金:`storage_fee_refund_octas`、これは`gas_used`や
/// `total_charge_gas_units`には含まれません。正味請求/返金は
/// `total_charge_gas_units` * `gas_unit_price` - `storage_fee_refund_octas`で計算されます。
///
/// これはモジュールイベントとして出力されることを意図しています。
struct FeeStatement has drop, store {
/// 総ガス請求額
total_charge_gas_units: u64,
/// 実行ガス請求額
execution_gas_units: u64,
/// IOガス請求額
io_gas_units: u64,
/// ストレージ手数料請求額
storage_fee_octas: u64,
/// ストレージ手数料返金額
storage_fee_refund_octas: u64,
}

ガス価格とトランザクションの優先順位付け

Section titled “ガス価格とトランザクションの優先順位付け”

Aptosネットワークでは、Aptosガバナンスが絶対的な最小ガスユニット価格を設定します。しかし、特定のガスユニット価格のトランザクションがどれだけ迅速に処理されるかは市場が決定します。例えば、Ethereum Gas Trackerを参照してください。これはEthereumのガス価格の市場価格変動を示しています。

現在の市場価格よりも高いガスユニット価格を指定することで、より大きな処理手数料を支払うことでブロックチェーン上のトランザクションの優先度レベルを向上させることができます。コンセンサスの一部として、リーダーが次のブロックの一部として提案するためにメモリプールからトランザクションを選択する際、より高いガスユニット価格のトランザクションを優先的に選択します。高いガス手数料は次のブロックでのトランザクション選択のみを優先することに注意してください。

ただし、ブロック内では、トランザクション実行の順序はシステムによって決定されます。この順序は、競合パターンを考慮することで並列実行をより効率的にするtransaction shufflingに基づいています。ほとんどの場合これは不要ですが、ネットワークが負荷を受けている場合、この措置によりトランザクションがより迅速に処理されることを保証できます。詳細については、シミュレーションによるガスユニットの推定の下のgas_unit_priceエントリを参照してください。

トランザクション内でのガス手数料の指定

Section titled “トランザクション内でのガス手数料の指定”

トランザクションがAptosブロックチェーンに送信される際、トランザクションには以下の必須ガスフィールドが含まれている必要があります:

  • max_gas_amount:トランザクション送信者がトランザクション実行のために支払う意思のあるガスユニットの最大数。これは、トランザクションが消費できる最大計算およびストレージリソースを決定します。

  • gas_price:トランザクション送信者が支払う意思のあるガスユニットあたりの価格。これはOctasで表現されます。

    トランザクション実行中、以下のように表現される総ガス量:

    (消費された総実行ガスユニット) + (消費された総ストレージガスユニット)

    max_gas_amountを超えてはならず、そうでなければトランザクションは実行を中止します。

クライアントに請求されるトランザクション手数料は最大でgas_price * max_gas_amountになります。

ガバナンスによって設定されるガスパラメータ

Section titled “ガバナンスによって設定されるガスパラメータ”

以下のガスパラメータはAptosガバナンスによって設定されます。

  • txn.maximum_number_of_gas_units:消費できるガスユニットの最大数(これはトランザクションのmax_gas_amountガスパラメータに許可される最大値)。これは、動的価格調整が支払う意思のある総額を超えないことを保証するためです。
  • txn.min_transaction_gas_units:消費できるガスユニットの最小数。トランザクションのmax_gas_amount値は、このパラメータの値より大きく設定する必要があります。

また、カテゴリ別のグローバル制限も存在します:

  • txn.max_execution_gas:トランザクションが実行に消費できるガスユニットの最大数。
  • txn.max_io_gas:トランザクションがIOに消費できるガスユニットの最大数。
  • txn.max_storage_fee:トランザクションが永続ストレージに消費できるAPTの最大量。 これらの制限は、あるカテゴリを別のカテゴリから切り離すのに役立ち、悪用を心配することなくtxn.maximum_number_of_gas_unitsを寛大に設定することを可能にします。

トランザクションのストレージ手数料は、グローバル状態で割り当てられた新しいスロットの数と既存スロットのサイズ増加に応じて請求されます。

価格変更や歴史的な「無料クォータ」以下のスロットサイズに対して支払わなかった従来のスロットに関して、いくつかの微妙な点があります。詳細については、AIP-65を参照してください。

また、後方互換性の理由により、トランザクションの総ストレージ手数料は現在、総gas_usedの一部としてクライアントに提示されることに注意してください。これは、同じトランザクションでもガスユニット価格に基づいて金額が変動する可能性があることを意味します。

例を示します。実行とIOで100ガスユニット、ストレージ手数料で5000 Octasのコストがかかるトランザクションがあるとします。ネットワークは以下のガスユニットを使用したと表示します:

  • ガスユニット価格が100の場合:100 + 5000 / 100 = 150ガスユニット、または
  • ユニット価格が200の場合:100 + 5000 / 200 = 125ガスユニット。

これが混乱を招く可能性があることは認識しており、将来的にはこれらを別々のアイテムとして提示する予定です。しかし、これにはトランザクション出力フォーマットとダウンストリームクライアントへの変更が必要なため、実現に向けて懸命に取り組んでいる間はご容赦ください。

トランザクションが状態アイテムを削除する場合、解放されたストレージスロットに対してトランザクション支払者に返金が発行されます。現在、完全返金が発行されます。つまり、アイテムの生涯にわたってスロットとバイトに対して支払われたすべてのストレージ手数料です。

返金額はAPTで表示され、ガスユニットに変換されたり、総gas_usedに含まれたりしません。代わりに、この返金額はFeeStatementstorage_fee_refund_octasフィールドで具体的に詳述されます。その結果、トランザクションの支払者のAPT残高への正味効果はgas_used * gas_unit_price - storage_refundによって決定されます。結果が正の場合、アカウント残高からの控除があり、負の場合は入金があります。

例1:アカウント残高 vs トランザクション手数料

Section titled “例1:アカウント残高 vs トランザクション手数料”

送信者のアカウントはトランザクション手数料を支払うのに十分な資金を持っている必要があります。

例えば、アカウントからすべてのお金を転送して、トランザクション手数料を支払う残高がなくなった場合、Aptosブロックチェーンはトランザクションが失敗することをお知らせし、転送も成功しません。

例2:トランザクション金額 vs トランザクション手数料

Section titled “例2:トランザクション金額 vs トランザクション手数料”

トランザクション手数料はトランザクション内の転送金額とは無関係です。

例えば、トランザクションAで1000コインを1つのアカウントから別のアカウントに転送しているとします。トランザクションAと同じガスフィールド値を持つ2番目のトランザクションBで、今度は100,000コインを1つのアカウントから別のアカウントに転送します。トランザクションAとBが大体同時に送信されたと仮定すると、トランザクションAとBのガスコストはほぼ同一になります。

シミュレーションによるガス消費の推定

Section titled “シミュレーションによるガス消費の推定”

トランザクションで使用されるガスは、ここで説明されているようにチェーン上でトランザクションをシミュレーションするか、Aptos CLIのガスプロファイリング機能を使用してローカルで推定できます。シミュレートされたトランザクションの結果は、シミュレーション時のブロックチェーンの正確な状態で必要な正確な量を表しています。使用されるこれらのガスユニットは、チェーンの状態に基づいて変更される可能性があります。この理由から、シミュレーションから出てくる量は推定値に過ぎず、最大ガス量を設定する際は、快適さのレベルと過去の動作に基づいて適切な余裕を含める必要があります。最大ガス量を低く設定しすぎると、トランザクションが中止され、消費されたガスに対してアカウントが請求されます。

チェーン上でトランザクションをシミュレートするには、SimulateTransaction APIを使用します。このAPIは、実行予定の正確なトランザクションを実行します。

トランザクションをローカルでシミュレートするには、Aptos CLIに統合されたガスプロファイラーを使用します。 これにより、トランザクションの正確なガス使用量を理解するのに役立つWebベースのレポートが生成されます。 詳細については、Gas Profilingを参照してください。

トランザクションをシミュレートするには、2つのフラグがあります:

  1. estimate_gas_unit_price:このフラグは、estimate_gas_price APIと同じアルゴリズムを使用してトランザクションのガスユニット価格を推定します。
  2. estimate_max_gas_amount:このフラグは、使用できる最大可能ガスを見つけ、実際のgas_usedを教えるためにトランザクションをシミュレートします。

トランザクションの正しいガス量を見つけるためのシミュレーション手順は以下の通りです:

  1. estimate_gas_unit_priceestimate_max_gas_amountの両方をtrueに設定してシミュレーションでガスを推定します。
  2. 返されたトランザクションのgas_unit_priceを新しいトランザクションのgas_unit_priceとして使用します。
  3. 返されたトランザクションのgas_used * gas_unit_price値をトランザクションコストの下限として表示します。
  4. コストの上限を計算するには、返されたトランザクションのmax_gas_amountgas_used * 安全係数最小値を取ります。CLIでは安全係数1.5の値が使用されます。この値をトランザクションを送信したいmax_gas_amountとして使用します。トランザクションコストの上限max_gas_amount * gas_unit_price、つまりトランザクション送信者に請求される最大額であることに注意してください。
  5. この時点で、以下のようにトランザクションを送信するためのgas_unit_pricemax_gas_amountを取得しました:
    1. 返されたシミュレートされたトランザクションからのgas_unit_price
    2. gas_used * 安全係数またはトランザクションからのmax_gas_amountの最小値としてのmax_gas_amount
  6. トランザクションを優先または非優先にする必要がある場合は、トランザクションのgas_unit_priceを調整します。高い優先度には値を増加させ、低い優先度には値を減少させます。