简体   繁体   English

ERC721 NFT 创建一个 function 来购买/出售由合约所有者预制的 NFT,安全问题

[英]ERC721 NFT creating a function to buy/sell NFTs that have been preminted by the contract owner, security question

I came across this answer while researching creating a function for someone to buy an NFT:我在研究为某人购买 NFT 创建 function 时遇到了这个答案:

https://stackoverflow.com/a/67384225/1414721 https://stackoverflow.com/a/67384225/1414721

The relevant lines are相关线路是

            IERC20 tokenContract = IERC20(tokenAddress);
            require(tokenContract.transferFrom(msg.sender, address(this), price),
                "buy: payment failed");

I don't want people to be able to buy my NFTs in anything other than Ethereum, although the author here says:我不希望人们能够在以太坊以外的任何地方购买我的 NFT,尽管作者在这里说:

prevent an edge case where if gas runs out during execution, the buyer could end up with their NFT for free防止出现边缘情况,即如果在执行过程中气体用完,买家最终可能会免费获得他们的 NFT

This caught my eye and from reading the code it seems the check that is being done here is to prevent this edge case.这引起了我的注意,从阅读代码来看,这里所做的检查似乎是为了防止这种边缘情况。

What I'm not sure of is how the applies when the currency the NFT is being bought in is Ethereum.我不确定的是,当购买 NFT 的货币是以太坊时,它是如何应用的。

I have adjusted my buy function to look like我已经调整了我的购买 function 看起来像

    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);
        IERC20 tokenContract = IERC20(address(0));
        require(tokenContract.transferFrom(msg.sender, address(this), price), "buy: payment failed");
        payable(seller).transfer(msg.value);
        _transfer(seller, msg.sender, _tokenId);
        tokenIdToPrice[_tokenId] = 0;
        emit NftBought(seller, msg.sender, msg.value);
    }

which I believe a) incorporates the token Contract from being the Ethereum token ( IERC20(address(0)) - I understand address(0) is the Ethereum token address?) and b我相信 a) 将代币合约纳入以太坊代币( IERC20(address(0)) - 我理解address(0)是以太坊代币地址?)和 b

require(tokenContract.transferFrom(msg.sender, address(this), price), "buy: payment failed");

makes sure the gas limit edge case mentioned is handled.确保处理提到的 gas limit edge case。

Is this correct, Googling this was quite hard.这是正确的吗,谷歌搜索这很困难。

One last question (unrelated, I hope that's OK) - when a market displays all the NFTs available for a collection, i assume that the way they are doing that is the contract has a function that returns the NFT IDs and the Token URIs?最后一个问题(不相关,我希望没问题)——当市场显示一个集合的所有可用 NFT 时,我假设他们这样做的方式是合约有一个 function 返回 NFT ID 和令牌 URI? Is that correct, or does OpenZeppelin provide this functionality and I don't have to concern myself with adding this function?这是正确的,还是 OpenZeppelin 提供了这个功能,我不必担心添加这个 function?

i think the gas edge case was solved by changing the order of operations.我认为 gas edge case 是通过改变操作顺序解决的。 first pay then transfer the token.先付款再转移代币。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM