如果您让任何人调用该approve
函数,它将允许任何人批准自己接受 NFT!的目的approve
是让资产的所有者能够允许其他人转移该资产,就好像它是他们的一样。
任何销售的基本前提是您要确保您获得付款,并且买方收到货物以换取销售。Petr Hedja 的解决方案通过让buy
功能不仅转移 NFT,还包括发送代币价格的逻辑来解决这个问题。我想推荐一个类似的结构,但有一些变化。一个是该功能也适用于 ERC20 代币,另一个是防止出现边缘情况,即如果在执行过程中 gas 用完,买方最终可能会免费获得 NFT。不过,这是建立在他的答案之上的,并且可以自由地使用该答案中的一些代码用于架构。
address(0)
通过输入零地址 ( ) 作为代币的合约地址,仍可以将以太币设置为可接受的货币。
如果以 ERC20 代币进行销售,则买方将需要批准 NFT 合约才能花费销售金额,因为该合约将直接从买方账户中提取资金。
pragma solidity ^0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol';
contract MyToken is ERC721 {
event NftBought(address _seller, address _buyer, uint256 _price);
mapping (uint256 => uint256) public tokenIdToPrice;
mapping (uint256 => address) public tokenIdToTokenAddress;
constructor() ERC721('MyToken', 'MyT') {
_mint(msg.sender, 1);
}
function setPrice(uint256 _tokenId, uint256 _price, address _tokenAddress) external {
require(msg.sender == ownerOf(_tokenId), 'Not owner of this token');
tokenIdToPrice[_tokenId] = _price;
tokenIdToTokenAddress[_tokenId] = _tokenAddress;
}
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);
address tokenAddress = tokenIdToTokenAddress[_tokenId];
if(address != address(0){
IERC20 tokenContract = IERC20(tokenAddress);
require(tokenContract.transferFrom(msg.sender, address(this), price),
"buy: payment failed");
} else {
payable(seller).transfer(msg.value);
}
_transfer(seller, msg.sender, _tokenId);
tokenIdToPrice[_tokenId] = 0;
emit NftBought(seller, msg.sender, msg.value);
}
}