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_wallet
with their account (e.galice
)
- a.
alice
must 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_wallet
with their account (e.gbob
)
- a.
bob
may have a 0 balance
Note: For testing purpose, the accounts may be in the same wallet
1. Generate a “preimage” (depositor)
alice
must generate a “preimage” (think: password) and keep is safe frombob
until 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 Preimage
and “preimage_length” is11
bytes
2. Calculate the “preimage_hash” (depositor)
alice
must 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)
alice
will create the HTLC using thehtlc_create
command with syntax ofhtlc_create <from> <to> <amount> <symbol> <hash_algo> <preimage_hash> <preimage_length> <expiration> <broadcast>
- a. is
alice
our depositor - b. is
bob
our 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.
300
for 5 minutes) - i. is a boolean value which must be set to
true
to be sent by thecli_wallet
software
alice
will 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
bob
to verify and redeem. - The 100 TEST tokens are deducted from the account balance of
alice
and are locked into the HTLC, protected by both the hashlock and timelock conditions.
4. Verify the HTLC (recipient)
bob
must validate the HTLC created byalice
meets his requirements. He can do this by looking at the recent account history operations for his account to find the active HTLC.bob
will 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
alice
created - ii. Retain the complete HTLC “database_id” (e.g
1.16.99
)
- i. “XX” will also be a numeric value unique to the HTLC
bob
will use the “database_id” to execute this command: $(unlocked)>get_htlc 1.16.99
bob
will verify the following transfer values meet his expectations, as agreed to previously withalice
:
- a. from
- b. to
- c. amount
- d. asset
bob
will now learn about the two conditionsalice
applied 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
bob
validates everything, he may proceed to Redeem the HTLC - Else,
alice
will automatically receive the value locked in the HTLC when the timelock expires
5. Redeem the HTLC (recipient)
bob
will obtain thepreimage
fromalice
, likely after performing the agreed upon task- The
htlc_redeem
command has the following syntax:htlc_redeem <htlc_database_id> <fee_paying_account> <preimage> <broadcast>
bob
will 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”
bob
supplied satisfies the hashlock condition on the HTLC and the100 TEST
are 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.