メタトランザクション(ERC-2771)とは?
すべてのEthereumトランザクションはガスを使用し、各トランザクションの送信者はガス代を支払うのに十分なEtherを保有している必要があります。これにより、新規ユーザーはdappを使い始める前にEtherを購入する必要が生じ(これは面倒な作業になり得ます)、ユーザーオンボーディングにおける大きな障壁となっています。
いわゆる「メタトランザクション」は、ユーザーに代わってガス代を支払うことを可能にしました。
しかし、こうしたソリューションの多くはAccount Abstraction(ERC-4337)インフラへ移行しつつあります。これはガスの抽象化に関してより有望で洗練された方法であり、多くの機能を備えているためです。
メタトランザクションとは何か
メタトランザクションのアイデアはシンプルです。Relayerと呼ばれる第三者が、ユーザーに代わってトランザクションを送信し、ガス代を支払います。
ユーザーは、実行されるトランザクションの情報を含むメッセージ(できればEIP-712準拠のもの)に署名します。
署名されたメッセージはRelayerに渡され、Relayerは自身が対価を得られるかどうかを検証し(これはオプションの場合もあり、詳細は後述します)、ガス代を支払うのに十分な資金があるかを確認し、ネイティブトランザクションに署名して実行のために送信する責任を負います。
OpenZepplinのRelayerを例に、メタトランザクションを理解していきましょう。

メタトランザクションリクエストはどのようなものか
サンプルのメタトランザクションメッセージは以下のようになります。

上記のメッセージはNFTをミントするものであり、fromアドレス0x7099797...によって署名されます。
メッセージが署名されると、クライアント(またはユーザー)はメタトランザクションリクエスト(下記参照)を作成できます。これはPOSTリクエストとしてAutotaskに送信されます。AutotaskはWebhookであり、呼び出されると内部的にRelayerの秘密鍵を使ってネイティブトランザクションに署名します。

メタトランザクションのRelayerとは何か
Relayerとは、ユーザーのガス代をスポンサーするための資金を保有するEthereumアカウントです。このアカウントの秘密鍵は、プロバイダーのサーバー上の安全なvaultに保管されます。
開発者はRelayerに資金を送金することで、ユーザーのトランザクション手数料をカバーできます。
開発者は好きなだけRelayerを立ち上げることができますが、それぞれ個別にETHで資金を供給する必要があります。
OZ Relayでは、Relayerの一時停止、Whitelistされたアドレスからのリクエストの受け入れ、Gas Price Cappingが可能です。必要であれば、さらに条件付きロジックをAutotaskにプログラムすることもできます。
なお、ユーザーが定義したトランザクションは、現在Relayerのネイティブトランザクションのdataフィールド内に格納されています。メタトランザクションとは、あるトランザクションの中に入った別のトランザクションなのです。
メタトランザクションにおけるMinimalForwarderとは何か
ここまで、オンチェーンでの検証は一切行われていません。ここで登場するのがMinimalForwarderです。
MinimalForwarderは、ユーザーが署名したメッセージの妥当性とリプレイ保護を検証するオンチェーンのスマートコントラクトです。
struct ForwardRequest {
address from;
address to;
uint256 value;
uint256 gas;
uint256 nonce;
bytes data;
}
function verify(ForwardRequest calldata req, bytes calldata signature) public view returns (bool) {
address signer = _hashTypedDataV4(
keccak256(
abi.encode(
_TYPEHASH,
req.from,
req.to,
req.value,
req.gas,
req.nonce,
keccak256(req.data)
)
)
).recover(signature);
return _nonces[req.from] == req.nonce && signer == req.from;
}検証に成功すると、MinimalForwarderは適切なcalldataを使ってリクエスト先のコントラクトを呼び出すことで、トランザクションを実行します。
function execute(ForwardRequest calldata req, bytes calldata signature)
public
payable
returns (bool, bytes memory)
{
require(verify(req, signature), "MinimalForwarder: signature does not match request");
_nonces[req.from] = req.nonce + 1;
(bool success, bytes memory returndata) = req.to.call{gas: req.gas, value: req.value}(abi.encodePacked(req.data, req.from));
// Validate that the relayer has sent enough gas for the call.
// See
if (gasleft() <= req.gas / 63) {
// We explicitly trigger invalid opcode to consume all gas and bubble-up the effects, since
// neither revert or assert consume all gas since Solidity 0.8.0
//
/// @solidity memory-safe-assembly
assembly {
invalid()
}
}
return (success, returndata);
}ここにメタトランザクションの欠点も現れます。というのも、MinimalForwarderが呼び出すコントラクト側で、MinimalForwarderがユーザーに代わってそのコントラクトを呼び出せるようにする必要があるからです。
ERC-2771とは何か
最終的に、呼び出しが目的のターゲットコントラクトに到達したとき、そのコントラクトはRelayerのトランザクションの中にネストされた、元のユーザー(msg.sender)とcalldata(msg.data)を特定できる必要があります。このプロセスを標準化するためにERC2771が提案されました。
OpenZepplinは、ERC2771Contextというユーティリティコントラクトを提供しており、スマートコントラクト開発者がMinimalForwarderから送られてきたデータから、本来のmsg.senderとmsg.dataを容易に取り出せるようにしています。
contract YourContract is ERC2771Context {
constructor(MinimalForwarder forwarder, string memory uri_)
ERC2771Context(address(forwarder))
{}
// Depending on whether the call is made by the `MinimalForwarder` or not the `msg.sender` and `msg.data` will be inferred accordingly
}各スマートコントラクトはメタトランザクションの読み取り方法を知っておく必要があるため、すでにデプロイ済みのコントラクトに対してこれを実装するのは難しく、バグの原因にもなりかねません。
他にも多くのメタトランザクションインフラサービスが存在しますが、そのいずれも_msg.sender_と_msg.data_を導出するために、対象コントラクトがEIP-712またはEIP-2771ベースのコントラクトを継承していることを要求します。
この標準は優れたものですが、遡及的には機能しません。これが、ERC-4337が作られた理由であり、既存の多くのERC-2771ソリューションを置き換えつつあります。
よくある質問
メタトランザクションとは何か
メタトランザクションは、Relayerと呼ばれる第三者がユーザーに代わってトランザクションを送信しガス代を支払うことを可能にする仕組みで、ユーザーがアプリを利用する前にEtherを保有していなければならないという障壁を取り除きます。
メタトランザクションはどのように機能するか
ユーザーはトランザクション情報を含むメッセージに署名し、それがRelayerに渡されます。Relayerはリクエストを検証し、ガス代を支払い、ネイティブトランザクションに署名して、ブロックチェーン上での実行のために送信します。
ERC-2771とは何か
ERC-2771は、信頼されたforwarderを通じてメタトランザクションを受け取った際に、スマートコントラクトが元のユーザーとcalldataを特定できるようにする標準であり、正しいmsg.senderとmsg.dataの抽出を保証します。
メタトランザクションにおけるMinimalForwarderとは何か
MinimalForwarderは、ユーザーが署名したメッセージの真正性とリプレイ保護を検証したうえで、ターゲットコントラクトを呼び出してトランザクションを実行するオンチェーンのスマートコントラクトです。
ERC2771Contextとは何か
ERC2771ContextはOpenZeppelinのユーティリティコントラクトで、スマートコントラクト開発者がMinimalForwarderから送られてきたメタトランザクションから、本来のmsg.senderとmsg.dataを容易に取り出せるようにします。
ERC-2771のメタトランザクションにはどのような制約があるか
ERC-2771は、対象コントラクトがEIP-712またはEIP-2771ベースのコントラクトを継承することでこの標準を明示的にサポートする必要があるため、すでにデプロイ済みのコントラクトへの実装が難しく、バグを引き起こす可能性があります。
ERC-2771とERC-4337はどのように比較されるか
ERC-2771はRelayerとforwarderを通じてガスレストランザクションを可能にしますが、ERC-4337(Account Abstraction)は遡及的に機能し、既存のコントラクトを変更する必要がないため、ほとんどのERC-2771ソリューションを置き換えつつあります。
メタトランザクションにおいてRelayerはどのような役割を果たすか
RelayerはユーザーのガスFeeをスポンサーするEthereumアカウントであり、その秘密鍵はプロバイダーのサーバー上に安全に保管されます。また、Whitelist登録、Gas Price Capping、条件付きロジックといった機能を設定することもできます。
関連する概要
ウォレット2026年9月2日
エージェントウォレット: AIエージェントのためのセッションと権限モデル
AIエージェントが秘密鍵を保持せずにスコープ化された取り消し可能なウォレットアクセスを得る仕組み: セッション、委任署名、即時失効。
ウォレット2026年7月29日
Cursorに秘密鍵を貼り付けるのをやめる:コーディングエージェントにウォレットを持たせる方法
秘密鍵を渡さずに、コーディングエージェントにウォレットを持たせる方法。Alchemy CLIのエージェントウォレットがスコープ付きセッションを使い、.envに秘密鍵を置かずにエージェントが取引できる仕組みを解説します。
ウォレット2026年6月24日
暗号資産Bundlerとは?
暗号資産のBundlerは、バッチ処理、MEV、ロールアップ、トークンローンチ、アカウントアブストラクションにわたって、複数のトランザクションや操作を1つのオンチェーン送信にまとめます。

ブロックチェーンで魔法を生み出す
Alchemyは、最も強力なweb3開発者向けプロダクトとツールを、豊富なリソース、コミュニティ、そして卓越したサポートと組み合わせて提供します。