Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[issue:558]remove Address.sol, replace isContract with address(...).code.length > 0 #721

Merged
merged 1 commit into from
May 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 0 additions & 14 deletions 34_ERC721/Address.sol

This file was deleted.

39 changes: 20 additions & 19 deletions 34_ERC721/ERC721.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import "./IERC165.sol";
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./String.sol";

contract ERC721 is IERC721, IERC721Metadata{
using Address for address; // 使用Address库,用isContract来判断地址是否为合约
using Strings for uint256; // 使用String库,

// Token名称
Expand All @@ -26,6 +24,9 @@ contract ERC721 is IERC721, IERC721Metadata{
// owner地址。到operator地址 的批量授权映射
mapping(address => mapping(address => bool)) private _operatorApprovals;

// 错误 无效的接收者
error ERC721InvalidReceiver(address receiver);

/**
* 构造函数,初始化`name` 和`symbol` .
*/
Expand Down Expand Up @@ -165,7 +166,7 @@ contract ERC721 is IERC721, IERC721Metadata{
bytes memory _data
) private {
_transfer(owner, from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "not ERC721Receiver");
_checkOnERC721Received(from, to, tokenId, _data);
}

/**
Expand Down Expand Up @@ -225,22 +226,22 @@ contract ERC721 is IERC721, IERC721Metadata{
}

// _checkOnERC721Received:函数,用于在 to 为合约的时候调用IERC721Receiver-onERC721Received, 以防 tokenId 被不小心转入黑洞。
function _checkOnERC721Received(
address from,
address to,
uint tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
return
IERC721Receiver(to).onERC721Received(
msg.sender,
from,
tokenId,
_data
) == IERC721Receiver.onERC721Received.selector;
} else {
return true;
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
revert ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC721InvalidReceiver(to);
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}

Expand Down
82 changes: 46 additions & 36 deletions 34_ERC721/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,24 +150,32 @@ interface IERC721Receiver {

我们看下`ERC721`利用`_checkOnERC721Received`来确保目标合约实现了`onERC721Received()`函数(返回`onERC721Received`的`selector`):
```solidity
function _checkOnERC721Received(
address from,
address to,
uint tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
return
IERC721Receiver(to).onERC721Received(
msg.sender,
from,
tokenId,
_data
) == IERC721Receiver.onERC721Received.selector;
} else {
return true;
function _checkOnERC721Received(
address operator,
address from,
address to,
uint256 tokenId,
bytes memory data
) internal {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(operator, from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
// Token rejected
revert IERC721Errors.ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
// non-IERC721Receiver implementer
revert IERC721Errors.ERC721InvalidReceiver(to);
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}
```

## IERC721Metadata
Expand Down Expand Up @@ -199,11 +207,9 @@ import "./IERC165.sol";
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./Address.sol";
import "./String.sol";

contract ERC721 is IERC721, IERC721Metadata{
using Address for address; // 使用Address库,用isContract来判断地址是否为合约
using Strings for uint256; // 使用String库,

// Token名称
Expand All @@ -219,6 +225,9 @@ contract ERC721 is IERC721, IERC721Metadata{
// owner地址。到operator地址 的批量授权映射
mapping(address => mapping(address => bool)) private _operatorApprovals;

// 错误 无效的接收者
error ERC721InvalidReceiver(address receiver);

/**
* 构造函数,初始化`name` 和`symbol` .
*/
Expand Down Expand Up @@ -294,7 +303,7 @@ contract ERC721 is IERC721, IERC721Metadata{
_approve(owner, to, tokenId);
}

// 查询 spender地址是否可以使用tokenId(他是owner或被授权地址)。
// 查询 spender地址是否可以使用tokenId(需要是owner或被授权地址)
function _isApprovedOrOwner(
address owner,
address spender,
Expand Down Expand Up @@ -358,7 +367,7 @@ contract ERC721 is IERC721, IERC721Metadata{
bytes memory _data
) private {
_transfer(owner, from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "not ERC721Receiver");
_checkOnERC721Received(from, to, tokenId, _data);
}

/**
Expand Down Expand Up @@ -418,22 +427,22 @@ contract ERC721 is IERC721, IERC721Metadata{
}

// _checkOnERC721Received:函数,用于在 to 为合约的时候调用IERC721Receiver-onERC721Received, 以防 tokenId 被不小心转入黑洞。
function _checkOnERC721Received(
address from,
address to,
uint tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
return
IERC721Receiver(to).onERC721Received(
msg.sender,
from,
tokenId,
_data
) == IERC721Receiver.onERC721Received.selector;
} else {
return true;
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
if (to.code.length > 0) {
try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, data) returns (bytes4 retval) {
if (retval != IERC721Receiver.onERC721Received.selector) {
revert ERC721InvalidReceiver(to);
}
} catch (bytes memory reason) {
if (reason.length == 0) {
revert ERC721InvalidReceiver(to);
} else {
/// @solidity memory-safe-assembly
assembly {
revert(add(32, reason), mload(reason))
}
}
}
}
}

Expand All @@ -455,6 +464,7 @@ contract ERC721 is IERC721, IERC721Metadata{
return "";
}
}

```

## 写一个免费铸造的APE
Expand Down