初心者文系主婦がブロックチェーンを学ぶブログ

IT革命のビッグウェーブに乗り遅れた主婦が、ブロックチェーン革命の波にのるべく、ブロックチェーン技術を学ぶブログです。

【CryptZombies】レッスン5チャプター5&6:ERC721トランスファーのロジック

チャプター5:ERC721規格の所有権の移転

ERC721規格は、2つの異なるトークン移転法を持ちます。

function transfer(address _to, uint256 _tokenId) public;
function approve(address _to, uint256 _tokenId) public;
function takeOwnership(uint256 _tokenId) public;

①一番目の方法は、トークン所有者が送り先のaddress、そして送りたいトークンの_tokenId(ゾンビID)を送ってtransfer関数を呼び出すものです。
②二番目の方法は、トークン所有者がまずapprove関数を呼び出し、一番目と同じ情報を関数に送ります。
すると、コントラクトが誰がトークン受け取りを許可されたのかを、通常はmapping (uint256 => address)にて記録します。
さらに誰かがtakeOwnershipを呼び出すと、コントラクトはそのmsg.senderがトークンを受け取ることを所有者から承認されているかをチェックし、承認済みの場合は彼にトークンを移転します。

transferとtakeOwnershipのどちらも同じ転送ロジックを含みますが、順序が逆になります。(ひとつはトークンの送り手が関数を呼び出すケース、もうひとつはトークンの受け手が関数を呼び出すケース)。

したがって、このロジックを独自のプライベート関数 _transferに抽象化し、これを両方の関数で呼び出すようにします。そうすれば、同じコードを2回繰り返さなくて済むので。

テストの実行

_transferのロジックを定義しよう。

①_transferという名前の関数を定義せよ。これはaddress _from、address _toそしてuint256 _tokenIdの3つの引数を受け取り、private関数とすること。

function _transfer(address _from, address _to, uint256 _tokenId) private {
    
  }

②オーナーシップが変わるとき、2つのマッピングが更新される: ownerZombieCount (所有者のゾンビ保有数を記録する)と、zombieToOwner (誰がどのゾンビを所有しているか記録する)。

まずこの関数で行うべきは、ゾンビを 受け取る 者(address _to)のownerZombieCountを加算することだ。加算には++を使うように。

function _transfer(address _from, address _to, uint256 _tokenId) private {
    ownerZombieCount[_to]++;
  }

③次にゾンビを 送る 者(address _from)のownerZombieCountを 減らす ことが必要だ。--を使うこと。

function _transfer(address _from, address _to, uint256 _tokenId) private {
    ownerZombieCount[_to]++;
    ownerZombieCount[_from]--;
  }

④最後にzombieToOwnerマッピングを変更したい。この_tokenIdが今度は_toを指し示すようにせよ。

function _transfer(address _from, address _to, uint256 _tokenId) private {
    ownerZombieCount[_to]++;
    ownerZombieCount[_from]--;
    zombieToOwner[_tokenId] = _to;
  }

⑤おっと、まだ最後ではなかった!もう一つやらねばならぬことがある。

ERC721規格は、Transferイベントを含む。この関数の最終行で、適切な情報を渡してTransferイベントを起こさなくてはならない。erc721.solを見て、呼び出しに際してどんな引数を求められているのかをチェックして実装せよ。

erc721.solのTransferイベントは次の通りです。

event Transfer(address indexed _from, address indexed _to, uint256 _tokenId);

したがって、上記に該当する引数を渡します。

function _transfer(address _from, address _to, uint256 _tokenId) private {
    ownerZombieCount[_to]++;
    ownerZombieCount[_from]--;
    zombieToOwner[_tokenId] = _to;
    Transfer(_from, _to, _tokenId);
  }



チャプター 6: ERC721トランスファーの続きとテストの実行

ここではパブリックのtransfer関数を実装します。

トークン/ゾンビの所有者だけがそれを移転できるよう確認したい。所有者だけに関数へアクセスできるよう制限するやり方を覚えているだろうか?そうだ、お主が覚えているようにonlyOwnerOf修飾詞がそれを行う。この関数に追加しよう。

function transfer(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) {
    // 2. ここで関数を定義せよ
  }

②今度は関数の中身についてだが、1行でなくてはならない...ただ_transferを呼び出すだけだ。address _fromの引数にmsg.senderが渡されているようにすること。

function transfer(address _to, uint256 _tokenId) public onlyOwnerOf(_tokenId) {
    _transfer(msg.sender, _to, _tokenId);
  }


お疲れさまでした!


<参考>
CryptoZombies - イーサリアム上でゲームを開発する方法を学習。Powered by Loom Network