Server Signing

Goals:

  • Keep value-critical computations (ex. breeding) on blockchain to ensure fairness and transparency.

  • Prevent cheating from man-in-the-middle data injection attacks.

  • Give players control over alterations/upgrades to the NFTs.

  • Allow complex gameplay actions like spending cryptocurrency and soft currency “at the same time.”

Background Context:

In the past, games stored data and processed actions in two places; the client is the authority over player input, and the server is the authority over the recorded game-state. Crypto Unicorns introduces the blockchain as a third member of the system. With crypto-based games, data now needs to be replicated to two other parties.

The blockchain introduces limitations that we need to account for:

  • Smart contracts cannot “read” data from an API. The blockchain cannot make REST calls out to an endpoint. The only stateful information the blockchain can access comes from function parameters or saved state from previous function parameters.

  • Every function call on the blockchain is deterministic for the block in which it is processed. Validators can re-run functions and the results will always be equal to the result which was officially written into the block. (This makes random numbers complicated.)

  • Any RPC that mutates data on the blockchain is executed asynchronously. Putting a transaction into the queue does not guarantee that it will be processed or that it will succeed. Sometimes a transaction can take minutes or hours to resolve.

  • The blockchain “calls out” by emitting subscriptable events.

  • Polygon writes new blocks about every 2 seconds, which causes frequent Uncle Blocks. The more confirmations added on top of our transaction, the less likely it will be orphaned. This leads to a grey area where a processed transaction may still be undone. We combat this by waiting for more confirmation blocks (20-80 blocks) before accepting transaction events.

Our Solution:

A generalized system/pattern that allows the player to call blockchain functions which include arguments that have been cryptographically signed by the server.

In the general case, the sequence of events will be:

  1. A player takes an action which requires a blockchain transaction (state change) using data from the server.

  2. The front-end sends this request to the game server.

  3. The game server verifies the request, deducts any in-game resources being spent, and generates a payload for the blockchain.

  4. The game server uses a private key to sign the payload.

  5. The signed payload is returned to the client which adds it as an argument of the web3 function call.

  6. The client prompts the player to sign the web3 transaction with their Metamask wallet and submit the transaction.

  7. The smart contract uses the server’s public key to verify that the payload is authentic before executing the transaction.

  8. The smart contract emits an event letting any listeners (front end, back end, etc) know that the transaction finished.

Last updated