68
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ERC-721におけるsetApprovalForAllを理解する

Last updated at Posted at 2019-07-24

はじめに

ERC-721とは、Ethereum上でNon-Fungible Token(NFT)を実現するための現実的な標準規格です。

以下のEventとFunctionのインターフェースを実装することで、様々な発行者のNFTを共通に取り扱うことができるようになります。

interface ERC721 /* is ERC165 */ {
    event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
    event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);

    function balanceOf(address _owner) external view returns (uint256);
    function ownerOf(uint256 _tokenId) external view returns (address);
    function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
    function approve(address _approved, uint256 _tokenId) external payable;
    function setApprovalForAll(address _operator, bool _approved) external;
    function getApproved(uint256 _tokenId) external view returns (address);
    function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}

この規格があることにより、OpenSeaといったNFT取引所はいくつものNFTを同じように取り扱うことができます。

transfer

ERC-721にてトークンの所有情報を譲渡する場合には、ERC-721コントラクトへtransferFrom関数を実行することで実現されます。
通常、そのトークンの所有者であれば、相手がEOA(秘密鍵によるアカウント)であっても、コントラクトアカウントであっても、譲渡が可能です。

下図は、EOAであるAliceからEOAのBobもしくは、コントラクトCarolにトークンの譲渡を行うイメージです。

image.png

ここで、トランザクションの発行対象は、ERC-721のコントラクトになります。

approve

Charlieコントラクトという預け入れコントラクトがあったとします。
ここで、ERC-721へのtransferFromではなく、Charlieコントラクトのdeposit機能を使って預けたい場合があります。

image.png

このとき、Charlieコントラクトでは、deposit機能内で、ERC-721コントラクトに向けてtransferFromの内部トランザクションを発行しますが、当然トークンの所有者でないため失敗します。

image.png

そこで、「転送の許可」であるapproveを実行し前もってCharlieへ譲渡を許可します。

image.png

具体的なユースケースとしては、トークンのマーケットプレイスがあります。

image.png

マーケットコントラクトに対して事前にトークンのapproveを実行し、出品exhibitをします。

トークンの買い手Bobが現れた際には、指定の金額を送付し1つのトランザクションでトークンの売買が成立します。

image.png

setApprovalForAll

前述のapproveによって、トークンの譲渡を自動化することができ、条件によって転送させることができるようになりました。
NFTにおいてトークン一つ一つは代替不可能なものであり、トークン1つごとにapproveの必要があります。

そこで、ERC-721では、setApprovalForAllが規定されています。
これは、特定のアカウントに対して、所有する全てのトークンの転送を許可することができます。

image.png

つまり、マーケットコントラクト上で煩わしいapproveは不要になります。

また、Ethereum上では、全てのトランザクションにGasというコストがかかります。
すでに、setApprovalForAllにより譲渡の許可がされているのであれば、
信頼できるマーケットの管理者が、代理で出品を行うことで販売者はコストを0にし、利便性が上がるでしょう。

image.png

悪意のあるsetApprovalForAll

さて、煩わしいapproveと、それを一気に解決してくれるsetApprovalForAllですが、
悪意のあるコントラクトへ許可してしまった場合はどうでしょう?

image.png

Evilコントラクトは、Aliceの保有トークンを好きに動かせるようになります。
つまり、悪意のあるアカウントであるMalloryは、Evilコントラクトを経由して、Aliceのトークンを盗み出すことができます。

image.png

さいごに

Ethereumは、非中央集権である部分がもてはやされていますが、現実的なサービスは管理者が存在しユーザーの利便性のためsetApprovalForAllを利用しているケースがあります。
setApprovalForAllは全権の移譲です。全てを自己責任とすることもできます。
しかしながら、第三者によるソースコードの保証があり悪意の働けないコントラクトになっていることが確認できる場合や、信頼できるサービス提供者であることを確認した上でsetApprovalForAllを実行するほうが良いでしょう。

また、サービス提供者も、最低限のソースコード公開は必須だと思います。

68
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?