如何使用ERC721将NFT从一个帐户转移到另一个帐户?
我正在使用 OpenZeppelin ERC721Full 合约编写 NFT 智能合约。我可以铸造 NFT,但我想要一个可以购买它们的按钮。我正在尝试编写此功能:
function buyNFT(uint _id) public payable{
//Get NFT owner address
address payable _seller = ownerOf(_id);
// aprove nft sell
approve(_seller, _id);
setApprovalForAll(msg.sender, true);
//transfer NFT
transferFrom(_seller, msg.sender, _id);
// transfer price in ETH
address(_seller).transfer(msg.value);
emit NftBought(_seller, msg.sender, msg.value);
}
这不起作用,因为功能批准必须由所有者或已批准的地址调用。我不知道应该如何构建购买功能。我知道我必须使用一些需求,但首先我希望该功能可以用于测试,然后我将编写需求。
购买功能应该如何编码?因为我找到的唯一解决方案是覆盖批准函数并省略谁可以调用此函数的要求。但看起来这不是应该的方式。
谢谢!
回答
您可以仅使用_transfer()函数,buy()有关实现示例,请参阅我的函数。
销售批准可以使用自定义映射来完成 - 在我的示例中tokenIdToPrice。如果该值不为零,则令牌 ID(映射键)可供出售。
这是允许销售 NTF 的基本代码。随意扩展我的代码以允许“免费赠送”、“白名单买家”或任何其他功能。
pragma solidity ^0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
contract MyToken is ERC721 {
event NftBought(address _seller, address _buyer, uint256 _price);
mapping (uint256 => uint256) public tokenIdToPrice;
constructor() ERC721('MyToken', 'MyT') {
_mint(msg.sender, 1);
}
function allowBuy(uint256 _tokenId, uint256 _price) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
require(_price > 0, 'Price zero');
tokenIdToPrice[_tokenId] = _price;
}
function disallowBuy(uint256 _tokenId) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
tokenIdToPrice[_tokenId] = 0;
}
function buy(uint256 _tokenId) external payable {
uint256 price = tokenIdToPrice[_tokenId];
require(price > 0, 'This token is not for sale');
require(msg.value == price, 'Incorrect value');
address seller = ownerOf(_tokenId);
_transfer(seller, msg.sender, _tokenId);
tokenIdToPrice[_tokenId] = 0; // not for sale anymore
payable(seller).transfer(msg.value); // send the ETH to the seller
emit NftBought(seller, msg.sender, msg.value);
}
}
如何模拟销售:
- 合约部署者 (
msg.sender) 获得令牌 ID 1。 - 执行
allowBuy(1, 2)这将允许任何人以 2 wei 的价格购买令牌 ID 1。 - 从第二个地址,执行
buy(1)发送 2 wei,购买令牌 ID 1。 - 调用(父 ERC721)函数
ownerOf(1)来验证所有者现在是第二个地址。