Introduction
An HTLC is a conditional transfer of value from “depositor” to “recipient” where two distinct conditions prevent immediate execution. 1) The hashlock requires presenting the proper “preimage” to the blockchain prior to the 2) timelock expiration, else the value automatically returns to “depositor”.
This allows two parties to exchange tokens on independent platforms trustlessly and securely and thus enables Atomic Cross-Chain Swaps (ACCS) among other useful functionalities.
Getting Started with HTLC
There are 5 steps to progress through when working with an HTLC:
- Generate a “preimage” (depositor)
- Calculate the “preimage_hash” (depositor)
- Create the HTLC (depositor)
- Verify the HTLC (recipient)
- Redeem the HTLC (recipient)
0. Prerequisites
- The “depositor” must have an unlocked
cli_walletwith their account (e.galice)
- a.
alicemust have a balance of TEST tokens in her wallet - b. anyone may issue this command to verify: $>
list_account_balances alice
- The “recipient” must have an unlocked
cli_walletwith their account (e.gbob)
- a.
bobmay have a 0 balance
Note: For testing purpose, the accounts may be in the same wallet
1. Generate a “preimage” (depositor)
alicemust generate a “preimage” (think: password) and keep is safe frombobuntil she is ready to reveal it him.- Using this external website generate a “preimage”
- Enter your “preimage” text into the textbox
Warning: Using a popular preimage is large security risk. The recipient can redeem the HTLC by comparing the preimage_hash to a dictionary of popular hashes. The best preimage is a long, random one.
- Count how many characters your entered, including spaces, this is your “preimage_length” in bytes
- Retain your “preimage” and “preimage_length” for later use
- Example: “preimage” is
My Preimageand “preimage_length” is11bytes
2. Calculate the “preimage_hash” (depositor)
alicemust calculate the “preimage_hash” from the preimage she generated above- Just below the textbox will be the SHA256 hash of your preimage string
- Retain this as your “preimage_hash” for later use
- Example: “preimage_hash” is
650BFCEF53BD8E6E030613E0B75EC0CBA4FCD25C53BF0D15A6283593B269DF79
3. Create the HTLC (depositor)
alicewill create the HTLC using thehtlc_createcommand with syntax ofhtlc_create <from> <to> <amount> <symbol> <hash_algo> <preimage_hash> <preimage_length> <expiration> <broadcast>
- a. is
aliceour depositor - b. is
bobour recipient - c. is the number of tokens to be locked into the contract (e.g.
100) - d. is the token symbol (e.g.
TEST) - e. <hash_algo> will be
SHA256(future releases may support additional hash algorithms) - f. <preimage_hash> is the calculated value from #2 (not the preimage which remains private)
- g. <preimage_length> is the number of bytes from #1
- h. is the timelock expressed as the number of seconds the HTLC will remain valid upon broadcast to the blockchain (e.g.
300for 5 minutes) - i. is a boolean value which must be set to
trueto be sent by thecli_walletsoftware
alicewill execute this command: $(unlocked)>htlc_create alice bob 100 TEST SHA256 "650BFCEF53BD8E6E030613E0B75EC0CBA4FCD25C53BF0D15A6283593B269DF79" 11 300 true- The JSON response will be returned (else an assert error – check your parameters)
- The HTLC is now active and the hashlock expiration is counting down the seconds for
bobto verify and redeem. - The 100 TEST tokens are deducted from the account balance of
aliceand are locked into the HTLC, protected by both the hashlock and timelock conditions.
4. Verify the HTLC (recipient)
bobmust validate the HTLC created byalicemeets his requirements. He can do this by looking at the recent account history operations for his account to find the active HTLC.bobwill execute this command: $(unlocked)>get_account_history bob 1
- a. This will return the most recent operation, which should begin with “Create HTLC to bob”
- b. Locate the HTLC “database_id” having the format
1.16.XX- i. “XX” will also be a numeric value unique to the HTLC
alicecreated - ii. Retain the complete HTLC “database_id” (e.g
1.16.99)
- i. “XX” will also be a numeric value unique to the HTLC
bobwill use the “database_id” to execute this command: $(unlocked)>get_htlc 1.16.99bobwill verify the following transfer values meet his expectations, as agreed to previously withalice:
- a. from
- b. to
- c. amount
- d. asset
bobwill now learn about the two conditionsaliceapplied to the HTLC.
- Within the hashlock he observes:
- a. hash_algo
- b. preimage_hash
- c. preimage_length
- Within the timelock he observes:
- d. expiration_string
- If
bobvalidates everything, he may proceed to Redeem the HTLC - Else,
alicewill automatically receive the value locked in the HTLC when the timelock expires
5. Redeem the HTLC (recipient)
bobwill obtain thepreimagefromalice, likely after performing the agreed upon task- The
htlc_redeemcommand has the following syntax:htlc_redeem <htlc_database_id> <fee_paying_account> <preimage> <broadcast> bobwill execute the following command: $(unlocked)>htlc_redeem 1.16.99 bob "My Preimage" true- The JSON response will be returned (else an assert error – check your parameters)
- The “preimage”
bobsupplied satisfies the hashlock condition on the HTLC and the100 TESTare moved into his account balance (less 0.4 TEST which is paid as the transaction fee, less 0.8 TEST which is paid as the kilobyte fee for storing the “preimage”). - Anyone may issue this command to verify: $>
list_account_balances bob
Using Two HTLCs to Perform an Atomic Swap
An atomic swap involves a pair of HTLCs related by the same hashlock within both, allowing for trustless exchange of distinct tokens between distinct accounts. More on how to perform this on the TESTNET shortly.
Performing an Atomic Cross Chain Swap (ACCS)
The ultimate goal for our HTLC implementation is to allow the trustless exchange of tokens on the BitShares blockchain for tokens on a foreign blockchain. We will likely start with TESTBTC instructions in the coming weeks. Please practice on our chain first.
