mappingの定義の仕方、Approve、takeOwnership、require再び、括弧問題解決?という感じでしょうかね。それぞれの意味であったり、使い方を復習するような内容です。
チャプターとしては6〜8まで完了する内容なので、わりかし長い記事となりますのでご了承ください!
CryptoZombies | イーサリアムでのゲーム開発を学ぶ
それでは開演します!
さぁ、前日のブログを見てたらそのまま行けると思うが、もし不安なら前回の記事を見てみてくれ!
👉レッスン5:ERC721はコレクター要素だ③
さあテストだ!!
1では、ゾンビちゃんが作ってくれたtransfer関数にonlyOwnerOf修飾子を追加せよ、との事なので、、publicのあとに追加するだけなので、、
function transfer(/*省略*/) public onlyOwnerOf(_tokenId) {}
となります。
2では、_transferを呼び出すのだが、引数にmsg.senderが渡されているようにする事、なので、
_transfer(msg.sender, _to, _tokenId);
となります!
とまあこんなところでしょう!
次いきましょか!
approveを実装という事で、、意味としては「承認する」ですね。
承認してから、オーナーシップを取得する、というのがapprove / takeOwnershipの意味ですな。
ポンポンポンとテストにて実装していくので、、テストだ!!
1では、マッピングを定義せよ!と言っているので、定義するのはコントラクト宣言したすぐ後に定義するので、、、
mapping (uint => address) zombieApprovals;
となりますな。
2では、approve関数も所有者onlyの関数にしなけばいけないので、、追加ですね。
function approve(/*省略*/) public onlyOwnerOf(_tokenId) {}
となります。
3では、_tokenIdがキーのzombieApprovalsが、_toと同等になるように設定せよ、なので、
zombieApprovals[_tokenId] = _to;
となります!!ここ[]ですね!なぜならマッピングをつかっているし、設定しているから、、と私は理解していますw
4では、Approvalイベントを発生させよ、との事なので、erc721.solからApprovalイベントに渡す引数の情報を確認して(下記参照)、_ownerにはmsg.senderを使うよう確かめる事との事なので、
erc721.sol:
これを参考にすると、
Approval(msg.sender, _approved, _tokenId);
となりそうですが、、、
Approval(msg.sender, _approved, _tokenId);ではなく、
Approval(msg.sender, _to, _tokenId);
が回答となります!
はて??どうしてだろうか、、とも思ったので、初心者プログラマとしてはわからない部分だったので、こちらはせっかくの質問機会があるので、Loom NetworkさんのDelegateCall日本語の質問コーナーに投稿させていただきました。
ど初心者の不可解な質問だなと、思われても仕方ないのを承知の上で、恥を晒すのは知らないうちにどんどんかいて成長していけばいいのだから、、という気持ちで、
32歳、できれば恥をかきたくないが、今は挑戦している身なので、どんどん恥をかいて、そして成長・進化できるよう、クソみたいなプライドなんて必要ないのだから、さらけ出していきますぜw
これをまとめると、、
mapping (uint => address) zombieApprovals;
・
・
function approve(/*省略*/) public onlyOwnerOf(_tokenId) {
zombieApprovals[_tokenId] = _to;
Approval(msg.sender, _to, _tokenId);
}
となります!
チャプター7のテストは長かったですが、こんなところでしょう!
いいですね、このまま次も行っちゃいます!
ここではtakeOwnership関数を実装していきます。翻訳すると「所有権を得る」となります。
承認されているか確認し、承認されていれば、、、という処理を実装するぞ!
それではテストだ!!
1では、requireを使ってAがBと同等になるように、って事なので、、
require(zombieApprovals[_tokenId] == msg.sender );
となります。zombieApprovalsはマッピングですからね、、[]ですねw
ちなみに、、transfer関数やapprove関数では、トークンIDの所有者しかできないように処理をする必要があったので、onlyOwnerOf修飾子をつかった訳ですね。このtakeOwnership関数は、不特定多数の誰もが対象になるので、この修飾子が入らないのは当然の事なので、間違えないようにね(自分に言い聞かせ)
2では、とても親切にaddress型のownerという名前で、ownerOf(_tokenId)と同等になるように、との事なので、、
address owner = ownerOf(_tokenId);
となります。
3では、_transfer関数を呼び出して、引数は_toにはmsg.senderを渡せとのことなので、、(理由は書いてますな)、、
_transfer(owner, msg.sender. _tokenId);
となりますね。
注意書きに書いてますが、2と3は一行でできちゃうとの事ですね。その場合、どうすればいいのか、、というのも考える事も必要だと感じます。
3で渡した引数「owner」に「ownerOf(_tokenId)」を入れる、っていうコードになるのかな?
今はまだ、その答えはわからない、、、w
まとめると、、、
require(zombieApprovals[_tokenId] == msg.sender );
address owner = ownerOf(_tokenId);
_transfer(owner, msg.sender. _tokenId);
となりますな!
ふむふむ、、ここら辺は大丈夫そうだぞ!
今日はもしかしたら娘を病院に連れて行くかもしれないのでお昼からの更新はできないかも、、
なんかね、寝ている時とかご飯食べてる時に、吐きそうなくらい咳をするんですよね、、、心配になるくらいなんだけど、、、おさまれば普通に寝てるし、ご飯食べるしで、、、
なんか痰が絡んでいる音とかしているから、そこらへんなんだと思うけど、、心配だから連れて行きます。。
という事で、この辺で!
CryptoZombies | イーサリアムでのゲーム開発を学ぶ
それではまた後ほど!