DeBio Techstack

As mentioned, DeBio aim to revolutionize the current biomedical industry by giving patients full sovereignty over their data using the most cutting-edge blockchain technologies. We believe that the future of medical data relies partly on the use of blockchain, especially in the specialization of technology use cases as well as interoperability.

To guarantee patient sovereignty over their data, our entire tech stack consists of decentralized solutions ranging from decentralized authentication to decentralized file storage. We have incorporated a slew of cutting-edge technologies in our solution, including but not limited to:

Polkadot

Polkadot enabling developers to build purposeful blockchains by allowing specialized blockchains to communicate between different blocks and applying stricter security standards of the host relay chain. We build our core services using Polkadot so the security of our distributed ledger improve.

  • Generate Account

    • Keyring

      Keyring will allows us to manage a set of keys in a consistent environment, that allows to perform operations on these keys (such as sign/verify). Keyring is responsible for managing a set of keypairs. As such the only function it has it to allow adding and removing pairs to an interface. Each pair in itself is a specific account and on each of these accounts you can perform functions such as signing, verification and encryption/decryption of the account.

      To create the keyrings, after installation, import and create it with ed25519 type.

    • Create Account

      Create an account with the specified mnemonic, encrypt the account with the password and attach some metadata to the account. It returns a pair instance as well as the encrypted json as is saved to the store.

      import { mnemonicGenerate } from "polkadot/util-crypto"
      
      ...
      // generate a random mnemonic, 12 words in length
      const mnemonic = mnemonicGenerate(12);
      
      // add the account, encrypt the stored JSON with an account-specific password
      const { pair, json } = keyring.addUri(mnemonic, "myStr0ngP@sswoorD", {
      	name: "mnemonic acc"})
  • Chain State and Extrinsics on Polkadot-provider

    DeBio team developed a Javascript Library to connect and interact with the DeBio Network blockchain, namely @debionetwork/polkadot-provider. It was build to make it easier to develop a project without having to re-create the functions repeatedly.

    Polkadot-provider contain all the functions we need to get all chain state and extrinsics in API. When the API connects to a node, one of the first things it does is to retrieve the metadata and decorate the API based on the metadata information.

    The metadata effectively provides data in the form of api.<type>.<module>.<section>

    On DeBio Network Blockchain, we use following categories:

    • query - All chain state, e.g. api.query.system.account(<accountId>).

    • tx - All extrinsics, e.g. api.tx.balances.transfer(<accountId>, <value>).

    API Creation

    The API creation is done via the ApiPromise.createinterface and then waiting until its connected. API stored in Vuex store

    import { ApiPromise } from "@polkadot/api"
    async connect () {
    	const api = await ApiPromise.create({ provider: wsProvider })
    	await api.isReady
      commit("SET_API", api)
    }

    As we use @debionetwork/polkadot-provider, we have to send the API as parameter to @debionetwork/polkadot-provider. Example below:

    import { queryAccountBalance } from "@debionetwork/polkadot-provider"
    import { mapState } from 'vuex'
    
    export default {
      computed: mapState({
        api: state => state.api
        }
      })
    }
    
    async getBalance () {
    	const address = "5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE"
    	const balance = await queryAccountBalance(this.api, address)
    }

  • Events

    Additionally the metadata also provides information on events. Below are how we got the events on DeBioNetwork, we also store this event in Vuex store

    api.query.system.events((events) => {
    	events.forEach((record) => {
    	const { event } = record
    	if (allowedSections.includes(event.section)) {
    		commit("SET_LAST_EVENT", event)
    	}
    })

Metamask & Ethereum Smart Contract

Metamask

MetaMask is a cryptocurrency wallet that enables users to store Ether and other ERC-20 tokens. DeBio use Metmask to pay order, and user need to install Metamask extension on the browser.

DeBio Demo runs on Rinkeby Test Network, while the mainnet is runs on Ethereum Mainnet.

Here is the tutorial of How to get Free Testnet Token on Rinkeby.

Below is to verify if the browser is running MetaMask.

import detectEthereumProvider from "@metamask/detect-provider"
const provider = await detectEthereumProvider()

if (provider) {
	if (provider !== window.ethereum) {
	  throw "Do you have multiple wallets installed?"
  }
	return connectToMetamask()
} else {
	console.log("Please install MetaMask!")
	return { currentAccount: "no_install" }
}

Ethereum Smart Contract

Smart contract is program runs on the Ethereum blockchain. It's a collection of code and data that resides at a specific address on the Ethereum blockchain. It is not controlled by a user. A smart contract deployed to the network and run as programmed. Then user can interact with it by submitting transactions that execute a function defined on the smart contract. Smart contracts can define rules, like a regular contract, and automatically enforce them via the code.

Smart contracts have balance and can send transaction over network. They locks the number of tokens required to pay. On DeBio payment from customer to Lab is lock in escrow smart contract until lab complete the test and send the result to customer.

How to interact with Ethereum Smart Contract ?

To interact with Ethereum Smart Contract, install web3 library firsts ‌that is used to make requests to Ethereum chain.

$ npm install web3

Perform operation need the address that the contract was deployed to and the contract’s Application Binary Interface(ABI). ABI is the interface that specifies how to interact with a specific Ethereum contract. Below is how DeBio send the transaction to Ethereum Smart Contract

const Escrow = require("./abi/Escrow.json")
import Web3 from "web3"
import contracts from "./contracts"

async sendTransaction(to, data, from) {
  const transactionParameters = {
    to: to, // Required except during contract publications.
    maxFeePerGas: "2000000000",
    maxPriorityFeePerGas: "1000000000",
    from: from, // must match user's active address.
    data: data, // Optional, but used for defining smart contract creation and interaction.
    chainId: "0x4" // Used to prevent transaction reuse across blockchains. Auto-filled by MetaMask.
  }

  const txHash = await window.ethereum.request({
    method: "eth_sendTransaction",
    params: [transactionParameters]
  })
  return txHash
}

const ethAccount = "0xdCad3a6d...1D3AF"
const contractAddress = "0xdCad3a6d...3E6DD"
const contract = new web3.eth.Contract(Escrow.abi, contractAddress)
const txData = EscrowContract.methods.payment()
const txHash = await sendTransaction(contractAddress, txData, ethAccount)

Kilt

Kilt is a blockchain protocol for creating, attesting, and verifying identities anonymously on Web3. We use Kilt to encrypt-decrypt our users data to prevent genetic data misuse, privacy and security violations, and the practice of selling genetic data without consent.

We use Kilt to secure our user authentication and also to send the user’s genomic data and results to IPFS.

Installation:

$ npm install @kiltprotocol/sdk-js
  • BoxKeyPair

In this process we are need public key and secret key to check the user credentials. As we sending the data between two users. Below is the example of how to get the keys.

import Kilt from "@kiltprotocol/sdk-js"
import { u8aToHex } from "@polkadot/util"

const mnemonic = "crack glass claw illegal parroDecryption k buddy nephew slim red write weird"
const identity = Kilt.Identity.buildFromMnemonic()
publicKey = u8aToHex(identity.boxKeyPair.publicKey)
secretKey = u8aToHex(identity.boxKeyPair.secretKey)
  • Encryption

To encrypt the file, we will need customerSecretKey and labPublicKey

import Kilt from "@kiltprotocol/sdk-js"

 async encrypt () {
		const text = "data text"
		const labPublicKey = "string"
		const customerSecretKey = "string"
		const encrypted = await Kilt.Utils.Crypto.encryptAsymmetric(text, labPublicKey, customerSecretKey)
  }
  .then(() => {
	   console.log("Encrypted")
  })
  .catch(console.error)
  • Decryption

To decrypt the file, we will need labSecretKey and customerPublicKey

import Kilt from "@kiltprotocol/sdk-js"

async decrypt () {
	const data = "data"
	const labSecretKey = "string",
	const customerPublicKey = "string"
	const decrypted = await Kilt.Utils.Crypto.decryptAsymmetric(data, customerPublicKey, labSecretKey)
}
.then(() => {
	console.log("Decrypted")
})
.catch(console.error)

IPFS Pinata

The InterPlanetary File System(IPFS) is decentralized, peer to peer file storing and sharing system. It was created a solution for decentralized projects that want to store an amount of data that is too large to be stored in the blockchain itself.

IPFS creates unique content addresses by hashing the content itself. Each unique content will have a different address pointing to its location. DeBio implements IPFS into our solution to store biomedical data such as encrypted human genomes and encrypted electronic medical records.

Additionally, we choose to use Pinata dedicated gateway to ensure the process of store and serve files on IPFS is as fast as possible, as no rate-limiting.

To simplify how the App interact with the Pinata API, we use @debionetwork/pinata-ipfs

import { uploadFile as pinataIpfsUploadFile } from "@debionetwork/pinata-ipfs"

const pinataKey = "pinatasecretkey"
export const uploadFile = val => {
  const options = {
    pinataMetadata: {
      name: val.title,
      keyvalues: {
        required: process.env.PINATA_DOCUMENT,
        type: val.type,
        fileSize: val.size,
        date: +new Date()
      }
    },
    pinataOptions: { cidVersion: 0 }
  }

  return pinataIpfsUploadFile( options, val.file, pinataKey)
}

export const getFileUrl = cid => {
  return `${process.env.PINATA_GATEWAY}/${cid}`
}

Backend API

DeBio Frontend use Axios to communicate with Backend API

Installation:

$ npm install axios

Setup Connection:

const baseURL = "<http://localhost:3000/>"
const apiClientRequest = axios.create({
  baseURL,
  headers: {
    "Content-Type": "application/json",
    "debio-api-key": "string"
  },
  auth: {
    username: "username",
    password: "password"
  }
})

Last updated