Now and Nawoo

NFTの制作記録、技術メモ → C#, Solidity, Blockchain, Bitcoin, Ethereum, NFT

ERC-721トークンのtransferとapprove

ERC-721を別のアドレスに送るのってどうやればいいのかわからなかったので調べてみました。

ERC 721 - OpenZeppelin Docs

transferFromとsafeTransferFrom

transferFrom(address from, address to, uint256 tokenId)

tokenIdのトークンをfromからtoに送る。 fromとcaller(関数呼び出した人)が異なる場合は、approve か setApprovalForAll が必要。 送り先はEOAでもコントラクトでもOK

safeTransferFrom(address from, address to, uint256 tokenId)

transferFromの内容に加えて、送り先がコントラクトだった場合に、onERC721Receivedが実装されているかを確認し、実装されていなければrevertする。

つまり、transferFromでonERC721Receivedが実装されていないコントラクトに送付すると、取り出す方法はないため失われてしまう。(という理解でいいのかな?)

基本的には safeTransferFromを使いましょうとのこと。

safeTransferFrom(address from, address to, uint256 tokenId, bytes data)

というバージョンもあった。dataは何に使うのかな?

approveとsetApprovalForAll

approve(address to, uint256 tokenId)

toに対してtokenIdのトークンを他のアカウントにtransferする許可を与える。 一度に1つのアカウントにしかapproveできないので、toを0x0にすれば前の許可を取り消せる。

setApprovalForAll(address operator, bool _approved)

operatorに対してcallerの持つすべてのトークンをtransferする許可を与える/取り消す。 第2引数がtrueなら許可を与える。falseなら許可を取り消す。

ERC-20のapproveもそうだけど、相手に全権を渡してるってことを知ってしまうと使うの怖いよなぁ。 (相手を信頼しないと成り立たない。。。トラストレスとは一体。。。)

疑問点

transferFromとsafeTransferFromの2つに分けた意味は?

そもそもtransferFromにonERC721Receivedのチェックを追加すればいいだけなのに、 なんで2つに分けたんだろう?と思っていたら、同じ疑問がStackExchangeにありました。

solidity - Why does ERC721 have transferFrom and safeTransferFrom? - Ethereum Stack Exchange

「そもそもチェックはウォレット側でやるべきだから。コントラクトはシンプルなのが一番。」という答え(意訳)だけど、だったら、safeTransferFromいらんやろって思うけど、、、。 チェックすべき派とチェックいらん派で揉めて、妥協案として2つに分けたのかな。

safeTransferFromの第3引数(data)の使いみちは?

erc 721 - How is the ERC721TokenReceiver.onERC721Received data parameter used in practice? - Ethereum Stack Exchange

価格情報をdataとして送る用途を想定してたけど、あまり使われてないってことかな。