Skip to content

Commit

Permalink
[issue:558]remove Address.sol, replace isContract with address(...).c…
Browse files Browse the repository at this point in the history
…ode.length > 0
  • Loading branch information
Alexzhuangyao committed May 6, 2024
1 parent 3e0ab22 commit 5cc2809
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 69 deletions.
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

0 comments on commit 5cc2809

Please sign in to comment.