Chain-key Bitcoin

From Internet Computer Wiki
Revision as of 21:59, 3 February 2023 by Thomas.locher (talk | contribs)
Jump to: navigation, search

Overview

Chain-key Bitcoin (ckBTC) is a token on the Internet Computer that is backed 1:1 by bitcoin (BTC) such that 1 ckBTC can always be redeemed for 1 BTC and vice versa.

Unlike other tokens pegged to bitcoin, the ckBTC token does not rely on a third-party bridge for the conversion between BTC and ckBTC, making it a substantially more secure alternative to “wrapped” tokens.

While chain-key bitcoin and regular bitcoin have the same value, the advantage of chain-key bitcoin is fast and cheap transfers: A transfer is finalized within a few seconds (a speed-up of roughly three orders of magnitude compared to transfers on the Bitcoin blockchain) and only costs 0.0000001 ckBTC (approximately two orders of magnitude lower than the Bitcoin miner fees).

Architecture

The ckBTC functionality is built upon the Bitcoin integration of the Internet Computer, which makes it possible for canisters to receive, hold, and send bitcoin.

There are two canisters, the ckBTC minter and ckBTC ledger, that together provide the ckBTC functionality. The ckBTC minter mints new ckBTC tokens whenever it receives bitcoin. Likewise, it burns ckBTC tokens whenever an owner of ckBTC tokens requests a withdrawal of bitcoin. The ckBTC ledger is ICRC-1 compliant, updating the balance accounts when ckBTC tokens are transferred and executing the mint and burn operations coming from the ckBTC minter. An overview of the basic architecture is depicted in the following figure.

High-level overview of chain-key Bitcoin.

The figure shows the main flow at a high level of abstraction: Users interact with the ckBTC minter and the ckBTC ledger to convert ckBTC/BTC and transfer ckBTC, respectively. The ckBTC minter interacts with the Bitcoin canister to retrieve information about the Bitcoin network state and send Bitcoin transactions.

Technical Details

ckBTC Ledger

The ckBTC ledger is a canister, controlled by the NNS (specifically, the NNS root canister), running on the pzp6e subnet. Since it is ICRC-1 compliant, it offers all functions defined in the ICRC-1 standard. In particular, it provides the functionality to transfer ckBTC between accounts.

The minting account is the ckBTC minter’s default account, that is, the account derived from the ckBTC minter’s principal ID and the all-zero subaccount.

The initial supply of the ckBTC ledger is 0. ckBTC tokens are minted only when the ckBTC minter receives bitcoin, ensuring that the ckBTC supply managed by the ckBTC ledger is upper bounded by the amount of bitcoin held by the ckBTC minter.

ckBTC Minter

The ckBTC minter is a canister that is controlled by the NNS and running on the pzp6e subnet as well. It has a few important configuration parameters including:

  • retrieve_btc_min_amount: This is the minimum ckBTC amount that can be burned and, correspondingly, the minimum BTC amount that can be withdrawn. The parameter is set to 0.001 BTC, or 100,000 satoshi.
  • max_time_in_queue_nanos: Any BTC retrieval request should be kept in a queue for at most this time. Caching requests rather than handling them right away has the advantage that multiple requests can be served in a single transaction, saving Bitcoin miner fees. The parameter is set to 10 minutes, which corresponds to the expected time between Bitcoin blocks.
  • min_confirmations: The number of confirmations required for the ckBTC minter to accept a Bitcoin transaction. In particular, the ckBTC minter does not mint ckBTC before a transaction transferring BTC to a Bitcoin address managed by the ckBTC minter reaches this number of transactions. The parameter is initially set to 72 but may be reduced over time.

The other parameters are self-explanatory and can be found in the ckBTC minter Candid file.

The ckBTC minter provides the following endpoints:

  • get_btc_address: Returns a specific Bitcoin address that the caller can use to obtain ckBTC by sending BTC to this address.
  • track_balance: Instructs the ckBTC minter to track a certain Bitcoin address until funds are added, which will trigger the minting of the equivalent amount in ckBTC.
  • update_balance: Instructs the ckBTC minter to check the balance of a Bitcoin address and potentially mint ckBTC right away.
  • get_withdrawal_account: Returns a specific ckBTC account where the owner must transfer ckBTC before being able to retrieve BTC.
  • retrieve_btc: Instructs the ckBTC minter to burn a certain ckBTC amount and send the corresponding BTC amount to a provided Bitcoin address.
  • retrieve_btc_status: Returns the status of a previous retrieve_btc call.
  • get_events: Returns a set of events at the ckBTC minter.

The endpoints are discussed in more detail in the following.

get_btc_address(owner: opt principal, subaccount: opt blob) =

The provided principal ID and subaccount are concatenated to form the derivation path for the ecdsa_public_key function, which returns the derived public key. If no principal ID is provided, then the sender’s principal ID is used. If no subaccount is provided, then the default subaccount (all zeros) is used.

This public key is encoded as a pay-to-witness-public-key-hash (P2WPKH) Bitcoin address and returned as a text.

Note that the key derivation is not BIP-32 compliant where 31 bits are used for each derivation level. Instead, a single derivation is performed based on the full principal ID and subaccount. Since the derivation is deterministic, a canister can derive this Bitcoin address itself.