Creating a block¶
In order to complete a transaction with a peer, we need to create a block. A block in TrustChain is a little different than in bitcoin-style blockchains. In bitcoin-style blockchains, a block is a collection of transactions that happened in the network. A block is created by a node and is propagated through the network. All connected nodes validate the block and the transactions. In TrustChain a block is formed by two peers who wish to agree on a transaction. Therefore a TrustChainBlock only has one transaction.
Both parties need to agree on a transaction, so there has to be some interaction between peers. The way this is done in TrustChain is to first create an incomplete block, called a half block. This half block is then send to the second peer, which creates a full block from the half block and sends it back to the first peer. This process is explained in more detail below.
Structure of blocks¶
A block has the following attributes:
public_key
- The public key of the peer that created this blocksequence_number
- Represents the position this block has in the chain of the creating peerlink_public_key
- The public key of the other partylink_sequence_number
- The position the connected block has in the chain of the other partyprevious_hash
- A hash of the previous block in the chainsignature
- The signature of the hash of this blocktransaction
- The data that both parties need to agree on, this can be anything, from text to documents to monetary transactions
Note that link_sequence_number
will be unknown for the first half block created, because peer A won’t be sure when peer B inserts the linked block in his chain. This will stay unknown, as updating a block already in the chain is not desirable, since it might invalidate later blocks. When an interaction is completed peer A will have the block of peer B in its database as well, so it can always find out the position of the linked block in peer B’s chain.
Create block¶
There are two situation that require creating a block. Initiating the creation of a transaction with another peer and completing a block send to you by another peer. This is both done by calling the signBlock
method in Communication.java. This method calls the createBlock
method in TrustChainBlock.java, signs the block, and validates the correctness of the block, before it gets added to the chain and send.
Initiating a transaction¶
When you want to initiate a transaction, you need to provide the bytes of the transaction, your public key, and the public key of the other party, and a link to the database containing your chain to createBlock
. The latest block in your chain will be retrieved from the database, to be able to set sequence_number
and prev_hash
. The other attributes will be set according to the input, signature
will remain empty for now.
Received a half block¶
A half block was received and it contains a transaction that we agree with. In this Android implementation we always want to complete the block, regardless of the transaction, so we don’t need to check the transaction. The attributes are again set according to the input, with as difference that we now retrieve transaction
and link_sequence_number
from the linked block. signature
will again remain empty.
Sign block¶
The next step is signing the block. This is as simple as creating a sha256 hash of the block and giving this digest to the build-in signing function of the crypto library.
Validate block¶
Block validation is the most important step here, as this ensures the validity of the blockchain. The validation function is located in TrustChainBlock.java. There are 6 different validation results:
VALID
PARTIAL
- There are gaps between this block and the previous and nextPARTIAL_NEXT
- There is a gap between this block and the nextPARTIAL_PREVIOUS
- There is a gap between this block and the previousNO_INFO
- We know nothing about this block, it is from an unknown peer, so we can say nothing about its validityINVALID
- It violates some rules
The validation function starts of with a valid result and will update the validity result according to whether the rules hold for the block. Validation consists of six steps:
- Step 1: Retrieving all the relevant blocks from the database if they exist (previous, next, linked, this block)
- Step 2: Determine the maximum validity level according to the blocks retrieved in the previous step
- Step 3: Check whether the block is created correctly, e.g. whether it has a sequence number that comes after the sequence number of the genesis block
- Step 4: Check if we already know this block, if so it should be the same as we have in our database
- Step 5: Check if we know the linked block and check if their relation is correct
- Step 6: Check the validity of the previous and next block
For a more detailed explanation of the validation function, please take a look in the code and try to understand what happens there.