Being a blockchain developer, you will know way more than average people about how things work under the hood. You will be familiar with blocks, hashes, nodes, transactions, various data types and many more. However, if you have some idea of how to implement blockchain in a specific environment with casual users, you won’t be sharing all your wisdom with them, let alone forcing them to learn how every single operation is done. Contemporary users are spoiled with easy and interfaces with outstanding user interfaces that ensure great user experience. If you want to make your blockchain project more appealing than you should at least make it easy to use. That is where decentralized applications or dApps come into play.
Decentralized apps are a new trend in software development. They became popular after the ICO craze that started in 2017. The major distinctive feature of dApps is that they fully rely on the blockchain and therefore cannot be controlled or shut down by any third party. In addition, dApps can also utilize smart contracts, which we discussed earlier, to perform various operations securely and autonomously. Otherwise, dApps resemble centralized apps and could be anything from exchanges to games. You can check some of them from our list of 10 dApps here.
Although there are some dedicated programming languages for smart contract and dApp programming, such as Solidity, Vyper, and Simplicity, other languages can also be used for this purpose. For the purpose of this tutorial, we chose Python as it’s one of the most comprehensive and versatile languages out there. Today we will show you a simple app created with Python, launch it and explain how it works. Let’s not put it off any longer and get down to work!
Structure and properties of a dApp
First, let’s outline how a dApp should look and go over its elements. There are two major parts of a dApp:
We should also note that since backend tasks happen on the blockchain where everything is immutable, an engineer building a dApp should perform multiple deep check-ups of their project to ensure that there are no vulnerabilities in the code. This makes building dApps look more like making hardware, rather than software, that can be tweaked on the fly. On the bright side, if a dApp is perfectly written, its virtually unhackable as there is no central point of failure. Secondly, code for dApps is usually published as open-source. Otherwise the community will have trust issues and avoid using some applications.
Creating a backend
Now that we know that a dApp relies on the blockchain, let’s create one with Python locally. This is a safer approach for learning and testing things, as we don’t want to congest a real network with unnecessary code. Moreover, this demonstration is more inclined to show you the principles of how things work – the real world dApps are much more complex.
As everything will happen on your computer, the blockchain will be physically located on your hard drive, essentially making it a node. For this purpose create a folder somewhere you like and call it ‘Project’. Within the folder let’s create another one, call it ‘blockchain’ and hard code a first block there. Create a text file and open it in your code editor of choice. We will be using Atom.
Initializing the genesis block
In the first block, we will specify that a payer paid a payee one thousand coins. As you probably remember from our article about hash power, each block’s head is hashed and every block’s hash is included into the next one to ensure that the network hasn’t been tampered with. A genesis block doesn’t have a block before it, so there will be an empty hash.
Next, to our folder with the blockchain let’s create a file with the script. Start with importing JSON library as we will be using this formatting. Proceed with the ‘if __name__ == "__main__":’ statement to allow verification of whether the script will be launched from the console or not. This step will help you while importing. For our local blockchain to function we should write a function that creates new blocks. In addition, there should be a function to check if the blockchain was amended or not.
Writing new blocks
Let’s code the function to create the following blocks in the chain. To do so, we need to specify all the data types we written in the genesis block. Then we create a ‘with’ statement with a function to make a new file to make the code within new blocks more suitable for reading specify the indentation. Once it’s done, we can run the script and get a file with our test block.
The test function works! Now we can extend it to receive data and write it into next blocks. To do so we will put the payee, amount, payer and p_hash (previous block’s hash) arguments in the function.t Then, we need to make the function write the blocks in the respective folder. For this purpose, import OS for working with the computer’s file system. Afterwards, in the function let’s define the directory that we created for our blocks via ‘os.curdir’. Next, specify this declaration in the statement that writes a new file.
Going further, we can’t leave the test file labeled as it is, we want each new block to be named in a consecutive manner. As our genesis block is ‘0’, the next block should be 1 and so on. This one is rather simple, our function should be able to analyze the core blockchain directory. Find the latest number of the most recent block, increment that number by one and name the next block. To get all the blocks we will use ‘listdir’ of the OS and provide our blockchain directory variable to it. Bear in mind, that ‘listdir’ doesn’t sort blocks by their names, so the latest file, in this case, might not be what we need. Hence, we need to use list comprehension to return integers for all of the file names and sort them via ‘sorted’ function. Finally, let’s teach our blockchain to label blocks by returning the last block’s name and incrementing it by one. Make sure that you convert the label back to string and add block name to the ‘with’ function.
Now each time you run the script, you’ll get a new block. However, this is still not a blockchain, as the nodes should also be able to check the integrity and therefore the security of the data. Each of the blocks will have a hash of a previous one. Let’s start with hashing data within blocks. First, we will import ‘hashlib’ module. Then, we will create a function that will read the contents of a block, run them through the SHA-256 hashing algorithm and return a hash. Please note that you should specify ‘blockchain’ folder location here, or the function won’t find blocks. In the function that creates blocks define a variable for a previous hash that will launch our hashing function for the previous block. As we test it, we can see that the new block contains the hash of the previous one. You can easily verify hash by copying contents of the block number 1 to an online SHA256 generator and compare the results.
So far we have the block creation function and the hashing function. It’s time to introduce a verification algorithm for our node. The function that we will create will be able to get the list of all the files in the blockchain, read previous block’s hashes starting from the second block, generate a hash of each previous block again, compare them and return the result.
We will begin by declaring a variable that gets all of the files in the ‘blockchain’ directory, a variable that returns the list of the files, and one that sorts blocks in increasing order. The next thing we should do is to make the function able to iterate through the blocks and read previous blocks’ hashes. This can be done via a ‘for’ loop that loads all the data from a block and returns only what corresponds with the ‘hash’. Now to creating hash once again to verify it against that a function receives. Inside the ‘for’ loop we will leave a ‘true_h’ variable that will launch hashing function for the previous block. The last step is to compare hashes using an ‘if/else’ statement. Results will be written into an array that we set for them and everything will be shown in the console.
After cleaning up some redundancies we have a local blockchain coded in Python.
Building a frontend
Setting up the environment
In the project’s main directory create a folder for the virtual environment that will act as the backend. If you haven’t previously done so, please download Python from the official page or via a command line in your OS (we use homebrew in OSX) and install it. Going further, install Virtualenv & Pip via appropriate command line commands. After that, launch a virtual environment from the command line within the ‘UI’ folder, you will get a new folder if everything was done correctly. Time to activate it and install flask via Pip.
Let’s put our back end next to the frontend. Cut the ‘blockchain’ folder and the script and paste them in the ‘app’ folder in the main directory. Within the backend folder, we need to create the main script file.
Creating the structure
In our main script, we should first import Flask and place a link to the name of the file to enable Flask to comprehend the paths. We also should put a standard statement that checks if the script is launched from the console and runs our application. Make sure to add ‘debug’ to allow Flask reload every time you change something in the code.
If you launch the script at this point, you can see that localhost:5000 is up, but displays the 404 error. This is normal, as the app is still empty. Let’s begin filling it by creating a function that will make our node process users’ queries. Within it (by placing ‘@’ before the function) we will put an index function. This will create a structure of local URLs and corresponding functions. The ‘index’ function will show users index.html via the ‘render_template’ module.
Now we can proceed to create our HTML structure. There will be two files, one for the general information and another for the UI of the first page. In base.html we will import Bootstrap library for creating layout via CSS. Let’s create a centered column and put a block for content there in a format that can be interpreted by Flask’s Jinja.
Composing the UI
Our application will be a simple payment system. There will be a payer, a payee, and an amount of money transferred. Everything will be done via blockchain, but for a user, it will look like a regular app. When you transfer money on the internet, you usually fill out some form and submit it. Bootstrap has various forms to help us with some presets. You can copy the one we chose from here and copy the code to your index.html. There will be only two fields in the pre-written form and a checkbox, we will remove the checkbox and add a field. Then we will adjust the proper labels, ids, types, and placeholders. Finally, we will attribute our index function to the form. When a user will input their name, amount and a counter agent, all the information need to be saved somewhere and then included in a block. For this let’s amend our input fields by adding ‘name’ and ‘value’. The value will use the ‘get’ method to extract whatever a user puts in the ‘Payer’ field. Don’t forget to specify an empty string in case a user doesn’t input anything.
Let’s get back to our main script. The script should be able to understand whether the request sent by a user is POST or not. To enable it doing so, we will import the request module from the flask and specify the methods in our app. Within the app, we will declare variables that will request respective data from the form.
Going further, we will need to pass all the data collected to a new block. This requires us to connect the main script to the one that writes blocks. To do so within the ‘if’ statement that checks the type of a request we will put a ‘write’ function with arguments corresponding to what we have in our blocks.
Now if we return to our browser and submit a transaction we will get a new block in our blockchain folder that will contain the information we communicated. However, you can see that the fields didn’t refresh. For this purpose, we need to redirect a user to a new instance of index.html. Don’t forget to import the modules we use from Flask. Voila, everything refreshes after you submit.
The final touch to our user interface will be a button that makes our node check for any security breaches in our blockchain. To do so, we will create another routing for verification with a function within it. Next, let’s go back to our base.html and specify two more containers for a button and verification results with top margins defined as 5. Put a block inside one container and inside the index.html too.
For the next step, we will choose a button from the Bootstrap library and place it within base.html in a form. In the form put our ‘verify’ function as action and attach it to the ‘check’ function in the main script. Once it’s done, return to the main script and put the verification function from the script for creating blocks in the check function. Go to the base.html, here we want to make a ‘for’ loop for each variable in the ‘results’ array. In the ‘for’ loop we will make a div that will display verification results.
Testing the dApp
So there you have it. Return to your browser and refresh the page. From now on our dApp can record transactions onto the blockchain and verify if any of the blocks were hacked. To make sure that everything works submit a transaction with the data of your choice and go to the blockchain folder. You should have a new text file there with the payer, amount and payee that you specified and the hash of the previous block.
Get back to the browser, make some more blocks, and launch the verification process. You will see that at this point all of the blocks are genuine. It’s time to hack our node! Go to the blockchain folder and change one of the blocks that you have created prior to the latest one. Now back to the browser again and verify our chain once more. As you can see, our node signals that one block is corrupted and we should not trust this blockchain’s data.
To sum up, today we showed you a simple decentralized application on a locally operated blockchain. Building applications in a decentralized manner has its features, but it’s also similar to building regular applications. After all, applications are meant for the end user, so on the surface, one wouldn’t probably find much difference.
If you are looking into coding dApps, you need to know the principles of blockchain technology and understand how to write for both frontend and backend. With such an advanced level of knowledge required, you’d better choose a fast and easy programming language like Python. With Python, you will be able both to make compact code and run a local server with no hassle. The latter is very important, as you want to make all the necessary security checks prior to publishing because blockchain is immutable.
We hope this tutorial helped you a lot in getting a grasp of dApps. Enjoy!