3

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

Arthur
  • 4,870
  • 3
  • 32
  • 57

1 Answers1

2

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.

Petr Hejda
  • 40,554
  • 8
  • 72
  • 100
  • If want user to win ETH after win a fight, so I think I have to use smart contract. If I can understand well, the best solution is to move all required metadata to my smart contract. But I do not understand what you say by "Transfer the data" ? Do I have to populate all existing metadata in the smart contract at the beginning (before fight) or do user have to transfer their own data when they're calling the fight function ? (And if it's the second case, how can I verify it ?) I also thinking about using Polygon network to reduce fees, it's like Ronin Chain for Axis Infinity right ? – Arthur Jan 05 '22 at 09:57
  • And If I have to transfer all data at the beginning, what's the best way to populate that much data into the smart contract without paying large amount of fee? – Arthur Jan 05 '22 at 09:58
  • 1
    @Arthur In order to calculate the fight result in a smart contract, all metadata (required for the fight) should be present in the smart contract. So yes, you should populate the contract before the fight - or better each time a player updates their fighting skills (loads new equipment, etc). Othwerwise, if you let the players to control the logic (submit fight data) themselves, the contract could not verify it and that would open the game to cheating. – Petr Hejda Jan 05 '22 at 10:35
  • 2
    A cheap way to populate large amount of data into a contract is to create a merkle tree, publish its root to the contract, and let each player claim their metadata providing the proof to the merkle tree (e.g. their address). – Petr Hejda Jan 05 '22 at 10:36
  • Okay, I understand everything. Merkle tree look to complicated for me, but thank you for all your answer =] – Arthur Jan 05 '22 at 10:39
  • Also, you talk about Axis Infinity, so If i understand well they are using the solution to push all metadata on their smart contract right ? – Arthur Jan 05 '22 at 12:37
  • 2
    @Arthur Thats correct. But also, they use a L2 sidechain so that the fees are lower compared to the main Ethereum chain. – Petr Hejda Jan 05 '22 at 15:25