0

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

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 时,它显示了调用该方法的帐户mintTokenfrom这是我用来部署拍卖合同的同一个帐户),哪个意味着它应该与beneficiary变量一致。

在此处输入图像描述

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

4

1 回答 1

1

在给定的上下文中,msg.sender指向调用链中的直接父级(当前合约的调用者),并tx.origin指向调用链的根(入口点)。

考虑一个调用链:

user
  contract A
    contract B
      contract C

对于合同 C 的上下文,msg.sender是合同 B 并且tx.origin是用户。

from屏幕截图中的值是tx.origin,但不一定msg.sendermsg.sender仅是合同 A 的值)。

于 2021-07-22T17:06:45.357 回答