Architecture

Postchain consists of the following components:

  • Core: Defines common interfaces which allow different modules to interoperate with each other.
  • Base: Defines base classes which are geared towards enterprise blockchains. They can either be used as is, or serve as a base classes for customization.
  • GTX: Defines a generic transaction format. It is a general-purpose format with several useful features, such as native multisignature support. It is optional (it is easy to define custom format), but is recommended. GTX also offers a way to define modules with blockchain logic which can work together with each other.
  • API: REST API for submitting transactions and retreiving data.
  • EBFT: Consensus protocol, based on PBFT. (Replaceable.)
  • Client library/SDK: Currently only JavaScript SDK is available, in future we will offer SDK for JVM. Client library contains functions for composing and parsing transactions, interacting with Postchain node using client API.

Core

The goal of Postchain core is to define interfaces which help with code organization, enable interoperabiity between different modules. It also implements several commonly used classes and functions.

Core should be flexible enough for following scenarios:

  • building custom blockchains (public or private/federated)
  • indexing data of an existing blockchain (Bitcoin, Ethereum, …)
  • implementing sidechains (which combine custom blockchains with public blockchains)

What is included in core:

  • class interfaces (implied): Block, Transaction, BlockFactory, TransactionFactory
  • base implementations: AbstractBlock, BlockFactory, TransactionFactory
  • utilities: Storage (pg connector), crypto utilities
  • “example” implementations: BlockStore, ByteTx, ByteTxStore, SimpleSignedBlock

It’s not clear if “example implementations” are actually a part of the core, or are just examples.

Perhaps core should include more stuff, like logging.

Since JS has no notion of interfaces, they will be defined in documentation.

Framework documentation should also include recommendations on schema design, best practices, etc.

Base

The goal of base is to provide tools for building custom blockchains, particularly enterprise private/federated blockchains. Ideally, it should be possible to use it both as a complete solution, and as a collection of building blocks and helpers.

Base includes the following component:

  • inter-peer networking, with ASN.1-based message format and ECDSA message signing
  • an implementation of Block which is designed for proof-of-authority kind of blockchain (having a room for validator signatures)
  • a PBFT-derived consensus algorithm, designed to work with aforementioned Block implementation
  • compiler for a Ratatosk-like language which is used to define transaction implementations (it is also possible to implement it in a custom way)
  • client-facing RPC server (submit transactions, query-data)
  • client SDK
  • some minimal configuration

GTX

Postchain GTX makes it possible to compose application from modules. Using pre-made modules can help to reduce implementation time.

Currently ChromaWay offers only two GTX modules (which are bundled with Postchain code):

  • Standard – implements time lock and transaction expiration feature.
  • FT – Flexible Tokens, provides a simple way to implement tokens. (Can be used in applications like payments, loyalty points, crowdfunding, securities trade, …)

GTX transaction format has following features:

  • Format is based on ASN.1 DER serialization (standardized by ITU-T, ISO, IEC)
  • Has native support for multi-signature
  • Has native support for atomic transactions

GTX transaction is consists of one or more operations, and each operation is defined by its name and list of arguments. E.g. one transaction might encode two operations:

  • issue(<Alice account ID>, 1000, USD)
  • transfer(<Alice account ID>, <Bob account ID>, 100, USD)

This looks similar to making function calls, so GTX operations can be understood as a kind of RPC, where client submits calls (operations) to be performed on server (network of Postchain nodes). GTX transaction is a batch of such operations signed by clients which wish to perform them. Usually operations update database, but they might only perform checks. GTX transaction is atomic: either all operation succeed, or it fails as a whole. GTX modules

Postchain provides a convenient way to define GTX operations and organize them into modules. Multiple modules can be composed together into a composite module.

Besides operations, modules also define queries which can later be performed using client API.

GTX client SDK

GTX client SDK for JavaScript is provided in postchain-client npm package. Example of use is provided in README file here.

FT

FT comes with its own client library for JS which also includes examples, see Postchain FT

Network

Network components take care of “boring” stuff like messaging, signing messages, checking message signatures.

MVP implementaiton will use a rudimentary static configuration, future versions might use dynamic reconfiguration.

Consensus algorithm

Consensus algorithm is inspired by Castro’s PBFT, but works on block level and restricts concurrency as much as possible. (It seems IBM is taking similar approach in hyperledger/fabric/consensus/simplebft.)

Block implementation

Might be very similar to SimpleSignedBlock, except with ASN.1 serialization format.

Compiler

A Ratatosk-like language can be used to define a list of actions:

(defblockchain ledger
    (actions
        (send-money ((from :type pubkey) (to :type pubkey) (amount :type integer))
            (guard (signatures from))
            (sql (foobar_send_money from to amount)))))

A compiler will take this description and use it to define:

  • ASN.1 serialization format for transaction
  • Transaction classes which handle deserialization and check authorization according to specified guard clauses
  • Store classes

Together with SQL schema definition this is enough to define a custom blockchain in the context of Kit.

Client RPC

Postchain nodes will both serve as peers in a Postchain network, and serve as a RPC server for clients.

Clients should be able to:

  • submit a transaction; transaction is automatically routed to a primary
  • check transaction status
  • query blocks & transactions
  • (TBD) transaction creation helper (client sends JSON, server constructs & signs transaction)
  • (TBD) query blockchain data (???)

One problem is that queries are blockchain-specific. We can either leave that to blockchain implementors (it’s not hard to query the DB and return data…), but we might also make use of aforementioned compiler & language to define blockchain-specific queries.

(Another possibility is to user a 3rd-party REST API for read queries, e.g. Postgrest.)

Client SDK

Client SDK should include tools to construct transactions & sign them. It might be necessary to link with compiler-generated message codecs. (One option is for compiler to generate SDK bundle for a specific blockchain.)

Configuration

We should make it easy for user to launch a Postchain Kit server for a specific blockchain(s) and using a pre-defined network peer configuration. In the initial version we only need to make it work with a static configuration.

Transactions

However, to benefit from blockchain-like features, transaction messages should be:

  • As simple as possible; they should be easy to analyze and leave no room for ambiguity
  • Carry a proof of authorization within them (e.g. transaction signatures)

For example, a good transaction message should include only a type of operation to perform and necessary data, as well as signatures which authorize the operation. For example, an e-money transaction message might be (pay, sender, recipient, amount, sender’s signature) tuple.

A message which includes an SQL query in a textual form is an example of a bad message format. While it’s technically possible, it will result in poor security characteristics, as it’s hard (or impossible) to check whether a free-form SQL query is properly authorized.

Transaction logic

Normally transaction-handling logic is implemented in a JavaScript class which implements a transaction. However, this class is supposed to interact with an SQL database, and thus logic can also be implemented in database’s stored procedures.

We recommend to implement cryptography-related parts in JS, and state manipulation and validation parts in SQL, but it’s not a hard requirements.