Closed25

[EIP-1559] viem におけるトランザクションの挙動

Taisei.MTaisei.M

まずは、EIP1559トランザクションを投げてみる

Taisei.MTaisei.M

コードはこんな感じ

EIP-1559のトランザクションを送信する関数
import {
  createWalletClient,
  formatEther,
  http,
  parseEther,
  publicActions,
  type Address,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";

/**
 * EIP-1559のトランザクションを送信する関数
 */
const main = async function () {
  const account = privateKeyToAccount(process.env.PRIVATE_KEY as Address);

  try {
    const walletClient = createWalletClient({
      account,
      chain: sepolia,
      transport: http(),
    }).extend(publicActions);

    const balance = await walletClient.getBalance(account);
    console.log("Balance:", formatEther(balance));

    const feeData = await walletClient.estimateFeesPerGas();
    console.log("Fee Data:", feeData);

    const tx = {
      account: account,
      chain: sepolia,
      type: "eip1559" as const,
      maxFeePerGas: feeData.maxFeePerGas,
      maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
      to: process.env.TO_ADDRESS as Address,
      value: parseEther("0.01"),
    };
    console.log("Transaction Data:", tx);

    const txHash = await walletClient.sendTransaction(tx);
    console.log(`https://sepolia.etherscan.io/tx/${txHash}`);
  } catch (error) {
    console.error(error);
  }
};

main();
Taisei.MTaisei.M


指定した値が、実際に作成されたトランザクションのmaxFeePerGas、maxPriorityFeePerGasに設定されていることがわかる

Taisei.MTaisei.M

実際に支払ったGas Priceは、 BaseFeePerGas と MaxPriorityFeePerGas を加算した値になっていることも確認できる

Gas Price: 50.209795374 Gwei (0.000000050209795374 ETH)

Base: 50.193740627 Gwei 
Max Priority: 0.016054747 Gwei
Taisei.MTaisei.M

次に、レガシートランザクションを投げてみる

Taisei.MTaisei.M

レガシートランザクションについてはviem のドキュメントにも記載あり

Legacy Transaction
A Legacy Transaction in Ethereum refers to a transaction that was created using an older version of Ethereum's transaction format, known as "transaction type 0". This transaction format was used prior to the introduction of the EIP-1559 upgrade, which was implemented in August 2021.

https://viem.sh/docs/glossary/terms#legacy-transaction

Taisei.MTaisei.M

トランザクションの作り方は、type: "legacy" と指定するだけでよい

Taisei.MTaisei.M

maxFeePerGas、maxPriorityFeePerGasを指定したままだともちろん怒られる

Taisei.MTaisei.M

コードはこんな感じ

レガシートランザクションを送信する関数
import {
  createWalletClient,
  formatEther,
  http,
  parseEther,
  publicActions,
  type Address,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";

/**
 * レガシートランザクションを送信する関数
 */
const main = async function () {
  const account = privateKeyToAccount(process.env.PRIVATE_KEY as Address);

  try {
    const walletClient = createWalletClient({
      account,
      chain: sepolia,
      transport: http(),
    }).extend(publicActions);

    const balance = await walletClient.getBalance(account);
    console.log("Balance:", formatEther(balance));

    const feeData = await walletClient.estimateFeesPerGas({
      type: "legacy",
    });
    console.log("Fee Data:", feeData);

    const tx = {
      account: account,
      chain: sepolia,
      type: "legacy" as const,
      to: process.env.TO_ADDRESS as Address,
      value: parseEther("0.01"),
      gasPrice: feeData.gasPrice,
    };
    console.log("Transaction Data:", tx);

    const txHash = await walletClient.sendTransaction(tx);
    console.log(`https://sepolia.etherscan.io/tx/${txHash}`);
  } catch (error) {
    console.error(error);
  }
};

main();

estimateFeesPerGas でレガシートランザクションのGasPriceも見積もりできるらしい
https://viem.sh/docs/actions/public/estimateFeesPerGas#estimatefeespergas

Taisei.MTaisei.M

estimateFeesPerGas で見積もりしたGasPriceがちゃんと設定されていることを確認できたけど、Baseが安かったので少し過払いになった。

Gas Price: 41.216599554 Gwei (0.000000041216599554 ETH)

Base: 39.231596798 Gwei
Taisei.MTaisei.M

etherscan のOther Attributes: の箇所を見るとTx Typeが0(Legacy) になってることを確認できる

Taisei.MTaisei.M

何も指定しない場合はどの扱いになるのか

Taisei.MTaisei.M

コードはこんな感じ

Tx Typeを指定せずにトランザクションを送信する関数
import {
  createWalletClient,
  formatEther,
  http,
  parseEther,
  publicActions,
  type Address,
} from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";

/**
 * Tx Typeを指定せずにトランザクションを送信する関数
 */
const main = async function () {
  const account = privateKeyToAccount(process.env.PRIVATE_KEY as Address);

  try {
    const walletClient = createWalletClient({
      account,
      chain: sepolia,
      transport: http(),
    }).extend(publicActions);

    const balance = await walletClient.getBalance(account);
    console.log("Balance:", formatEther(balance));

    const tx = {
      account: account,
      chain: sepolia,
      to: process.env.TO_ADDRESS as Address,
      value: parseEther("0.01"),
    };
    console.log("Transaction Data:", tx);

    const txHash = await walletClient.sendTransaction(tx);
    console.log(`https://sepolia.etherscan.io/tx/${txHash}`);
  } catch (error) {
    console.error(error);
  }
};

main();
Taisei.MTaisei.M

何も指定しない場合でも、EIP1559トランザクションになっている

Taisei.MTaisei.M

EIP-1559のトランザクションを送信する関数 のときと、MaxPriorityFeePerGasの値が全く同じだった

estimateFeesPerGasで見積もりした値を指定してたけど、トランザクションを作成する際に見積もりで得たMaxPriorityFeePerGasを指定するのはあまり意味はなさそう 🤔

Taisei.MTaisei.M

MaxPriorityFeePerGasは、うまく指定することで優先的にブロックに格納してもらうための手数料を節約できる

さっき作成したトランザクションはMaxPriorityが0.016054747 Gweiとなっていたため、それより低い値を指定したトランザクションを投げてみる

    const tx = {
      account: account,
      chain: sepolia,
      to: process.env.TO_ADDRESS as Address,
      value: parseEther("0.01"),
      maxPriorityFeePerGas: parseGwei("0.005"), ← 追加
    };
Taisei.MTaisei.M

Max Priority: 0.005 Gweiとなって優先手数料が節約できていることがわかる

あまり低すぎるとブロックに取り込まれるのに時間がかかってしまう可能性があるため、ユースケースに合わせて設定するのが良さそう

Taisei.MTaisei.M

MaxFeePerGasは、BaseFee + MaxPriorityFee の上限を決めることができる

トランザクションのmaxFeePerGasのみを指定した場合、Base Fee + Max Priorityがその値を超えないように決定されることになる

    const tx = {
      account: account,
      chain: sepolia,
      to: process.env.TO_ADDRESS as Address,
      value: parseEther("0.01"),
      maxFeePerGas: parseGwei("35"), ← 追加
    };
Taisei.MTaisei.M


このように指定することで、ネットワークが混雑していたとしてもGas Priceは35 Gweiを絶対に超えない

Taisei.MTaisei.M

viemにおけるトランザクションの挙動 :kanzen_rikai:

このスクラップは2025/01/31にクローズされました