Smart Contract #5 - Escrow Flow

The escrow smart contract locks both assets and releases assets to the parties involved once specific conditions are met.

Description

In this scenario, a seller wants to sell his car to a buyer. In return, the buyer will give the seller the bicycle that he owns.
Both seller and buyer will send their assets to the escrow smart contract, which will lock both assets.
The smart contract will first release the car to the buyer. The buyer must confirm if he is satisfied with his purchase.
If he is satisfied, he takes ownership of the asset. Note that ownership cannot be reversed.
Since the buyer has indicated he is satisfied with the asset, the smart contract then releases the bicycle to the buyer.

Summary

The smart contract involves the following steps:

  • The seller creates a digital asset called sample_car
  • The buyer creates another digital asset called sample_car but with different properties
  • Publish a escrow smart contract
  • Transfer the digital assets to the escrow contract 
  • Buyer takes delivery of car asset, escrow releases car asset
  • Seller takes delivery of the buyer car asset
  • Buyer confirms satisfaction with received digital asset
  • Escrow releases buyer car asset
  • Seller takes delivery of buyer car asset

Steps

Creation of a digital asset

Create a digital asset and assign it type sample_car. This is the asset that the seller will sell:

tymlez-sc createAsset --type=sample_car --jsonAssetData='{"type":"gas_vehicle", "color":"red", "serialNo":1234}' 
The asset ID of the created digital asset is returned::
[INFO] commands.createAsset - Signed tx...

[INFO] commands.createAsset - Post signed tx ....

[INFO] commands.createAsset - Asset Id: <SELLER_ASSET_ID>
As a second step, create and use the public key that represents the buyer of the car.
First, clone your existing default environment:
tymlez-dev config cloneContext --source=cloud --target=cloud1
Now, set the default context to the newly cloned environment:
tymlez-dev config setContext --defaultContext=cloud1
Generate a new keypair. This keypair represents the buyer of the car:
tymlez-dev config generateKeyPair
Using the buyer keypair, create a digital asset and assign it the type sample_car, for example, ensuring that the type found in jsonAssetData is different from that of the first asset:
tymlez-sc createAsset --type=sample_car --jsonAssetData='{"type":"electric_vehicle", "color":"white", "serialNo":1234}' 
This will return the asset ID of the digital asset of the car:
[INFO] commands.createAsset - Signed tx...

[INFO] commands.createAsset - Post signed tx ....

[INFO] commands.createAsset - Asset Id: <BUYER_ASSET_ID>
Now, assume the role of the seller once again by changing the default context:
tymlez-dev config setContext --defaultContext=cloud

Publish the escrow smart contract

Trigger the escrow smart contract, using the public key of the first owner:
tymlez-sc publish --templateName=SC_Escrow <SELLER_PUBLIC_KEY> <BUYER_PUBLIC_KEY> <SELLER_ASSET_ID> <BUYER_ASSET_ID>
The escrow contract ID will then be returned:
[INFO] commands.publish - publishing contract escrow_Part2....

[INFO] commands.publish - Signed tx...

[INFO] commands.publish - Post signed tx ....

[INFO] commands.publish - Smart Contract published successfully

[INFO] commands.publish - Contract id: <GENERATED_CONTRACT_ID>
Now, check the state of the escrow smart contract:
tymlez-sc call --functionName=getContractMemory
The public keys for both buyer and seller, along with the asset IDs of the created objects, will be displayed:
[INFO] commands.call - { seller: '<SELLER_PUBLIC_KEY>',

buyer: '<BUYER_PUBLIC_KEY>',

sellerAssetId:

'<SELLER_ASSET_ID>',

buyerAssetId:

'<BUYER_ASSET_ID>',

state: 'Initialized' }
The contract executes the escrow function once both parties transfer their assets to the smart contract; the escrow will hold the assets of both parties.

Transfer assets to the escrow


As the seller, transfer the seller asset to the escrow smart contract:
tymlez-sc transferCall --functionName=transferAsset --assetId=<SELLER_ASSET_ID>
Assume the role of the buyer:
tymlez-dev config setContext --defaultContext=cloud1
As the buyer, transfer the buyer asset to the escrow:
tymlez-sc transferCall --functionName=transferAsset --assetId=<BUYER_ASSET_ID>
Obtain the state of the contract:
tymlez-sc call --functionName=getContractMemory
The smart contract is now the owner of both assets:
[INFO] commands.call - { seller: '<SELLER_PUBLIC_KEY>',

buyer: '<BUYER_PUBLIC_KEY>',

sellerAssetId:

'<SELLER_ASSET_ID>',

buyerAssetId:

'<BUYER_ASSET_ID>',

state: 'assetsLocked' }

Transfer assets from the escrow

The escrow first releases the seller asset to the buyer when the buyer requests it.
The buyer begins with taking delivery of the car asset:
tymlez-sc transferCall --functionName=transferReward --assetId=<BUYER_ASSET_ID>
Now, the seller attempts to take delivery of the buyer asset:
Assume the role of the seller:
tymlez-dev config setContext --defaultContext=cloud
Now, take delivery of the buyer asset:
tymlez-sc transferCall --functionName=transferReward --assetId=<SELLER_ASSET_ID>
If the seller tries to obtain the asset from the smart contract before the buyer takes ownership of the car asset, an error message is displayed:
[ERROR] commands.call - Buyer has not confirmed the delivery !!
To protect the buyer, the buyer asset is only released to the seller if the buyer indicates he/she is satisfied with the asset he received.
To indicate buyer satisfaction, assume the role of the buyer:
tymlez-dev config setContext --defaultContext=cloud1
The buyer indicates whether he is satisfied with the asset he bought.
The value true indicates he/she is not satisfied, whereas the value false indicates that he is satisfied with the purchase.
In the command below, the buyer is satisfied with the purchase and indicates false:
tymlez-sc call --functionName=setCancel false
Take on the role of the seller:
tymlez-dev config setContext --defaultContext=cloud
Now, the seller is then able to take delivery of the electric vehicle asset:
tymlez-sc transferCall --functionName=transferReward --assetId=<SELLER_ASSET_ID>
Check the latest state of the escrow contract:
tymlez-sc call --functionName=getContractMemory
The escrow smart contract has been brought to a conclusion:
[INFO] commands.call - { result: 'finished' }

Additionally, you can also use the smart contract explorer to track the status of the contract, described in this article. 

Navigation

Ready for more? You can also run a smart contract with escrow function but with a divisible asset here.

In addition, you can use Node-RED with your TBSP instance on Google Cloud here

Return to the smart contract main menu.