Search code examples
metadatasolidityipfs

Get token metadata inside the smart-contract for game functions


Context

I'm working on my first Game working with a Smart contract and I have some question.

On my game I have characters and cards, and both player will duel each other using one character and 10 card each.

For that, no issue: All players and cards metadata are stored into an IPFS buckets, and some extra metadata (like experiences) are stored into the smart-contract to be updated by the game.

The problem

Now I want to be able to create a duel function into my smart-contract. But I don't know how I can access to players and cards metadatas to be able to know you'll win.

"Solutions" I have in mind

  • #1: I never saw any IPFS fetcher to get the metadata, nor JSON parser.. So it's probably not the good way to do it.

  • #2: Do I have to implement a mapping(uint => Players) private playersMetadata; into my contract and load all metadata on it to be able to use it on the duel function ??

    • But #2.1: It'll enlarge the storage needed a lot !
    • And #2.2: How can I even load it ? By creating a function setPlayer(uint idx, Players playerMetadata) and mint 10k+ times this function ? It'll cost me so much !
  • #3: Do not implement this function on the smart-contract and do it on my web-server.. But I don't like that because I want the user to be able to read the smart-contract code and trust it (but don't trust me). So if I do it on my server side, they'll not be able to trust the function.

Thank you for helping me ! Have all a good day


Solution

  • There's no synchronous and straightforward way to access off-chain data (including IPFS, since it's on a different chain) from a smart contract.

    You could use the oracle pattern to request the specified IPFS data from an offchain app that sends it back to the contract asynchronously (in a later block). But since one of your concerns is users' trust in the code, and this pattern introduces an element that the users can't control (the offchain app can theoretically pass to your contract a different value from what is actually stored on the IPFS), I won't go deeper into this approach.

    Another option is to move the metadata required for the fight logic to the contract. You can shift the transaction fees to the users, so each time they want to perform an action (e.g. create a card, update a character, fight other player), their wallet will pop up asking them to pay the transaction fees.

    Usually onchain games require a significant amount of data to be transferred. Some game authors make use of sidechains (e.g. Axie Infinity and their Ronin chain, which is a layer 2 chain connected to Ethereum), where the overall fees can be significantly lower (but a chain without fees would attract spam transactions flooding the network). This is also one of the approaches worth taking a look at.

    Or possibly, smart contract just might not be a good tool for your use case. You could also create the game in a web technology, opensource the code, make getter endpoints publicly available, so that anyone can verify that the code that runs on your server really does what you claim it does.