Over the past months, I have discussed various cryptographic techniques. Now it's time to show their interesting applications in practice. I have already revealed in the title what the following entry will be about. I will start with blockchain or blockchain. Blockchain is mainly associated with Bitcoin and other cryptocurrencies, but it is a mechanism that also allows you to implement other interesting ideas. It allows data to be secured by building a distributed, integral register using hash functions and digital signatures , among other things.
Blockchain and digging
It is very common for us to create various registers, that is, records evidencing sequentially performed operations. If we write them without any protection then at any time such a register can be modified and we will not be able to detect such a disturbance. An attacker can change a given entry or delete those he finds inconvenient. This applies, for example, to system logs. An intruder often removes entries from them that allow detection of the attack and identification of the attacker. The solution to this problem may be to build the log in such a way that consecutively written blocks have integrity. Then it will not be possible to change a single block. However, this is not enough, because still an attacker will be able to simply delete them. Thus, the integrity of a given block must be ensured, taking into account all its predecessors. When calculating the hash function, it is not necessary to calculate it for the entire register, it is enough to use the last calculated value because it ensures the integrity of the predecessors.
The idea is shown in the following figure. The first hash is calculated from the data of the first block. Subsequent hashes include the hash of the previous block and the new data. Thanks to the property of the hash function, the integrity of the entire register is ensured. Any disruption of it will affect subsequent blocks. The data also cannot be easily forged, that is, replaced by other data giving the same hash. Shortcut functions are immune to such attacks.
The register shown in the figure is a blockchain. If we store it only locally then an attacker can still recalculate the hash functions after making his changes. However, if the registry is distributed, that is, a copy of it is stored in multiple locations and synchronized on an ongoing basis then such a change will be difficult. Network nodes will detect that something that was already distributed has been changed. The blockchain should be owned by the entire network, and by storing it in different places, modification will be difficult. In the event of an attack, the network nodes will detect changes to previous blocks and most nodes will reject them. The more new blocks there are behind the block from which the data is of interest, the more difficult such an attack is. You have to disrupt more blocks and try to pass them to other nodes.
Since the register is distributed, who should validate the next blocks, that is, calculate their hash functions? Every node in the network has the right to do so. Since the hash function is easy to calculate it would be impossible to effectively synchronize such a register due to new blocks appearing too often. A slightly modified solution is used. The most popular is the use of the so-called proof of work (proof of work). Only the node that performs a certain work, approved by other nodes, has the right to confirm the block. Popularly performing this task is called digging ( mining). A network node is rewarded for doing the work (digging a block). The work usually involves solving some problem that is computationally complex. For example, in the Bitcoin network, the task is to attack a hash function. Only the node that finds a number that gives, together with the block being validated, a hash value starting with a certain number of zeros is considered the winner in the digging. So blockchain realized in practice is not only a way of storing data but also the algorithms that manage the network of nodes.
Transactions
A registry is a series of records of any information that will remain in the blockchain forever. You can put your book or a description of an invention in it, for example, and if such a blockchain is a registry recognized by everyone then you get a structure that provides proof of authorship. Registries are mainly associated with accounting records. In order to complete secured transactions, it is not enough to store mere balances associated with accounts, because anyone will be able to modify this balance. The user must be in control of his account.
Let's use the already known digital signature mechanism for this. The user's account will be identified by his public key and the balance of his funds will be associated with this key. When ordering a transaction, we create a package containing:
- source account (identified by the public key of the sender account),
- the destination account (identified by the recipient account's public key),
- transaction data (for example, the amount of the transfer),
- transaction signature (made by the sender's private key).
By analyzing the entire history in the blockchain, the balance of each account (the balance assigned to the public keys) can be calculated from the transaction entries. This is the idea behind how cryptocurrencies work. Note that we don't need to set up an account anywhere, we just need someone to make a transfer to our public key and only then we will appear in the blockchain with a non-zero balance. To use these funds it is necessary to have a corresponding private key.
The security of our account is related to the security of the private key. This means that if we lose our private key or someone steals it from us, we lose full control over our assets. Similarly, if we order a transfer and make a mistake in the target public key. There is then no way to recover such funds. Blockchain consistency and clear rules come first (or at least they should).
Blockchain in Ethereum
Let's check in practice how blockchain works. For this we will use one of its implementations which is Ethereum. In order to create a private chain you will need software that performs the tasks of a node. This program is called geth
and can be downloaded from the Ethereum repository. For the preparation of the examples below, I used version 1.6.0. This may be important, since the project is being developed intensively and some configuration settings may change. The Mist client is also useful, allowing us to conveniently create accounts and order transactions. I recommend downloading a version that is fully compatible with the architecture of the computer we are using (32 or 64 bit).
Ethereum is an elaborate blockchain with many functions, but to begin with we will benefit from the ability to store data associated with a user's account. In particular, there will be records of the number of accumulated Ether (ETH for short). This is the unit of account in this network. Each Ether is $$10^{18}$$$ wei. Wei is the smallest unit of accountability in Ethereum. The hash function used in Ethereum is Keccak-256.
In order to start a private chain, it is necessary to create the first block. Below I present the basic configuration file for the genesis block in Ethereum (it should be saved to the genesis.json
file). The options given in it determine:
- the computational difficulty of the task performed when validating a block - the example value allows to validate them with relatively small computational resources in several seconds, if necessary, it can be reduced,
- the limit of calculations performed for transactions - the assumption of Ethereum is that each transaction consumes fuel ( gas), which is converted into a fee in Ether,
- configuration - the network ID (100) and the version of the blockchain structure used,
- initial funds for selected accounts (none).
1{ 2 "difficulty": "0x400000", 3 "gasLimit": "0x8000000", 4 "config": { 5 "chainId": 100, 6 "homesteadBlock": 0, 7 "eip155Block": 0, 8 "eip158Block": 0 }, 9 "alloc": { } 10}
Command
1geth --datadir ./eth init genesis.json
will generate in the eth
directory our private blockchain based on the genesis block. There will be only one block in it.
In the next step, you need to start the local node. Use the command
1geth --datadir ./eth --networkid 100
Once the node is running, you can communicate with it using RPC commands sent in JSON format. The following channels are available:
- local communication with the node via IPC,
- remote and local communication with the node using HTTP (the default is port 8545).
By communicating with the node, we can read the current state of the blockchain, view the data in it and order new transactions. In particular, we can run the geth
console using the geth attach
command and the Mist client. The node communicates with other nodes (forms a P2P network) using port 30303. Thanks to the P2P network, the blockchain under construction is synchronized and information about ordered transactions is transmitted to other nodes.
To start using the created blockchain it will be necessary to start digging. Before we do that, however, we need to make sure we have at least 2GB of free space on disk and create the first account to get paid for the dug blocks. We can do this by launching the Mist client. It will connect to our local node and detect that we are operating on a private network. After generating a new account (generating an ECDSA algorithm key pair), the application screen will look like the following figure.
Having the main account set up (its ID is the calculated hash function from the public key, the keys are stored in the ./eth/keystore
directory) we can start digging. We start the geth
console ( geth attach
command) and execute the miner.start(1)
command in it. This will start the digging process with a single thread using one core of our processor. The first startup also involves generating a large graph on which the algorithm will be executed. The graph will be stored in a file and regenerated every few days. This may take several minutes. After that, every few seconds, entries will begin to appear in the console indicating the creation of a new block, and our account will begin to receive five Ether for each block.
1Successfully sealed new block number=1 hash=0743ae3155b3 2🔨 mined potential block number=1 hash=0743ae3155b3 3Commit new mining work number=1 txs=0 uncles=0 elapsed=0s 4...
It is worth creating a second account now and try to perform a transaction between them. When committing the transaction, we give the addresses of the source and destination accounts, the number of ether to be transferred and the proposed transaction fee. It will be received by the node that digs up the block, which in this case is ourselves. Nodes broadcast ordered transactions and dug blocks among themselves. Being a node, there is no obligation to dig, but in our case it is necessary for a chain to form - we are the only node in our network for now.
The order approval screen determines how much fuel and therefore how much Ether our transaction will cost. The limit set is greater than the expected consumption, so there should be enough fuel for the transaction to reach the recipient.
Once the transaction is approved and the block that will contain it is kicked in, the funds will show up in the recipient's account. Observe that with the transaction in Mist, the number of consecutive blocks dug up is marked in real time. It is assumed that if at least six of them are created, the transaction is already certain because the blockchain has, in all probability, been propagated throughout the network.
I encourage you to create one more account and perform several transactions. We stop the digging process with miner.stop()
. The node is still active, accepting transactions, but they are not validated. You can also run the digging process together with the node using the command
1geth --datadir ./eth --networkid 100 --mine --minerthreads=1 --etherbase=0x0000000000000000000000000000000000000000
in which we insert the address of the account accepting ether for digging up the block.
Summary
So far, in the created registry we have stored records related to the state of accounts represented by the public keys of their owners. It is possible to go a step further - not to store only static data in the blockchain, but to put there applications that can be executed under certain conditions. In this way you will get a contract that will work as implemented and will be an independent entity living in the chain. I will present examples of such contracts in Ethereum in my next post.