Blockchain Through the Eyes of a Developer
Why this story? When I studied the publicly available information on blockchain, such as what’s on Wikipedia, it struck me as fragmentary and disjointed. It took time for the bits and pieces to form a coherent picture. Now, I think I know which words to use and which order to put them in when introducing blockchain so that any professional developer will be able to see the big picture in 1–1.5 hours. There will be some simplifications in this text. Any subject has complexities where the interested are welcome to delve in.
So, let’s get started. Asymmetric cryptography has existed for a long time. Remember that there are public and private keys. We encrypt with the public key and decrypt with the private one. Or vice versa. You cannot derive one key from the other. As a result, using only asymmetric cryptography, I can send someone a message, such as “I transferred 100 dollars,” and everyone will know that it was it was sent by me and delivered without alterations.
Let’s assume that ten people have agreed that each of them has a million units of a new currency. Each of them can make sure (and everyone can make sure) that it was person X who sent 300,000 units. But it is unknown whether X actually had these 300,000 units or not. To find out, we can learn about the balances of each person. To do this, we just need to add up all of the incoming transactions and deduct all of the expenses. Therefore, we need information about income and expenses. Hence the public ledger. It allows us to say whether or not a particular person can actually send 300,000 units.
Bitcoin: The Beginning
There’s still one problem — what if I’m sending all of my money to two people at the same time? This is called double-spending. Of course, these two should not simultaneously receive an amount equal to the balance of my account before the transaction. And it’s inconvenient for them to communicate with each other to figure out who ended up getting the payment. Looking at the timestamps to see whom I sent the money to first isn’t fail-safe. There is a solution, however — we need to streamline the transactions. If we do, it will be clear that the first payment was sent to John, and I simply cannot send it to the second person, since I have no more money. But now it is unclear who will decide on the order of transactions. In banks and other centralized systems, there is a trustee represented by the bank itself, the single point of failure and point of trust. The bank says to whom my money was sent first. In blockchain, there is no single trustee. It could be most of the network (of course, this means the network as a whole, because you cannot trust every single participant, since there are certainly some crooks among them). It is assumed that the network is not controlled by one person and that most participants act strictly in their own financial interest.
But the problem of streamlining the transactions is still not resolved — this requires what we call “consensus” among network participants. This problem is dealt with by a consensus algorithm, a key algorithm in each blockchain.
Before we talk about a specific consensus algorithm, a few words about the notorious blockchain blocks. Blocks are a technical measure, an instance of batch processing (called batching), so that the consensus for a number of transactions can be computed in a “batch” and overhead costs of the network can be “spread” across multiple transactions. The order of transactions within the block is defined by a network participant, the one who generates the block (also known as the “miner”). But the order of the blocks is determined by the consensus algorithm. Consensus algorithms exist for quite a long time. For example, this includes such algorithms as Paxos and Raft in multi-master NoSQL systems. But they will hardly be suitable for a network with a million peer participants.
Bitcoin represented something quite revolutionary at the time it appeared — an algorithm of proof-of-work (PoW) consensus. New blocks are generated simultaneously by many network participants, the miners. It is necessary to decide which block should be used as the next one. For the block to become the next block in the chain, a miner must perform specially selected and very time-consuming hashing. A block (along with the nonce, an incremented number) is hashed until the hash viewed as a large number meets certain conditions, such as containing 10 leading zeros. This will require billions of hashing operations, which represent the work of the miner to “prove” the existence of his block. At the same time, it is very easy to check whether this work was done correctly — all you need is just one hashing operation. It is important to understand that the work is selected in such a way that, on average, only one block can be generated in ten minutes (the average interval of generating blocks in Bitcoin) across the entire network (which includes thousands of miners!). This dramatically reduces the likelihood of collisions, i. e. simultaneously providing two or more blocks as the next one.
However, the possibility of collisions still remains. Therefore, there is the following rule — the network participants accept the block that forms the longest chain (one of the alternatives will become longer when yet another block is generated).
In fact, it is not a chain, but a directed acyclic graph (DAG) with many branches and chains, while the chain is usually called the “common history” (it is the longest chain). Since consensus cannot be reached at once, but only after a few blocks, you have to wait a while. To prevent double-spending in Bitcoin, people usually wait six blocks (in Bitcoin, it takes an hour).
In addition to transactions, a block includes the hash of the previous block. Therefore, it is impossible to modify something in the past, as this will make invalid all subsequent hashes. At the same time, together with a block, you are issued a reward for mining, which gives you new money! Otherwise, it would be unclear how to introduce the money into the system — the money would have to be issued to someone, which would make that person special and contradict the idea of decentralization. Issuing money for mining seems to be a logical and acceptable solution.
By the way, a few words about mining. You need to understand that the primary job of the miner is to ferociously hash the new block; there’s no asymmetric cryptography here, since it’s only needed to check transactions before adding them to the block. Bitcoin uses an SHA-256 hash; in Ethereum, it’s Keccak-256. If you’re mining alone, then be prepared to live on “rice and water” for a very long time (on average) before you generate a block (a block is generated once every ten minutes, and your competitors number in the hundreds of thousands!). As a result, miners get together in pools. Within a pool, the reward is distributed one way or another (there are different approaches) among the participants, which means that you get money more often (although in smaller amounts than the reward for a block). In this case, both the risks and the benefits are “spread”. As time approaches infinity, the mathematical expectation of profit from mining in the pool (disregarding the pool commission) is equal to the mathematical expectation of profit from mining alone.
So far, we’ve dealt mostly with the exchange of data among network participants, without getting into too much detail. And we won’t. It’s important to keep in mind that data is exchanged through network peering, which allows our transaction to reach the miners.
And that’s the technology of Bitcoin blockchain.
Smart Contracts and ICO
Let’s continue. Two operations (addition and subtraction) are performed on each account in Bitcoin, and they can be checked by anyone, but primarily by the miners. But what if we add internal variables to the account (storage) and, for example, comparisons to the operations. Let’s assume that I want to stop accepting money to my account when I accumulate 10 millions — this means that I want to add not just money to my account, but also a certain condition. By developing this idea, we get a Turing machine, the deterministic kind (everyone will still be able to check my account). As a result, we have a smart contract. Hereinafter, by smart contracts we mean smart contracts in the Ethereum network, since they’re the most popular at the time I’m writing.
Determinism implies that with the same arguments of transaction and the same initial state of storage, we end up with the same results and same changes in the storage. Only under these conditions can the network reach consensus on each transaction. You have to understand that a smart contract is fairly isolated from the outside world due to the requirement for determinism, verifiability, and decentralization. For example, it cannot trigger a decentralized-style web API (there are solutions, so-called “oracles,” but these are complicated and need to be treated separately). In addition, the control exercised by the contract over the outside world is also very limited. For example, it is difficult to rent an apartment through a smart contract by exchanging cryptocurrency for an electronic key (despite the enthusiastic claims you can find on the Net) — I still need to trust the landlord to know that when I come to the door, there won’t be an old-fashioned padlock on top of the electronic lock.
To know a smart contract execution result (a new balance or a change to storage), the network nodes have to perform operations prescribed by that contract. Computations on multiple nodes cannot be free of charge. As a result, Ethereum introduced the concept of gas to avoid the hard-coding of commissions in cryptocurrency for computations and allow users to calculate the number of computations and set their price. This structure provides an additional layer of indirectness, which allows the user to choose between a low-cost transaction and fast transaction.
When the money is sent to the contract as to an account (by simply using the address), it triggers the fallback function, the default point of entry. Unlike an account, a contract has more than one point of entry — these are the methods that can take parameters. To modify the contract (regardless of the point of entry), you will have to send a transaction to the network in order to make changes. But if you want just to look into something in read-only mode, you can do it locally by having an up-to-date blockchain. Also, unlike accounts, smart contracts have no private key. You cannot withdraw funds directly from their balance — this can be done by using clearly defined methods which, of course, should have security restrictions, such as checking the address of the user who is trying to access the funds.
In the end, we get smart contract technology on top of Bitcoin-style blockchain.
Many cryptocurrencies, or so-called “tokens”, are based on Ethereum smart contracts. Yes, usually such cryptocurrency is just an Ethereum contract (a single one!). Balances are entries in the storage of smart contract made in the form of a map, and the currency transfer from one participant to another is as follows:
map[Alice] –= payment;
map[Bob] += payment;
They do not need their own mining and network — they can use the infrastructure of Ethereum. In Ethereum, ICO/ITO is the exchange of ether (the cryptocurrency of the Ethereum network) for cryptocurrency (tokens). The ERC20 standard says which methods must be defined in the cryptocurrency, thanks to which many cryptocurrencies can be supported by exchanges and immediately be supported by wallets working with Ethereum.
In addition to smart contracts, there are many other ideas on top of the basic idea of blockchain, such as “zero-knowledge proof” and “self-regulated network.”
Zero-knowledge proof is based on the eponymous family of cryptographic protocols which, in essence, are designed to prove the ownership of an object without revealing it entirely. For example, I can prove that I own a particular 1 GB file if I am able to answer ten questions about bytes in various random positions of that file. Clearly, in this case, I will reveal only 10 bytes out of 1 GB, which the verifying party probably knows anyway. Since RSA encryption involves exponentiation, and
(Y ∗ X) ^ a = Y^a ∗ X^a,
then we end up with
encrypted(Y ∗ X) = encrypted(Y) ∗ encrypted(X).
This means, for example, that anyone can check whether the balance of my account was correctly multiplied. Moreover, there’s no need to reveal how much money I had on my account! By building on this idea, we can create a cryptocurrency with private information on balances and payment (actually, it already exists; see Zcash) and completely hide the arguments of computations in the smart contract.
Blockchains have common settings for the network written into the program code of the network clients, such as the number of transactions to be included in the block. Usually, changing them requires that the community of network participants accepts these changes (seen in the form of code updates), which poses the threat of network forks (when some participants decide not to accept the change and simply continue working with the “old” code). Self-regulation attempts to address these problems (see, for example, Tezos or EOS blockchains). The essence of this idea is that for each change, you will be able to vote with your own funds (without losing them, of course).
In short, the technology went through the following path:
signature of transactions (asymmetric cryptography) + openness of transactions + streamlining of transactions + expansion of operations up to the Turing machine + (zero knowledge proof | self-regulation | ...)
A few words about the blockchain landscape. I already mentioned that many cryptocurrencies are, in fact, Ethereum smart contracts, i.e. they use Ethereum blockchain. But there are projects other than Bitcoin and Ethereum — they may differ both in details (such as forks) and in major features; there have been attempts to create fundamentally new blockchains, like EOS, and even different block topologies, like Tangle and AElf.
A word on studying Ethereum smart contracts. Sometimes the infrastructure is rough (not particularly user-friendly), but it’s fairly reliable. Here’s a set of links that I used to learn about writing and ensuring the security of smart contracts (let’s not forget about security, because money is at stake!). I recommend going in order:
- Bitcoin: A Peer-to-Peer Electronic Cash System — sections 1–8
- Just Enough Bitcoin for Ethereum
- Ethereum White Paper
- If you want to get some practice: The Hitchhiker’s Guide to Smart Contracts in Ethereum
- Solidity Documentation
- Ethereum Natural Specification Format
- Contracts in Zeppelin Solidity
- Onward with Ethereum Smart Contract Security
- Ethereum Contract Security Techniques and Tips
- Only the relevant stuff from Hacking, Distributed