【问题标题】:Unexpected msg.sender in onERC721ReceivedonERC721Received 中的意外 msg.sender
【发布时间】:2021-07-22 03:01:31
【问题描述】:

我与如下构造函数签订了拍卖合同:

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

这个想法是,部署拍卖合约的人应该是唯一可以将代币转移到拍卖合约中的人。

问题是,即使我使用与部署拍卖合约的帐户相同的帐户来铸造新令牌,但当我尝试使用构造函数时,我从 onERC721Received 方法中收到错误 Only the beneficiary can transfer the token into the auction.用于铸造代币并将其转移到拍卖合约的功能。

我不确定msg.sender 是否会变成MyMintingContract,因为它是调用onERC721Received 方法的直接那个,但是当我检查Remix 时,它显示调用mintToken 的帐户是from (这是我用来部署拍卖合约的同一个帐户),这意味着它应该与beneficiary 变量一致。

如果我查询beneficiary 变量,我会得到0x5B38Da6a701c568545dCfcB03FcB875f56beddC4,它与上图中from 中的地址相同。我是否正确假设 msg.senderfrom 相同?

【问题讨论】:

    标签: blockchain ethereum solidity smartcontracts evm


    【解决方案1】:

    在给定的上下文中,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)。

    【讨论】:

    • 我可以使用和引用tx.originmsg.sender 在智能合约中的使用方式吗,例如在revert 修饰符中?
    • 是的。它是一个特殊的全局变量。此处列出所有全局变量:docs.soliditylang.org/en/latest/…
    猜你喜欢
    • 1970-01-01
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 2016-05-21
    • 2021-06-16
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多