はじめに
初めまして。
CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です!
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。
代表的なゲームはクリプトスペルズというブロックチェーンゲームです。
今回は、ERC2612の仕組みをERC1155形式のNFTに適用して、approve
+ transferFrom
のUXを向上させる仕組みを提案している仕組みを提案しているERC7604についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIPについてまとめています。
概要
ERC2612やERC4494を使用したPermitのフローは、ERC20やERC721トークンのUXを大幅に改善しました。
この規格では、ERC1155にPerimtの仕組みを定期ようすることを提案しています。
ERC1155では、tokenId
とvalue
の両方を考慮する必要があるため、新しい規格として提案しています。
Permitとは、第3者に自信が保有するトークンの送付をガス代を負担させて実行させることができる仕組みです。
通常、自信が保有しているトークンを運営などの第3者に実行してもらうためには、approve
関数を実行して送付許可を与える必要があります。
ただ、この処理はトランザクションを発行する必要があるため、少額でもETHが必要になります。
つまりユーザーは少額のETHを入手してからしか実行できないためUXが良いとは言えません。
そこで提案されたERC2612やERC4494では、approve
部分を署名を行うだけにして、コントラクト側で署名の検証が通れば運営などの第3者のアドレスがapprove
とtransferFrom
を実行できるようにする仕組みを提案しています。
これにより、ユーザーはガス代を保有する必要がなくなります。
ERC2612については以下の記事を参考にしてください。
ERC4494については以下の記事を参考にしてください。
この規格は、ERC5216も使用しています。
ERC5216は、ERC1155形式のNFTを保有する特定のアドレスが、自信が保有するtokenId
の保有量の内一部を他のアドレスにapprove
する仕組みを提案しています。
ERC5216については以下の記事を参考にしてください。
ERC20については以下の記事を参考にしてください。
ERC721については以下の記事を参考にしてください。
ERC1155については以下の記事を参考にしてください。
動機
ERC2612とERC4494では、ERC20とERC721にしかPermitの仕組みを適用できないため、この規格ではERC1155に適用させる仕組みを提案します。
仕様
ERC1155とERC5216に以下の3つの機能を追加する必要があります。
interface IERC1155Permit {
function permit(address owner, address operator, uint256 tokenId, uint256 value, uint256 deadline, bytes memory sig) external;
function nonces(address owner, uint256 tokenId) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
permit
実行には、allowance(owner, spender, tokenId)
で保有している特定のtokenId
の保有量の一部であるvalue
を指定し、nonces(owner, tokenId)
を1
だけインクリメントし、ERC5216で定義されているApproval
イベントを発行する必要があります。
また、以下の条件も満たす必要があります。
- 現在のブロックタイムが
deadline
以下である。 - トークンの所有者(
owner
)がゼロアドレスでない。 - 指定された
tokenId
のnonce
(nonces[owner][tokenId]
)が現在のnonce
と一致する。 - 署名sigがsecp256k1やERC2098、ERC1271などの有効な署名である。
keccak256(abi.encodePacked(
hex"1901",
DOMAIN_SEPARATOR,
keccak256(abi.encode(
keccak256("Permit(address owner,address spender,uint256 tokenId,uint256 value,uint256 nonce,uint256 deadline)"),
owner,
spender,
tokenId,
value,
nonce,
deadline))
));
これらの条件が満たされない場合、permit
の実行は失敗します。
ERC2098については以下の記事を参考にしてください。
ERC1271については以下の記事を参考にしてください。
また、DOMAIN_SEPARATOR
はEIP712に従って定義される必要があります。
DOMAIN_SEPARATOR
は、他のドメインからのリプレイ攻撃を防ぐために、コントラクトとチェーンで一意でなければなりません。
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
keccak256(bytes(name)),
keccak256(bytes(version)),
chainid,
address(this)
));
よって、署名のメッセージは以下のような構造になります。
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"Permit": [
{
"name": "owner".
"type": "address"
},
{
"name": "spender",
"type": "address"
},
{
"name": "tokenId",
"type": "uint256"
},
{
"name": "value",
"type": "uint256"
},
{
"name": "nonce",
"type": "uint256"
},
{
"name": "deadline",
"type": "uint256"
}
],
"primaryType": "Permit",
"domain": {
"name": erc1155name,
"version": version,
"chainId": chainid,
"verifyingContract": tokenAddress
},
"message": {
"owner": owner,
"spender": spender,
"tokenId": tokenId,
"value": value,
"nonce": nonce,
"deadline": deadline
}
}}
上記に加えて以下の条件があります。
permit
関数は署名者がゼロアドレスでないことをチェックする必要があります。
この仕組みでは、msg.sender
(関数実行アドレス)を参照する仕組みがなく、permit
関数の呼び出しもとは任意のアドレスにすることができます。
EIP165
この規格にはEIP165が必要になります。
EIP165を使用することで、他のNFTコントラクトがこのEIPを実装しているか簡単に検証できるようになります。
この規格で提案されているコントラクトがEIP165で返されるインターフェースIDは0x7409106d
です。
ERC165については以下の記事を参考にしてください。
補足
permit
関数は追加のトランザクションを必要とせずに、safeTransferFrom
を実行できるようになります。
このフォーマットは予期しないコードへの呼び出しを避けるように設計されています。
また、リプレイ保護のためにnonces
マッピングが提供されています。
一般的なpermit
の使用ケースとして、リレーヤーが所有者に代わってPermitを提出するシナリオがあります。
この場合、リレーヤーはPermitを提出するかどうかの選択権を持つことになります。
この点が懸念される場合、所有者はdeadline
を近い将来に設定することで、Permitの有効期間を制限できます。
また、deadline
引数をuint(-1)
に設定することで有効期限のないPermitを作成することもできます。
ERC712形式のメッセージはERC2612やERC4494での使用を考慮しており、多くのウォレットプロバイダで広く採用されているためこのEIPでも採用されています。
ERC2612ではapprove
するvalue
に焦点を当てていて、ERC4494ではapprove
するtokenId
に焦点を当てています。
このEIPはpermit
によってapprove
されるNFTのtokenId
とvalue
の両方に焦点を当てています。
また、ERC1155ではvalue
によるapprove
をネイティブにサポートしていないため、ERC5216が必要になります。
ERC2612では署名がv
, r
, s
のコンポーネントに分割されていますが、このEIPでは可変長のバイト配列を使用してEIP2098署名(64
バイト)をサポートします。
EIP2098署名はr
, s
, v
コンポーネント(65
バイト)から簡単に分離・再構成することができません。
セキュリティ
以下と同じ内容です。
引用
calvbore (@calvbore), emiliolanzalaco (@emiliolanzalaco), "ERC-7604: ERC-1155 Permit Approvals [DRAFT]," Ethereum Improvement Proposals, no. 7604, January 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7604.
最後に
今回は「ERC2612の仕組みをERC1155形式のNFTに適用して、approve
+ transferFrom
のUXを向上させる仕組みを提案している仕組みを提案しているERC7604」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!