News Headline: Over 2,000 in Mumbai duped in fake vaccine drives, says Govt

News Headline: WHO issues medical alert on fake Covishield vaccines

News Headline: 2,73,000 doses of fake Remdesivir injections seized in Gujarat

Covid-19 has been bad enough for all of us, but these kind of incidents reveal just how much worse things can get when you throw in human greed. It is said that we should never let a crisis go waste. These peddlers of fake vaccines and medicines seem to have taken this saying to heart and tried to make quick bucks.

Recently at work, we had a hackathon to ideate and build solutions around the theme of Covid. A bunch of us decided to tackle the above problem and develop a prrof-of-concept solution to verify the authenticity of the medicines and vaccines we consume. After some brainstorming, we decided to explore blockchain as a tool for building this solution. As none of us were familiar with blockchain, this was also a great opportunity to familiarize ourselves with the various blockchain platforms available. The below post gives an introduction to blockchain as we understood and the very simple app that we created.

What is Blockchain?

Blockchain, in very simple terms, is a technology that allows us to record information in a way that makes it practically impossible to modify or tamper with. This Wikipedia article is a good place to start if you are new to Blockchain.

Permissionless and Permissioned Blockchains

While searching for a simple open-sourced blockchain platform that we could use for our mini-project, we encountered two types of blockchain platforms. Permissionless and Permissioned. A brief comparison is given below. For a more detailed comparison, check here.

Permissionless Permissioned
Participants are anonymous. Anyone can join and conduct transactions on the blockchain network. All participants are known and verified before they are allowed to join the network and perform transactions.
Transactions are public, ie known to all participants in the network. Transactions are private and only known to select participants.
Since anyone can submit transactions, a proof of work has to be performed, before the transaction is verified and added to the chain. Transactions are digitally signed by certificates and once the signature is verified by all participants, the transaction is added to chain. No proof of work required.

Principal actors

  • Manufacturer of the vaccine or medicine (asset)
  • Traders, both wholesale and retail, who form the supply chain between the manufacturer and the end consumer.
  • A Regulator who administers the entire system
  • The end consumer who would like to verify the authenticity

Use Cases

  • Manufacturers would like to have all the assets manufactured by them to be recorded on the blockchain so that they can assure their end customers that they are buying a genuine product. Only a certified manufacturer would have permission to add assets on to the blockchain
  • Certified traders would be the only ones to participate in transfer of asset from one owner to another.
  • Spurious traders or black marketeers would not have access to the system and would not be able to add fake products on to the blockchain.
  • End customer would be able to query the asset id on a website controlled by regulators. Only genuine products would be available on the website that is internally backed by the blockchain.
Use Case Diagram

Architecture

The overall architecture of the system would look something like this

Architecture diagram
State diagram

Key Components

  • Blockchain network: The actors like manufacturer, traders, client applications connect to each other on the blockchain network. The network consists of distributed nodes that can be hosted by any of the parties involved in the network. Follow this link for more details about blockchain networks.

For our POC we just used the default test network provided by hyperledger fabric and got it running on our local machine. For a production grade network setup, you would have to design the configuration of your network, set up clusters, peers and nodes and CAs (certificate authorites) that can be used to validate and sign transactions.

  • Smart Contracts: These contracts capture the logic of business transactions between actors as executable code. The contracts are executed on the blockchain network and can create, update or read entries made into the blockchain. In our case, we are going to capture the functions of creating an asset and transfer of asset as smart contracts. You can read more about there here

  • Client application: These contain client code to invoke smart contracts. These can be in the form of mobile, web or backend applications.

Sourced from https://hyperledger-fabric.readthedocs.io/en/release-2.2/_images/AppConceptsOverview.png

Code Samples

You can refer the complete code here. This is a very basic application that can create some assets on a hyperledger using simple smart contracts.

Github Repo

Writing a simple Smart Contract to create and manage an asset on the blockchain

Defining a class that represents the Smart Contract

@Contract(name = "MyAssetContract",
        info = @Info(title = "MyAsset contract",
                description = "My Smart Contract",
                version = "0.0.1",
                license =
                @License(name = "Apache-2.0",
                        url = ""),
                contact = @Contact(email = "contact.us@example.com",
                        name = "blockchain",
                        url = "http://example.com")))
@Default
public class MyAssetContract implements ContractInterface {
  ...
}

Adding some basic CRUD operations for assets in blockchain through the smart contract

    @Transaction()
    public boolean myAssetExists(Context ctx, String myAssetId) {
        byte[] buffer = ctx.getStub().getState(myAssetId);
        return (buffer != null && buffer.length > 0);
    }

    @Transaction()
    public void createMyAsset(Context ctx, String myAssetId, String manufacturer, String manufactureDateTime, String expiryDate, String status, String owner) {
        boolean exists = myAssetExists(ctx, myAssetId);
        if (exists) {
            throw new RuntimeException("The asset " + myAssetId + " already exists");
        }

        MyAsset myAsset = MyAsset.builder()
                .id(myAssetId)
                .manufacturer(manufacturer)
                .manufactureDateTime(manufactureDateTime)
                .expiryDate(expiryDate)
                .status(status)
                .owner(owner)
                .build();

        ctx.getStub().putState(myAssetId, myAsset.toJSONString().getBytes(UTF_8));
    }

    @Transaction()
    public MyAsset readMyAsset(Context ctx, String myAssetId) {
        boolean exists = myAssetExists(ctx, myAssetId);
        if (!exists) {
            throw new RuntimeException("The asset " + myAssetId + " does not exist");
        }

        MyAsset newAsset = MyAsset.fromJSONString(new String(ctx.getStub().getState(myAssetId), UTF_8));
        return newAsset;
    }

Finally, get history of the asset to show all the transactions it has gone through.

    @Transaction()
    public String readMyAssetHistory(Context ctx, String myAssetId) {
        ChaincodeStub stub = ctx.getStub();
        String assetJSON = stub.getStringState(myAssetId);

        if (assetJSON == null || assetJSON.isEmpty()) {
            String errorMessage = String.format("Asset %s does not exist", myAssetId);
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
        }

        QueryResultsIterator<KeyModification> historyForKey = stub.getHistoryForKey(myAssetId);

        StringBuilder history = new StringBuilder();
        history.append("{\"currentState\": ").append(assetJSON).append(",\"history\": [");

        history.append(StreamSupport.stream(historyForKey.spliterator(), false)
                .map(a -> String.format("{\"txId\": \"%s\", \"state\": %s, \"timestamp\": \"%s\"}",
                        a.getTxId(), a.getStringValue(), a.getTimestamp().toString()))
                .collect(Collectors.joining(","))
        );
        history.append("]}");

        return history.toString();
    }

A client app that can execute the smart contracts written above

Sample code to call the createMyAsset smart contract. (Showing only the relevant lines of code)

import org.hyperledger.fabric.gateway.Contract;
import org.hyperledger.fabric.gateway.ContractException;

public class AssetFabricRepository {

    private Contract contract;

    public void createAsset(Asset asset) {
        try {
            byte[] result = getContract().createTransaction("createMyAsset")
                    .submit(asset.getId(), asset.getManufacturer()
                            , asset.getManufactureDateTime(), asset.getExpiryDate(),
                            asset.getStatus(), asset.getOwner());
            log.info("Created transaction : {}", result);
        } catch (ContractException | InterruptedException | TimeoutException e) {
            log.error("Exception while submitting transaction", e);
        }
    }

    private Contract getContract() {
        if (contract != null) return contract;

        contract = GatewayConfig.get()
                .getNetwork("mychannel")
                .getContract("smart-contract");
        return contract;
    }
}

The GatewayConfig class mentioned above, is a class that handles the connections to the blockchain network. See the github repo for more details on this class.

Conclusion

Hope this basic introduction to blockchains and hyperledger will encourage you to get your feet wet into the world of blockchain. This technology is getting more mainstream and more use cases for it are being discovered. The day is not far when blockchains could become as ubiquitous as the relational database.


Comments