【问题标题】:Openzeppelin ERC20 make revertOpenzeppelin ERC20 恢复
【发布时间】:2019-03-09 12:44:11
【问题描述】:

我的意图是让 ERC721 代币只能通过我的 ERC20 代币转移

传输流是

  1. 买方批准 ERC20 给卖方。
  2. 卖方将 ERC721 转让给买方。
  3. 我的ERC721 Token的转账功能先将ERC20从买家转账给卖家,再将ERC721从卖家转账给买家。

ERC20 传输步骤发生还原错误。

我尝试删除每一行以找到还原点。 我发现了。

这是我的测试代码

const token20 = artifacts.require("MyToken20");
const token721 = artifacts.require("MyToken721");

contract("Test", async()=>{

//...

  // Buyer token20 approve to Seller
  it("Token20 approve", async()=>{
    var value = web3.toWei(token721Price, "ether");
    await contract20.approve(seller, value, {from:buyer});

    var allowed = await contract20.allowance(buyer, seller);
    allowed = web3.fromWei(allowed, "ether");
    assert.equal(allowed, token721Price);
  });

  // Seller transfer token721 to Buyer
  // token20 transfer to Seller inside of function transferMy721
  it("Token721 transfer", async()=>{
    var allowed = await contract20.allowance(buyer, seller);
    allowed = web3.fromWei(allowed, "ether");
    assert.equal(allowed, token721Price);

    await contract721.transferMy721(buyer, token721Id, {from:seller});  // <--- revert here

    var newOwner = await contract721.ownerOf(token721Id);
    assert.equal(newOwner, buyer);
  });

});

我的合同中的还原点在这里

contract MyToken721 is ERC721Token{                                                       
  string public name = "My ERC721 Token Product";                                         
  string public symbol = "MTP";                                                           

  mapping(uint256 => uint256) my721TokenPrice;                                            

  MyToken20 token;                                                                        

  constructor(MyToken20 _token) public ERC721Token(name, symbol){                         
    require(_token != address(0));                                                        
    token = _token;                                                                       
  }                                                                                       

  function mint(address _to, uint256 _tokenId, uint256 _price) public {                   
    _mint(_to, _tokenId);                                                                 
    my721TokenPrice[_tokenId] = _price;                                                   
  }                                                                                       

  function transferMy721(address _to, uint256 _tokenId) public returns(bool){             
    require(msg.sender == ownerOf(_tokenId));                                             

    uint256 tokenPrice = my721TokenPrice[_tokenId];                                       

    if( token.transferFrom(_to, msg.sender, tokenPrice) == false )  // <--- revert here   
      return false;                                                                       

    super.approve(_to, _tokenId);                                                         
    super.transferFrom(msg.sender, _to, _tokenId);                                        

    return true;                                                                          
  }                                                                                       
//...                                                                                                                                                                                
}      

ERC20 StandardToken 合约中的还原点在这里

contract StandardToken is ERC20, BasicToken {                                 

  mapping (address => mapping (address => uint256)) internal allowed;         

  function transferFrom(address _from, address _to, uint256 _value)                                                                           
    public returns (bool)
  {                                                                           
    require(_value <= balances[_from]);                                       
    require(_value <= allowed[_from][msg.sender]);  // <--- revert here       
    require(_to != address(0));                                               

    balances[_from] = balances[_from].sub(_value);                            
    balances[_to] = balances[_to].add(_value);                                
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);      
    emit Transfer(_from, _to, _value);                                        
    return true;                                                              
  }  
//...
}

如您所见,在我的测试代码中,我仔细检查了

allowed[_from][msg.sender]

请查看我的完整代码here

【问题讨论】:

    标签: solidity revert erc20 openzeppelin


    【解决方案1】:

    调用 transferFrom 的是我的 erc721 合约。 所以,我改变了测试代码

    await contract20.approve(seller, value, {from:buyer});

    改成

    await contract20.approve(contract721.address, value, {from:buyer});

    感谢 SylTi

    【讨论】:

      猜你喜欢
      • 2021-08-06
      • 2021-09-23
      • 1970-01-01
      • 2021-06-03
      • 2021-02-01
      • 2020-01-23
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      相关资源
      最近更新 更多