简体   繁体   English

onERC721Received 中出现意外的 msg.sender

[英]Unexpected msg.sender in onERC721Received

I have an auction contract with a constructor like following:我与构造函数签订了拍卖合同,如下所示:

address payable public beneficiary;
ERC721 nftContract;
bool tokenAdded;
uint256 public tokenId;

constructor() public payable {
    beneficiary = msg.sender;
}

I have enabled the contract to receive tokens using safeTransferFrom :我已启用合约以使用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;
}

Following is how I mint tokens:以下是我铸造代币的方式:

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;
    }
}

The idea is that whomever deploys the auction contract should be the only one that can transfer a token into the auction contract.这个想法是,部署拍卖合约的人应该是唯一可以将代币转移到拍卖合约中的人。

The problem is that even though I'm using the same account I've deployed the auction contract with to mint a new token, I get the error Only the beneficiary can transfer the token into the auction.问题是,即使我使用与部署拍卖合同相同的帐户来铸造新代币,我Only the beneficiary can transfer the token into the auction.收到错误消息, Only the beneficiary can transfer the token into the auction. from the onERC721Received method when I try to use the constructor function to mint and transfer the token to the auction contract.来自onERC721Received方法,当我尝试使用构造函数来铸造令牌并将其转移到拍卖合约时。

I wasn't sure if msg.sender becomes MyMintingContract since it's the immediate one that's calling the onERC721Received method, but when I checked Remix, it showed the account that called the mintToken to be from (which is the same account I've used to deploy the auction contract), which means it should coincide with the beneficiary variable.我不知道,如果msg.sender成为MyMintingContract因为它是直接一个调用了onERC721Received方法,但是当我检查混音,这表明被称为帐户mintTokenfrom (这是我用过的同一帐户部署拍卖合约),这意味着它应该与beneficiary变量一致。

在此处输入图片说明

If I query the beneficiary variable, I get 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 which is the same as the address in from from the image above.如果我查询beneficiary变量,我得到0x5B38Da6a701c568545dCfcB03FcB875f56beddC4这是相同的地址from上面的图像。 Am I correct in assuming that msg.sender is the same as from ?我假设msg.senderfrom相同是否正确?

In a given context, msg.sender points to immediate parent (caller of current contract) in call-chain, and tx.origin points to the root (entry-point) of call-chain.在给定的上下文中, msg.sender指向调用链中的直接父(当前合约的调用者),而tx.origin指向调用链的根(入口点)。

Consider a call chain:考虑一个调用链:

user
  contract A
    contract B
      contract C

For context of contract C, msg.sender is contract B and tx.origin is user.对于合约 C 的上下文, msg.sender是合约 B, tx.origin是用户。

from value in your screenshot is tx.origin , but not necessarily msg.sender (it's the msg.sender of contract A only).截图中的from值是tx.origin ,但不一定是msg.sender (它只是合约 A 的msg.sender )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Solidity 基础知识:“msg.sender”代表什么 - Solidity basics: what "msg.sender" stands for OpenZeppelin 的可拥有合约 vs 需要 msg.sender - OpenZeppelin's ownable contract vs require msg.sender 如何在solidity 0.5.0中将etherenum发送到msg.sender - How to send etherenum to msg.sender in solidity 0.5.0 Msg.sender在“视图”功能中不起作用,为什么? 有解决方法吗? - Msg.sender does not work inside a “view” function, why? Is there a workaround? 无法从智能合约向 msg.sender 发送以太币 - Not able to send ether to msg.sender from smart contract 在 Solidity 中,`msg.sender` 优于 `tx.origin` - `msg.sender` preferred over `tx.origin` in Solidity require(msg.sender == owner(), 'not owner') 抛出异常,尽管在事件中检查 msg.sender 等于 owner() - require(msg.sender == owner(), 'not owner') throwing exception although msg.sender equals owner() when inspected in event Solidity - 我如何从另一个合约转移到 msg.sender - Solidity - how do i transfer from another contract to msg.sender 允许合约从 msg.sender 获取 ERC20 代币 - Allowing contract to take ERC20 tokens from msg.sender ParserError:应为“;” 但得到了“事件”——solidity 0.8 address payable(msg.sender) - ParserError: Expected ';' but got 'event' -- solidity 0.8 address payable(msg.sender)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM