Understanding how a blockchain works, with Php and Json
This article aims at a first introduction to the very basic principles of blockchain for (web) developers with no experience in this field. I am going to review the structure of a very simple blockchain, by building one with Json and a little Php script.
By the end of this tutorial we will have a blockchain saved on our system, and a test web page that we can use to post new blocks to our chain.
Controlling the creation of new blocks via proof of concept, setting up a distributed blockchain and other advanced tasks are not covered by this introductory article.
1. Structure of a blockchain
Let’s start with a basic definition of what a blockchain can be:
A digital log book, accessible by everyone, recording all the transactions in a given currency, in a chronological order.
As we know nowadays, a blockchain can be used to store various data, not just economic transactions. Moreover, the most interesting blockchain systems use a distributed architecture, where no one is the actual owner of the log.
As a first step into the world of blockchains, anyway, I’d like to keep things as simple as possible: we are going to create a centralized (not distributed) blockchain that could log transactions made with PippoCoin, our preferred test currency for this tutorial.
In a blockchain, each new data (a transaction) is stored in a block added at the end of the chain. To be added to the chain, this last block uses some of the information of the previous block, in order to ensure the integrity and immutability of the log.
Our first goal will be to shape our blockchain by defining the structure of its blocks. I choose to use a simple json file to store the blockchain. Json is a widely known format, and can be read and written easily with Php, the scripting language we are going to use to interact with data.
Let’s start by building our basic blockchain with the first block in it, in a new file called chain.json
Our blockchain to manage PippoCoin transaction is made by blocks, each one having the following attributes:
Index: a simple unique numeric integer ID (increment by 1), starting at 0. Keeping it this simple will be useful to count the total blocks in our chain anytime, easily.
Hashid: I choose an arbitrary value for this first block. For the next blocks we are going to calculate the value of the hashid attribute using a dedicated function, that will use some of the data stored in the previous block to get a unique and consistent value.
Timestamp: the creation date of the block. In this case I am using a simple Unix Timestamp (in milliseconds).
Proof-of-work: in a fully functional blockchain system, a proof of work is needed in order to create a new block in the chain. Typically, a proof of work is the solution of a complex cryptographic problem, but it can be really anything, depending on the blockchain environment your are designing. For example, we could build a blockchain environment that rewards people subscribing to our newsletter with PippoCoins: in this case, our proof of work could be a valid subscription id to our newsletter. For this very basic introduction to blockchain, we won’t go any depeer about proof-of-work: all the blocks in our chain will have the proof-of-work attribute set to “xyz”.
Content: this attribute stores structured information about the transaction itself. In its simplest form, a financial transaction is identified by a sender (from), a recipient (to) and a quantity of exchanged currency (amount).
This first transaction’s sender is the system itself (network), the recipient is a user called simone, and the exchanged amount is 1 PippoCoin.
Reading this blockchain, we can understand that a user called “simone” earned 1 PippoCoin from the PippoCoin System, identified by the special user named as “network”. This special user is the only one allowed to create new PippoCoins. Other users are allowed to change PippoCoins among each other.
As a basic rule in our PippoCoin environment, all the other users in the system can exchange coins only if they have some (give by network or other users).
How can a user obtain PippoCoins from network? By doing some work, and showing proof-of-work to the network.
2. Read the blockchain
Once the basic structure of our blockchain has been defined, we can start coding a basic Data Access Object in Php. Our object should be able to:
- read our blockchain
- read data about the last block in the blockchain
- calculate a valid hash to be used by a new block, and insert it in the blockchain
The following code is placed in includes/dao.php
The first function, read_all(), reads the whole blockchain and place it in a multidimensional array. Useful for testing this small prototype, but clearly not to be used in a production environment, where the blockchain could grow to gigabytes of data.
The following functions, get_previous_hashid() and get_previous_index(), help us to retrieve index and hashid values of the last inserted block in the chain. We need those data to calculate the correct hashid used by the next block we want to append.
Each system sets its own rules to calculate a new block’s data. As a rule in our PippoCoin system, we decide that each new block must contain an attribute called hashid which is the hash (sha256) of 4 strings: hashid, index and timestamp taken form the previous block, and content from the new block that we are creating. Now you can better understand why the first block doesn’t have any calculated hashid.
The last function in dao.php, read_content(), helps us to save in a multidimensional array the content of a block (sender, recipient and amount), so that it will be easier to work on them later, while creating a new block.
3. Write a new block
Now that our Data Access Object is completed, we can write a simple script to start playing with our blockchain prototype. In the root of our application folder we create a new file named chain.php and start writing the following code, which let us read and visualize the full content of the blockchain.
The following code helps us reading the index and hashid of the last block in the blockchain:
Now we can calculate the new block values.
Retrieving the index of the new block is pretty straightforward: in our PippoCoin environment index is an integer , just the previous block’s index incremented by 1.
The new hashid is calculated using get_new_hashid() method in DAO class. It will be a new hash (sha256) based on the concatenation of:
last block’s hash id +
new block’s index +
new block’s timestamp +
new block’s content
You’ve probably noticed that the variable $content, which should contain the meaningful data of our transaction, has the value of a “json_data” POST variable. In order to test and play with our little blockchain environment we can create in a new file, called post.php and placed in the same folder, a simple form that can POST json data to our chain.php script. Manually posting new transactions to our blockchain, we can verify that each new block is appended correctly.
Here’s our post.php file:
As you can see, this form sends raw json data to chain.php. Changing the values of From, To, and Amount will lead to different transactions registered in our blockchain.
Obviously this is a very simple prototype, useful to test the basic features of our PippoCoin, focusing on its structure and rules.
Next articles could introduce the role of the network, proof-of-work, distributed ledgers and so on.