Ethereum or Hyperledger Fabric?

The sole purpose of the article is to analyze the key differences between Distributed Ledger Technologies (DLT) namely Ethereum, and Hyperledger Fabric. Both frameworks are suited for very different visions in regards to their fields of application.

Hyperledger Fabric provides a customizable and extendable architecture that may be used in diverse fields ranging from banking to supply chain to healthcare et al. Ethereum’s unique feature of providing us with a cross-disciplinary platform for all kinds of transactions and use cases.

Also, Read Our Next Article on Hyperledger

The course of the article is as follows:

  • Theoretical knowledge the following with respect to Ethereum and Hyperledger Fabric:
    • Participation of Peers/Nodes in the decentralized network
    • Consensus Mechanism
    • Smart Contracts
    • Cryptocurrency
  • Discussion on the architecture of:
    • Ethereum
    • Hyperledger Fabric
  • Block structure (data model) in blockchain for Ethereum and Hyperledger Fabric

So let’s get started!

Participation of Peers/Nodes

Participation of peers/nodes depends on two modes of operation in the network:

  1. Permissionless: Anybody is allowed to participate in the network. This mode is true for Ethereum because it is a public blockchain.
  2. Permissioned: Participants are selected beforehand and only the selected participants have access to the network. This is true for Hyperledger Fabric because it is a private blockchain.
    ‘Participating in the network’ means that entities (nodes) that participate in decentralised ledger management are permitted to contribute to it. Since every node has a copy of ledger in a blockchain, it matters how everyone decides upon a common truth. Hence, to decide upon that common truth , participation of nodes in the network becomes mandatory.

Consensus Mechanism

The result of arriving at a common consensus happens by engaging with various algorithms like Proof of Work (PoW), or Byzantine Fault Tolerant (BFT).

Achievement of consensus in Ethereum

All peers taking part in the network have to reach consensus so that the transaction can be appended to the blockchain. Peer has to take part in achieving the consensus even if it has not taken part in the transaction. You might think why should the peer take part in validating the transaction when it has got nothing to do with it. The catch is that- there is an incentive. If a peer proves the correctness of a transaction in the Ethereum network, it will be rewarded with Ethers. In the current implementation of Ethereum, the mechanism is established by mining based on Proof of Work algorithm.

Issues with proof of work

  1. It requires a lot of computational power (CPU cycles, GPU, electricity) to get random bits.
  2. Tragedy of the commons — Miners reward reduces over time when this occurs fewer miners will mine these blocks. This could open up window for malicious users who can easily acquire more than 51% of the network and thus destroying the network.

Ethereum is trying to switch from proof of work to proof of stake consensus algorithm.

There is a problem of double spend here. Maybe there are two parallel transactions which transfer the same coin to two different recipients. In easier terms, suppose a person has only $10 but ends up spending $20 without going into debt.

Security is also of paramount importance here. The data recorded on the ledger is accessible to everyone which is a problem for applications that require a more serious degree of privacy.

Achievement of Consensus in Hyperledger Fabric

The definition of consensus in Hyperledger Fabric is different. It doesn’t narrow down to mining based on PoW or any other derivative thereof. Since it is operating in permissioned mode, there is more fine grained access control to improve privacy.

Here, consensus encompasses the entire transaction flow right from the beginning (from proposing a transaction to the network) till the end (committing the transaction to the ledger). In this case, every node assumes a different role to play while reaching consensus, unlike Ethereum where every node has an identical role to play.

Nodes are differentiated based on whether they are:

1. Clients: They act on behalf of an end-user and creates and thereby invokes transactions. They communicate with both peers and orderers.

2. Peers: They maintain the ledger and receive ordered update messages for committing new transaction to the ledger. Endorsers are special type of peers where their task is to endorse a transaction by checking whether they fulfil necessary and sufficient conditions. (eg. Provision of required signatures)

3. Orderers: They provide a communication channel to clients and peers over which messages containing transaction can be broadcasted.

At this point, the problem arises that there might occur faults in the delivery of messages when many mutually untrusting orderers are employed. As a consequence, a consensus algorithm has to be used in order to reach consensus despite faults, e.g. inconsistent order of messages, thus making the replication of the distributed ledger faults tolerant. With Fabric, the algorithm employed is “pluggable”, meaning that depending on application specific requirements various algorithms can be used. For example, in order to deal with random or malicious replication faults as outlined above a variant of the Byzantine fault-tolerant (BFT) algorithms could be used.

Furthermore, channels partition message flows, meaning that clients only see the messages and associated transactions of the channels they are connected to and are unaware of other channels. This way, access to transactions is restricted to involved parties only with the consequence that consensus has only to be reached at the transaction level and not at ledger level as with Ethereum.

Transaction flow

A client sends a transaction to connected endorsers in order to initiate an update of the ledger. All endorsers have to agree upon the proposed transaction, thus some sort of consensus has to be reached regarding the proposed ledger update. The client now successively collects approval of all endorsers. The approved transaction is now sent to connected orderers which again reach consensus. Subsequently, the transaction is forwarded to peers holding the ledger for committing the transaction. Without going further into detail, it becomes clear that Fabric allows fine grained control over consensus and restricted access to transactions which results in improved performance scalability and privacy.

Smart Contracts

Following are the languages in which smart contracts are written for various frameworks:

  • Ethereum: Solidity
  • Hyperledger Fabric: Go or Java. (The term “chaincode” is used as a synonym for smart contract.)

Cryptocurrency

Another noteworthy difference is that Ethereum features a built-in cryptocurrency called Ether. It is used to pay rewards to nodes that contribute to reach consensus by mining blocks as well as to pay transaction fees. Therefore, decentralized apps (DApps) can be built for Ethereum that allow monetary transactions. Furthermore, a digital token for custom use cases can be created by deploying a smart contract that conforms to a pre-defined standard. This way, own currencies or assets can be defined. Hyperledger Fabric does not require a build-in cryptocurrency as consensus is not reached via mining. With Fabric, however, it is possible to develop a native currency or a digital token with chaincode.

Ethereum Architecture

The purpose of decentralization is to not rely on a centralized server. So, the community has come up with solutions (hosted blockchain servers, metamask etc.) where you don’t have to spend a lot of your hard disk and RAM downloading and running a full copy of the blockchain but also not compromise on the decentralized aspect.

Ethereum or Hyperledger Fabric

The Ethereum blockchain has 2 main parts:

  1. Database: Every transaction in the network is stored in the blockchain. When you deploy your contract, it is considered as a transaction. All these transactions are public and anyone can see this and verify. This data can never be tampered with. To make sure all the nodes in the network have the same copy of the data and to ensure no invalid data gets written to this database, Ethereum uses an algorithm called Proof of Work to secure the network. (http://ethereum.stackexchange.com/questions/14/what-proof-of-work-function-does-ethereum-use)
  2. Code: In Ethereum world, you write the logic/application code (called contract) in a language called Solidity. You then use the solidity compiler to compile it to Ethereum Byte Code and then deploy that byte code to the blockchain (There are few other languages you could use to write contracts but solidity is by far the most popular and relatively easier option). So, not only does Ethereum blockchain store the transactions, but it also stores and executes the contract code.
    So basically, the blockchain stores your data, stores the code and also runs the code in the EVM (Ethereum Virtual Machine).

To build web-based Dapps, Ethereum comes with a handy javascript library called web3.js which connects to your blockchain node. So you can just include this library in your famous js framework like reactjs, angularjs etc and start building.

Hyperledger Fabric Architecture

Hyperledger Fabric is an implementation of a distributed ledger platform for running smart contracts, leveraging familiar and proven technologies, with a modular architecture allowing pluggable implementations of various functions. The distributed ledger protocol of the fabric is run by peers. The fabric distinguishes between two kinds of peers:

  • Validating peer: is a node on the network responsible for running consensus, validating transactions, and maintaining the ledger.
  • Non-validating peer: is a node that functions as a proxy to connect clients (issuing transactions) to validating peers. A non-validating peer does not execute transactions but it may verify them.

The validating peers run a BFT consensus protocol for executing a replicated state machine that accepts three types of transactions as operations:

  1. Deploy transaction: Takes a chaincode (representing a smart contract) written in Go as a parameter; the chaincode is installed on the peers and ready to be invoked.
  2. Invoke transaction: Invokes a transaction of a particular chaincode that has been installed earlier through a deploy transaction; the arguments are specific to the type of transaction; the chaincode executes the transaction, may read and write entries in its state accordingly and indicates whether it succeeded or failed.
  3. Query transaction: Returns an entry of the state directly from reading the peer’s persistent state; this may not ensure linearisability.
    As the fabric implements a permissioned ledger, it contains a security infrastructure for authentication and authorisation. It supports enrolment and transaction authorisation through public-key certificates, and confidentiality for chaincode realised through in-band encryption.

Ethereum Block Structure

Ethereum or Hyperledger Fabric 2
Source

The block in Ethereum is the collection of relevant pieces of information (known as the block header ), H, together with information corresponding to the comprised transactions, T, and a set of other block headers U that are known to have a parent equal to the present block’s parent’s parent (such blocks are known as ommers ). The block header contains several pieces of information:

parentHash: The Keccak 256-bit hash of the parent block’s header, in its entirety; formally Hp.

ommersHash: The Keccak 256-bit hash of the ommers list portion of this block; formally Ho.

beneficiary: The 160-bit address to which all fees collected from the successful mining of this block be transferred; formally Hc.

stateRoot: The Keccak 256-bit hash of the root node of the state trie, after all, transactions are executed and finalisations applied; formally Hr.

transactionsRoot: The Keccak 256-bit hash of the root node of the trie structure populated with each transaction in the transactions list portion of the block; formally Ht.

receiptsRoot: The Keccak 256-bit hash of the root node of the trie structure populated with the receipts of each transaction in the transactions list portion of the block; formally He.

logsBloom: The Bloom filter composed from indexable information (logger address and log topics) contained in each log entry from the receipt of each transaction in the transactions list; formally Hb.

difficulty: A scalar value corresponding to the difficulty level of this block. This can be calculated from the previous block’s difficulty level and the timestamp; formally Hd.

number: A scalar value equal to the number of ancestor blocks. The genesis block has a number of zero; formally Hi.

gasLimit: A scalar value equal to the current limit of gas expenditure per block; formally Hl.

gasUsed: A scalar value equal to the total gas used in transactions in this block; formally Hg.

timestamp: A scalar value equal to the reasonable output of Unix’s time() at this block’s inception; formally Hs.

extraData: An arbitrary byte array containing data relevant to this block. This must be 32 bytes or fewer; formally Hx.

mixHash: A 256-bit hash which, combined with the nonce, proves that a sufficient amount of computation has been carried out on this block; formally Hm.

nonce: A 64-bit hash which, combined with the mix-hash, proves that a sufficient amount of computation has been carried out on this block; formally Hn.

Hyperledger Fabric Block Structure

Ethereum or Hyperledger Fabric 3
Source

Fabric’s block consists of three segments which are Header, Data, and Metadata. Both Header and Metadata are smaller segments as compared to Data. In this article (part 1), we dive into the content of the Header and Metadata segment of a block. In part 2, we look at the content of the main components, i.e., Data.

 

type Block struct {
    Header   *BlockHeader   
    Data     *BlockData     
    Metadata *BlockMetadata 
}

Block Header

The header of each block consists of three items which are

  1. Number — the unique block number.
  2. PreviousHash — hash of the previous block’s header.
  3. DataHash — hash of the data segment of the current block.

The block number of each block is unique and is assigned sequentially starting from zero. The first block in a chain is special and is called genesis block which gets zero as its Number. The PreviousHash of the genesis blocks is set to nil, whereas the PreviousHash of the next block holds SHA256 hash of BlockHeader of the previous block. The DataHash holds SHA256 hash of BlockData of the current block.

type BlockHeader struct {
    Number       uint64 
    PreviousHash []byte 
    DataHash     []byte 
}

SizeOf(BlockHeader) = 8 bytes for Number + 32 bytes for PreviousHash + 32 bytes for DataHash = 52 bytes

Block Metadata

The BlockMetadata stores four metadata, each as a byte array in Metadata field.

type BlockMetadata struct {
    Metadata [][]byte 
}

 

The four metadata stored in a block are listed below along with its index.

  • SIGNATURES: signature on the block creation. (index: 0)
  • LAST_CONFIG: reference to the last configuration block. (index: 1)
  • TRANSACTIONS_FILTER: valid and invalid transactions in a block. (index: 2)
  • ORDERER: the last offset persisted (kafka ordering metadata). (index: 3)

The SIGNATURE, LAST_CONFIG, and ORDERER metadata are added by the ordering service, whereas the TRANSACTION_FILTER is added by the committer after validating the transaction based on the endorsement policy, verification of read-write set, etc… The TRANSACTION_FILTER is a byte array of size equal to the number of transactions in the block. For each transaction, committer sets validation code in the byte array appropriately to represent the validation result. A set of validation code is given below.

TxValidationCode_VALID                        TxValidationCode = 0
TxValidationCode_NIL_ENVELOPE                 TxValidationCode = 1
    TxValidationCode_BAD_PAYLOAD                  TxValidationCode = 2
    TxValidationCode_BAD_COMMON_HEADER            TxValidationCode = 3
    TxValidationCode_BAD_CREATOR_SIGNATURE        TxValidationCode = 4
    TxValidationCode_INVALID_ENDORSER_TRANSACTION TxValidationCode = 5
    TxValidationCode_INVALID_CONFIG_TRANSACTION   TxValidationCode = 6
    TxValidationCode_UNSUPPORTED_TX_PAYLOAD       TxValidationCode = 7
    TxValidationCode_BAD_PROPOSAL_TXID            TxValidationCode = 8
    TxValidationCode_DUPLICATE_TXID               TxValidationCode = 9
    TxValidationCode_ENDORSEMENT_POLICY_FAILURE   TxValidationCode = 10
    TxValidationCode_MVCC_READ_CONFLICT           TxValidationCode = 11
    TxValidationCode_PHANTOM_READ_CONFLICT        TxValidationCode = 12
    TxValidationCode_UNKNOWN_TX_TYPE              TxValidationCode = 13
    TxValidationCode_TARGET_CHAIN_NOT_FOUND       TxValidationCode = 14
    TxValidationCode_MARSHAL_TX_ERROR             TxValidationCode = 15
    TxValidationCode_NIL_TXACTION                 TxValidationCode = 16
    TxValidationCode_INVALID_OTHER_REASON         TxValidationCode = 255

 

Other three metadata added by the orderer service, such as SIGNATURE, LAST_CONFIG, and ORDERER, stores the metadata information along with a signature. For LAST_CONFIG and ORDERER metadata, the last configuration block number and last offset persisted are set to Value field in Metadata struct given below.

type Metadata struct {
    Value      []byte               
    Signatures []*MetadataSignature 
}

 

The Signature field holds the signature of the orderer as well as respective headers using MetadataSignature struct.

type MetadataSignature struct {
SignatureHeader []byte 
    Signature       []byte 
}

 

The Creator field holds x.509 certificate, public key and membership service provider (MSP) who issued these identities to the client. The Nounce field contains some random bytes.

type SignatureHeader struct {   
    Creator []byte 
    Nonce []byte 
}

 

The SIGNATURE metadata (i.e., index 0) uses the above three structures but set the Value field in Metadata struct to nil as it wants to add just the signature on block creation.

Launch your blockchain project with Quillhash: https://quillhash.typeform.com/to/KQ5Hhm

Thanks for reading. Also, do check out our earlier blog posts.