Blockchain code Metaverse VR

SmartContract×VR×Crypto(584)

スポンサーリンク

//tips

//smart contract

構造理解継続。

_mintの代わりに使用が推奨されている_safeMintとは、_mintの後に_checkOnERC721Receivedのrequire文の処理を追加している。

function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}

_checkOnERC721Receivedについて詳しく見ていく。返り値はboolなのでyesかno。

最初に実施されている分岐のisContract()は、もしtoがコントラクトだった場合にtrueを返す。

https://docs.openzeppelin.com/contracts/2.x/api/utils#Address-isContract-address-

It is unsafe to assume that an address for which this function returns false is an externally-owned account (EOA) and not a contract.

toがコントラクトアドレスのとき、ERC721Receiverに従ってonERC721Received()を呼ぶ。これはbyte4で返し、_ERC721_RECEIVEDと等しいかどうか確認するもの。

_ERC721_RECEIVEDはbytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
と定数で定義されている。

そもそもこれが何を行っているかわからなかったので調べてみると、ERC721ではトークンが行方不明になるのを防ぐため、コントラクトがトークンを受け取る場合にはコントラクトがonERC721Received(_from, _tokenId, _data) を呼びだされた時に受け取りを許可するならば戻り値としてマジックナンバー 0xf0b9e5ba を返すことを決めているよう。

このマジックナンバーをきちんと返すかの確認。

https://qiita.com/shora_kujira16/items/6efd834e6a3a3eb8a98c

つまり、 return retval == IERC721Receiver.onERC721Received.selector;の部分で0xf0b9e5baで一致しているかの判断をおこない、その値を返している。

Selector部分がよくわからないのでもう少し突っ込む。
シンプルな説明は見つけた。

If is usually called after a token has been transferred (in same tx).

If the receiver of the token is a contract, it checks if the contract implements the onERC721Received interface.

If no, it reverts the transaction.

If yes, the receiver contract has a onERC721Received method. The ERC721 calls this method, and now execution goes to the receiver contract to do whatever he wants. For example - staking the received token. [or more dangerously - reenter the ERC721 contarct.]

After the receiver token's onERC721Received finishes, the execution resumes in the ERC721 contract.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/IERC721Receiver.sol

The ERC721 smart contract calls this function on the recipient after a IERC721.safeTransferFrom. This function MUST return the function selector, otherwise the caller will revert the transaction. The selector to be returned can be obtained as this.onERC721Received.selector. This function MAY throw to revert and reject the transfer. Note: the ERC721 contract address is always the message sender.

https://docs.openzeppelin.com/contracts/2.x/api/token/erc721

やはりselectorがいまいちわからない。

https://ethereum.stackexchange.com/questions/72363/what-is-a-function-selector

たどり着いた。コードをコンパイルした時に生成されるabiの内容のよう。

https://docs.soliditylang.org/en/v0.8.12/abi-spec.html

web3.eth.contract#methodsなどを使って、Contractの関数を呼び出すtransactionを作成した場合は、必ずtransactionのdata部の先頭4byteに対象となる関数のfunctionIdが埋め込まれ、
EVMではこのdata部を引数として受け取り、解析することで実行すべき関数を探索しているとのこと。

function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}

to.isContract()がtureの場合、つまりコントラクトの場合でもstakingの処理を行うことにつなげられるよう。一般的には変なコントラクトにトークンを送らないためのgox対策のよう。

Requireでエラーになるとは_mintは取り消される。この場合は_mintを実行した際にかかったgas代は戻ってこない。

次はapproveを確認。これは指定されたトークンIDをtoに転送することの許可。

function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");

require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner nor approved for all"
);

_approve(to, tokenId);
}

人気の記事

1

コロナによる需要変化 コロナパンデミックの影響で、人々は外に出られなくなり、自宅で過ごす時間が増えました。 この自粛ムードの中、下記のようなビジネスの需要変化が引き起こされています。 【利用者減少】 ...

2

米国レストランの決済時に毎日お世話になっていた「Square」のビジネスモデルについて本日はふれていきたいと思います。 「Square」とは、ネットにつながったモバイル端末と専用のカードリーダーを用意 ...

3

無料でネットショップを開けるアプリとして多くの人に驚きを与えたBASE株式会社が、2019年10月25日東証マザーズに上場しました。2020年2月時点で90万店を超えるショップを抱えるまでに成長してい ...

4

2011年にサービスを開始してから圧倒的な成長率を誇るインテリア通販サイト 【FLYMEe/フライミー】を皆さんご存じでしょうか。 「自分のイメージするインテリア、本当に欲しいインテリアがどこにあるの ...

5

ナイキのSNKRSが、なぜこれほどまでに人気なのか?調べてみました。 きっかけは米国での友達との会話。彼は自分のシューズをみせて、「これ20万円もしたんだぜ。」と語ってくれました。 あまり靴に興味がな ...

-Blockchain, code, Metaverse, VR
-, ,

Copyright© BUSINESS HUNTER , 2022 All Rights Reserved Powered by AFFINGER5.