Openzeppelin ERC20 сделать возврат
Мое намерение сделать так, чтобы токен ERC721 мог передаваться только моим токеном ERC20
поток передачи
- Покупатель одобряет ERC20 Продавцу.
- Продавец передает ERC721 Покупателю.
- Функция передачи моего токена 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