简体   繁体   English

拍卖完成后将ERC721令牌推入钱包

[英]Pushing an ERC721 token into a wallet after auction completion

I'm trying to develop a set of contracts in where an ERC721 token is auctioned off, then the winner gets the token placed into their wallet. 我正在尝试开发一套合同,在其中拍卖ERC721令牌,然后获胜者将令牌放入他们的钱包。 I'm not entirely sure how to structure this. 我不完全确定该如何组织。 These are the contracts I was thinking would be needed. 这些是我当时认为需要的合同。

WALLET 钱包

  1. Contains the mapping of addresses to tokens owned 包含地址到拥有的令牌的映射
  2. Upon deployment, creates deploys an AuctionFactory contract and saves the address 部署后, AuctionFactory会部署一个AuctionFactory合同并保存地址

AUCTIONFACTORY AUCTIONFACTORY

  1. Deploys an Auction contract upon command, with the item being the ERC721 token specified 根据命令部署Auction合同,该项目为指定的ERC721令牌

AUCTION 拍卖

  1. Contains all the logic for an auction 包含拍卖的所有逻辑
  2. Inherits from Wallet , allowing manipulation of the mapping state variable found in the contract, placing ERC721 tokens won into the winners wallet 继承自Wallet ,允许操作合同中找到的mapping状态变量,将赢取的ERC721代币放入​​赢家的钱包中

The problem is that Auction can't inherit from Wallet . 问题是Auction不能从Wallet继承。 The compiler will throw an error when AuctionFactory tries to deploy an auction - cannot create instance of derived or same contract . AuctionFactory尝试部署拍卖时,编译器将引发错误- cannot create instance of derived or same contract And that makes sense to me, since Wallet deploys the factory, and if the factory deploys an Auction that inherits from Wallet , it's technically deploying its parent contract. 这对我来说很有意义,因为Wallet部署了工厂,并且如果工厂部署了继承自WalletAuction ,则从技术上来说,它正在部署其父合同。

So my question is, how can I structure this set of contracts? 所以我的问题是,如何构造这组合同? How can I allow an instance of an auction contract to communicate and manipulate with a store on another contract? 如何允许拍卖合同的一个实例与另一个合同的商店进行通信和操纵?

I'm not sure why you need to inherit from a Wallet contract. 我不确定为什么您需要继承Wallet合同。 The Auction structure should be something like: 拍卖结构应类似于:

  • Owner of token X calls a function createAuction from your contract to create an auction 令牌X的所有者从您的合约中调用函数createAuction来创建拍卖
  • createAuction(tokenId, minPrice, duration) will: createAuction(tokenId, minPrice, duration)将:
    1. Store the owner address, token id and some other information (minimum price, duration, etc.) into a mapping. 将所有者地址,令牌ID和一些其他信息(最低价格,期限等)存储到映射中。 You'll probably use your token id as the mapping key. 您可能会使用令牌ID作为映射键。
    2. Use the transferFrom function from your ERC721 contract to transfer the ownership from current owner to the Auction contract itself, something like: erc721.transferFrom(owner, this, tokenId) . 使用ERC721合同中的transferFrom函数将所有权从当前所有者转移到拍卖合同本身,例如: erc721.transferFrom(owner, this, tokenId) This is required later when you have to transfer the ownership to the buyer. 以后在您必须将所有权转让给买方时需要这样做。
  • A buyer joins the game, and bid on this auction by calling a bidOnAuction(tokenId) . 买家加入游戏,并通过调用bidOnAuction(tokenId)竞标该拍卖。 Check the parameters ( msg.value > minPrice , duration, etc.). 检查参数( msg.value > minPrice ,持续时间等)。 And if these are bid winning conditions, then you transfer the money to the seller (owner) and you transfer the token owrnership from your contract to the buyer, again by calling the erc721 method: erc721.transferFrom(this, msg.sender, tokenId) . 并且如果这些是中标条件,那么您再次将货币所有权从您的合同转移到卖方(所有者),然后通过调用erc721方法将令牌所有权从买方转移到买方: erc721.transferFrom(this, msg.sender, tokenId)

The Auction contract works as an escrow, it keeps the ERC721 token ownership until the auction is finished (bought or cancelled). 拍卖合同是一种托管,它将保留ERC721令牌的所有权,直到拍卖完成(购买或取消)。 You don't have to "manipulate ownership", you only have to let the owner transfer the token to your contract and then, your contract transfer the ownership back to the previous owner if the auction was cancelled or to the buyer if the auction was completed. 您不必“操纵所有权”,只需要让所有者将令牌转移到您的合同中,然后,如果拍卖被取消,则您的合同将所有权转移给先前的所有者,如果拍卖被取消,则将所有权转移给买方。完成。

Here is an example contract which can deposit tokens and then auction them off. 这是一个示例合同,可以存放令牌然后将其拍卖掉。 This is a basic auction model which shows the control flow for transferring possession of the token. 这是一个基本拍卖模型,显示了转移令牌所有权的控制流程。

Here is the setup. 这是设置。 First we have to import the ERC-721 headers. 首先,我们必须导入ERC-721标头。 I am using the reference implementation for ERC-721 for this: 我为此使用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";

Here is the contract and the main data structure: 这是合同和主要数据结构:

// 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;
    }
}

We add in the deposit mechanism. 我们添加了存款机制。 This works by allowing people to send tokens directly to the auction contract. 通过允许人们将代币直接发送到拍卖合同来工作。 You may implement a different mechanism to start auctions, but this one works just as well. 您可能会采用其他机制来开始拍卖,但是这种机制同样有效。

    // 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;
    }

Here is a mock implementation for your auction process. 这是您拍卖过程的模拟实现。 Your actual auction will certainly be more complicated. 您的实际拍卖肯定会更加复杂。

    function completeAuction(uint256 auctionId) external {
        auctionDetails[auctionId].bidIsComplete = true;
    }

Lastly, when the auction is done then the winning bidder needs to take the token. 最后,当拍卖完成时,中标者需要获得代币。

    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];
    }

The above is a fully-functioning starting point for this project. 以上是该项目的功能全面的起点。

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

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