Ethereum 拍卖完成后将ERC721代币推入钱包

Ethereum 拍卖完成后将ERC721代币推入钱包,ethereum,solidity,smartcontracts,Ethereum,Solidity,Smartcontracts,我正在尝试制定一套合同,其中一个ERC721代币被拍卖,然后获胜者将代币放入他们的钱包中。我不完全确定如何构造这个。这些是我认为需要的合同 钱夹 包含地址到所拥有令牌的映射 部署时,创建部署一个AuctionFactory合同并保存地址 拍卖厂 根据命令部署拍卖合同,指定的物品为ERC721令牌 拍卖 包含拍卖的所有逻辑 继承自钱包,允许操作合同中的映射状态变量,将ERC721赢得的代币放入赢家钱包 问题是,拍卖无法从钱包继承。当AuctionFactory尝试部署拍卖时,编译器将抛出错误-无法

我正在尝试制定一套合同,其中一个ERC721代币被拍卖,然后获胜者将代币放入他们的钱包中。我不完全确定如何构造这个。这些是我认为需要的合同

钱夹

  • 包含地址到所拥有令牌的映射
  • 部署时,创建部署一个
    AuctionFactory
    合同并保存地址
  • 拍卖厂

  • 根据命令部署
    拍卖
    合同,指定的物品为ERC721令牌
  • 拍卖

  • 包含拍卖的所有逻辑
  • 继承自
    钱包
    ,允许操作合同中的
    映射
    状态变量,将ERC721赢得的代币放入赢家钱包
  • 问题是,
    拍卖
    无法从
    钱包
    继承。当
    AuctionFactory
    尝试部署拍卖时,编译器将抛出错误-
    无法创建派生或相同合约的实例。这对我来说很有意义,因为
    Wallet
    部署了工厂,如果工厂部署了从
    Wallet
    继承的
    Auction
    ,那么从技术上讲,它是在部署其父合同


    所以我的问题是,我如何构建这套合同?如何允许拍卖合同的实例与另一合同上的商店进行通信和操作

    我不知道你为什么需要继承
    钱包
    合同。拍卖结构应类似于:

    • 令牌X的所有者从合同中调用函数
      createAuction
      ,以创建拍卖
    • createAuction(tokenId、minPrice、duration)
      将:
    • 将所有者地址、令牌id和一些其他信息(最低价格、持续时间等)存储到映射中。您可能会使用您的令牌id作为映射密钥
    • 使用ERC721合同中的
      transferFrom
      功能将所有权从当前所有者转移到拍卖合同本身,例如:
      ERC721.transferFrom(所有者,此,令牌ID)
      。当您以后必须将所有权转让给买方时,这是必需的
    • 买家加入游戏,并通过调用
      bidOnAuction(tokenId)
      在此拍卖中出价。检查参数(
      msg.value>minPrice
      、持续时间等)。如果这些是中标条件,那么您将资金转移给卖方(所有者),并再次通过调用erc721方法将令牌owrnership从合同转移给买方:
      erc721.transferFrom(this,msg.sender,tokenId)

    拍卖合同作为第三方托管,它保留ERC721代币所有权,直到拍卖完成(购买或取消)。您不必“操纵所有权”,您只需让所有者将代币转移到您的合同中,然后,如果拍卖被取消,您的合同将所有权转移回前一位所有者,如果拍卖完成,则将所有权转移回买家。

    以下是一个示例合同,可以存放代币,然后将其拍卖出去。这是一个基本的拍卖模型,显示了转移代币所有权的控制流

        function withdraw(uint256 auctionId) external {
            AuctionDetails storage details = auctionDetails[auctionId];
    
            require(details.bidIsComplete);
            require(msg.sender == details.winningBidder);
            // Collect money from winning bidder
    
            details.nftContract.safeTransferFrom(address(this), details.winningBidder, details.tokenId);
            // Send money to seller
            // Do event logging
            delete auctionDetails[auctionId];
        }
    
    这是设置。首先,我们必须导入ERC-721头文件。为此,我使用ERC-721的参考实施:

    pragma solidity 0.5.1;
    import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/erc721.sol";
    import "https://github.com/0xcert/ethereum-erc721/src/contracts/tokens/erc721-token-receiver.sol";
    
    以下是合同和主要数据结构:

    // This implements an ERC-721 auction by taking ownership of tokens
    contract CollectableAuction is ERC721TokenReceiver {
        mapping (uint256 => AuctionDetails) auctionDetails;
    
        struct AuctionDetails {
            ERC721 nftContract;
            bool bidIsComplete;
            address seller;
            address winningBidder;
            uint256 tokenId;
        }
    }
    
    我们加入了存款机制。这允许人们将代币直接发送到拍卖合同中。您可以实现一种不同的机制来启动拍卖,但这种机制同样有效

        // Deposit an asset and start an auction
        function onERC721Received(
            address,
            address from,
            uint256 tokenId,
            bytes calldata
        )
            external
            returns(bytes4)
        {
            uint256 auctionId = uint256(keccak256(abi.encode(uint256(msg.sender), tokenId)));
            auctionDetails[auctionId] = AuctionDetails({
                nftContract: ERC721(msg.sender),
                bidIsComplete: false,
                seller: from,
                winningBidder: address(0),
                tokenId: tokenId
            });
            return 0x150b7a02;
        }
    
    这是一个模拟的拍卖过程的实现。你的实际拍卖肯定会更复杂

        function completeAuction(uint256 auctionId) external {
            auctionDetails[auctionId].bidIsComplete = true;
        }
    
    最后,拍卖完成后,中标人需要领取代币

        function withdraw(uint256 auctionId) external {
            AuctionDetails storage details = auctionDetails[auctionId];
    
            require(details.bidIsComplete);
            require(msg.sender == details.winningBidder);
            // Collect money from winning bidder
    
            details.nftContract.safeTransferFrom(address(this), details.winningBidder, details.tokenId);
            // Send money to seller
            // Do event logging
            delete auctionDetails[auctionId];
        }
    
    上述内容是本项目全面运作的起点