Use Node-RED to create the track and trace sample application

Consult this tutorial for a step-by-step tutorial on how to build the track and trace sample application flow in Node-RED.

Video

This video provides a step-by-step tutorial on how to build the track and trace sample application flow in Node-RED.

GCP_BuildSampleApplications

Introduction

Note that this tutorial is based on the track and trace sample application.

In this article, we will create and deploy the track and trace sample application in Node-RED.

Specifically, this single flow will be divided into three main parts:

  1. the creation of different public keys for the different entities
  2. the creation and transfer of a digital asset between the different entities. 
  3. obtaining the asset history and transaction history for each entity.

To begin, log into the Node-RED UI of your TBSP running instance.

Required Nodes

This flow involves the following TYMLEZ digital asset nodes:

  • Generate keypair

Screen Shot 2020-05-18 at 10.37.30 AM

  • Set txContext

Screen Shot 2020-05-18 at 10.37.53 AM

  • create digitalAsset

Screen Shot 2020-05-18 at 11.16.12 AM

  • transfer digitalAsset

Screen Shot 2020-05-18 at 10.38.19 AM

  • get owner of Asset

Screen Shot 2020-05-18 at 10.58.01 AM

  • get asset history

Screen Shot 2020-05-18 at 10.38.37 AM

  • get transaction history

Screen Shot 2020-05-18 at 10.38.54 AM

  • appLogin

Screen Shot 2020-05-18 at 10.38.00 AM

The entire flow should look like this:

Screen Shot 2020-05-18 at 11.27.43 AM

Let's create this flow, one node block at a time.

Part 1: Create the public keys for the car manufacturer, Alice and Bob

In this section, we will create the different entities involved in the transaction: the car manufacturer, Alice and Bob.

As well, we'll add the appLogin node to require authentication by the Digital Asset application key to run the flow.

  • In the Node-RED UI, create a new flow called Track:

Screen Shot 2020-05-18 at 3.42.06 PM

  • Add a http node from the left-side panel to the blank canvas:

Screen Shot 2020-05-18 at 5.13.39 PM

Open the newly added node and enter the following parameters:

GET
/trackAndtrace
trackAndTrace
  • Add a function node to the canvas and name it read Appkey. Give it 2 outputs:
Screen Shot 2020-05-26 at 10.54.53 AM

Open the node and enter the following parameters:

msg.appKey = msg.req.query.appKey;

if (msg.appKey === "" || msg.appKey === "your_appkey_here"){
msg.payload = {
state: false,
message: "Add the appKey in the config..."
};
return [msg, null]
}else{
return [null, msg]
}
  • Add a rollback node to the canvas:

Screen Shot 2020-05-18 at 5.51.30 PM

  • Add a generateKeyPairs node for the manufacturer:

Screen Shot 2020-05-18 at 5.55.12 PM-1

Open the node and enter the following parameters:

Name: Manufacturer KeyPair
variable: manufacturer
  • Add a generateKeyPairs node for Alice:

Screen Shot 2020-05-18 at 5.59.37 PM-1

Open the node and enter the following parameters:

Name: Alice Keypair
variable: alice
  • Add a generateKeyPairs node for Bob:

Screen Shot 2020-05-18 at 5.59.46 PM-1

Open the node and enter the following parameters:

Name: Bob KeyPair
variable: bob
  • Add a txContext node to the canvas:

Screen Shot 2020-05-18 at 6.00.37 PM-1

Select tendermint_blob as the asset type.

  • Add an appLogin node to the canvas. This node ensures that only the flow can only be executed if the user has a valid application key for the Digital Asset plugin.

Screen Shot 2020-05-19 at 11.29.27 AM

  • If you want to manually trigger the flow, begin by adding a inject node to the canvas:

Screen Shot 2020-05-19 at 10.03.38 AM-1

  •  Add a function node to the canvas. Name it Add digital asset AppKey here:
Screen Shot 2020-05-19 at 12.05.15 PM

Open the node and add the digital asset app key from your running instance:

msg.appKey = "<YOUR_DIGITAL_ASSET_APP_KEY_HERE>";

return msg;
  • Link all nodes together, and proceed to part 2. You have now created the app keys for the different entities. 
Screen Shot 2020-05-19 at 10.15.45 AM

Part 2: Create a new asset and transfer the asset 

In this section, you will create a digital asset, a car, and transfer the asset between different entities.

  • Add a function node and name the node create the car asset owned by Manufacturer. Open this node and enter the following:
const carAsset = {
type: "Car",
carSerialNo: "1234449890"
};

const carAssetMetadata = {
registrationDate: new Date("2015-03-25")
};

const amount = "1";

msg.txContext.txMethod = "Commit";
msg.txContext.digitalAssetType = "sample_car";

msg.carAssetMetadata = carAssetMetadata;

msg.payload={
txContext: msg.txContext,
amount,
txMetadata:carAssetMetadata,
digitalAssetData:carAsset,
publicKey:msg.manufacturer.publicKey,
privateKey:msg.manufacturer.privateKey
}

return msg;
  • Add a createDigitalAsset node:

Screen Shot 2020-05-19 at 2.47.06 PM

  • Add a new function node and name the node transfer the car asset from manufacturer to Alice. Open this node and enter the following:
console.log("CREATE transaction id : ",msg.payload);

msg.createTransactionId = msg.payload;

console.log("Transfer to Alice...");

txContext = msg.txContext;
createTransactionId = msg.createTransactionId;
carAssetMetadata = msg.carAssetMetadata;
manufacturerPublicKey = msg.manufacturer.publicKey;
manufacturerPrivateKey = msg.manufacturer.privateKey;
alicePublicKey = msg.alice.publicKey;

msg.payload={
txContext,
unspentTransactionId: createTransactionId,
txMetadata: carAssetMetadata,
publicKey: manufacturerPublicKey,
privateKey: manufacturerPrivateKey,
receiverPublicKey: alicePublicKey
}

return msg;
  • Add a transferDigitalAsset node:

Screen Shot 2020-05-19 at 3.18.35 PM

  • Add a new function node and name the node transfer the car asset from Alice to Bob:
Screen Shot 2020-05-19 at 3.45.17 PM
Add the following information to the node:
console.log("TRANSFER 1 transaction id: ",msg.payload);

msg.transfer1TransactionId = msg.payload;

console.log("Transfer to Bob...");

txContext = msg.txContext;
transfer1TransactionId = msg.transfer1TransactionId;
carAssetMetadata = msg.carAssetMetadata;
alicePublicKey = msg.alice.publicKey;
alicePrivateKey = msg.alice.privateKey;
bobPublicKey = msg.bob.publicKey;

msg.payload={
txContext,
unspentTransactionId: transfer1TransactionId,
txMetadata: carAssetMetadata,
publicKey: alicePublicKey,
privateKey: alicePrivateKey,
receiverPublicKey: bobPublicKey
}

return msg;
  • Add a transferDigitalAsset node.

Part 3: Obtaining the asset history and transaction history of each entity

  • Add a new function node and name the node get the current owner of the car asset:

Screen Shot 2020-05-19 at 3.53.24 PMOpen this node and enter the following:

console.log("TRANSFER 2 transaction id: ",msg.payload);

msg.transfer2TransactionId = msg.payload;

console.log("get the current owner of the car asset");

txContext = msg.txContext;
createTransactionId = msg.createTransactionId;

msg.payload={
txContext,
assetId:createTransactionId
}

return msg;
  • Add a get-owner-of-asset node:
Screen Shot 2020-05-19 at 4.02.43 PM
  • Add a new function node and name the node Asset history of car asset:
Screen Shot 2020-05-19 at 4.04.35 PM-1
Open this node and enter the following:
msg.assetOwner = msg.payload;

console.log("Asset history of car asset:",msg.payload);

txContext = msg.txContext;
createTransactionId = msg.createTransactionId;

msg.payload={
txContext,
assetId:createTransactionId
}

return msg;
  • Add an get-asset-history node:

Screen Shot 2020-05-19 at 4.14.39 PM

  • Add a new function node and name the node get the transaction history of the manufacturer

Screen Shot 2020-05-19 at 4.23.49 PM

Open this node and enter the following:

msg.assetHistory = msg.payload;
console.log("Asset history of car asset:",msg.payload);

txContext = msg.txContext;
manufacturerPublicKey = msg.manufacturer.publicKey;

msg.payload={
txContext,
publicKey:manufacturerPublicKey
}

return msg;
  • Add a get-transaction-history node:

Screen Shot 2020-05-19 at 4.27.22 PM

  • Add a new function node and name the node get the transaction history of Alice:

Screen Shot 2020-05-19 at 4.29.31 PM

Open this node and enter the following:

msg.txHistoryOfManufac = msg.payload;

console.log("Tx history of alice:",msg.payload);

txContext = msg.txContext;
alicePublicKey = msg.alice.publicKey;

msg.payload={
txContext,
publicKey:alicePublicKey
}

return msg;
  • Add a get-transaction-history node:

Screen Shot 2020-05-19 at 4.35.15 PM

  • Add a new function node and name the node get the transaction history of Bob:

Screen Shot 2020-05-19 at 4.37.01 PM
Open this node and enter the following:

msg.txHistoryOfAlice = msg.payload;

console.log("Tx history of bob:",msg.payload);

txContext = msg.txContext;
bobPublicKey = msg.bob.publicKey;

msg.payload={
txContext,
publicKey:bobPublicKey
}

return msg;
  • Add a get-transaction-history node:

Screen Shot 2020-05-19 at 4.42.27 PM

  • Add a new function node and name the node return data:

Screen Shot 2020-05-19 at 4.49.33 PMOpen this node and enter the following:

msg.txHistoryOfBob = msg.payload;

console.log("Tx history of bob:",msg.payload);

msg.payload = {
"Manufacturer public Key": msg.manufacturer.publicKey,
"Alice public Key": msg.alice.publicKey,
"Bob public Key": msg.bob.publicKey,
"Tx id of the car asset owned by Manufacturer": msg.createTransactionId,
"Tx id of the transfer of car asset from manufcturer to alice": msg.transfer1TransactionId,
"Tx id of the transfer of car asset from alice to bob": msg.transfer2TransactionId,
"The current owner of the car asset": msg.assetOwner.ownerPublicKey[0],
"Asset history of car asset": msg.assetHistory,
"Transaction history of the manufacturer": msg.txHistoryOfManufac,
"Transaction history of the alice": msg.txHistoryOfAlice,
"Transaction history of the bob": msg.txHistoryOfBob
}


return msg;
  • Complete the flow with a http response node and name it done.

Screen Shot 2020-05-19 at 4.51.48 PM

  • Connect all the nodes together:

Screen Shot 2020-05-19 at 4.57.57 PM

  • Deploy the flow with the Deploy button in the right hand corner above:

Screen Shot 2020-05-19 at 5.00.51 PM

Import the Flow

Alternatively, you can also import the entire sample application as a flow in the JSON format.

First, navigate to the repo ng-rt-digitalAsset-sdk-samples > examples > nodeRedFlow > trackAndtrace.json. 

Copy the JSON code: and import that into the Node-RED UI:

Screen Shot 2020-05-27 at 12.52.50 PM

In the import nodes dialog, paste the JSON code for the track and trace flow, starting at "nodes":

Screen Shot 2020-05-27 at 12.52.08 PM

Deploy the flow with the Deploy button in the right hand corner above:

Screen Shot 2020-05-19 at 5.00.51 PM

Execute the flow using the CLI

Once you have deployed the flow with the Node-RED UI, open a terminal session to execute the flow you just created.

First, you'll have to retrieve the access token for accessing Node-RED:

tymlez-dev nodeRed getAccessToken --username=admin --password=<YOUR_GENERATED_PASSWORD>

Now run the flow you just created:

tymlez-dev nodeRed runFlow --context=<YOUR_CONTEXT_HERE> --flowName=<YOUR_FLOW_NAME_HERE>

The Node-RED flow is then executed.

Navigation

As a next step, learn how to create a plugin and upload it to your TBSP instance on Google Cloud Platform here.

Go back