Tag Archives: cryptocurrency

A Brief Overview Of Blockchains

It’s early 2022, and blockchain has amassed more attention than ever. Initially emerged in the form of a cryptocurrency, followed by the rising of additional ones operating on open-source development platforms, and further catalyzed by a frenzy of NFT, the word “blockchain” has effectively evolved from a geek keyword into a household term.

While a majority of the public is still skeptical about the legitimacy of the blockchain phenomenon, apparently many bystanders are beginning to be bombarded by a mix of curiosity and a feeling of being left out, especially with the recent NFT mania.

It should be noted that by “blockchains”, I’m generally referring to public permissionless blockchains for brevity.

Permissionless vs permissioned

Most of the blockchains commonly heard of, such as Bitcoin, Ethereum, Cardano, are permissionless blockchains which anyone can anonymously participate. Many of these blockchains are open-source. On the other hand, permissioned blockchains from products like Hyperledger Fabric require permissions and proof of identity (e.g. KYC/AML) from their operators for participation.

From a programming enthusiast’s perspective, there is some interesting technological aspect in blockchain that warrants a deep dive. Rather than only authoring smart contracts at the user-application layer, exploring how a blockchain’s participating nodes competing to grow a decentralized immutable ledger via a consensus algorithm will give one a full picture of its technological merit. That’s one of the motivations for me to develop a proof-of-concept crypto-mining blockchain system back in 2020.

Last I surveyed the blockchain landscape, the choice for a development platform was simple. That was about 3 years ago. Excluding permissioned-only blockchains, the only platform ready for “big time” development back then was Ethereum with scripting language Solidity and framework Truffle for smart contracts. By “big time”, I mean ready for the average programming enthusiasts to participate the ecosystem through available tech docs and self-learning. Much has evolved since.

Trending blockchain development platforms

There is now a big list of open-source blockchains besides Bitcoin and Ethereum — Solana, Cardano, Polkadot, Avalanche, Polygon, Algorand, Tezos, Flow, …, to name a few. From a technological perspective, what’s more significant is the abundance of dApp (decentralized application) development platforms provided by many of these blockchains. These dApp platforms built using contemporary programming languages like Go, Rust, Python, are competing among themselves, thus widening choices and expediting improvement that ultimately benefit the rapidly growing dApp development community.

While there are relatively few business cases for building a custom blockchain system, a much greater demand has emerged over the past couple of years for developing smart contract applications particularly in industries such as supply chain, DeFi, collectibles, arts, gaming and metaverse. Many blockchain platforms provide programming SDKs (software development kits) for popular languages like JavaScript, Python, or DSLs (domain specific languages) such as Solidity that many Ethereum dApp developers are already familiar with.

Meanwhile, frameworks for smart contract development that help boost developers’ productivity have also prospered. Within the Ethereum ecosystem, the once predominant Truffle is now competing head to head with other frameworks like Hardhat.

Bitcoin versus Ethereum

Even though Bitcoin remains the blockchain network with the largest market cap, it primarily serves a single purpose as a decentralized cryptocurrency. It wasn’t designed as a platform for development of business/financial applications like many other blockchain platforms were. Hence comparing Bitcoin with, say, Ethereum is like comparing apples to oranges. That said, Bitcoin’s price apparently is still driving the ups and downs of almost every average blockchain network out there.

Despite all the relatively new blockchain development platforms emerged over the past few years, Ethereum remains the distinguished leader with its TVL (total value locked) taking up well over half of the pie comprising all chains. To overcome the known issues of its underlying PoW (Proof of Work) consensus in scalability (and eco-friendliness), resulting in slow transactions and high gas fees, Ethereum is undergoing a major transition to Ethereum 2.0 with a PoS (Proof of Stake) consensus that will supposedly allow it to cope with future growth.

Layer-2 blockchains on top of Ethereum

To circumvent Ethereum’s existing scalability problem, various kinds of off-chain solutions have been put in place. They are oftentimes broadly referred to as layer-2 blockchain solutions, supplementing the underlying layer-1 blockchain (in this case Ethereum). The common goal of the layer-2 solutions is to alleviate loads from the main chain (i.e. Ethereum) by delegating the bulk of compute-intensive tasks to auxiliary chains with more efficient way of handling those tasks.

Here’s a quick rundown of the most common types of layer-2 blockchain solutions:

Rollup – a kind of the off-chain solutions that executes transactions in rolled-up batches outside of the main chain while keeping transaction data and proof mechanism on the chain. A zero-knowledge (ZK) rollup performs validity proof whereas an optimistic rollup (e.g. Optimism) assumes transactions are valid and runs fraud proof upon challenge calls. e.g. Loopring is a ZK rollup and Optimism is an optimistic rollup.

State Channel – another kind of solutions that allows its participants to bypass node validation process on the main chain by locking certain portion of the state via a multi-signature smart contract, perform transactions off-chain and unlock the state with appended state changes back to the main chain. Examples of state channel operators are Raiden, Connext.

Plasma – a “nested” blockchain with its own separate security from the main chain that performs basic transactions and relies on fraud proof upon validity challenge. e.g. OMG Plasma Project.

Sidechain – a relatively more independent off-chain setup with its own security, consensus mechanism and block structure. e.g. Polygon is a popular layer-2 blockchain of this category.

For more details, visit Ethereum’s developer site re: off-chain scaling.

Other layer-1 blockchains

Meanwhile, a number of layer-1 blockchains such as Avalanche, Solana, Algorand, have been steadily growing their market share (in terms of TVL). Many of these blockchains were built using leading-edge tech stacks like Rust, Go, Haskell, with improved architectures and more efficient, scalable eco-friendly consensus mechanisms. By offering the dApp development community cutting-edge technology and versatile tools/SDKs, these blockchain operators strategically grow their market share in the highly competitive space.

While “Ethereum killers” sounds like a baiting term, it’s indeed possible for one or more of these blockchains to dethrone Ethereum before its v2.0 has a chance to succeed the underperforming v1.0 in mid/late 2022. With things evolving at a cut-throat pace in the blockchain world and Ethereum’s upgrade taking considerable time, wouldn’t it be logical to expect that one of the newer blockchains with improved design would swiftly take over as the leader? Evidently, Ethereum’s huge lead in market share (again, in terms of TVL) and early adopters buy-in has helped secure its leader position. Perhaps more importantly is the inherent limitations imposed on any given blockchain that improvement can’t be made simultaneously in all aspects.

Trilemma vs CAP theorem

Somewhat analogous to the CAP theorem (consistency/availability/partition tolerance) for distributed systems, the blockchain trilemma claims that security, scalability and decentralization cannot be simultaneously maximized without certain trade-off among them. For distributed systems, a decent degree of partition tolerance is a must. Thus they generally trade consistency for availability (e.g. Cassandra) or vice versa (e.g. HBase).

On the other hand, a blockchain by design should be highly decentralized. But it also must be highly secured, or else immutability of the stored transactions can’t be guaranteed. For a given blockchain, there is much less room for trade-off given that security and decentralization are integrally critical, in a way leaving scalability the de facto sacrificial lamb.

This is where the trilemma differs from CAP. Under the well formulated CAP theorem, suitable trade-off among the key requirements can result in a practical distributed system. For instance, Cassandra defers consistency for better availability and remains a widely adopted distributed storage system.

Given the axiomatic importance of security and decentralization in a blockchain, developers essentially have to forgo the trade-off approach and think outside the box on boosting scalability. Sharding helps address the issue to some extent. Some contemporary blockchains (e.g. Avalanche) boost up scalability and operational efficiency by splitting governance, exchange and smart contract development into separate inter-related chains each with optimal consensus algorithm. Then there are always the various intermediary off-chain (layer-2) solutions as described earlier.

What about layer-0?

While a layer-1 blockchain allows developers to create and run platform-specific dApps/smart contracts, a layer-0 blockchain network is one on which blockchain operators build independent blockchains with full sovereignty. To build a custom blockchain, developers may elect to repurpose from an existing open-source layer-1 blockchain which consists of specific features of interest. When high autonomy and custom features (e.g. custom security mechanism) are required, it might make more sense to build it off a layer-0 network which provides an inter-network “backbone” with an underlying consensus algorithm, standard communication protocols among blockchains and SDKs with comprehensive features.

One of the popular layer-0 networks is Cosmos which some high-profile blockchains like Binance Chain were built on top of. Another layer-0 network is Polkadot that offers a “centralized” security model, contrary to Cosmos’ leaving the responsibility of security setup to individual blockchain operators. For core feature comparisons between the two networks, here’s a nice blog post.

Blockchain oracles

Then there are blockchain projects whose main role is to connect a blockchain with data sources from the outside world. A blockchain can be viewed as an autonomous ecosystem operating in an isolated environment with its own governance model. Such isolation is by-design, disallowing on-chain smart contracts to arbitrarily reference external data like currency rates, IoT sensor data, that can be prone to fraud.

An oracle provide a “gateway” for the smart contracts on a blockchain to connect to off-chain data sources in the real world. To ensure trustlessness, decentralized oracles emerge to follow the very principle embraced by general-purpose blockchains. Examples of such oracles are Chainlink and Band Protocol.

NFT – provenance of authenticity

NFT, short for non-fungible token, has taken the world by storm. It’s riding on the trend of blockchain in its early stage when a majority of the general public are still wondering what to make of the phenomenon. At present, the most popular use case of NFT is probably in provenance of authenticity. By programmatically binding a given asset (e.g. a painting) to a unique digital token consisting of pointers to unchangeable associated transactions (e.g. transfers of ownership) on a blockchain, the NFT essentially represents the digital receipt of the asset.

A majority of the NFTs seen today are associated with digital assets such as digital arts. A similar provenance mechanism can also be extended to cover physical assets like collectible arts by having the corresponding NFTs referencing immutable “digital specs” of the physical items. The “digital specs” of a given physical item could be a combination of the unique ID of the engraved tag, detailed imagery, etc.

Given the prominence of Ethereum, most NFTs follow its standards such as ERC-721 standard which requires a “smart contract” that programmatically describes the key attributes of the token and implements how the token can be transferred among accounts. Once a smart contract is deployed on a blockchain, it cannot be changed. Nor can any results from executing the contract that are stored in validated blocks.

Outside of the Ethereum arena, some blockchain projects come up with their own native NFT standards. For example, Algorand’s NFT is treated as one of it’s own built-in asset types and can be created by parametrically specifying certain attributes in the metadata of the digital asset without the need of an explicit smart contract. There are also blockchains like Avalanche providing both their native NFTs as well as Ethereum-compatible ones.

Final Thoughts

Over the years, the various emerged blockchains have interwoven into an inter-network that is increasingly more structured and functionally rich. The blockchain-powered inter-network is being touted by many early players as the next generation of the internet and is sometimes referred to as Web3. Layer-0 blockchain projects aim exactly to be an inter-network of independent blockchains. Among other blockchain projects, some aim to create a blockchain-powered internet extension (e.g. Internet Computer).

From a technological point of view, there are definitely merits of using blockchain’s underlying technology. In particular, the trustless decentralized ledger on a blockchain that keeps an immutable log of transactions can be used in many business use cases in various industry sectors like asset management. Some real-world applications using permissioned blockchains have demonstrated success in, for instance, improving traceability and transparency in the supply chain industry. The permission and proof of identity requirement does make fraud attempts significantly harder. Nonetheless, that inevitably breaks trustlessness, although such requirement is generally acceptable in operating a private alliance network.

Viewing from a different angle, cryptocurrencies except for stablecoins like Tether are volatile and will likely be so in the foreseeable future. Given that most prominent public blockchains are operated in conjunction with a corresponding cryptocurrency, when evaluating for a blockchain platform to land on, it warrants a good look at its cryptocurrency counterpart. Even though volatility may not be as critical for the purpose of development as for investment, it does make assessment of a given blockchain’s long-term prospect non-trivial.

Another obstacle to mainstream adoption of public blockchains is that many blockchain projects have emerged with superficial or even downright fraudulent plans for opportunistic reward in the prospering space. And the NFT frenzy permeated with scams also hasn’t helped gaining public trust either. In addition, people are overwhelmed by the numerous blockchain projects out there. As of this post, there are thousands of public blockchain projects, over 80 of which each with its corresponding cryptocurrency market cap above $1 billion. It’s likely only a small percentage of them will prevail when the dust settles.

All those issues are in some way hindering blockchain technology from becoming a lasting mainstream computing class. On the other hand, for those who are adventurous and determined to make the most out of the yet-to-be-mature but improving computing technology, it may be the right time now to dive in.

Actor-based Blockchain In Akka Typed

As blockchain computing continues to steadily gain momentum across various industries, relevant platforms such as Ethereum, Hyperledger, etc, have emerged and prospered. Even though the term blockchain has evolved beyond a mere keyword for cryptocurrency, its core underlying operational structure still adheres to how a cryptocurrency fundamentally maintains a decentralized ledger — that is, as distributed copies of a growing blockchain kept by individual nodes on the system to agree on an eventual version of the blockchain via a consensual algorithm.

Blockchain application using Akka classic actors

In 2020, I developed an Actor-based blockchain application (source code at GitHub) in Scala using Akka Actor’s classic API. While it’s primarily for proof of concept, the application does utilize relevant cryptographic functions (e.g. public key cryptography standards), hash data structure (e.g. Merkle trees), along with a simplified proof-of-work consensus algorithm to simulate mining of a decentralized cryptocurrency on a scalable cluster.

Since the blockchain application consists of just a handful of Actors mostly handling common use cases, migrating it to using the typed Actor API serves a great trial exercise for something new. While it was never expected to be a trivial find-and-replace task, it was also not a particularly difficult one. A recent mini-blog series highlights the migration how-to’s of some key actor/cluster features used by the blockchain application.

The Akka Typed blockchain application

For the impatient, source code for the Akka Typed blockchain application is at this GitHub link.

Written in Scala, the build tool for the application is the good old sbt, with the library dependencies specified in “{project-root}/built.sbt”. Besides akka-actor-typed and akka-cluster-typed for the typed actor/cluster features, Bouncy Castle and Apache Commons Codec are included for processing public key files in PKCS#8 PEM format.

For proof of concept purpose, the blockchain application can be run on a single computer on multiple Shell command terminals, using the default configurations specified in “{project-root}/src/main/resources/application.conf”. The configuration file consists of information related to Akka cluster/remoting transport protocol, seed nodes, etc. The cluster setup can be reconfigured to run on an actual network of computer nodes in the cloud. Also included in the configuration file are a number of configurative parameters for mining of the blockchain, such as mining reward, time limit, proof-of-work difficulty level, etc.

The underlying data structures of the blockchain

Since all the changes to the blockchain application are only for migrating actors to Akka Typed, the underlying data structures for the blockchain, its inner structural dependencies as well as associated cryptographic functions remain unchanged.

As an attempt to make this blog post an independent one, some content of the application overview is going to overlap the previous overview for the Akka classic application. Nonetheless, I’m including some extra diagrams for a little more clarity.

Below is a diagram showing the blockchain’s underlying data structures:

  • Account, TransactionItem, Transactions
  • MerkleTree
  • Block, RootBlock, LinkedBlock
  • ProofOfWork

The centerpiece of the blockchain data structures is the abstract class Block which is extended by RootBlock (i.e. the “genesis block”) and LinkedBlock. Each of the individual blocks is identified by the hash field and backward-linked to its predecessor via hashPrev.

Field difficulty carries the difficulty level pre-set in the application configuration. The nonce field is initialized also from configuration and will be updated with the proof value returned from the proof-of-work consensual algorithm (which is difficulty-dependent).

Class Transactions represents a sequence of transaction items, along with the sender/receiver (of type Account) and timestamp. Both the transaction sequence and its hashed value merkleRoot are kept in a Block object. The Account class is identified by field key which is the Base64 public key of the PKCS keypair possessed by the account owner. As for object ProofOfWork, it’s a “static” class for keeping the consensual algorithmic methods for proof-of-work.

For a deeper dive of the various objects’ inner workings, please read the following blogs:

  1. Transaction Hash Tree in a Blockchain
  2. Blockchain Mining and Proof-of-Work

Source code for the data structures can be found under akkablockchain/model in the GitHub repo.

The typed actors that “run” the blockchain

As for the actors, aside from being revised from loosely to strictly typed actors, their respective functionalities within a given cluster node as well as among the peer actors on other cluster nodes remain unchanged.

The following diagram highlights the hierarchical flow logic of the various actors on a given cluster node:

Starter – On each cluster node, the main program of blockchain application is initialized with starting up the top-level Starter actor (a.k.a. the user guardian), which in turn spawns two actors: Blockchainer and Simulator.

Blockchainer – The Blockchainer actor on any given cluster node maintains a copy of the blockchain and transaction queue for a miner identified by their cryptographic public key. It collects submitted transactions in the queue and updates the blockchain according to the proof-of-work consensual rules by means of the cluster-wide distributed pub/sub. The actor delegates mining work to its child actor Miner and validation of mined blocks to child actor BlockInspector.

Miner – The mining tasks of carrying out computationally demanding proof-of-work is handled by the Miner actor. Using an asynchronous routine bound by a configurable time-out, actor Miner returns the proofs back to the parent actor via the Akka request-response ask queries.

BlockInspector – This other child actor of Blockchainer is responsible for validating content of a newly mined block before it can be appended to the existing blockchain. The validation verifies that generated proof within the block as well as the intertwined hash values up the chain of the historical blocks. The result is then returned to the parent actor via Akka ask.

Simulator – Actor Simulator simulates mining requests and transaction submissions sent to the Blockchainer actor on the same node. It generates periodic mining requests by successively calling Akka scheduler function scheduleOnce with random variations of configurable time intervals. Transaction submissions are delegated to actor TransactionFeeder.

TransactionFeeder – This child actor of Simulator periodically submits transactions to actor Blockchainer via an Akka scheduler. Transactions are created with random user accounts and transaction amounts. Accounts are represented by their cryptographic public keys. For demonstration purpose, a number of PKCS#8 PEM keypair files were created and kept under “{project-root}/src/main/resources/keys/” to save initial setup time.

Since the overall functional flow of this application remains the same as the old one, this previously published diagram is also worth noting:

Akka Blockchain - functional flow

Source code for the actors can be found under akkablockchain/actor in the GitHub repo.

Areas that could be feature-enhanced

This blockchain application is primarily for proof of concept, thus the underlying data structure and security features have been vastly simplified. For it to get a little closer to a real-world cryptocurrency, addition/enhancement of features in a few areas should be considered. The following bullet items are a re-cap of the “Feature enhancement” section from the old blog:

Data encryption: The transactions stored in the blockchain unencrypted. Individual transaction items could be encrypted, each of which to be stored with the associated cryptographic signature, requiring miners to verify the signature while allowing only those who have the corresponding private key for the transaction items to see the content.

Self regulation: A self-regulatory mechanism that adjusts the difficulty level of the Proof-of-Work in accordance with network load would help stabilize the digital currency. For example, in the event of a significant plunge, Bitcoin would impose self-regulatory reduction in the PoW difficulty requirement to temporarily make mining more rewarding that helped dampen the fall.

Currency supply: In a cryptocurrency like Bitcoin, issuance of the mining reward by the network is essentially how the digital coins are “minted”. To keep inflation rate under control as the currency supply increases, the rate of coin minting must be proportionately regulated over time. Bitcoin has a periodic “halfing” mechanism that reduces the mining reward by half for every 210,000 blocks added to the blockchain and will cease producing new coins once the total supply reaches 21 million coins.

Blockchain versioning: Versioning of the blockchain would make it possible for future feature enhancement, algorithmic changes or security fix by means of a fork, akin to Bitcoin’s soft/hard forks, without having to discard the old system.

User Interface: The existing application focuses mainly on how to operate a blockchain network, thus supplementing it with, say, a Web-based user interface (e.g. using Akka HTTP/Play framework) for miners to participate mining would certainly make it a more user-friendly system.

Sample console log: running on 3 cluster nodes

Running the application and examining its output from the console log would reveal how multiple miners, each on a separate cluster node, “collaboratively” compete for growing a blockchain with a consensual algorithm. In particular, pay attention to:

  • attempts by individual miners to succeed or fail in building new blocks due to timeout by the Proof-of-Work routine
  • miners’ requests for adding new blocks to their blockchain rejected by their occupied mining actor
  • how the individual copies of the blockchain possessed by the miners “evolve” by accepting the first successfully expanded blockchain done by themselves or their peers
  • the number of trials in Proof-of-Work for a given block (i.e. displayed as BLK()) as its rightmost argument (e.g. BLK(p98k, T(fab1, 3099/2), 2021-05-11 18:05:13, 3, 2771128); for more details about how the mining of blockchain works, please see this blog post)
  • how Akka cluster nodes switch their “leader” upon detecting failure (due to termination by users, network crashes, etc)

Below is sample output of running the blockchain application with default configuration on 3 cluster nodes.

An Akka Actor-based Blockchain

As proposed at the beginning of this blockchain mini blog series, we’ll have an Actor-based blockchain application at the end of the series. The fully functional application is written in Scala along with the Akka toolkit.

While this is part of a blog series, this post could still be viewed as an independent one that illustrates the functional flow of a blockchain application implemented in Scala/Akka.

What is a blockchain?

Summarizing a few key characteristics of a blockchain (primarily from the angle of a cryptocurrency system):

  • At the core of a cryptocurrency system is a distributed ledger with a collection of transactions stored in individual “blocks” each of which is successively chained to another, thus the term “blockchain”.
  • There is no centralized database storing the ledger as the authoritative data source. Instead, each of the decentralized “nodes” maintains its own copy of the blockchain that gets updated in a consensual fashion.
  • At the heart of the so-called “mining” process lies a “consensus” algorithm that determines how participants can earn the mining reward as an incentive for them to collaboratively grow the blockchain.
  • One of the most popular consensus algorithms is Proof of Work (PoW), which is a computationally demanding task for the “miners” to compete for a reward (i.e. a certain amount of digital coins) offered by the system upon successfully adding a new block to the existing blockchain.
  • In a cryptocurrency system like Bitcoin, the blockchain that has the highest PoW value (generally measured by the length, or technically referred to as height) of the blockchain overrides the rest.

Beyond cryptocurrency

While blockchain is commonly associated with cryptocurrency, the term has been generalized to become a computing class (namely blockchain computing) covering a wide range of use cases, such as supply chain management, asset tokenization. For instance, Ethereum, a prominent cryptocurrency, is also a increasingly popular computing platform for building blockchain-based decentralized applications. Its codebase is primarily in Golang and C++.

Within the Ethereum ecosystem, Truffle (a development environment for decentralized applications) and Solidity (a JavaScript alike scripting language for developing “smart contracts”), among others, have prospered and attracted many programmers from different industry sectors to develop decentralized applications on the platform.

In the Scala world, there is a blockchain framework, Scorex 2.0 that allows one to build blockchain applications not limited to cryptocurrency systems. Supporting multiple kinds of consensus algorithms, it offers a versatile framework for developing custom blockchain applications. Its predecessor, Scorex, is what powers the Waves blockchain. As of this post, the framework is still largely in experimental stage though.

How Akka Actors fit into running a blockchain system

A predominant implementation of the Actor model, Akka Actors offer a comprehensive API for building scalable distributed systems such as Internet-of-Things (IoT) systems. It comes as no surprise the toolset also works great for what a blockchain application requires.

Lightweight and loosely-coupled by design, actors can serve as an efficient construct to model the behaviors of the blockchain mining activities that involve autonomous block creations in parallel using a consensus algorithm on multiple nodes. In addition, the non-blocking interactions among actors via message passing (i.e. the fire-and-forget tell or query-alike ask methods) allow individual modules to effectively interact with custom logic flow or share states with each other. The versatile interaction functionality makes actors useful for building various kinds of modules from highly interactive routines such as simulation of transaction bookkeeping to request/response queries like blockchain validation.

On distributed cluster functionality, Akka provides a suite of cluster features — cluster-wide routing, distributed data replication, cluster sharding, distributed publish/subscribe, etc. There are different approaches to maintaining the decentralized blockchains on individual cluster nodes. For multiple independent mining processes to consensually share with each others their latest blockchains in a decentralized fashion, Akka’s distributed pub/sub proves to be a superb tool.

A blockchain application that mimics a simplified cryptocurrency system

UPDATE: A new version of this application that uses Akka Typed actors (as opposed to the Akka classic actors) is available. An overview of the new application is at this blog post. Also available is a mini blog series that describes the basic how-to’s for migrating from Akka classic to Akka Typed.

It should be noted that Akka Actors has started moving towards Typed Actors since release 2.5, although both classic and typed actors are being supported in the current 2.6 release. While the Akka Typed API which enforces type-safe code is now a stable release, it’s still relatively new and the API change is rather drastic, requiring experimental effort to ensure everything does what it advertises. Partly because of that, Akka classic actors are used in this blockchain application. Nonetheless, the code should run fine on both Akka 2.5 and 2.6.

Build tool for the application is the good old sbt, with the library dependencies specified in built.sbt and all the configurative values of the Akka cluster and blockchain specifics such as the proof-of-work difficulty level, mining reward, time-out settings in application.conf:

Note that Artery TCP remoting, as opposed to the classic Netty-base remoting, is used.

With the default configuration, the application will launch an Akka cluster on a single host with two seed nodes at port 2551 and 2552 for additional nodes to join the cluster. Each user can participate the network with their cryptographic public key (for collecting mining reward) provided as an argument for the main program on one of the cluster nodes to perform simulated mining tasks.

For illustration purpose, the main program will either by default enter a periodic mining loop with configurable timeout, or run a ~1 minute quick test by adding “test” to the program’s argument list.

Functional flow of the blockchain application

Rather than stepping through the application logic in text, the following diagram illustrates the functional flow of the Akka actor-based blockchain application:

Akka Blockchain - functional flow

Below is a summary of the key roles played by the various actors in the application:

Blockchainer – A top-level actor that maintains a distributed copy of the blockchain and transaction queue for a given network participant (e.g. a miner) identified by their cryptographic public key. It collects submitted transactions in the queue and updates the blockchain according to the consensual rules via the cluster-wide distributed pub/sub. Playing a managerial role, the actor delegates mining work to actor Miner and validation of mined blocks to actor BlockInspector.

Miner – A child actor of Blockchainer responsible for processing mining tasks, carrying out computationally demanding Proof of Work using a non-blocking routine and returning the proofs back to the parent actor via the Akka ask pattern.

BlockInspector – Another child actor of Blockchainer for validating content of a given block, typically a newly mined block. The validation verifies that generated proof and goes “vertically” down to the nested data structure (transactions/transactionItems, merkleRoot, etc) within a block as well as “horizontally” across all the preceding blocks. The result is then returned to the parent actor via Akka ask.

Simulator – A top-level actor that simulates mining requests and transaction submissions sent to actor Blockchainer. It spawns periodic mining requests by successively calling Akka scheduler function scheduleOnce with randomized variants of configurable time intervals. Transaction submissions are delegated to actor TransactionFeeder.

TransactionFeeder – A child actor of actor Simulator responsible for periodically submitting transactions to actor Blockchainer via an Akka scheduler. Transactions are created with random user accounts and transaction amounts. Since accounts are represented by their cryptographic public keys, a number of PKCS#8 PEM keypair files under “{project-root}/src/main/resources/keys/” were created in advance to save initial setup time.

As for the underlying data structures including Account, Transactions, MerkleTree, Block and ProofOfWork, it’s rather trivial to sort out their inter-relationship by skimming through the relevant classes/companion objects in the source code. For details at the code level of 1) how they constitute the “backbone” of the blockchain, and 2) how Proof of Work is carried out in the mining process, please refer to the previous couple of posts of this mini series.

Complete source code of the blockchain application is available at GitHub.

Test running the blockchain application

Below is sample console output with edited annotations from an Akka cluster of two nodes, each running the blockchain application with the default configuration on its own JVM.

Note that, for illustration purpose, each block as defined in trait Block‘s toString method:

is represented in an abbreviated format as:

where proof is the first incremented nonce value in PoW that satisfies the requirement at the specified difficulty level.

As can be seen in the latest copies of blockchain maintained on the individual cluster nodes, they get updated via distributed pub/sub in accordance with the consensual rule, but still may differ from each other (typically by one or more most recently added blocks) when examined at any given point of time.

Reliability and efficiency

The application is primarily for proof of concept, hence the abundant side-effecting console logging for illustration purpose. From a reliability and efficiency perspective, it would benefit from the following enhancements to be slightly more robust:

  • Fault tolerance: Akka Persistence via journals and snapshots over Redis, Cassandra, etc, woud help recover an actor’s state in case of a system crash. In particular, the distributed blockchain copy (and maybe transactionQueue as well) maintained within actor Blockchainer could be crash-proofed with persistence. One approach would be to refactor actor Blockchainer to delegate maintenance of blockchain to a dedicated child PersistentActor.
  • Serialization: Akka’s default Java serializer is known for not being very efficient. Other serializers such as Protocol Buffers, Kryo should be considered.

Feature enhancement

Feature-wise, the following enhancements would help make the application one step closer to a real-world cryptocurrency system:

  • Data privacy: Currently the transactions stored in the blockchain isn’t encrypted, despite PKCS public keys are being used within individual transactions. The individual transaction items could be encrypted, each of which to be stored with the associated cryptographic public key/signature, requiring miners to validate the signature while allowing only those who have the private key for certain transactions to see the content.
  • Self regulation: A self-regulatory mechanism that adjusts the difficulty level of the Proof of Work in accordance with network load would help stabilize the currency. As an example, in a recent drastic plunge of the Bitcoin market value in mid March, there was reportedly a significant self-regulatory reduction in the PoW difficulty to temporarily make mining more rewarding that helped dampen the fall.
  • Currency supply: In a cryptocurrency like Bitcoin, issuance of the mining reward by the network is essentially the “minting” of the digital coins. To keep inflation rate under control as the currency supply grows, the rate of coin minting must be proportionately regulated over time. For instance, Bitcoin has a periodic “halfing” mechanism that reduces the mining reward by half for every 210,000 blocks added to the blockchain and will cease producing new coins once the total supply reaches 21 million coins.
  • Blockchain versioning: Versioning of the blockchain would make it possible for future algorithmic changes by means of a fork, akin to Bitcoin’s soft/hard forks, without having to discard the old system.
  • User Interface: The existing application focuses mainly on how to operate a blockchain network, thus supplementing it with, say, a Web-based user interface (e.g. using Play framework) would certainly make it a more complete system.