Companies and organizations around the world are exploring how they can apply blockchain technology to augment the supply chain. The transparency of public blockchains has a lot of benefits over closed and internal systems. Most significantly, it puts control in the customers’ hands. DTL (Distributed Ledger Technologies) can prevent counterfeiting, reduce fraud, authenticate transactions and eliminate middlemen, which helps put the price down.
This is why we created Libellum. It started out as an experiment but grew into a fully fledged solution that taught us a lot about dApps (Decentralized Application Development). In this blog post, I would like to share how we approach some of the challenges we stumbled upon while working on an MVP, but firstly I will define the Libellum.
How does Libellum work?
Libellum is a decentralized platform that helps you to secure your assets on Ethereum Blockchain. Each manufacturer can easily sign a unique serial number that identifies a particular product. The reseller or a potential buyer can later verify the serial number.
We will soon be releasing a version that augments the entire supply chain by providing a full track record from the point of origin to the end customer. Think about diamonds, for example. You can be sure that the ring you buy doesn’t contain any blood diamonds. Libellum also applies to raw materials where their origin is a crucial factor for their quality, such as leather or wood.
Blockchain beer – our cooperation with wBrew
Additionally, it’s good time to announce that we’ve started our cooperation with Wbrew, a top-rated brewery from Wrocław. Libellum can play a significant role when it comes to consumer goods as well.
How does it work? We mark beer bottles with a QR code which leads to Libellum – the app tracks and authenticates unique items. The customer can check details about the beer and learn more about its taste, used ingredients, etc. As a result, we get the first beer in Poland powered by blockchain technology. This beer will be available at Gastro Miasto, the event taking place in Wrocław, where all the participants have the opportunity to taste two varieties of craft beer: Apanaceum and Magnotidotum.
Now I would like to share how we approach some of the challenges we stumbled upon while working on the MVP.
Keeping addresses in sync
What address do you have? Does it start with cee, five, ef and ends with four, oh, six? This question persistently arose in multiple variations when it came to debugging. Each smart contract exists under its own unique address and, after each deployment, a new address is calculated. During the rapid development phase, you deploy new contracts from time to time, but your coworkers, staging server and integration tests environment keep using the old one. These manual updates slow down everyone and are a source of silent bugs.
On Ethereum, the address of the contract is deterministically calculated from the creator’s address and the number of transactions that the creator has made (so-called nonce). Those two values are then RLP (Recursive Length Prefix) encoded and a Keccak-256 hash is calculated.
We found that using ENS (Ethereum Name Service) resolvers significantly mitigated this issue. Instead of continually changing hardcoded addresses or managing environment variables, you can rely on a .test domain. It is enough to update the address within your name resolver once you deploy a new version of the smart contract.
Learn more about registering .test domain with ENS.
Unfortunately, this solution has a few shortcomings. Test domains expire after 28 days and we would love to have some versioning capabilities. We are going to address these problems by implementing a custom resolver that will support version/tags, while still being compatible with ResolverInterface.sol. Stay tuned!
Lowering the entry bar
We are currently experimenting with using third-party payments systems like Stripe to authorize our less tech-savvy users. In some jurisdictions, it is still not clear how to account for cryptocurrency transactions and Libellum understands the concerns of clients that have not yet jumped on the blockchain bandwagon.
Our backend leverages serverless infrastructure to execute transactions on behalf of our users that prefer to use classic web 2.0 payment solutions. Once they can commit to signing transactions in their browser using Mist or MetaMask, we transfer the ownership of the serial number registry and they become the sole administrator of this registry.
Modularity through multiple contracts
Each registered manufacturer in Libellum becomes an owner of his smart contract free of charge, no strings attached. There is no central place where we store all the serial numbers of every manufacturer. This modular approach has multiple advantages over a monolithic design.
Businesses evolve and, as they do, so do their needs. Embracing the modularity of smart contracts makes it as cheap as possible to migrate the registry to a new version when needed. As long as every registry implements this common interface, it is compatible with the rest of Libellum infrastructure.
Implementing the same interface across multiple smart contracts that have a significantly different purpose is easier said than done, however, and presents a significant challenge. The API surface should be kept small, yet making the interface too generic reduces the usefulness of such a contract. In some cases, we decided to choose a different approach. Certain classes of serial number registers implement the same interface (so they can be accessed with common ABIs). Every contract inherits from DetailedRegistry, which makes a contract “aware” of its class.
By knowing just the address of the contract and the DetailedRegistry ABI, we can dynamically fetch the right ABI and adjust the user interface based on this information.
Manufacturers that have special needs can reach out to Tooploox and ask for a customized version of the registry that is tailor-made to fit their unique requirements. We understand that there is no one-size-fits-all solution when it comes to securing high-value assets.
2 unit tests. 0 integration tests. pic.twitter.com/FpForNhhyi
— The Practical Dev (@ThePracticalDev) March 25, 2017
Writing unit tests for smart contracts is relatively simple with Truffle. Tests run on Ganache or Truffle Develop in an isolated environment on a blockchain that mines blocks instantly. Unit testing the frontend of a dApp is also a no-brainer.
The situation looks a little different when it comes to integration tests. To test the majority of paths in a dashboard where manufacturers can register a new serial number requires having a web3 provider with an unlocked address. Usually, this is done via Mist or MetaMask extensions.
After playing a little bit with Cypress, we came up with a way to achieve just that.
We can modify the window object hooking into the window:before:load event and inject a web3 instance with a provider that does not prompt the user to sign each transaction. Despite its name, truffle-privatekey-provider is not a Truffle specific provider and also works with a standalone web3 instance.
The big challenge, in general, when working on dApps is the infancy of the tooling and the limitations of the underlying infrastructure. Unless your webpage is popular, it is hard to reliably serve static pages via IPFS without running your node to keep files available. The second thing is the user experience of the dApp itself. The lifecycle of the transaction is much more complex than the REST API POST request and spans a length of time that may confuse users, so you have to be very explicit in how you communicate what is happening. You can learn about this on the job, or meet fantastic people on GitHub/Gitter/Slack who are happy to help you!
We are undergoing a heavy development phase and, currently, we are running on the Rinkeby test network.