Openzeppelin ERC20 сделать возврат

Мое намерение сделать так, чтобы токен ERC721 мог передаваться только моим токеном ERC20

поток передачи

  1. Покупатель одобряет ERC20 Продавцу.
  2. Продавец передает ERC721 Покупателю.
  3. Функция передачи моего токена ERC721 сначала передает 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]

пожалуйста, проверьте мой полный код здесь

1 ответ

Один вызывающий TransferFrom - мой контракт с erc721. поэтому я меняю тестовый код

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

изменить на

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

спасибо за SylTi

Другие вопросы по тегам