Account Abstraction 2025 - Web3 UXの革命

2026.01.12

Account Abstractionとは

Account Abstraction(AA)は、Ethereumにおけるアカウントモデルの根本的な変革です。従来のEOA(Externally Owned Account)の制約を取り除き、スマートコントラクトをウォレットとして使用することで、Web3のユーザー体験を劇的に向上させます。

従来のEOAの課題

graph TB
    subgraph EOA["従来のEOA (Externally Owned Account)"]
        direction TB
        A[秘密鍵] --> B[公開鍵] --> C[アドレス]
        D["❌ 秘密鍵紛失 = 資産喪失"]
        E["❌ ガス代は必ずETHで支払い"]
        F["❌ 1トランザクション = 1操作"]
        G["❌ 署名アルゴリズム固定"]
        H["❌ リカバリ手段なし"]
    end

    subgraph AA["Account Abstraction"]
        direction TB
        I[スマートコントラクトウォレット]
        J["✅ ソーシャルリカバリ可能"]
        K["✅ 任意のトークンでガス支払い"]
        L["✅ バッチ処理で複数操作を1回で"]
        M["✅ カスタム署名検証"]
        N["✅ 支出制限、セッションキー"]
    end

ERC-4337の仕組み

ERC-4337は2023年3月にメインネットにデプロイされ、2025年にはWeb3の標準インフラとして定着しました。プロトコルレベルの変更なしにAccount Abstractionを実現する画期的な設計です。

アーキテクチャ

flowchart TB
    subgraph ERC4337["ERC-4337 Architecture"]
        User[ユーザー] --> UserOp[UserOp<br/>署名済み]
        UserOp --> Bundler[Bundler]
        Bundler --> EntryPoint[EntryPoint<br/>シングルトンコントラクト]

        EntryPoint --> SmartAccount[Smart Account<br/>ユーザーのウォレット]
        EntryPoint --> Paymaster[Paymaster<br/>ガス代スポンサー]
        EntryPoint --> Aggregator[Aggregator<br/>署名集約]
    end

UserOperationの構造

interface UserOperation {
  // 送信者(スマートアカウント)
  sender: address;

  // リプレイ攻撃防止用のノンス
  nonce: uint256;

  // アカウント未作成時のファクトリー呼び出しデータ
  initCode: bytes;

  // 実行するコールデータ
  callData: bytes;

  // ガス制限
  callGasLimit: uint256;
  verificationGasLimit: uint256;
  preVerificationGas: uint256;

  // ガス価格
  maxFeePerGas: uint256;
  maxPriorityFeePerGas: uint256;

  // Paymaster設定(オプション)
  paymasterAndData: bytes;

  // 署名
  signature: bytes;
}

EntryPointの処理フロー

// EntryPointの主要な処理
contract EntryPoint {
    function handleOps(
        UserOperation[] calldata ops,
        address payable beneficiary
    ) external {
        for (uint256 i = 0; i < ops.length; i++) {
            UserOperation calldata op = ops[i];

            // 1. アカウント作成(必要な場合)
            if (op.initCode.length > 0) {
                _createAccount(op.initCode, op.sender);
            }

            // 2. 検証フェーズ
            uint256 validationData = IAccount(op.sender)
                .validateUserOp(op, op.nonce, missingAccountFunds);

            // 3. Paymaster検証(設定されている場合)
            if (op.paymasterAndData.length > 0) {
                address paymaster = address(bytes20(op.paymasterAndData[:20]));
                IPaymaster(paymaster).validatePaymasterUserOp(op, maxCost);
            }

            // 4. 実行フェーズ
            (bool success,) = op.sender.call(op.callData);

            // 5. ガス代精算
            _handlePostOp(op, success);
        }
    }
}

スマートウォレットの実装

Safe(旧Gnosis Safe)

Safeは最も広く使用されているスマートウォレットで、2025年時点で**$100B以上の資産**を保護しています。

// Safe互換のスマートアカウント
contract SafeAccount is IAccount {
    address[] public owners;
    uint256 public threshold;

    // ERC-4337検証
    function validateUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 missingAccountFunds
    ) external returns (uint256 validationData) {
        // マルチシグ検証
        bytes32 dataHash = keccak256(
            abi.encodePacked(
                userOpHash,
                block.chainid,
                address(this)
            )
        );

        // 署名を検証
        require(
            checkSignatures(dataHash, userOp.signature, threshold),
            "Invalid signatures"
        );

        // 不足分のガス代を預金
        if (missingAccountFunds > 0) {
            (bool success,) = msg.sender.call{value: missingAccountFunds}("");
            require(success, "Failed to pay gas");
        }

        return 0; // 検証成功
    }

    // マルチシグ署名検証
    function checkSignatures(
        bytes32 dataHash,
        bytes memory signatures,
        uint256 requiredSignatures
    ) internal view returns (bool) {
        require(signatures.length >= requiredSignatures * 65, "Invalid sig length");

        address lastOwner = address(0);
        for (uint256 i = 0; i < requiredSignatures; i++) {
            (uint8 v, bytes32 r, bytes32 s) = signatureSplit(signatures, i);
            address recovered = ecrecover(dataHash, v, r, s);

            require(recovered > lastOwner, "Invalid sig order");
            require(isOwner(recovered), "Not an owner");
            lastOwner = recovered;
        }
        return true;
    }
}

Biconomy Smart Account

Biconomyは開発者フレンドリーなSDKと、モジュラーアーキテクチャが特徴です。

import {
  createSmartAccountClient,
  PaymasterMode,
  BiconomySmartAccountV2
} from "@biconomy/account";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { polygon } from "viem/chains";

// Biconomyスマートアカウントの初期化
async function initBiconomyAccount() {
  const account = privateKeyToAccount(`0x${PRIVATE_KEY}`);

  const walletClient = createWalletClient({
    account,
    chain: polygon,
    transport: http()
  });

  const smartAccount = await createSmartAccountClient({
    signer: walletClient,
    bundlerUrl: "https://bundler.biconomy.io/api/v2/137/xxx",
    biconomyPaymasterApiKey: PAYMASTER_API_KEY,
    chainId: 137
  });

  const smartAccountAddress = await smartAccount.getAccountAddress();
  console.log("Smart Account:", smartAccountAddress);

  return smartAccount;
}

// ガスレストランザクションの送信
async function sendGaslessTransaction(
  smartAccount: BiconomySmartAccountV2,
  targetContract: string,
  callData: string
) {
  const tx = {
    to: targetContract,
    data: callData
  };

  // Sponsored(完全ガスレス)モード
  const userOpResponse = await smartAccount.sendTransaction(tx, {
    paymasterServiceData: {
      mode: PaymasterMode.SPONSORED
    }
  });

  const receipt = await userOpResponse.wait();
  console.log("Transaction Hash:", receipt.receipt.transactionHash);

  return receipt;
}

ZeroDev Kernel

ZeroDevのKernelは、高度にモジュール化されたスマートアカウント実装です。

import { createKernelAccount, createKernelAccountClient } from "@zerodev/sdk";
import { KERNEL_V3_1 } from "@zerodev/sdk/constants";
import { signerToEcdsaValidator } from "@zerodev/ecdsa-validator";
import { createPublicClient, http } from "viem";
import { sepolia } from "viem/chains";

async function initKernelAccount() {
  const publicClient = createPublicClient({
    chain: sepolia,
    transport: http(RPC_URL)
  });

  // ECDSAバリデーターを使用
  const ecdsaValidator = await signerToEcdsaValidator(publicClient, {
    signer: privateKeyToAccount(`0x${PRIVATE_KEY}`),
    entryPoint: ENTRYPOINT_ADDRESS_V07,
    kernelVersion: KERNEL_V3_1
  });

  // Kernelアカウント作成
  const account = await createKernelAccount(publicClient, {
    plugins: {
      sudo: ecdsaValidator
    },
    entryPoint: ENTRYPOINT_ADDRESS_V07,
    kernelVersion: KERNEL_V3_1
  });

  // アカウントクライアント作成
  const kernelClient = createKernelAccountClient({
    account,
    chain: sepolia,
    bundlerTransport: http(BUNDLER_URL),
    paymaster: {
      getPaymasterData: async (userOp) => {
        // Paymaster設定
        return getPaymasterData(userOp);
      }
    }
  });

  return kernelClient;
}

Paymasterの実装

Paymasterは、ユーザーに代わってガス代を支払うコントラクトです。これによりガスレス取引が実現します。

Paymasterの種類

graph LR
    subgraph PaymasterTypes["Paymaster Types"]
        direction TB
        V["1. Verifying Paymaster<br/>・オフチェーン署名で承認<br/>・柔軟なポリシー設定可能<br/>・最も一般的な実装"]
        E["2. ERC-20 Paymaster<br/>・ERC-20トークンでガス代支払い<br/>・USDC, DAI等で支払い可能<br/>・レートオラクル連携"]
        D["3. Deposit Paymaster<br/>・事前デポジット方式<br/>・プリペイドガス"]
        S["4. Sponsoring Paymaster<br/>・プロジェクトが全額負担<br/>・ユーザーオンボーディング向け"]
    end

Verifying Paymasterの実装

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@account-abstraction/contracts/core/BasePaymaster.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";

contract VerifyingPaymaster is BasePaymaster {
    using ECDSA for bytes32;

    address public immutable verifyingSigner;

    // 有効期限とポリシーを含む署名データ
    struct PaymasterData {
        uint48 validUntil;
        uint48 validAfter;
        bytes signature;
    }

    constructor(
        IEntryPoint _entryPoint,
        address _verifyingSigner
    ) BasePaymaster(_entryPoint) {
        verifyingSigner = _verifyingSigner;
    }

    function _validatePaymasterUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) internal view override returns (bytes memory context, uint256 validationData) {
        // paymasterAndDataから署名データを抽出
        PaymasterData memory paymasterData = abi.decode(
            userOp.paymasterAndData[20:],
            (PaymasterData)
        );

        // 署名対象のハッシュを計算
        bytes32 hash = keccak256(abi.encode(
            userOpHash,
            address(this),
            block.chainid,
            paymasterData.validUntil,
            paymasterData.validAfter
        ));

        // 署名検証
        address recovered = hash.toEthSignedMessageHash().recover(
            paymasterData.signature
        );
        require(recovered == verifyingSigner, "Invalid signature");

        // 有効期限を返す
        return (
            "",
            _packValidationData(
                false,
                paymasterData.validUntil,
                paymasterData.validAfter
            )
        );
    }
}

ERC-20 Paymasterの実装

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@account-abstraction/contracts/core/BasePaymaster.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

contract ERC20Paymaster is BasePaymaster {
    IERC20 public immutable token;
    AggregatorV3Interface public immutable priceFeed;

    // マークアップ(10% = 110)
    uint256 public constant MARKUP = 110;
    uint256 public constant MARKUP_DENOMINATOR = 100;

    constructor(
        IEntryPoint _entryPoint,
        IERC20 _token,
        AggregatorV3Interface _priceFeed
    ) BasePaymaster(_entryPoint) {
        token = _token;
        priceFeed = _priceFeed;
    }

    function _validatePaymasterUserOp(
        UserOperation calldata userOp,
        bytes32 userOpHash,
        uint256 maxCost
    ) internal override returns (bytes memory context, uint256 validationData) {
        // トークン建てのコストを計算
        uint256 tokenCost = getTokenCost(maxCost);

        // ユーザーのトークン残高を確認
        require(
            token.balanceOf(userOp.sender) >= tokenCost,
            "Insufficient token balance"
        );

        // 事前にトークンを転送(または allowance を確認)
        require(
            token.allowance(userOp.sender, address(this)) >= tokenCost,
            "Insufficient allowance"
        );

        // コンテキストにコスト情報を保存
        return (abi.encode(userOp.sender, tokenCost), 0);
    }

    function _postOp(
        PostOpMode mode,
        bytes calldata context,
        uint256 actualGasCost
    ) internal override {
        if (mode == PostOpMode.postOpReverted) {
            return;
        }

        (address sender, uint256 maxTokenCost) = abi.decode(
            context,
            (address, uint256)
        );

        // 実際のトークンコストを計算
        uint256 actualTokenCost = getTokenCost(actualGasCost);

        // トークンを回収
        token.transferFrom(sender, address(this), actualTokenCost);
    }

    function getTokenCost(uint256 ethCost) public view returns (uint256) {
        (, int256 price,,,) = priceFeed.latestRoundData();
        require(price > 0, "Invalid price");

        // ETH/USDからトークン量を計算(マークアップ含む)
        return (ethCost * uint256(price) * MARKUP) /
               (MARKUP_DENOMINATOR * 1e8);
    }
}

ガスレス取引の実装

フロントエンド実装(React)

import { useState, useCallback } from 'react';
import { createSmartAccountClient, PaymasterMode } from '@biconomy/account';
import { encodeFunctionData, parseAbi } from 'viem';

const NFT_ABI = parseAbi([
  'function mint(address to) external',
  'function balanceOf(address owner) view returns (uint256)'
]);

export function GaslessMint() {
  const [isMinting, setIsMinting] = useState(false);
  const [txHash, setTxHash] = useState<string | null>(null);

  const mintNFT = useCallback(async () => {
    setIsMinting(true);
    try {
      // スマートアカウント初期化
      const smartAccount = await createSmartAccountClient({
        signer: walletClient,
        bundlerUrl: BUNDLER_URL,
        biconomyPaymasterApiKey: PAYMASTER_API_KEY,
        chainId: 137
      });

      const accountAddress = await smartAccount.getAccountAddress();

      // ミント用のcallDataを作成
      const mintCallData = encodeFunctionData({
        abi: NFT_ABI,
        functionName: 'mint',
        args: [accountAddress]
      });

      // ガスレストランザクション送信
      const { wait } = await smartAccount.sendTransaction(
        {
          to: NFT_CONTRACT_ADDRESS,
          data: mintCallData
        },
        {
          paymasterServiceData: {
            mode: PaymasterMode.SPONSORED
          }
        }
      );

      const receipt = await wait();
      setTxHash(receipt.receipt.transactionHash);
    } catch (error) {
      console.error('Mint failed:', error);
    } finally {
      setIsMinting(false);
    }
  }, []);

  return (
    <div className="gasless-mint">
      <h2>ガスレスNFTミント</h2>
      <p>ガス代なしでNFTをミントできます</p>

      <button
        onClick={mintNFT}
        disabled={isMinting}
        className="mint-button"
      >
        {isMinting ? 'ミント中...' : 'NFTをミント(無料)'}
      </button>

      {txHash && (
        <p className="success">
          成功!
          <a
            href={`https://polygonscan.com/tx/${txHash}`}
            target="_blank"
            rel="noopener noreferrer"
          >
            トランザクションを確認
          </a>
        </p>
      )}
    </div>
  );
}

バッチトランザクション

// 複数の操作を1トランザクションで実行
async function batchTransaction(smartAccount: BiconomySmartAccountV2) {
  // 1. トークン承認
  const approveData = encodeFunctionData({
    abi: ERC20_ABI,
    functionName: 'approve',
    args: [SWAP_ROUTER, parseEther('1000')]
  });

  // 2. スワップ実行
  const swapData = encodeFunctionData({
    abi: SWAP_ABI,
    functionName: 'swapExactTokensForTokens',
    args: [
      parseEther('100'),    // amountIn
      parseEther('95'),     // amountOutMin
      [TOKEN_A, TOKEN_B],   // path
      smartAccountAddress,  // to
      Date.now() + 60000    // deadline
    ]
  });

  // 3. ステーキング
  const stakeData = encodeFunctionData({
    abi: STAKING_ABI,
    functionName: 'stake',
    args: [parseEther('95')]
  });

  // バッチ送信(3つの操作が1トランザクションに)
  const { wait } = await smartAccount.sendTransaction(
    [
      { to: TOKEN_A, data: approveData },
      { to: SWAP_ROUTER, data: swapData },
      { to: STAKING_CONTRACT, data: stakeData }
    ],
    {
      paymasterServiceData: {
        mode: PaymasterMode.SPONSORED
      }
    }
  );

  const receipt = await wait();
  console.log('Batch transaction completed:', receipt.receipt.transactionHash);
}

ソーシャルリカバリの実装

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract SocialRecoveryModule {
    struct RecoveryConfig {
        address[] guardians;
        uint256 threshold;
        uint256 recoveryDelay;
    }

    struct RecoveryRequest {
        address newOwner;
        uint256 approvals;
        uint256 executeAfter;
        mapping(address => bool) hasApproved;
    }

    mapping(address => RecoveryConfig) public configs;
    mapping(address => RecoveryRequest) public pendingRecoveries;

    event RecoveryInitiated(
        address indexed account,
        address indexed newOwner,
        uint256 executeAfter
    );
    event RecoveryApproved(
        address indexed account,
        address indexed guardian
    );
    event RecoveryExecuted(
        address indexed account,
        address indexed newOwner
    );

    // ガーディアンの設定
    function setupGuardians(
        address[] calldata guardians,
        uint256 threshold,
        uint256 recoveryDelay
    ) external {
        require(guardians.length >= threshold, "Invalid threshold");
        require(threshold > 0, "Threshold must be > 0");

        configs[msg.sender] = RecoveryConfig({
            guardians: guardians,
            threshold: threshold,
            recoveryDelay: recoveryDelay
        });
    }

    // リカバリの開始(ガーディアンが呼び出し)
    function initiateRecovery(
        address account,
        address newOwner
    ) external {
        RecoveryConfig storage config = configs[account];
        require(isGuardian(account, msg.sender), "Not a guardian");

        RecoveryRequest storage request = pendingRecoveries[account];
        request.newOwner = newOwner;
        request.approvals = 1;
        request.executeAfter = block.timestamp + config.recoveryDelay;
        request.hasApproved[msg.sender] = true;

        emit RecoveryInitiated(
            account,
            newOwner,
            request.executeAfter
        );
    }

    // リカバリの承認
    function approveRecovery(address account) external {
        require(isGuardian(account, msg.sender), "Not a guardian");

        RecoveryRequest storage request = pendingRecoveries[account];
        require(request.newOwner != address(0), "No pending recovery");
        require(!request.hasApproved[msg.sender], "Already approved");

        request.hasApproved[msg.sender] = true;
        request.approvals++;

        emit RecoveryApproved(account, msg.sender);
    }

    // リカバリの実行
    function executeRecovery(address account) external {
        RecoveryConfig storage config = configs[account];
        RecoveryRequest storage request = pendingRecoveries[account];

        require(request.newOwner != address(0), "No pending recovery");
        require(
            request.approvals >= config.threshold,
            "Not enough approvals"
        );
        require(
            block.timestamp >= request.executeAfter,
            "Recovery delay not passed"
        );

        address newOwner = request.newOwner;

        // リクエストをクリア
        delete pendingRecoveries[account];

        // オーナーを変更(アカウントのコールバック)
        ISmartAccount(account).setOwner(newOwner);

        emit RecoveryExecuted(account, newOwner);
    }

    function isGuardian(
        address account,
        address guardian
    ) public view returns (bool) {
        address[] memory guardians = configs[account].guardians;
        for (uint256 i = 0; i < guardians.length; i++) {
            if (guardians[i] == guardian) return true;
        }
        return false;
    }
}

セッションキーの実装

セッションキーを使用すると、限定的な権限を持つ一時的なキーを発行でき、dAppとのインタラクションが大幅に簡素化されます。

import { createKernelAccount, createKernelAccountClient } from "@zerodev/sdk";
import {
  toPermissionValidator,
  toSudoPolicy,
  toCallPolicy,
  ParamCondition
} from "@zerodev/permissions";
import { toECDSASigner } from "@zerodev/permissions/signers";

async function createSessionKey() {
  // セッションキーを生成
  const sessionPrivateKey = generatePrivateKey();
  const sessionSigner = toECDSASigner({
    signer: privateKeyToAccount(sessionPrivateKey)
  });

  // 権限ポリシーを定義
  const callPolicy = toCallPolicy({
    permissions: [
      {
        // 特定のNFTコントラクトのみ
        target: NFT_CONTRACT,
        // mint関数のみ許可
        functionName: "mint",
        // パラメータ制約
        args: [
          {
            condition: ParamCondition.EQUAL,
            value: accountAddress  // 自分のアドレスにのみミント可能
          }
        ]
      },
      {
        // 特定のトークン
        target: USDC_ADDRESS,
        functionName: "transfer",
        args: [
          null,  // 任意の宛先
          {
            condition: ParamCondition.LESS_THAN,
            value: parseUnits("100", 6)  // 100 USDC未満
          }
        ]
      }
    ]
  });

  // Permission Validatorを作成
  const permissionValidator = await toPermissionValidator(publicClient, {
    entryPoint: ENTRYPOINT_ADDRESS_V07,
    kernelVersion: KERNEL_V3_1,
    signer: sessionSigner,
    policies: [callPolicy]
  });

  // セッションキー用のアカウントを作成
  const sessionAccount = await createKernelAccount(publicClient, {
    entryPoint: ENTRYPOINT_ADDRESS_V07,
    kernelVersion: KERNEL_V3_1,
    plugins: {
      sudo: ecdsaValidator,      // メインキー
      regular: permissionValidator  // セッションキー
    }
  });

  return {
    sessionKey: sessionPrivateKey,
    account: sessionAccount
  };
}

2025年の採用状況

主要な統計

指標2024年2025年
アクティブスマートアカウント1,200万5,800万
月間UserOperation数800万4,500万
TVL(スマートアカウント)$12B$89B
対応チェーン1545+
Paymaster取引量$2.5B$18B

主要プロジェクトの採用

graph TB
    subgraph AA["AA採用プロジェクト"]
        subgraph DeFi
            U[Uniswap: スマートオーダー、ガスレススワップ]
            AV[Aave: ワンクリックレバレッジ]
            I1[1inch: インテントベースのルーティング]
        end
        subgraph GameFi
            AX[Axie Infinity: セッションキーでシームレスプレイ]
            GU[Gods Unchained: ガスレスカードトレード]
            IL[Illuvium: バッチNFT操作]
        end
        subgraph NFT["NFT/Creator"]
            OS[OpenSea: ガスレスリスティング]
            BL[Blur: 一括購入・売却]
            FD[Foundation: クリエイター向けガススポンサー]
        end
        subgraph Enterprise["企業導入"]
            CB[Coinbase: スマートウォレット標準化]
            SN[Sony: Web3ゲーム基盤]
            DB[Deutsche Bank: 機関投資家向けカストディ]
        end
    end

ERC-7702との関係

2025年のPectraアップグレードで導入されたERC-7702は、EOAを一時的にスマートコントラクトとして動作させることができます。

graph LR
    subgraph Compare["ERC-4337 vs ERC-7702"]
        subgraph ERC4337["ERC-4337"]
            A1[新規スマートアカウント]
            A2[プロトコル変更不要]
            A3[Bundler依存]
            A4[完全なカスタマイズ性]
            A5[成熟したエコシステム]
        end
        subgraph ERC7702["ERC-7702"]
            B1[既存EOAの拡張]
            B2[Pectraで導入]
            B3[通常のトランザクション]
            B4[一時的な機能追加]
            B5[EOA互換性維持]
        end
    end

    subgraph Interop["相互運用"]
        C1[ERC-7702でEOAを一時的にAA化]
        C2[ERC-4337のEntryPointを使用]
        C3[最終的にスマートアカウントへ移行]
    end

Bundlerの運用

主要Bundlerサービス

bundler_providers:
  alchemy:
    特徴: Alchemy Embedded Accounts統合
    対応チェーン: 20+
    料金: API利用量ベース

  biconomy:
    特徴: モジュラーSDK、Paymaster統合
    対応チェーン: 15+
    料金: ボリュームディスカウント

  pimlico:
    特徴: ERC-4337 v0.7特化
    対応チェーン: 30+
    料金: UserOperation数ベース

  stackup:
    特徴: セルフホスト可能
    対応チェーン: 10+
    料金: オープンソース

セルフホストBundler

// Rundlerを使用したセルフホスト(Rust実装)
import { spawn } from 'child_process';

const rundlerConfig = {
  chain: 'ethereum',
  rpc_url: process.env.RPC_URL,
  entry_point: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
  builder_private_key: process.env.BUILDER_KEY,
  max_verification_gas: 5000000,
  max_bundle_gas: 25000000,
  min_balance: '0.1',
  bundle_interval: 10
};

// Rundler起動
const rundler = spawn('rundler', [
  '--chain', rundlerConfig.chain,
  '--rpc-url', rundlerConfig.rpc_url,
  '--entry-point', rundlerConfig.entry_point,
  '--builder-private-key', rundlerConfig.builder_private_key,
  '--max-verification-gas', rundlerConfig.max_verification_gas.toString(),
  '--max-bundle-gas', rundlerConfig.max_bundle_gas.toString(),
  '--min-balance', rundlerConfig.min_balance,
  '--bundle-interval', rundlerConfig.bundle_interval.toString()
]);

rundler.stdout.on('data', (data) => {
  console.log(`Rundler: ${data}`);
});

まとめ

2025年、Account Abstraction(ERC-4337)はWeb3のユーザー体験を根本から変革しました。

主要な成果

  • ガスレス取引: Paymasterにより、ユーザーはETHを持たずともdAppを利用可能
  • バッチ処理: 複数操作を1トランザクションで実行し、コストと手間を削減
  • ソーシャルリカバリ: 秘密鍵紛失時も資産を回復可能
  • セッションキー: ゲームやdAppでのシームレスな体験
  • 5,800万アクティブアカウント: 前年比380%成長

今後の展望

  • ERC-7702との統合: EOAからスマートアカウントへのシームレスな移行
  • Native AA: L2チェーンでのネイティブサポート拡大
  • インテントベースアーキテクチャ: より宣言的なトランザクション
  • クロスチェーンAA: チェーン間でのシームレスな操作

Account Abstractionは、Web3を「技術者向けの実験的ツール」から「誰もが使えるインフラ」へと進化させる重要な技術です。2025年の急速な普及は、この変革が確実に進行していることを示しています。

参考: ERC-4337 | Biconomy Docs | ZeroDev Docs

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

LINEで無料相談する
← 一覧に戻る