Digital Asset SDK sample - Track and Trace

This application sample illustrates the creation of a digital asset and the transfer of this asset between different owners.

The track and trace application sample involves multiple operations:

  • the manufacturer creates a digital asset (the car)
  • the manufacturer transfers the ownership of the car to Alice
  • Alice transfers the ownership of the car to Bob
  • Bob transfers the ownership of the car to Charlie
  • the asset history of the car is fetched
  • the transaction history of each person along with the metadata is fetched.

This flow is illustrated by the following diagram:

2Diagram_TrackTrace

In addition to retrieving the asset and transaction history, the sample contains two important functions:

  • Create a digital asset
  • Transfer a digital asset

You can see the source code (Javascript) of the sample here.

Run the sample application

In a terminal session, run the track and trace sample found in folder ng-rt-digitalasset-sdk-sample:

node ng-rt-digitalAsset-sdk-samples/examples/usecases/track_and_trace.js

(alias: track)

You should see output similar to this:

[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace -
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Car Manufacturer : AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Alice : 5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Bob : BRNtziit59DUra7xLdfNGux2rvXJsrKQ1HsJs5kF1vnE
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace -
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - CREATE transaction id : f2e91d7e8c16dcc10f08c82b97a65defeffd2723e4e7b7a8dfe7e21042b900a0
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - f2e91d7e8c16dcc10f08c82b97a65defeffd2723e4e7b7a8dfe7e21042b900a0
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - TRANSFER 1 transaction id: 0e9fc1025211fb89aa2bc4505bd80c5ff1f99f40b2db77d8f17bc9f5f1dc0333
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - 0e9fc1025211fb89aa2bc4505bd80c5ff1f99f40b2db77d8f17bc9f5f1dc0333
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - TRANSFER 2 transaction id: a18c1661e8f1462032f056fe836998e359759d4c68b64acb9e90bfe7aaa8d283
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - a18c1661e8f1462032f056fe836998e359759d4c68b64acb9e90bfe7aaa8d283
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Current owner of asset is :BRNtziit59DUra7xLdfNGux2rvXJsrKQ1HsJs5kF1vnE
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Asset history of car asset:
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - 3 entries
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace -
[ { from: [ 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh' ],
to: [ 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh' ],
amount: 1,
timestamp: 1570439165728 },
{ from: [ 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh' ],
to: [ '5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm' ],
amount: 1,
timestamp: 1570439167533 },
{ from: [ '5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm' ],
to: [ 'BRNtziit59DUra7xLdfNGux2rvXJsrKQ1HsJs5kF1vnE' ],
amount: 1,
timestamp: 1570439169382 } ]
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Tx history of manufacturer:
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - 2 entries
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - [ { direction: 'out',
from: [ 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh' ],
to: [ '5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm' ],
amount: 1,
assetType: 'tendermint_blob',
timestamp: 1570439167533 },
{ direction: 'create',
from: [ 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh' ],
to: 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh',
amount: 1,
assetType: 'tendermint_blob',
timestamp: 1570439165728 } ]
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Tx history of alice:
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - 2 entries
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - [ { direction: 'out',
from: [ '5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm' ],
to: [ 'BRNtziit59DUra7xLdfNGux2rvXJsrKQ1HsJs5kF1vnE' ],
amount: 1,
assetType: 'tendermint_blob',
timestamp: 1570439169382 },
{ direction: 'in',
from: [ 'AFkteNvJ5YMaxsRsKwB7DkhY15wKWgTgUvqVxsJSB2Lh' ],
to: '5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm',
amount: 1,
assetType: 'tendermint_blob',
timestamp: 1570439167533 } ]
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - Tx history of bob:
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - 1 entries
[INFO] ng-rt-digitalAsset-sdk.examples.business.track_and_trace - [ { direction: 'in',
from: [ '5WdzA2u3JthYCpQFgy9tWGK5vydXoNHVuTxHeHxAh5Hm' ],
to: 'BRNtziit59DUra7xLdfNGux2rvXJsrKQ1HsJs5kF1vnE',
amount: 1,
assetType: 'tendermint_blob',
timestamp: 1570439169382 } ]

To understand the output, click here.

Functions

The section below describes the code contained in the sample application and SDK that has been cloned to your local development machine.

Create a digital asset

This composite function createDigitalAsset is used when the manufacturer creates the digital asset (the car):

const createTxResult = await digitalAssetDriver.createDigitalAsset(txContext, carAsset, amount, carAssetMetadata, manufacturer.publicKey, manufacturer.privateKey);

This function is a composite function; it contains a number of simpler functions that carry out a single action.

Here, the creation of the digital asset actually comprises three single functions:

  • composeDigitalAssetCreateTx : creation of the data structure of the transaction
  • signTx : signing of the transaction by the owner of the asset
  • postSignedCreateTx : posting of the transaction to the server (blockchain)

Example:

const createDigitalAsset = async (txContext, asset, amount, txMetadata, ownerPublicKey, ownerPrivateKey) => {
const createTx = await composeDigitalAssetCreateTx(asset, amount, txMetadata, ownerPublicKey);
const signedTx = await signTx(createTx, ownerPrivateKey);
return daApi.postSignedCreateTx(txContext, signedTx, ownerPublicKey, getSdkInfo());

Transfer a digital asset

The function transferDigitalAsset is used when the manufacturer of the digital asset (the car) transfers ownership to Alice:

const transfer1TxResult = await digitalAssetDriver.transferDigitalAsset(txContext, createTransactionId,
carAssetMetadata, manufacturer.publicKey, manufacturer.privateKey, alice.publicKey);

Similar to createDigitalAsset, there are also three single functions:

  • composeDigitalAssetTransferTx : creation of the data structure of the transaction
  • signTx : signing of the transaction by the owner of the asset
  • postSignedCreateTx : posting of the transaction to the server (blockchain)

Example:

const transferDigitalAsset = async (txContext, unspentTransactionId, txMetadata, senderPublicKey, senderPrivateKey, receiverPublicKey) => {
const transferTx = await composeDigitalAssetTransferTx(txContext, unspentTransactionId, txMetadata, receiverPublicKey);
const signedTx = await signTx(transferTx, senderPrivateKey);
return daApi.postSignedCreateTx(txContext, signedTx, ownerPublicKey, getSdkInfo());

In both composite functions, the creation of the data structure for the transaction, the signing of the transaction, and the posting of the transaction takes place on the client side.

Customize a composite function

Generally speaking, you can run the sample track_and_trace without modifying the code if all these functions take place on the client side.

However, a number of use cases may require the modification of the functions within.

As an example, your use case requires the signing of the transaction on the server when you create a digital asset.

Here, you can simply remove the function signedTx from the call. As well, replace the function postSignedCreateTx with postUnsignedCreateTx to send an unsigned transaction to the server:

const createDigitalAsset = async (txContext, asset, amount, txMetadata, ownerPublicKey, ownerPrivateKey) => {
const createTx = await composeDigitalAssetCreateTx(asset, amount, txMetadata, ownerPublicKey);
return daApi.postUnsignedCreateTx(txContext, signedTx, ownerPublicKey, getSdkInfo());

Next Steps

Run another sample application here.
Access the database to see a record of all the transactions in this sample. Find out more here.

Return to Sample Applications