0

I have a game where, the more time users spend playing, interacting with the environment, etc they earn a number of tokens. As this is happening in real-time, this is currently just an incremented number in a database. I want to allow players to transfer out their tokens into their wallet and I'm wondering which is the most correct way to do this. So far, I see 2 options, both have limitations...

API initiated

  1. User clicks on transfer
  2. Transfer request sent to API
  3. API decrements the token amount in the database, creates a transaction for the transfer of X tokens, signs it and serializes it
  4. Serialized transaction is sent to the client
  5. Client signs the transaction and the transfer happens.

The problem I see here is, say the client doesn't sign the tx, there's a network problem, or any other reason for the tx to fail; Then the tokens have been decremented from the database and the tx didn't happen so the user looses out.

Client initiated

  1. User clicks on transfer
  2. Client creates a transaction for the transfer of X tokens, signs it and serializes it
  3. Serialized transaction with client signature is sent to the API
  4. API deserializes the transaction, validates the transaction is correct (valid number of tokens compared to the quantity in the database) and signs the transaction
  5. API decrements the token in the database, executes the transaction and monitors the response
  6. If the response is not successful then the API re-increments the tokens in the database.

Problem here is its a bit long winded, the latest block hash can expire and thus transactions are not reliable.

Can anyone shed some light as to what is the best way of handling this please?

1 Answer 1

0

Both approaches definitely work.

For approach number 1, you can improve it by signing the transaction, not decrementing their amount, and then store that signature somewhere else. Another job can loop through the stored signatures to see if the transaction has been confirmed -- only when the transaction is confirmed do you actually deduct their tokens.

To avoid someone overdrawing, however, you'll likely need another field for in-flight withdrawal requests, and make sure they don't go over their amount.

As for approach number 2, it seems perfect! I don't see why you think that'll take too long -- approach number 1 will take just as long, if not longer because the user needs to sign the transaction with whatever blockhash you provided.

1
  • Thank you Jon C. I went for a variation of the 2nd approach where the API first creates the transaction and then hashes it (along with a nonce). The transaction is sent to the client to sign. Once signed, sent back to the API, hashed again and if both hashes match then there's been no tampering and all good!
    – Needleski
    Commented Mar 15 at 7:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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