This blog series was jointly written by Tim McHale and Greg Scullard (Developer Advocates).
This is part 2 of a 4-part series. In part 1, we offered alternatives that gave greater control and privacy to token offerers through the use of a permissioned network alongside Hedera Consensus Service.
The second option for tokens using HCS – we’re getting to the heart of the reason this series exists – is to create a decentralized application.
The principles behind a HCS-based application have been covered in two prior webinars and a podcast:
Let’s recap quickly.
In the context of HCS, a decentralized application is...
“A network of applications that communicate with each other using HCS”
This may seem confusing at first, so let’s break things down and relate them back to what we’re used to. This probably rings closer to home:
A distributed ledger is...
“A network of nodes that come to agreement on transactions using a common consensus protocol”
Hedera runs a number of nodes, each running identical code and when one of these nodes receives a request to issue a transaction by a client via its API, it sends the transaction to the network for consensus. When consensus is reached, each node updates its local state (Account Balance, Smart Contract Function call, etc…) as a direct result of the transaction contents.
So far so good.
So, let’s assume we have a set of servers, desktop and/or mobile devices that run the same code, or code that is functionally identical. That means that for a given input, any instance of this code, wherever it’s running will result in the same output.
Those could be considered to be nodes in the Hedera context.
We now obviously need some sort of consensus between all these application instances (let’s call them decentralized application nodes from now on), we need a way for them to share changes and to do so in a fair, reliable, and deterministic manner. This is where HCS enters stage left.
If a decentralized application node receives a trigger from its operator (or one of its users), such as a transfer of 20 tokens from Alice to Bob. The decentralized application node would construct a message (the equivalent of a transaction from a Hedera node client) and submit it to Hedera using a Consensus Service transaction.
Once the Hedera network has come to consensus and shared the result with mirror nodes, the mirror nodes can broadcast the result of the Consensus transaction to all the decentralized application node, which can in turn apply the necessary calculations to transfer 20 tokens from Alice to Bob.
They would of course also perform a series of checks to ensure the state isn’t being compromised, such as verifying that Alice’s balance is sufficient.
There you have it, your own decentralized application, running on as many “nodes” as you desire, all synchronised by Hedera Consensus Service message transactions.
Decentralized application network synchronized by Hedera Consensus Service
Let’s look at different ways of deploying our decentralized application with increasing degrees of decentralization.
This server would be a single node running the decentralized application (maybe that’s not all that decentralized, but bear with me) and all clients would communicate with this server to transact and query state. While centralized (and hardly distributed), this has the benefit of all operations being public, if the code for the server was available through open-source for example, anyone could run a copy of the server software, subscribe to the same topic(s) and see for themselves that the server operator isn’t being malicious.
There remains a concern that the server operator could be malicious with regards to fairness (it could delay, indefinitely hold, or re-order client requests, for example). One mitigation would be for clients to submit their operations directly to HCS, the server operator would thus be unable to act maliciously in respect of fairness.
Single server application network
Each server acts as a decentralized application node and clients may choose any server to submit their operations or queries to.
This increases the decentralization of the application. There is no reliance on a single server operator.
Furthermore, this introduces the possibly for clients to query servers randomly to mitigate any potential malicious behaviour, it is in the interest of every server to act properly or risk being excluded from the decentralized application network.
Several server application network
The most decentralized option is for each end user to be able to run their own application node via a desktop or mobile application.
Users can trust their own application when it comes to queries and they don’t have to rely on one or more server operators to maintain the application network.
Device application network
The choice whether to run your own mirror node(s) - or even to allow individual users to do so - to serve your application network is up to you. Running and maintaining one or more mirror nodes will have a cost, whether this is desirable will depend on the business model and objectives of the application network.
Patience, it’s almost time.
We’ve built an example token project in Java to illustrate how an ERC-20 token might be implemented using HCS in the context of an application network.
The project will enable you to use a single HCS topic to manage a token. Operations to construct, mint, transfer, get balances, etc… are supported, just like an ERC-20 token.
The project implements all the necessary building blocks to get you started, improve upon to create more complex token types (such as ERC-721), or use as a foundation for a non-token related implementation.
The example has been kept simple on purpose, we could have built persistence to a database, we could have given it a REST API, but since these are bread and butter for us developers, we didn’t feel necessary to include here.
Broadly speaking a decentralized application on HCS requires the following building blocks:
That may seem like a lot of work, but most of it is highly reusable. Let’s compare and contrast with a Solidity implementation; I’ve highlighted the areas where custom work is required.
There is little difference here between the two as we can see, the state model and logic is obviously custom work, it will vary with each implementation, although in the context of tokens, by expanding upon the example, we could be close to a fully reusable solution already.
There are significant benefits to this approach however:
There are a few other considerations we should pay attention to, which we'll discuss in the next section. In part 3 of the series, we dive into code with a working example, comparing a ERC-20 token to how it could begin to be implemented using Hedera Consensus Service.