Lisk Smart Transport: NFC and Blockchain in Supply Chains
A major challenge in many blockchain solutions is to securely connect physical actors or objects to their digital representation in the blockchain. Some obvious examples are supply chain and anti-counterfeiting solutions, where digital information pertaining to the production, origin, chain of custody, or shipping conditions is immutably secured in the blockchain.
In most solutions, public/private key pairs representing digital and physical actors, machines, or goods are remotely managed in remote or cloud server back-ends. As ownership, identification, and trust in blockchain solutions are conveyed through the control of private keys, remote key management systems pose an expensive and laborious affair at best, and a serious security risk at worst. Thus, moving the key management process closer to the objects of interest not only saves valuable resources; it adds a significant layer of trust to the solution.
In this article, we describe how smart card NFC chips with blockchain capacities can be used for more secure key management in blockchain solutions, and specifically in solutions built with the Lisk SDK and JavaScript. Firstly, we briefly describe the technology that Gimly uses for this purpose. Secondly, we describe the Smart Transport proof-of-concept that was built by Marc Buma and Caspar Roelofs and that was funded through the Lisk Builders program. Finally, we dive a little bit deeper into the code, to show in more detail how the microchips interact with the Lisk blockchain in our JavaScript code base.
Tangem by Gimly: Made for Blockchain NFC chips
Gimly works with Tangem as supplier and implementation partner, to provide a new approach towards a more secure management of public/private key pairs in blockchain solutions. Tangem’s made-for-blockchain NFC smartcard chips are EAL6+ certified, containing a secure element where the keypairs are newly generated and from which the private key cannot be extracted, exposed, or copied. The chip’s firmware enables the use of these self-contained keys to sign blockchain transactions directly from the chip, and to sign, store and present encrypted data using its secure storage. Chip operations are protected by means of various security options (incl 2FA, passcodes, and multiple PIN options), and the firmware is independently audited by Kudelski security firm.
The chips are available in various form-factors, including durable physical creditcard format, adhesive stickers, or tags. The physical card format is currently available as pre-provisioned crypto-notes for all major cryptocurrencies, or as developer cards that can be provisioned to work with any blockchain that uses either secp256 or ed25519 cryptographic curves – including Lisk.
Lisk builders: Smart Lisk transport PoC
The Smart Lisk Transport PoC uses a Tangem smartcard to demonstrate how a hardware wallet can be used to secure a package using the Lisk SDK. In this demonstration, a new client application has been developed for the Lisk Transport demo that uses an NFC reader to communicate with a Tangem smartcard.
In the demo, we assume that the smartcard is part of a smart container, i.e. a container secured with its own hardware wallet that is used to sign all measurements of the temperature and alarm conditions that the container reports. During the transport, all parties connected to the transport, (client, supplier, and recipient) can determine the public key for the smart container and thus verify that the received data actually originates from this transport.
When the smart container is prepared for a new transport, a new account is created on the smartcard that is unique for this transport. This account is automatically funded with some LSK in order to be able to autonomously submit transactions.
While the transport is ongoing, all transactions that originate from the smart container (measurements, alarms) are signed by this account, thus proving their origin and authenticity.
Once the transport is finished, surplus LSK from the account is returned and the account is erased. Now the smart container can be used for a new transport.
The demo adds the following elements to the Lisk Transport example:
- A driver for PC/SC compatible smartcard readers. In our demonstration, we use an ACS ACR1252 reader. This driver is used to poll the smartcard reader.
- A driver for the Tangem protocol. This driver implements all functions that are required to make the steps above possible (create wallet, purge wallet, sign transaction hashes using the smartcard).
- Implementation of the register-measurement custom transaction.
- A new client application that is used to start and finish the transport and that can be used to simulate measurements.
- A new IoT application that uses the smartcard reader to sign simulated temperature measurements.
- Visualisation of temperature data stored on the blockchain during the transport.
Hands-on with the demo
Since this demo builds on the Lisk Transport workshop, you should at least proceed to step 0 (Workshop Part 0: Installation and Setup) before starting. At this point, you should have a running blockchain with all prerequisites installed.
In addition, you should make sure that the proper PC/SC drivers for your NFC reader have been installed.
Now you can clone the sources of the demo to a folder on your hard disk. The repository can be found here.
The project root for the next steps is located in the gimly-transport folder.
The demonstration will use 3 terminal windows:
- One window running the blockchain
- Navigate to the project root
- Install the node dependencies in the transactions folder
* cd transactions * npm install
- Install the node dependencies in the tangem-smart folder
- cd ../tangem-smart
- npm install
- Next, navigate into the node folder and start the blockchain
- cd ../node
- npm install
- node index.js | npx bunyan -o short
- One window running the client application
- navigate to the project root
- cd client
- npm install
- node app.js
- One window running the iot application
- navigate to the project root
- cd iot/temperature_and_humidity
- npm install
- node index.js
Now you can connect to your laptop to view the client application by opening http://localhost:3000 in your web browser
Step 1: Place smartcard on the NFC reader
Select one of the smartcards and put it on the reader. Now press refresh. The application will recognize the card and allow you to create a new shipment. If the smartcard is already in use, it will show the status of the current transport (step 3, 4 or 5, depending on the transport status)
Step 2: Create shipment
First select one of the demo accounts as sender for this package. Make sure that the sender has sufficient funds, otherwise creation of the shipment will fail. (You can use the fund button to acquire some LSK from the faucet).
Next, select the recipient and set the transport conditions (postage and security). Keep the trust level at 0 for your first transport. As you simulate more transport, the trust level of the employed carrier will increase.
Finally, press create to create the shipment. Keep an eye on the terminal window for the client to see what is happening:
- First, a new wallet account is created on the smartcard.
- Next, the wallet receives some funds from the faucet with a transfer transaction.
- Finally, the new shipment is registered on the blockchain with a register-packet transaction.
When these actions are completed, browser will notify you. Press back to return to the main page
Step 3: Start transport
First make sure that the carrier has sufficient funds to pay the security. (You can use the fund button to acquire some LSK from the faucet).
Next press start transport, A start-transport transaction is now sent to the blockchain. When the transaction has been sent, the browser will notify you. Press back to return to the main page.
Step 4: Track transport & add measurements
While the transport is ongoing, the iot process in the separate window will start adding simulated temperature measurements to the shipment every 15 seconds. Look at the output in the iot terminal window and the in blockchain window to check.
Before committing a measurement to the blockchain, a hash of the measurement data record is calculated and sent to the smartcard. The smartcard uses its private key to sign the transaction. Next the signature is added to the transaction and the transaction is committed to the blockchain.
When you press the yellow refresh button in the browser window, you can see the measurements appear in the graph.
Step 5: Finish transport
Finally, the recipient can select an end status for the shipment and finish the transport.
Step 6: Reset Smart container
Once the shipment is finished, you can reset the smart package. Now the funds remaining in the smart wallet account are sent back to the faucet and the account is erased from the card.
You can now re-use the card for the next shipment.
Tech deep dive: Looking @ the code starting point
Below, program code from the original lisk transport example is shown for a transaction that is processed using the Lisk SDK. It is part of the application that runs on the sensor module. After detecting that the package has been opened, the sensor module stores a new alarm transaction on the blockchain.
In this code example, a new LightAlarmTransaction is created (#27), signed using the transaction’s sign method (#35) and then broadcast to the network (#37). Signing is done using a passphrase that is stored in local memory.
In the transport demo, the packetCredentials account that signs the transaction is created using the client app and subsequently hardcoded in the program code.
In our version of the project, credential management is transferred to the smartcard. This makes the key management more secure and adds an extra level of provenance to the data committed to the blockchain.
Since the smartcard is an external device, some means of communication are required. In this case, messages to the card are sent using an NFC radio connection. In this post, we focus on the blockchain side of the code, but if you are interested in the inner workings of NFC communication using an USB NFC card reader and the implementation of the required methods of the tangem protocol, you can find these in the tangem-smart sub folder. In the tangemcard.js module, three important methods have been implemented:
- createWallet: this method creates a new generic wallet account on the smartcard. The public key from this account is used to generate an address on the lisk transport sidechain
- signData: this method is used to signs a hash or to hash and sign a packet of binary data using the private key stored on the smartcard
- purgeWallet: this method permanently erases the wallet account stored on the smartcard
Creating a wallet on the smartcard
Before the smartcard can be used for transaction signing, a new wallet needs to be created on the smartcard and some funds need to be sent to this wallet. Once this is done, the address for the wallet needs to be registered as a valid package account on the blockchain.
The process starts (see Step 2: Create shipment above) when the user places a blank smartcard near the NFC reader (ie. a smartcard without a wallet), fills in the transport conditions and presses the create button. This causes a function call on the handlerRegisterSmartPackage function. The code for this function is found in the handlers.js file in the client folder.
The process starts at line #40. A call to createWalletUsingActiveCard initializes a new wallet on the smart card. A wait loop on line #45 is required because it takes a while for the new wallet to be detected by the application: variable currentPacketID receives the wallet address.
An interesting bit of code related to this can be seen in the handlers.js file in the client folder.
This checkReader function is called periodically in the background using setTimeout. In this function, the NFC card reader is polled (line #5) and the activeCardData is retrieved. If a wallet is present on the card, the generic wallet public key is converted to a blockchain address using the getAddressFromPublicKey function from the Lisk SDK cryptography library.
The process in the handlerRegisterSmartPackage function now continues at line #55 where some funds are sent to the card. These funds are required when submitting transactions that are signed by the wallet on the card to the blockchain.
Again, a wait loop is entered (line #61) that halts until the account associated with the smartcard wallet has been located on the blockchain.
The getAccount function (from functions.js#49) implements this with a call to the lisk SDK (line #5).
Finally, at line #76 in the handlerRegisterSmartPackage function, a registerPackageTransaction is instantiated and signed by the package sender (line #93).
After broadcasting this transaction to the blockchain network, package registration is complete and the function exists. Once the transaction is committed to the blockchain, a valid package account with initial funds now exists on the smartcard.
Signing measurement data
After starting the transport (not described here), the sensor starts collecting data and committing this data to the blockchain using a register-measurement custom transaction on the sidechain. To prove the origin of the data, each package of measurement data is signed using the wallet on the smartcard. This is demonstrated in the
The important part of the register-measurement custom transaction is shown below:
While the transport is ongoing (line #10) new (simulated) measurements are stored in the measurements array in the packet’s asset structure (line #15). The client application visualizes these measurements in a graph on the smart package page. (see above at Step 4: Track transport & add measurements)
A demonstration of usage of this transaction is found in the temperature_and_humidity app. This is code that runs inside of the sensor module and is called periodically to measure the transport conditions. In this case, to be able to demonstrate the principle without actual hardware, the measurements are simulated. This can be seen here:
As already illustrated above, the active smartcard data is retrieved at line #21. Temperature data is generated at line #38 and stored in a measurement record at line #52. Next a RegisterMeasurementTransaction is instantiated.
Now things start working differently when compared to using a local wallet account.
At line #71, the transaction is converted to a byte array and a prefix consisting of the network identifier is added. The hash of this array of bytes is calculated at line #77 (using the hash function from the cryptography library in the Lisk SDK).
This hash is sent to the smartcard for signing using the signDataUsingActiveCardfunction. The returned signature is added to the transaction (line #79).
Finally, and id for the transaction is calculated (line #85) and the transaction is broadcast to the blockchain network (line #87)
Erasing the wallet on the Smartcard
Once the transport is complete, the wallet on the smartcard can be erased so that the card can be used for a new transport. This is done with a call to the purgeWalletfunction in the tangemcard library as depicted below. This function provides a good illustration on how the communication with the smartcard works under the hood:
At line #35, a request is transmitted to the smartcard reader. This request is a byte array that is composed by joining a number of data structures (line #24 and line #34) such as the card id (line #2), two hashed pin codes (line #22, 23) and command data (#26). After the command has been processed by the card, the returned data structure (response, line #35) is decoded to determine if the request was processed successfully.
In this case, command code 0xFC (line #28) tells the smart card that a purge wallet command is requested.
Lisk builders
This project was initiated by Caspar Roelofs who secured a Lisk Builders grant to enable the use of smartcard chips for private key management in Lisk blockchain solutions. As a founder of Gimly Blockchain Projects, he helps clients leverage blockchain, IoT and other new technologies for their business needs. Gimly believes that meaningful innovation is achieved through synergies, and maximalizes collaboration to build on the strengths of clients, partners, and community. Consultancy and development services include end-to-end product development, solutions architecture, technology, product and market research, product management, and business development.
Marc Buma joined the project as lead developer, with his expertise in IoT, blockchaina and javascript development. Marc started his career as R&D engineer at Noldus Information Technology and worked on the development of automated behavior measurement systems, and is self employed (Company name Bumos) since 2004. Worked on broadcast innovation projects with Jetix, Disney, MTV, KPN and the Netherlands Institute for Sound and Vision. He has a solid background in developing industrial strength systems. Currently, he is developing and maintaining bespoke products for hospitality onboard luxury yachts, blockchain based decentralized logistics tracking systems in the fashion industry, VR guided tours. Marc is active as mentor / technical advisor for several startups and projects in the blockchain and logistics sphere.
Working with Tangem by Gimly
If you are interested to use the technology in your own projects, visit gimly.io/tangem-by-gimly to find out how to obtain a trial kit, or reach out here if you are looking for higher volumes of customized cards, stickers or tags with custom design and wallet for your cryptocurrency.