2

I have a contract that implements the ERC721 interface, and I want to allow token owners to set their tokens as "buyable", so that any other address can buy their token without any action on the part of the owner, given constraints are met (proper price, etc).

It seems that approve and transferFrom are only callable by the owner of the transferred token, not a to-be buyer. So there would not be a straightforward way to let a buyer take ownership of a token without a transaction from the seller first.

Whats the standard way to implement this? Examples such as this marketplace implementation seem to suggest that marking a token as "buyable" results in approving a third party contract that takes control of asset, and does the transfer on behalf of the owner. Curious if there's an easier way or if this is the process implied by the spec.

0

There is no standard way to implement this.

The first decision you’ll need to make is whether you would like a first-party solution (the ERC-721 contract performs the sale) or a third-party solution (another contract performs the sale.

One first-party vending machine is Su Squares, although that only allows primary market (“gen 0”) sales.

One third-party auction is CryptoKitties, this allows selling ERC-721s through the ClockAuctionSale.

Since there is no standard implementation, I will hold you to the high standards of Stack Overflow and say: please come back with detailed requirements or an example implementation you tried before we can help you further.

0

So I ended up going with a solution that used my contract as an intermediate third party. The flow goes as follows:

  1. The seller approves the contract address to act on their behalf.
  2. Then, when the buyer wants to buy the token, the contract transfers the token from the buyer to the seller, and transfers the payment as well

Something along the lines of:

function setForSale(uint256 _tokenId) external {
    address owner = ownerOf(_tokenId);

    require(isValidToken(_tokenId));
    require(owner == msg.sender || authorized[owner][msg.sender]);

    allowance[_tokenId] = address(this);
    tokensForSale.push(_tokenId);
    // set the sale price etc

    emit Approval(owner, address(this), _tokenId);
}

function buy(uint256 _tokenId) external payable {
    address buyer = msg.sender;
    uint payedPrice = msg.value;

    require(isValidToken(_tokenId));
    require(getApproved(_tokenId) == address(this));
    // require payedPrice >= salePrice

    // pay the seller
    // remove token from tokensForSale

    transferFrom(ownerOf(_tokenId), buyer, _tokenId);
}

Obviously you can do this with a third-party contract, but I found this easy and fairly straightforward using the given interface.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.