如何解决onERC721Received 中出现意外的 msg.sender
address payable public beneficiary;
ERC721 nftContract;
bool tokenAdded;
uint256 public tokenId;
constructor() public payable {
beneficiary = msg.sender;
}
我已启用合约以使用 safeTransferFrom
接收代币:
function onERC721Received(address,address _from,uint256 _tokenId,bytes memory) public virtual override returns (bytes4) {
require(beneficiary == _from,"Only the beneficiary can transfer the token into the auction.");
require(tokenAdded == false,"The auction already has a token.");
nftContract = ERC721(msg.sender);
tokenId = _tokenId;
tokenAdded = true;
return this.onERC721Received.selector;
}
以下是我铸造代币的方式:
pragma solidity ^0.8.0;
import "./ERC721.sol";
import "./Counters.sol";
contract MyMintingContract is ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC721("MyToken","MTK") {}
function mintToken(address receiver) external returns (uint256) {
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
_safeMint(receiver,newTokenId);
return newTokenId;
}
}
这个想法是,部署拍卖合约的人应该是唯一可以将代币转移到拍卖合约中的人。
问题是,即使我使用与我部署拍卖合同的同一个帐户来铸造新代币,我在尝试时还是从 Only the beneficiary can transfer the token into the auction.
方法中收到错误 onERC721Received
使用构造函数来铸造代币并将其转移到拍卖合约中。
我不确定 msg.sender
是否变为 MyMintingContract
,因为它是调用 onERC721Received
方法的直接方法,但是当我检查 Remix 时,它显示了调用 {{ 1}} 为 mintToken
(这是我用来部署拍卖合约的同一个帐户),这意味着它应该与 from
变量一致。
如果我查询 beneficiary
变量,我会得到 beneficiary
,它与上图中 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
中的地址相同。我假设 from
与 msg.sender
相同是否正确?
解决方法
在给定的上下文中,msg.sender
指向调用链中的直接父级(当前合约的调用者),而 tx.origin
指向调用链的根(入口点)。>
考虑一个调用链:
user
contract A
contract B
contract C
对于合约 C 的上下文,msg.sender
是合约 B,tx.origin
是用户。
from
值是 tx.origin
,但不一定是 msg.sender
(它只是合约 A 的 msg.sender
)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。