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

皆さん、ついに、エアラインでも、サブスクリプションが始まったのはご存じですか? まだ実験段階ですが、ANAが、定額全国住み放題サービスを提供する「ADDress」と組んで、国内線を4回まで定額利用可能 ...

2

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

3

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

4

ついに、noteの月間アクティブユーザー数が4400万人(2020年3月時点)に到達しました。 そもそも、「note」とは、クリエイターが、文章やマンガ、写真、音声を投稿することができ、ユーザーはその ...

5

ボードゲームカフェが1日2回転で儲かるという記事をみつけたので興味を持ち、調べてみました。 まずは、需要がどれくらいあるのか、市場のようすからみていきましょう。 世界最大のボードゲーム市場はドイツで、 ...

-Blockchain, code, Metaverse, VR
-, ,

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