Kin Android development tutorial — part 9—Secure communication between backend and app for spending Kin
We’re already reaching the end of the Android development tutorial. The last 3 parts will be about spending Kin. Like earning Kin, it takes a bit of effort to create secure spending. It’s simple to make the transaction and give the reward, but like with earning Kin, everything can be faked and you need to make sure you’re not giving away stuff to people who are smart enough to fake the API calls. The way to handle spends securely is to treat spends the same way you would treat fiat money and a traditional payment gateway like Stripe or Adyen.
Suppose the user wants to buy a mug for 1000 Kin. You create a button that sends 1000 Kin from the user’s wallet to yours. When complete, you make a backend request to send the mug to the user’s address.
While this works fine, it is very easy to get free mugs. Someone can just read off the API call to the backend and start sending requests to the backend to get mugs. Without verifying that the payment actually happened, you for sure will be paying for a lot of free mugs! That’s why we’re building a secure way to handle spends. Unfortunately, this means the setup is also a bit more complex, just like with the earns. However, if you want to build an app, you don’t really have a choice, someone will eventually find the loophole and exploit it.
These kind of design flaws are actually way more common than you might think. Here’s an example of Domino’s pizza that had exactly this unsafe handling of payments, leading to anyone being able to order pizza for free.
Just as with earns, the only place where you have full control and can trust what goes on is your backend. So while the spend transaction happens on the device, verification that the spend is valid should be done on the backend. Here is the flow of a secure spend:
Step 1: Request a spend
If the user wants to buy something, an API call should be done to the app backend with a request to buy something. The app backend accepts this request and sends back a random token that is also saved in the backend for later.
Step 2: User spends Kin
The app follows by spending the Kin. The user will send the an amount of Kin to the app’s address with the token in the memo field (the token will be stored in the blockchain transaction). The transaction ID of the spend is saved. The amount of Kin to be sent is the price of the thing the user wants to buy, which can be saved in the app and in the backend, or returned along with the token in step 1 (that way you only have to define the price in the app backend).
Step 3: Request the thing you bought
Next, the app will make an API call to the backend again with the transaction ID of the spend. The backend will confirm that the transaction ID is a spend to the app’s wallet with the correct amount of Kin and the correct token. If something is wrong, deny the spend. If it was correct, proceed with giving the user what he bought and delete the token from the database (or mark the token as paid and add an extra verification that the token cannot have the paid property to prevent double spending).
All these steps are necessary. If you don’t check for the correct amount of Kin, one can simply just send a very small amount of Kin and still get the spend. If you don’t check the receiving address, one can just send Kin to himself and supply that transaction ID as a spend. If you don’t check on the token, one can make one real spend and then re-use that transaction ID multiple times to get multiple spends for the price of one.
So again, we need the app backend to validate transactions in order to make sure the spends are actually correct. In the next part, we will set up the app backend and in the part after we will create a spend button in the app.