Chainvoice — Invoicing on Blockchain

Andriy Shapochka
TechTale
Published in
13 min readDec 3, 2020

When hearing “Blockchain” first thing many people think about is cryptocurrency / bitcoin. Blockchain technology is much broader though and its applications go far beyond trading on crypto-exchanges for a quick profit. This post discusses one of many feasible applications of Blockchain to enterprise supply chain area, all the way down to the architecture and code.

An executive contemplating the Blockchain technology as a way to innovate their business, an architect thinking where to start on the design for the enterprise Blockchain application, or a software engineer looking for a guidance on the technology stack and patterns to use will find this write-up useful to their purpose.

Concept Recap

Before delving into the specific business case we briefly review a few concepts and terms essential to the Blockchain technology, including notions of “consortium”, “consensus”, “ledger”, “smart contract”, “token”, and others.

Organizations or individuals often need to act collaboratively, in “consortium of parties”, each of them working toward their own business goals and depending on each other to achieve it.

Collaborative business processes involving multiple parties require agile data exchange and synchronization while enforcing transactional behavior, mutual trust, provenance, non-repudiation, integrity, and accountability with respect to the data shared among participants.

From the technology perspective this requirement has led to invention of Blockchain. Blockchain platforms can be viewed as distributed transactional databases replicated to the nodes participating in a specific Blockchain network and owned by the parties (organizations or people) of a business consortium.

Simplistic view of Blockchain technology

Each Blockchain peer node plays a role of a database server synchronized with other nodes by way of P2P or broadcast communication.

This database server keeps the entire transactional history of data changes in a ledger (Blockchain’s name for the database) structured as a linked list of blocks. Each of the blocks packs one or several transaction records. Blocks point to their predecessors with a “pointer” — crypto-hash of the predecessor’s content to prevent modification of the data in the existing parts of the ledger.

A blockchain ledger is always an append-only database.

Transactions appending data to the ledger are validated and committed via consensus of the blockchain network nodes. Consensus might be based on the choice made by an elected leader-node, on a voting majority, on an authority of specific nodes, etc. You can read more about the notion of consensus and its types on the number of web sites dedicated to Blockchain (e.g. blockgeeks.com)

Many blockchain platforms support so called smart contracts which are similar to database stored procedures in the conventional RDBMS, intended to code business logics and to execute it as part of transaction validation and commit. Some platforms allow writing smart contracts in Go, JavaScript, Python, Java, or other conventional languages. Others, like Ethereum, have programming languages of their own and a virtual machine to execute them. E.g. Solidity and Viper are programming languages used to program smart contracts for Ethereum and Quorum blockchain platforms.

Finally, “tokenization”. A blockchain platform can frequently support different types of tokens or digital currencies. Public blockchain networks use them as true monetary instruments, that can be used for payments, converted to real “fiat” currencies, exchanged or traded on the crypto-exchanges. Enterprise blockchain networks can use tokens as a way to track or simulate payments between parties within the same business consortium. This is how we use tokens in the demo described in this post.

Business Case

Consider a practical, albeit, simplified invoicing process occurring in a supply chain network involving multiple organizations. Any organization might play a role of a seller or a buyer of certain products, parts, or services. A buyer would pick a number of items from seller’s catalogs and make an order. The seller would issue an invoice to the buyer, and the buyer would pay to it closing the business transaction.

Invoicing use cases

The outlined invoicing scenario is just one of many interesting interaction scenarios arising in supply chain networks and applicable to Blockchain technology. We take this scenario as a target for the project since it particularly well demonstrates an impact of Blockchain on these three objectives:

  1. Trust and transparency: each transaction is signed, verified, and becomes visible to both the seller and the buyer when committed. Moreover, these transactions are synchronized and owned by all the party nodes in the Blockchain network.
  2. Provenance: the entire history of transactional changes in the business data is available to the parties and cannot be erased or changed in the retrospective. Everything recorded in the ledger is fully traceable.
  3. Agility and cost savings: tokens representing currencies can easily be constructed on the Blockchain, relying on the smart contracts, protection from double-spend, strong transactional data integrity guarantees, and excellent traceability. As a result, the need to use regular banking and to rely on third parties such as payment processors can be substantially lower for everyday payment operations.

The objectives of trust, transparency, provenance, operational savings are a clear sign of the justified usage of Blockchain technology.

High-level Design

Let’s talk about important architectural decisions made to drive a software solution for our business case.

Why Consortium

First, we translate our primary business entities into the Blockchain notions.

Supply Chain network of organizations doing business with each other naturally maps to a Blockchain consortium of parties (= organizations), each of them hosting at least one Blockchain peer node. These nodes are connected to each other either directly or indirectly to exchange transaction block data keeping consortium’s ledger replicas the same at every node.

Supply chain consortium

This setup means each party owns the relevant business data and has it in the ledger physically stored on the node also owned and administrated by this party.

This distributed ownership model makes a significant distinction from the conventional approach of the centralized database hosted by a single organization on behalf of the other parties. The central database stores data of other parties, which own their data legally, but depend on that central organization to access it physically.

Blockchain networks unlock and enforce true ownership of the business data by the parties.

Each organization can build their enterprise systems directly querying the data kept in the ledger on their Blockchain node, never depending on anyone for access.

To ensure validity of the data across the Blockchain consortium network a consensus mechanism is used to validate and commit transactions appending data to the ledger. A version of Byzantine Fault Tolerance (BFT) consensus is frequently used in the consortium networks to ensure trust among parties based on voting for correct version of the data by majority.

Domain Model

Next, we introduce a concise domain model reflecting business entities critical for further design and implementation of the invoicing scenario.

Invoicing domain model

We include parties representing sellers and buyers and optionally owning catalogs for items for sale, such as one the figure:

Sample party record along with its catalogs and items tagged with a price

An Order entity along with order items is central to the model in the sense it serves to relate a seller, a buyer, and a list of the items picked up for the purchase transaction between them.

Finally, entities representing invoices and payments are those we will dedicate most of our effort at the next stages.

When designing a blockchain application we have to make a significant choice: which entities to store on the ledger and which keep off the ledger in a conventional relational or nosql database. This decision will affect various aspects of the future system: what data is fully tracked and trusted, what data structures are easier or harder to evolve, what data volume should be reserved for the blockchain and what data manipulation latencies should be expected.

As a rule, we want to put on the distributed ledger only the data that must definitely be shared between the businesses, bringing most value from sharing, and that does not drastically increase byte size of the blockchain transactions. In addition, this data should not be too sensitive to require erasure or extreme levels of hiding (aside from optional encryption).

Data important to track goes to the ledger. Bulky, sensitive, auxiliary data stays off-ledger.

In our case we intend to record invoices and tokens used for payments on the ledger. The rest of data will be kept in the regular relational databases. In other scenarios (e.g. fraud detection and prevention) we might have wanted to consider building a party registry or even order registry on the ledger as well. At the same time we would never put internal financial data of the parties or, say, pdf versions of orders/invoices on the distributed ledger.

It’s worth mentioning blockchain transactions and events recorded on the ledger also become part of the domain model as these records serve a proof of the executed invoicing and payment transactions.

Smart Contract Design

We want to make architectural decisions regarding invoicing and payment business logic implementation on the blockchain.

Immediately, we choose to rely on the smart contracts as primary means of coding business rules and operations on the ledger. Smart contracts are invoked as part of transaction validation and execution.

We make an observation that an invoice life cycle can be accurately modeled with a state machine as depicted below

Invoice state machine
  • Draft — a new invoice is created by the seller for an order made by the buyer but not yet sent to the buyer.
  • Unpaid — the invoice is sent to the buyer but not yet paid in full (can be partially paid for).
  • Paid — the invoice is paid in full.
  • Canceled — the invoice is canceled by the seller for some reason (still unpaid invoices can be canceled only).

In the actual smart contract the invoice states can be tracked with a field taking enum values. The smart contract will check the state field to validate whether an operation (e.g. pay invoice or cancel invoice) invoked for the invoice is allowed.

State machine driven processes especially well map to Blockchain technology which can be viewed as a distributed state machine by itself.

An invoice is represented as a record with a few business fields and a state field stored on the ledger. These fields are selected to enable enforcement of payment business rules directly in the smart contract.

struct Invoice {
bool isRegistered;
bytes invoiceId;
address seller;
address buyer;
uint256 tokenId;
uint256 amount;
uint256 paidAmount;
InvoiceState state;
}

Smart contracts are forbidden to reach to the outside world for data. The data kept on the ledger must be comprehensive and sufficient for smart contracts to operate.

Following the common pattern for Ethereum invoice records are stored in a persistent “hash map” like:

mapping(bytes => Invoice) public invoices;

Having figured out an important aspect of the invoice design, we move to the operations on the invoices. Arguably, the most useful and trickiest operation is a payment for an invoice.

We would like to rely on tokenization (preferably, using one or another token standard) to implement payments and we would like to separate concerns of invoice management and token transfers for a cleaner design and implementation. After all, token transfers may be useful outside of the scenario in focus.

While keeping them separate we want to automate change in invoice states in response to token transfers representing payments for the invoice.

The diagram visualizes our approach to the solution.

Payment with smart contracts

We plan to have two contracts:

  • one implementing the ERC-1155 token standard
  • second implementing an invoice registry/management

When a buyer wants to pay for an invoice, they make a token transfer using the token contract not to the seller but to the invoice registry contract. In turn the invoice registry validates the payment and either accepts or rejects it. If the payment is accepted, the invoice registry changes the invoice state and makes a second transfer of the tokens from its own wallet to the seller’s wallet who created this invoice.

The class diagram models these contracts applicable to the Solidity smart contract programming language. It relies on the third-party open source smart contract library OpenZeppelin to avoid doing boiler-plate implementation of the ERC standard.

Solidity smart contracts

These two contracts comprise the core of our system. By following the principle of building all secondary parts outside the ledger we keep the core small, exposing minimal surface to potential defects and change requests.

Implementation Detail

So far we have architected a few core concerns to lay ground for our Blockchain application. We are ready to think about technology, deployment, languages and frameworks.

Blockchain Platform Selection

Blockchain technology counts more than ten years of evolution resulting in the multitude of platform developed with various usage scenarios in mind.

We are interested in platforms suitable for enterprise consortiums, mature, well supported and documented, free/open source, development and operations friendly.

There are a few platforms fitting this check list: Hyperledger Fabric, R3 Corda, Quorum, and others. We decide to select Quorum for this demo project due to a few extra reasons:

  • Blockchain application made for Quorum are developed with the same Solidity language as used on Ethereum and the same blockchain clients such as web3 can be used to connect to Quorum nodes. It is possible to adopt our application to a public Ethereum network if we want to make an open consortium in the future.
  • Tokenization support and various token protocols are well developed for Quorum.
  • There are mature tools and frameworks available (driven by Ethereum community).
  • It is extremely fast to deploy a managed Quorum blockchain network on Azure. This public cloud supports managed Quorum available for a reasonable price tag.

These considerations are decisive in our case, but in a different context we might have been driven by other criteria and selected a different platform. Each blockchain platform is built on similar principles but with different use cases and strengths in mind.

Amount of blockchain core code makes a small portion of the entire application codebase, but the right choice of the blockchain platform and careful design for it makes all the difference for project success.

Technology Stack

We select Azure to deploy the application due to the reason mentioned in the last section — it takes a couple of cli commands or a few clicks in the Azure portal to spin up a Quorum blockchain consortium with one or a few transactional nodes and validators, all managed by Azure.

Demo deployment on Azure

Azure app services are used to host demo’s REST API and UI. These form a layer between a Quorum node and parties using this node to provide a number of operations on the off- and on-ledger data entities.

Off-ledger data is stored in a managed PostgreSQL database.

A few significant decisions were made regarding the implementation technology stack:

  • Solidity is a smart contract language of choice for the smart contracts implementing invoicing business logic. It is most mature and most supported smart language running on Ethereum Virtual Machine (EVM).
  • OpenZeppelin tools and libraries are used to develop smart contracts based on the best practices and standards.
  • Ganache — developer friendly EVM is used for local tests and debugging of the smart contracts.
  • Python 3.8, FastAPI REST API framework, Pydantic data object library, SQLAlchemy Core, asynchronous Databases, are selected to write Chainvoice’s REST API adhering to the best practices of asynchronous web development, boiler-plate code elimination, Swagger based API auto documentation, OAuth2 support.
  • Web3py provides production-grade integration of the python code with Quorum RPC-JSON API.
  • Vue.js / Nuxt.js / Vuetify running on top of Node.js enable fast development of a responsive, modern-looking web UI with minimal effort.

Right combination of technologies and tools smoothly working with each other reduces friction and enables productivity boost at the development phase.

Payment Scenario

The diagram shows, with a few insignificant simplifications, an actual implementation of the payment scenario discussed earlier in the post.

The client here can be a REST API client or the demo’s web user interface.

Payment implementation

It is interesting to observe how a simple operation should still involve disparate services to execute.

We need to build a usual API/service layer acting as a client to the Quorum node and the database.

We also need to involve a secure key store (Azure’s Key Vault) to keep and retrieve a private key for a party initiating a blockchain transaction. The transaction initiator is required to sign a transaction with the own private key before committing it to the ledger.

The actual transaction gets executed with a smart contract in the Quorum node and the results are committed to the ledger.

The transaction hash and, possibly, other outputs from the smart contract execution are saved into the application database as a proof-link to the actual transactional record on the ledger, that can be used to verify the payment at any time.

Final Thoughts

In this post, we demonstrated step by step how a meaningful business case can be mapped to the Blockchain terms and concepts, architected, successfully built on the stack of modern technologies, and deployed to the cloud, ready to operate.

Consider this and similar prototypes as a sound Proof of Concept showing feasibility and maturity of the Blockchain technology sufficient for usage in the enterprise contexts.

Proof of Value of Blockchain application to a specific scenario is a different, often, more complex matter. To justify extra-effort, extra-investment, technical trade-offs of using Blockchain instead of the conventional centralized database technology we always need to ask ourselves a question: “What benefit might we gain from Blockchain?”

When there are multiple collaborative businesses benefiting from the data continuously shared with the most technically achievable trust and strong integrity, and clear provenance, then the answer to this question will be fruitful and clear.

References

The code of the Chainvoice prototype and the read-only demo deployment are freely available for review and feedback:

  1. Chainvoice API and smart contract source code on Github
  2. Chainvoice UI source code on Github
  3. Chainvoice API Swagger documentation
  4. Chainvoice Web UI

If you like the post and are interested to build your next Blockchain application with us, feel free to contact SoftServe Inc.

--

--

Andriy Shapochka
TechTale

Software architect, who’s been working in software engineering for more than two decades. Interested in technical debt, architecture design, blockchain