- RFC: 02-005
- Authors: Ermyas Abebe, Venkatraman Ramakrishna, Sandeep Nishad, Krishnasuri Narayanam, Dhinakaran Vinayagamurthy
- Status: Proposed
- Since: 05-Jan-2023
- This document specifies the Hyperledger Fabric implementation of modules, and application adaptation guidelines, for the asset exchange protocol.
- There are two types of implementation for asset exchange in Fabric:
- The protocol unit functions are implemented in a library package that can be imported in any application chaincode.
- The Fabric Interoperation Chaincode will already import the above library, and its functions can be invoked from an application chaincode, using an interface that needs to be extended by the application chaincode.
- Within Weaver, the SDK will provide user agents (clients) the capability to trigger HTLC operations on particular chaincodes maintaining particular digital assets.
Weaver asset exchange capabilities are asset and application-agnostic. Weaver interoperation module verifies the HTLC parameters and maintains asset and claim state in the ledger for the corresponding asset exchange. Other verifications and operations must be done in the application contract. Following are the core capabilities of Weaver for HTLC asset exchange:
-
Lock Functions:
LockAsset
: Function to lock a non-fungible asset. It takes two parameters: base64 encoded serialized protobuf message of type AssetLock defining hash lock and time lock parameters of HTLC and AssetExchangeAgreement.LockFungibleAsset
: Function to lock fungible assets. Similar toLockAsset
, it also takes two parameters: base64 encoded serialized protobuf message of type AssetLock defining hash lock and time lock parameters of HTLC and FungibleAssetExchangeAgreement.
Both functions generate a unique ID called
contractId
for this asset exchange, and returns it, which can be used in other functions to refer to this asset exchange. These lock functions only creates a state in the ledger signifying that the corresponding asset is locked and the HTLC parameters. The application contract must make sure to not allow any changes to the state or ownership of the asset while it is locked. -
IsAssetLocked
: Function to query if the asset is locked. There can be two interfaces for this function, one that takes onlycontractId
as input, and other interface only for non-fungible assets, whereAssetExchangeAgreement
protobuf or its fields can be provided as input. -
ClaimAsset
: Function to claim asset by providing preimage of the lock. This function can also be implemented in two ways, one taking contractId and serialized protobuf AssetClaim as input, and another way for non-fungible assets taking serialized protobufs of type AssetExchangeAgreement and AssetClaim. The claim function creates a claim state in ledger, and deletes lock state. The actual transfer of asset must be done in the application contract. -
UnlockAsset
: Function to unlock asset after timeout has expired. This function can also be implemented in two ways, one taking contractId as input, and another way for non-fungible assets taking serialized protobuf AssetExchangeAgreement as input. The claim function only deletes lock state in ledger.
Utility functions:
GetHTLCHash
: Get the hash value used for lock for the given contractId or AssetExchangeAgreement.GetHTLCHashPreImage
: Get the preimage after the claim has occurred, for the given contractId or AssetExchangeAgreement.
Weaver SDK provides an interface Hash
, which is designed to allow different hashing algorithms to be used for HTLC. Currently there are two implementations: SHA256
and SHA512
. The interface Hash
in HashFunctions
has following API:
generateRandomPreimage(length: number): void
: generates a random preimage of sizelength
, and sets it to internal variablesetPreimage(preimage: any): void
: sets a user-provided preimagegetPreimage(): any
: returns the preimagegetSerializedPreimageBase64(): string
: returns serialized preimage in base64 encoded stringsetSerializedHashBase64(hash64: string)
: sets serialized hash value in base64 encoded stringgetSerializedHashBase64(): string
: returns serialized hash value in base64 encoded string
The Weaver SDK's AssetManager
API functions are listed below to help client application developers add HTLC functionalities in their app. Before going to API functions, the parameters used in those functions are explained below:
contract: Contract
: application chaincode handle obtained via Fabric SDK using the caller's credentialsassetType: string
: type of assetassetID: string
: ID of non-fungible assetnumUnits: number
: quantity of fungible assetslockerECert: string
: certificate of lockerrecipientECert: string
: certificate of recipienthash: Hash
: instance ofHash
interface explained above (by defaultSHA256
is used, and random preimage will be generated)expiryTimeSecs: number
: duration timeout in secondscontractId: string
: Unique ID for an asset exchange agreement/contract generated after locking the asset.timeoutCallback: (c: Contract, t: string, i: string, r: string, h: Hash)
: Callback function to be called after the corresponding chaincode transaction has been executed.
createHTLC( contract: Contract, assetType: string, assetID: string, recipientECert: string, hash: Hash, expiryTimeSecs: number, timeoutCallback: (c: Contract, t: string, i: string, r: string, h: Hash) => any, )
: To lock a non-fungible asset of typeassetType
and idassetID
. It returnscontractId
, a unique ID for an asset exchange agreement/contract, which can be used for subsequent transactions/queries.createFungibleHTLC( contract: Contract, assetType: string, numUnits: number, recipientECert: string, hash: Hash, expiryTimeSecs: number, timeoutCallback: (c: Contract, i: string, t: string, n: number, r: string, h: Hash) => any, )
: To lock fungible assets of typeassetType
and quantitynumUnits
. It returnscontractId
, a unique ID for an asset exchange agreement/contract, which can be used for subsequent transactions/queries.
claimAssetInHTLCusingContractId( contract: Contract, contractId: string, hash: Hash, )
: Claim for any kind of assetclaimAssetInHTLC( contract: Contract, assetType: string, assetID: string, lockerECert: string, hash: Hash, )
: Claim asset for non-fungible assetsclaimFungibleAssetInHTLC( contract: Contract, contractId: string, hash: Hash, )
: Claim asset for fungible assets
reclaimAssetInHTLCusingContractId( contract: Contract, contractId: string, )
: Reclaim/Unlock any kind of assetreclaimAssetInHTLC( contract: Contract, assetType: string, assetID: string, recipientECert: string, )
: Reclaim/Unlock for non-fungible assetsreclaimFungibleAssetInHTLC( contract: Contract, contractId: string, )
: Reclaim/Unlock asset for fungible assets
isAssetLockedInHTLCqueryUsingContractId( contract: Contract, contractId: string, )
: Query to check if any kind of asset is locked.isAssetLockedInHTLC ( contract: Contract, assetType: string, assetID: string, recipientECert: string, lockerECert: string, )
: Query to check if non-fungible asset is locked.isFungibleAssetLockedInHTLC( contract: Contract, contractId: string, )
: Query to check if fungible asset is locked.
The onus on the changes required to be made lies both on the application developer (as Weaver is agnostic to the client application) and on Weaver as the platform provider.
HTLC can be implemented in a network using Weaver in one of two ways:
-
Using AssetExchange library: All HTLC capabilities are encapsulated in
assetexchange
library, which any Fabric chaincode can import and extend to implement asset exchange. -
Using Interoperation Module (InteropCC): Weaver's interoperation module also provides asset exchange capabilities built-in. This requires to install the weaver chaincode on the channel. An interface
asset-mgmt
is designed to help application chaincode invoke different HTLC transactions on interoperation chaincode. The interface also has same API as explained in HTLC Asset Exchange Capabilities in Weaver.
Weaver handles most of the core/generic HTLC operations, but application smart contract needs to perform several application/asset specific checks, and then use assetexchange
library or asset-mgmt
interface (using interoperation module) to exercise different HTLC functions in smart contract. Contract developers needs to make sure of:
- Asset to be locked should exist and the caller party has the access to lock the asset.
- After
LockAsset
call to the library or interface, the asset status should be marked locked so that it can't be spent during locked state. - After
ClaimAsset
/ReclaimAsset
call to the library or interface, the actual transfer of asset must be done in the application contract.
Developers need to utilize the Weaver SDK to adapt their client application to perform HTLC operations.