In this part of the Android development tutorial we are going to set up the app backend for handling spends. To create a secure spend, the app backend needs to handle two things: request a spend and verify a spend.

Request a spend

Before the user actually spends Kin, the app needs to request a spend from the backend so it can be verified later. Just like with storing users, you typically store payment requests in a database. But for simplicity’s sake, we again are are going to use the filesystem as a makeshift database. On the app backend, create a folder called “payments”. Similar to what we did in the users folder, we are going to store our spend requests here, in the “payments” folder.

The endpoint to request a spend will be:

http://SERVER-IP:8001/spend_request?device_id=DEVICE_ID

The app backend will create a random token, store it together with the amount to be payed and device ID in the payments folder, and return the token to the app. The token can then be added in the transaction by the app.

Let’s create the endpoint: open the server.py file and add the new endpoint:

# Add to imports

import random

import string

def spend_request():

device_id = request.args.get('device_id')

amount = "5" # Define as string because we save it in a file

token = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) @app .route('/spend_request')def spend_request():device_id = request.args.get('device_id')amount = "5" # Define as string because we save it in a filetoken = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10)) with open("payments/" + token, "w") as text_file:

text_file.write("%s

%s" % (device_id, amount)) return token

Try it out! Navigate to the endpoint. You should see a random string in the browser. Then check the payments folder. A file should be there with the token as filename with the supplied amount and device ID in the file.

A note on security: Just like with the earns, here you should also take care of XSS and SQL attacks (if you use a database). One can still inject actual Python code in the device_id parameter, which is then stored in the filesystem.

Validate a spend

After the app has sent the requested amount of Kin to your wallet, the device should ask the backend to validate the spend and give the user what they bought. The app should send the transaction ID to the app backend so the app backend can verify the transaction.

When the app backend receives a request to validate the spend, it should retrieve the transaction details from the Kin blockchain using the Kin backend. If you do an API call to the Kin backend to get payment information for a particular transaction ID, the Kin backend will return the amount of Kin that was sent, the sender and receiver address and the memo which should contain the token.

The backend can then open the token file in the payments folder and verify that the transaction matches all the fields from the spend request:

Sender address is associated with the correct device ID

Receiver address is your app wallet

Transaction amount is equal to the amount in the payment request

If the file could not be found, the token is incorrect and we should deny the payment. If all goes well, we can confirm the spend transaction and give the user what he bought. Then, we delete the token file again so you cannot use the same transaction twice.

The endpoint will be the following:

First, let’s see what we get if we try to retrieve a transaction from the Kin backend. Add the following endpoint to the server.py file:

Now run the server and navigate to that endpoint with some transaction. This can be a test transaction of your own, or you can take one from the Kin blockchain explorer (select the testnet and a payment transaction; create account transactions won’t work). Here is an example of a result:

{

"amount": 10.0,

"destination": "G...",

"memo": "1-abc-MEMO",

"source": "G...",

"timestamp": 1566617609.0

}

As you see from the Python code, we call the Kin backend with a GET request to get the payment information of a particular transaction. The Kin backend returns the amount, destination address, memo, source address and the timestamp when the transaction was executed.

The memo contains 3 parts: the number 1, the app ID (it will be ABCD if you follow the tutorial), and the memo field. The app is responsible for putting the token there, the string returned from the spend_request endpoint.

Now we can validate all these properties to see if the transaction is valid. Modify the endpoint so it reads as:

# Add to imports

import os

def spend_validate():

transaction_id = request.args.get('transaction_id')

result = requests.get('

tx = result.json() @app .route('/spend_validate')def spend_validate():transaction_id = request.args.get('transaction_id')result = requests.get(' http://localhost:8000/payment/' + transaction_id)tx = result.json() token = tx["memo"].split("-")[2] try:

with open("payments/" + token, "r") as pay_file:

data = pay_file.read().split("

")

device_id = data[0]

amount = int(data[1]) with open("users/" + device_id, "r") as user_file:

data = user_file.read().split("

")

address = data[0] # Validations

if amount != tx["amount"]:

return "Amount incorrect"

elif address != tx["source"]:

return address + " " + tx["source"]

return "Sending address incorrect"

elif tx["destination"] != "YOUR-RECEIVING-KIN-ADDRESS":

return "Destination address incorret" # Spend is valid. You can add logic here to give the user

# what they bought # Now delete the file to prevent double spending.

os.remove("payments/" + token) return "Spend is valid"

except:

return "Payment is incorrect"

This is what happens: First we get the transaction and from the transaction we retrieve the token. Then we try the validation and if it fails (because the token file doesn’t exist, or the device ID has no matching Kin address, for example), we return “Payment is incorrect”.

For the validation, we need to first open the transaction file, with the token as filename. From the device_id in that file we can fetch the source Kin address because that is stored in the users/device_id file. When we have all that data, we validate everything. If nothing is wrong, the payments file is removed to prevent double spending and return that the spend is valid. There you can add logic to give the user what he bought. This is like setting a premium attribute to true, or notifying a shipping party to send a mug. Note that this needs to be done in the backend because it’s the only place you have full control over everything.

Now we can try it out: It will be a bit tricky to pass all validation with a test transaction because everything must be correct. But that is precisely the point. As a “homework assignment”, try to create a user and payment file combination that matches a random payment transaction in the block explorer (search for a payment transaction, not a ‘create user’ transaction). Then see if you get the payment to be valid; you’ll notice that you have to set everything to the actual transaction. It is not possible to cheat the system.

Wrapup

We now have a working backend that supports secure spending. In the next tutorial, we will connect the app to the app backend by creating a button to spend Kin.