ERC404について: 仕様の探索とユースケースの検討
こんにちは、web3技術を扱ったさまざまな企画を送り出すプロダクトスタジオ SenspaceのCTO りょーまです。
このポストでは2月頭に話題になったERC404について、調べたことやその使いどころについて思いつくことを紹介でしていきます。
ERC404は2月に発表されたトークン実装で、FTとNFTのトークンスタンダードであるERC20とERC721の両方の特性をもっているトークンを発行することができるものです。
名前に404とついていることから汲み取れるように、Not Found、そんなものは存在しないということのユーモアを表現した技術的実験のアートとしてとらえることもできるかもしれないです。正式なERCではなく勝手に名乗っているだけで、EIPのサイトでは実際に404ページが表示されます笑
概要
ERC404のスマートコントラクトには、ERC20のFTとERC721のNFTの両方が存在し、FTの集合体がNFTとなるというイメージで理解するのがわかりやすいとおもいます。
unitsという定数が定義されておりこれにはFTの量を設定します。そして、unitsで規定した量のFTをあるアドレスが保有するたびに、NFTが自動的に発行されるという仕組みになっています。
例えば、unitsを100と設定した場合以下のように表せます。
アドレス | FTの量 | NFTの量 |
---|---|---|
0xabc... | 340 | 3 |
0x123... | 280 | 2 |
FTもしくはNFTをTransferさせることで、それに連動してもう片方も自動的に移動していきます。
0xabc...からFTを100、0x123...にTransferした場合以下のようになります。また、NFTをひとつTransferした場合も同じようになります。
アドレス | FTの量 | NFTの量 |
---|---|---|
0xabc... | 240 | 2 |
0x123... | 380 | 3 |
このようにFTとNFTは運命共同体のようなもので、どちらかに何らかの変化があるとunitsによって定義された条件をもとにもう片方にも影響するということになります。
TokenIDの扱い方
一つのスマートコントラクトの中で2つのトークンスタンダードを扱うためには、両方のスタンダードで実装するべき同じ名前の関数の処理をうまく分岐させる必要があります。
例えば、approve
という関数はERC20、ERC721の両方で定義されており、その両方を適切に扱える必要があります。そのために、ERC721のTokenIDにprefixをつけるひと工夫を施して、_isValidTokenId
というNFTのTokenIDとして適切かどうかを判断する内部関数が用意されています。
_isValidTokenId
を通すことによって、approve
関数できているリクエストがERC20宛なのか、ERC721宛なのかを判定しています。
/// @notice For a token token id to be considered valid, it just needs
/// to fall within the range of possible token ids, it does not
/// necessarily have to be minted yet.
function _isValidTokenId(uint256 id_) internal pure returns (bool) {
return id_ > ID_ENCODING_PREFIX && id_ != type(uint256).max;
}
ID_ENCODING_PREFIX
という定数名でビットシフトした数値を用意し、PrefixとしてNFTのIDにつけることで、ERC20のamountとERC721のtokenIdを判別できるようにしています。
id = ID_ENCODING_PREFIX + minted;
ビットシフトは、数字のビット(0か1の情報)を左右に動かす操作です。例えば、1 << 2は、1(二進数で001)を左に2ビット動かして100(二進数で4)にします。数字を増やす(左シフト)か減らす(右シフト)かの方法です。
ERC404では左シフトをしたPrefixを用いています。
uint256 public constant ID_ENCODING_PREFIX = 1 << 255;
ERC721TransferExempt
_erc721TransferExemptという変数が定義されています。
/// @dev Addresses that are exempt from ERC-721 transfer, typically for gas savings (pairs, routers, etc)
mapping(address => bool) internal _erc721TransferExempt;
この変数では、特定のアドレスがERC721を所有できるかどうかを真偽値で管理することができます。Exemptがtrueの場合、規定量のFTを受け取ったとしてもNFTを受け取ることはありません。
実験
ここまででERC404の概要について理解できたとおもいます。そのうえで、私の方で気になった細かな仕様について実験をしたのでその結果について紹介します。
ERC20とERC721のどちらかを移動すると、もう片方も本当に移動するのか?
こちらは、仕様の確認程度の実験ですが、先程記載した通りERC20とERC721は一心同体のように動きます。スマートコントラクトに存在するFTとNFTの関係性は常に
ERC20のtotalSupply / units = ERC721のtotalSupply
が成り立つようになっています。
TransferのtoのAddressがExemptに入っている場合はbankという領域に一時的に保持されます。そして、次にNFTが必要になったときbankにNFTが入っている場合はそこから引き出されるようになります。
ERC721TransferExemptに入っていたアドレスがERC20を貯めたあと、途中で外されるとどうなるのか?
この実験では、Exemptを途中で変更した場合について考えます。
以下のようなフローを想定します。
- unitsを100に設定する。
- user1がExemptに入れられる。
- user1に500FT送る。
- user1のExemptを外す。
- user1に100FT送る。(user1のFTの保有量は600)
ここではuser1がNFTをいくつ所有するかが問題になります。
結果は、user1は6個のNFTを持つようになります。
途中からスタートということにはならず、それまで受け取れていたNFT全部がその時に配布されるというような仕様になっています。
複数のNFTを所持した状態でERC20を移動したとき、どのNFTが一緒に移動されるのか?
この実験では、NFTの移動について考えます。
以下のフローを想定します。
- unitsを100に設定する。
- user1に対して200FTを発行する。(user1はNFTを2つ保持し、TokenIdは1と2)
- user2に対して100FTを発行する。(user2はNFTを2つ保持し、TokenIdは3)
- user1からuser2に100FTを送る。(user1はNFTを1つ保持し、TokenIdは??、user2はNFTを2つ保持しTokenIdは3と??)
ここではuser1が持つNFTのTokenIdはどれになるかが問題になります。
結果は手に入れた順番が新しいものから転送され、user1が持つNFTのTokenIdは1で、user2が持つNFTのTokenIdは3と2です。
この状態からさらにuser2からuser1に対して100FTを送り返すと
user1はNFTを2つ保持し、TokenIdは1と2、user2はNFTを1つ保持し、TokenIdは3になります。
この仕様であることから、NFTにレアリティをつけると不用意にFTを売ることが難しくなります。レア度の高いNFTがようやく手に入ったのに、FTを売ることでそれも一緒に転送されてしまうということがありうるからです。
ERC404のユースケース
以上のような特性を持つERC404ですが、実際のプロジェクトではどのように使えるでしょうか?思いついた3つを紹介します。
売りインセンティブを下げてトークンプライス戦略にする
先程述べたように、FTとNFTが一心同体かつ、NFTが新しいもの順に移動するということから気軽にFTを売るということが難しくなります。もちろん手元に残しておきたいNFTは別のウォレットにあずけておいて、いらないものだけを売るというハノイの塔のようなパズルは可能ですが面倒です。
昨今のweb3プロジェクトでは、エアドロップやLPリワードを実施したあとのトークンプライスをどのように維持するかがとても重要です。エアドロップハントが終わったらあとはトークンを売り払って終わりという動きが一般的な中なかなか難しい問題です。
そんなとき、ERC404でNFTという一定量のFTを擬似的にロックするという仕組みは、売るインセンティブを下げる有効な手段になりうるだろうと考えられます。
ある一定量トークンを稼ぐインセンティブになる
現在さまざまなプロジェクトでトークンファーミング機能が実装されています。毎日サービスを訪れて特定のアクションを実行すると100トークン、誰かにサービスを紹介してリファラルすると500トークン、SNS上で相互にポイントを送りあう、などなど。
これらの仕組みはサービスリリースまでの準備期間としてアクティブユーザーを増やしたり、大型アップデートに向けてなるべくユーザーのアテンションを引き続けたりするためのマーケティング戦略の一つとして利用されています。
ここに、単にトークンを発行するだけでなく、500トークン集めると1つNFTがついてきてそのレアリティはランダムで決まる、などの遊びを追加することができると思います。
FTとNFTの価格差を利用して、流動性を活性化させる
FTとNFTの供給量は線形で常に同期しています。しかし、それぞれの値段は同期している必要はあるのでしょうか?
つまり、units: 100
で 100FT: 100ドル
の場合、NFTの価格も100ドルである必要があるのでしょうか?そうでなくてもいいと思います。
むしろ、NFTにレアリティがついている場合、その価格は異なるはずです。しかし、それを構成するFTの価格は同じ。ここに価格の複雑性がうまれます。
FTの相場 | FT換算の価格 | NFTの価格 | NFTのレアリティ |
---|---|---|---|
1ドル | 100ドル | 1,500ドル | 5 |
1ドル | 100ドル | 100ドル | 1 |
この特性を活かすことで、より流動性の高いトークンにも低いトークンにもできるような気がしています。
このポストではERC404についての概要と実験、ユースケースについて紹介してきました。今後も新しい技術について少しづつまとめていけたらと思います。
このポストは@0xApollo716にレビューしていただきました、ありがとうございます!
もしよければ、Twitter、Farcasterのフォローお願いします。
Discussion