NFT mapping predicate?


#1

After discussion with @yuriko, I found the idea.
Special thank you to @yuriko for having reviewing!

Abstract

Deposit NFT to Predicate and deposit Predicate on Plasma chain.

Challenge that we are facing now:

NFT IDs usually hold 256 byte (uint256), which is more than the current Plasma core’s objectIds is 64 byte field, it include 32 byte start and 32 byte end.

Solution

We can solve this by depositing Predicate that has a map with ETH NFT on Plasma chain. Advantage of this design is that you can simply add this code on the generalized Plasma spec.

Code

NFT mapping predicate pseudo codes: contain mapping NFT id to 32 byte integer

tokens: mapping(uint32, uint256)
# tokenId is within 0-2^32
tokenNonce: uint32
depositedNonce: uint256
	
def deposit(id: uint256):
    tokens[tokenNonce] = id
    self.approve(msg.sender, tokenNonce)
    self.tokenNonce += 1

def transferFrom(from: address, to: address, amount: uint256):
    assert amount == 1
    // check approval
    // transfer tokens[depositedNonce] to `to` address
    self.depositedNonce += 1

// other methods are almost same as ownership predicate
	
 @public
 @payable
 def onExitGameFinalized(
     stateUpdate: StateUpdate
 ):
 	assert stateUpdate.start == stateUpdate.end
 	// tokens[stateUpdate.start] is your NFT id

Common codes to deposit NFT to plasma contract.

 NFTMappingPredicate.deposit(nft_id)
 PlasmaChain.deposit(1, new StateObject("NFT mapping predicate address", "owner address"))

#2

It’s too complex and not good because this NFT can’t be locked by other predicate. And also withdrawn is problem. Basically We need support by plasma chain contract for NFT deposit.


#3

This is a great thought, we have had some similar discussions as well in the past to see if you could hack it into an ERC20 plasma, and while complex it seemed like you can do it how you described. :slight_smile:

One invariant seems to be that the predicate has to be able to call the ERC721 transfer, which is a problem for reusing ERC20 predicates on ERC721s–meaning you would have to rebuild atomic swap, etc. logic into separate ERC721 predicates, which is not ideal.

One mitigation might be to create an “ERC721 withdrawal” predicate which allows you to do the withdrawal. That way, atomic swaps, transfers, etc. could be done without reference to the ERC721, and could not be used to exit the. Then, the owner could put it into the ERC721 withdrawal state after this to get the NFT out.

However, these all feel like hacks and would be problematic for things like defragmentation–so it is probably best to just build an ERC721 deposit contract separately.