Difference between revisions of "Bitcoin Integration"

From Internet Computer Wiki
Jump to: navigation, search
 
(51 intermediate revisions by 7 users not shown)
Line 1: Line 1:
 
== Overview ==
 
== Overview ==
  
Bitcoin is a decentralized digital currency based on an open-source P2P protocol. Bitcoin uses the unspent transaction output (UTXO) accounting model, i.e., transactions create outputs which are used as inputs to other transactions that create new transaction outputs. A UTXO is always fully consumed by a transaction.
+
[https://en.wikipedia.org/wiki/Bitcoin Bitcoin] is a decentralized digital currency based on an open-source [https://en.wikipedia.org/wiki/Bitcoin_network P2P protocol]. Bitcoin uses the [https://en.wikipedia.org/wiki/Unspent_transaction_output unspent transaction output] (UTXO) accounting model, i.e., transactions create outputs which are fully consumed when used as inputs for other transactions that create new transaction outputs.
  
Bitcoin is a payment network without support for smart contracts. Smart contract support for Bitcoin through the Internet Computer adds tremendous value: It leverages the combined strength of the Bitcoin network as the world's digital gold reserve and the Internet Computer as a platform for securely and efficiently executing smart contracts. An example class of applications that will become possible with this integration are decentralized finance (DeFi) applications, which can currently be implemented only with wrapped Bitcoin requiring additional trusted entities. Moreover, Bitcoin could be used for paying for any kind of services on the Internet Computer, which opens up a sheer endless number of application scenarios.
+
Bitcoin is a payment network without support for [https://en.wikipedia.org/wiki/Smart_contract smart contracts]. Smart contract support for Bitcoin through the Internet Computer adds tremendous value: It leverages the combined strength of the Bitcoin network as the world's digital gold reserve and the Internet Computer as a platform for securely and efficiently executing smart contracts. An example class of applications is decentralized finance (DeFi) built around Bitcoin, which can currently be implemented only with wrapped Bitcoin requiring additional trusted entities. Moreover, Bitcoin can be used to pay for any kind of services on the Internet Computer, which opens up a sheer endless number of application scenarios.
  
The Internet Computer is integrated with the Bitcoin blockchain with the goal of making powerful smart contract functionality available for Bitcoin through a direct, "trustless," integration of the two blockchains. "Trustless" in this context means that no trust assumptions are required other than trust in the correct functioning of the Bitcoin network and the Internet Computer. In other words, there can be no additional parties, such as bridges or other types of intermediaries, resulting in a much cleaner and more secure integration.
+
The Internet Computer is integrated with the Bitcoin blockchain to make powerful smart contract functionality available for Bitcoin through a direct, bridgeless, integration of the two blockchains. "Direct" in this context means that no trust assumptions are required other than trust in the correct functioning of the Bitcoin network and the Internet Computer. In other words, there are no additional parties required, such as bridges or other types of intermediaries, resulting in a much cleaner and more secure integration.
In this trustless integration of Bitcoin and the Internet Computer, canisters can directly hold Bitcoin on the Bitcoin blockchain.
 
  
This direct integration is based on the following features:
+
This direct integration has the following main features:
  
 
* Canisters can have Bitcoin addresses (and therefore receive and hold bitcoin directly on the Bitcoin blockchain).
 
* Canisters can have Bitcoin addresses (and therefore receive and hold bitcoin directly on the Bitcoin blockchain).
* Canisters can access the UTXO set of the addresses they control.
+
* Canisters can access the balance and UTXO set of Bitcoin addresses.
 +
* Canisters can access block headers on the Bitcoin blockchain.
 
* Canisters can securely sign Bitcoin transactions.
 
* Canisters can securely sign Bitcoin transactions.
 
* Canisters can submit Bitcoin transactions to the Bitcoin network.
 
* Canisters can submit Bitcoin transactions to the Bitcoin network.
  
The trustless aspect of the integration relies on a threshold ECDSA protocol that enables a subnet to compute ECDSA signatures based on a secret-shared private key on a canister's request. With this protocol, each canister can "control" a vast number of derivable ECDSA keys and obtain signatures for them, making it possible for canisters to eceive, hold, and transfer Bitcoin directly on the Bitcoin blockchain in a secure manner. Naturally, a canister must be able to retrieve the UTXOs associated with its Bitcoin addresses. To this end, the Internet Computer pulls in blocks directly from the Bitcoin network. In the following, the underlying architecture of this integration is explored in more detail.
+
The direct, bridgeless, integration relies on a novel [https://internetcomputer.org/docs/current/developer-docs/integrations/t-ecdsa threshold ECDSA protocol] that enables a subnet to compute ECDSA signatures based on a secret-shared private key upon a canister's request. With this protocol, each canister can "control" a vast number of derivable ECDSA keys and obtain signatures for them, making it possible for canisters to receive, hold, and transfer bitcoin directly on the Bitcoin blockchain in a secure manner. Naturally, a canister must be able to retrieve the UTXOs associated with its Bitcoin addresses. To this end, the Internet Computer pulls in blocks directly from the Bitcoin network. In the following, the underlying architecture of this integration is explored in more detail.
  
 
== Architecture ==
 
== Architecture ==
  
In this section, we present the architecture for the direct integration with the Bitcoin blockchain on a high level. The integration requires components to be changed or added at every layer of the Internet Computer (IC) protocol stack.
+
This section presents the architecture for the direct integration with the Bitcoin blockchain on a high level. The integration changes and adds components at every layer of the Internet Computer (IC) protocol stack.
  
[[File:Bitcoin integration architecture.png|thumb|center|upright=3|A high-level overview of the Bitcoin integration architecture.]]
+
[[File:Updated Bitcoin integration architecture overview.png|thumb|center|upright=3|A high-level overview of the Bitcoin integration architecture.]]
  
The ''Bitcoin canister'', a virtual canister implemented at the execution layer as part of the replica, exposes APIs for querying UTXO sets and submitting transactions. The UTXO set and balance of any given Bitcoin address are made available through the functions <span style="font-family: 'Courier New';">get_utxos</span> and <span style="font-family: 'Courier New';">get_balance</span>, respectively. Bitcoin transactions are sent to the Bitcoin network using the <span style="font-family: 'Courier New';">send_transaction</span> function.
+
The main component is the Bitcoin canister, which runs on a system subnet and exposes the Bitcoin integration endpoints through the [https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-management-canister virtual management canister] interface. The API offers functions to query Bitcoin state (UTXOs, balances, and current transaction fees) and to submit transactions.
  
Serving UTXO sets by the Bitcoin canister requires that Bitcoin blocks be pulled into the IC from nodes of the Bitcoin network to extract the transaction inputs and outputs and update the set of unspent transaction outputs (UTXOs). This requires an architecture that spans all layers of the IC protocol stack and also includes a new component external to the replica.
+
In order to serve up-to-date information about the Bitcoin state, Bitcoin blocks must be pulled continuously into the Internet Computer from the Bitcoin network and the set of all UTXOs (referred to as the "UTXO set") updated based on the transaction inputs and outputs contained in the blocks.  
  
The Bitcoin canister maintains a set of recent Bitcoin blocks, the entire UTXO set, and a set of outgoing transactions submitted by canisters. The UTXO set and the recent blocks are used for responding to UTXO queries of canisters.
+
The Bitcoin canister maintains a set of recent Bitcoin blocks and the entire UTXO set, which are used together to respond to UTXO and balance queries of canisters. Additionally, it stores the entire list of Bitcoin block headers.
  
The Bitcoin adapter, a sandboxed OS-level process external to the replica, connects to multiple Bitcoin nodes randomly using Bitcoin's peer discovery protocol. The Bitcoin adapter synchronizes the block headers and blocks of the Bitcoin network.  The Bitcoin adapter maintains a recent view of the Bitcoin network's blocks as well and provides blocks to the IC protocol stack on request.
+
The ''Bitcoin adapter'', an OS-level process external to the replica, connects to multiple Bitcoin nodes chosen randomly using Bitcoin's peer discovery protocol. The Bitcoin adapter maintains a local copy of the whole block header chain as well as a small cache of blocks that it provides to the replica upon request.
  
In every IC round, the active block maker, a core component of the consensus layer, makes a request for a new Bitcoin block to the networking layer. The networking layer retrieves part of the state of the Bitcoin canister that comprises the headers of the recent Bitcoin blocks the Bitcoin canister maintains as well as the outgoing transactions. Both those items are used as parameters in a Bitcoin block request to the Bitcoin adapter. The Bitcoin adapter matches the received block hashes with its recent view of the Bitcoin network and, if it holds a block that is a successor to one of the blocks represented through the hashes, returns this block. Furthermore, it adds the transactions received in the request to a queue for outgoing transactions to be submitted asynchronously to the Bitcoin network. If a block is returned by the Bitcoin adapter, it is put into the proposed IC block by the block maker.
+
In every IC round, the block maker, a core component of the consensus layer, sends a request from the Bitcoin canister to the Bitcoin adapter and gets the response, which is then included in the IC block's payload. More precisely, the Bitcoin canister makes a call to access internal replica APIs to store the request in the replicated state, where it is picked up by the payload builder in the Consensus layer. The payload builder uses interprocess communication to relay the request to the external Bitcoin adapter, which handles the request and returns the result to the payload builder. The payload builder then incorporates the result in the IC block.
 +
A request contains hashes of recent block headers for which the Bitcoin canister has the block of transactions as well as the outgoing transactions. The Bitcoin adapter compares the received block hashes against its view of the Bitcoin network: if its cache contains one or more successors of the blocks that the Bitcoin canister has, it returns one or more of these blocks. Furthermore, it adds the transactions received in the request to a queue for outgoing transactions to be submitted asynchronously to the Bitcoin network.
  
Let's assume that an IC block containing a Bitcoin block has been proposed in the current IC protocol round. This IC block is gossiped to the subnet nodes as usual and needs to go through the notarization and finalization process. The notarization process is extended for the Bitcoin integration: Each replica performs a deterministic validity check of the Bitcoin block contained in the IC block. It is crucial that the block maker propose a block only if it is guaranteed that the block will be successfully validated by all honest replicas as otherwise consensus of the subnet may fail, causing the entire IC block to be dropped.
+
Every IC block is broadcast to the subnet nodes and needs to go through the notarization and finalization process. The notarization process is extended for the Bitcoin integration: Each replica performs a deterministic validity check of the Bitcoin payload contained in the IC block. It is crucial that the block maker propose a block only if it is guaranteed that the block will be successfully validated by all honest replicas as otherwise consensus may not be reached, causing the entire IC block to be dropped.
  
Once the IC block with the Bitcoin block payload has been validated successfully, finalization proceeds without changes. Once the block is finalized, the Bitcoin payload needs to be extracted in the message routing layer and posted to the according subnet queue to get executed. When the Bitcoin block reaches the execution layer, it gets executed by the BTC canister at the execution layer: The block is validated and its view of the Bitcoin blockchain updated accordingly.
+
Once the IC block with the Bitcoin payload has been validated successfully, finalization proceeds without changes. Once the block is finalized, the Bitcoin payload needs to be extracted in the message routing layer and posted to the correct subnet queue for execution. When the Bitcoin payload reaches the execution layer, it gets sent to the Bitcoin canister where the payload is validated and the state of the Bitcoin canister is updated accordingly.
  
Creating a Bitcoin transaction requires computing one ECDSA signature per UTXO used as transaction input. Canisters can request ECDSA signatures from a threshold ECDSA API that is implemented as part of dedicated ECDSA signing subnets. One such subnet will be deployed initially and, if demand increases, multiple signing subnets may be made available in the future. Figure 1 shows the threshold ECDSA functionality in a simplified manner as part of the Bitcoin-enabled subnet instead of being located on a separate subnet. The threshold ECDSA API makes it possible for a canister to request an ECDSA signature computed jointly by the replicas of the ECDSA subnet based on a secret-shared private key.
+
Creating a Bitcoin transaction requires computing one ECDSA signature per UTXO used as transaction input. Canisters can request ECDSA signatures through the threshold ECDSA API that is implemented as part of dedicated chain-key signing subnets. There is one such subnet deployed and, if demand increases, multiple signing subnets may be made available in the future. Figure 1 shows the threshold ECDSA functionality in a simplified manner as part of the Bitcoin-enabled subnet instead of being located on a separate subnet. The threshold ECDSA API makes it possible for a canister to request an ECDSA signature computed jointly by the replicas of the ECDSA subnet based on a secret-shared private key.
  
 
== Technical Details ==
 
== Technical Details ==
  
As described in the previous section, canisters interact with the (virtual) Bitcoin canister to make use of the Bitcoin integration API. The Bitcoin canister in turn depends on the Bitcoin adapter, which is the component that interacts with the Bitcoin network.
+
As described in the previous section, canisters interact with the Bitcoin canister to retrieve information about the Bitcoin state and send transactions. The Bitcoin canister in turn depends on the Bitcoin adapter, which is the component that interacts with the Bitcoin network. In this section, technical details about the individual components are provided, starting bottom-up with the Bitcoin adapter.
In this section, technical details about the individual components are provided, starting bottom-up with the Bitcoin adapter.
 
 
 
Note that some technical details are '''not''' implemented in the [[#Developer Preview|developer preview]], which is discussed in the next section. For example, several validity checks are not performed. These omissions are not crucial for a local testing environment.
 
  
 
=== Bitcoin Adapter ===
 
=== Bitcoin Adapter ===
Line 52: Line 50:
 
==== Connecting to Bitcoin Nodes ====
 
==== Connecting to Bitcoin Nodes ====
  
By default, the Bitcoin adapter connects to 8 randomly chosen Bitcoin nodes but the number of connections is configurable.
+
By default, the Bitcoin adapter connects to 5 randomly chosen Bitcoin nodes but the number of connections is configurable. In order to ensure that the Bitcoin adapter of each replica connects to a different random set with high probability, the Bitcoin adapter queries the Bitcoin nodes for addresses until it has received 2000 addresses and randomly chooses nodes from these addresses until 5 connections have been established. Experiments showed that this process results in the Bitcoin adapter of each replica connecting to mostly different addresses.
In order to ensure that the Bitcoin adapter of each replica connects to a different random set with high probability, the Bitcoin adapter queries the seed nodes for addresses until it has received at least 1000 addresses and randomly chooses nodes from these addresses until the desired number of connections have been established.
 
Experiments showed that this process results in the Bitcoin adapter of each replica connecting to mostly different addresses.
 
  
 
==== State ====
 
==== State ====
  
The Bitcoin adapter aims to maintain the following state:
+
The Bitcoin adapter maintains the following state:
 
* All Bitcoin block headers.
 
* All Bitcoin block headers.
 
* A cache for Bitcoin blocks, which it expects the Bitcoin canister to request next.
 
* A cache for Bitcoin blocks, which it expects the Bitcoin canister to request next.
 
* A cache for outgoing transactions that are advertised but not transmitted to Bitcoin nodes yet.
 
* A cache for outgoing transactions that are advertised but not transmitted to Bitcoin nodes yet.
  
Initially, the adapter does not have any block headers and the caches are empty.
+
Initially, the adapter only has the hard-coded genesis block header and the caches are empty.
  
 
==== Bitcoin Adapter in Operation ====
 
==== Bitcoin Adapter in Operation ====
  
When the Bitcoin adapter is started, it connects to Bitcoin nodes and starts pulling in block headers from genesis until it has caught up. For each downloaded block header, the Bitcoin adapter performs the following checks:
+
When the Bitcoin adapter is started, it connects to Bitcoin nodes and starts pulling in block headers until it is fully synced. For each downloaded block header, the Bitcoin adapter performs the following checks:
  
 
* The block header is well-formed, i.e., it can be parsed as a correct block header.
 
* The block header is well-formed, i.e., it can be parsed as a correct block header.
Line 74: Line 70:
 
* The timestamp in the block header is greater than the [https://en.bitcoin.it/wiki/Block_timestamp median of the 11 previous blocks].
 
* The timestamp in the block header is greater than the [https://en.bitcoin.it/wiki/Block_timestamp median of the 11 previous blocks].
  
The caches remain empty until messages from the Bitcoin canister are received.
+
The caches remain empty until requests from the Bitcoin canister are received. Periodically, the Bitcoin canister sends a list of block header hashes of the recent block headers for which it already has the full blocks (containing all transactions). Details on which block header hashes are sent are provided in the section about the Bitcoin canister.
Periodically, the Bitcoin canister sends a list of block header hashes of the recent block headers for which it already has the full blocks (containing all transactions). Details on which block header hashes are sent is described in more detail in the section about the Bitcoin canister.
 
  
The Bitcoin adapter checks if it has any block headers on the chain with the most hash work (typically the longest chain) whose hashes are not in the received list, indicating that the Bitcoin canister did not receive the corresponding blocks yet.
+
The Bitcoin adapter checks if it has any blocks that the Bitcoin canister is missing and responds with a message containing the missing blocks, prioritizing blocks with a lower height. Multiple blocks can be returned in a single message up to a soft cap of 2 MB, ensuring that at least one Bitcoin block can be returned even if its size exceeds 2 MB. This upper bound implies that only one block is returned for most of the recent blocks whose size is typically over 1 MB. The ability to send multiple blocks in one message is advantageous mainly for the Bitcoin testnet where blocks are usually significantly smaller. In addition to the Bitcoin block(s), the adapter also appends up to 100 block headers of subsequent blocks to its response. The purpose of these block headers is explained in the section about the Bitcoin canister.
If the Bitcoin adapter has some of the missing blocks that extend the current chain in the Bitcoin canister in its cache, it will respond with a message containing the next missing blocks including the corresponding block headers up to a total maximum size of 2 MB. This upper bound implies that only one block (and block header) is returned for the recent blocks whose size is typically over 1 MB. The ability to send multiple blocks in one message is useful to ingest older blocks more quickly as they were significantly smaller.
 
  
If the Bitcoin adapter does not have the missing blocks in its cache, it immediately returns an empty message in order not to delay consensus. Having an accurate view on the state of the Bitcoin canister, the Bitcoin adapter then downloads the next missing blocks so that it can pack them into a return message in a future request from the Bitcoin canister.
+
If the Bitcoin adapter does not have the missing blocks in its cache, it immediately returns an empty message to prevent an unnecessary delay in the Consensus layer. Having an accurate view on the state of the Bitcoin canister, the Bitcoin adapter then downloads the next missing blocks so that it can put them into a return message in a future request from the Bitcoin canister. Since the Bitcoin adapter does not keep track of transactions, it cannot verify the validity of transactions in received blocks. However, in order to prevent spamming the Bitcoin canister with invalid blocks, it performs a few basic checks:
Since the Bitcoin adapter does not keep track of transactions, it cannot verify the validity of transactions in received blocks. However, in order to prevent spamming the Bitcoin canister with invalid blocks, it performs a few basic checks:
 
 
* The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
 
* The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
 
* The Merkle tree root hash corresponds to the hash in the corresponding block header.
 
* The Merkle tree root hash corresponds to the hash in the corresponding block header.
  
Blocks are dropped from the cache as soon as the received set of block header hashes indicates that the Bitcoin canister has received the block.
 
 
When the Bitcoin adapter receives outbound transactions, they are placed in the transaction cache and advertised to the Bitcoin network. As soon as the transaction has been transmitted to the connected Bitcoin nodes, the transaction is removed from the cache.
 
 
=== Passing through Consensus ===
 
  
Technically, the Bitcoin adapter of a replica is queried for Bitcoin blocks whenever the replica is chosen as the next (IC) block maker. When the Bitcoin adapter’s response contains one or more Bitcoin blocks, Consensus calls a function to check the validity of the Bitcoin blocks before putting them into an IC block.
 
It is important to ensure that the validity checks lead to consistent results across all replicas in a subnet as otherwise the whole IC block might be dropped as mentioned before. The validity checks must therefore be a deterministic function, i.e., factors such as local time and the locally available state of the Bitcoin adapter cannot be considered. The following validity checks are performed:
 
* The block header is well-formed, i.e., it can be parsed as a correct block header.
 
* The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
 
* The Merkle tree root hash corresponds to the hash in the corresponding block header.
 
  
Again, the transactions are not validated at this stage.
+
Blocks are dropped from the cache as soon as the received set of block header hashes indicates that the Bitcoin canister has received the blocks.
  
Once the IC block has passed through consensus (and message routing), the Bitcoin blocks (and corresponding block headers) are offered to the Bitcoin canister for ingestion.
+
When the Bitcoin adapter receives outbound transactions, they are placed in the transaction cache and advertised to the Bitcoin network. The transactions are transmitted to the connected Bitcoin peers upon request and removed from the cache after 10 minutes. There is no guarantee that the transactions are ever requested by connected peers.
  
 
=== Bitcoin Canister ===
 
=== Bitcoin Canister ===
  
The Bitcoin canister is a virtual canister, similar to the [https://smartcontracts.org/docs/interface-spec/index.html#ic-management-canister management canister], which means that it appears to other canisters as a regular canister but it is effectively part of the replica itself.
+
As mentioned above, the Bitcoin canister is the main component as it provides access to the Bitcoin integration API.
The Bitcoin integration API is offered through the Bitcoin canister to enable other canisters to incorporate Bitcoin functionality.
 
  
 
==== State ====
 
==== State ====
  
The Bitcoin canister stores the following state:
+
For a certain block height h, defined below, the Bitcoin canister stores the following state:
* The full UTXO set from genesis up to a certain block height h.
+
* The full UTXO set from genesis up to block height h.
* Blocks including their block headers starting at height h.
+
* The balances of all addresses in the UTXO set.
* The set of outgoing transactions.
+
* Blocks including their block headers starting from block height h+1.
 +
* The full history of block headers of ''stable blocks'' (the notion of stability is defined below).
  
 
Since the Bitcoin canister does not store the full history of transactions, it must decide when it is safe to drop a block, relying only on the information in the UTXO set that it maintains.
 
Since the Bitcoin canister does not store the full history of transactions, it must decide when it is safe to drop a block, relying only on the information in the UTXO set that it maintains.
  
Due to the risk of long-running forks, the Bitcoin canister does not use the confirmation count to determine when to drop a block. Instead, it uses a slightly more complex concept, which we call stability. Simply put, we consider a block stable if there are a certain number of subsequent blocks, reducing the risk that the block will be discarded in the future, and the tip of any other fork is also at least the same number of blocks behind.
+
==== Fork Resolution ====
More formally, if h(b) denotes the number of predecessor blocks of block b since genesis and d(b) denotes the length of the longest successor path starting at block b, stability is defined as follows.
+
 
 +
The Bitcoin canister uses [https://en.bitcoinwiki.org/wiki/Difficulty_in_Mining block difficulty] for fork resolution to determine the "correct" chain just like Bitcoin. Concretely, the chain with the largest sum of block difficulties is considered the "correct" chain.
 +
 
 +
Due to the risk of long-running forks, the Bitcoin canister further uses a concept called ''stability'' to determine which blocks can be dropped and to count confirmations for transactions. Simply put, a block is considered ''stable'' if there is a certain number of subsequent blocks, reducing the risk that the block will be discarded in the future, and the tip of any fork is also at least the same number of blocks behind the tip of the chain containing the block.
 +
 
 +
More formally, if <code>h(b)</code>  denotes the number of predecessor blocks of block <code>b</code> since genesis and <code>d(b)</code> denotes the length of the longest successor path starting at and including block <code>b</code>, stability is defined as follows.
 +
 
 +
Definition (𝜹-stability): Let B denote the set of locally available blocks.
 +
For a parameter 𝜹>0, it is said that a block b is 𝜹-stable if the following conditions hold:
 +
* d(b) ≥ 𝜹
 +
* ∀ b’ ∈ B \ {b}, h(b’) = h(b): d(b) - d(b’) ≥ 𝜹
 +
 
 +
Note that the genesis block is always considered stable. Given the latest stable block and a set of unstable blocks, a generalization of 𝜹-stability, dubbed difficulty-based 𝜹-stability, is used to determine when an unstable block becomes stable. Thus, difficulty-based stability is used to define the cut-off block height h mentioned in the description of the state above: h is the largest height with a difficulty-based 𝜹-stable block.
 +
 
 +
The difference to 𝜹-stability is its use of a difficulty-based depth function <code>d<sub>h</sub>(b)</code>: The depth <code>d<sub>h</sub>(b)</code> is the sum of the difficulty of block <code>b</code> itself and all successor blocks, divided by the difficulty of the latest stable block.
  
Definition (𝜹-stability): For a parameter 𝜹>0, we say that a block is 𝜹-stable if the following conditions hold:
+
Note that if all blocks have the same difficulty, then <code>d(b) = d<sub>h</sub>(b)</code> for every block <code>b</code>.
* d(b) ≥ 𝜹
 
* ∀ b’ ∈ B, h(b’) = h(b): d(b) - d(b’) ≥ 𝜹
 
  
The Bitcoin canister is configured with a stability threshold 𝜹 of 144, i.e., if there are no forks, the Bitcoin canister keeps all blocks around for about one day (at one block every 10 minutes on average). Once a block becomes 𝜹-stable, the transactions are applied to the UTXO set and the block is discarded. Thus, stability is used to define the cut-off block height h mentioned in the description of the state above.
+
The Bitcoin canister is configured with a ''difficulty-based stability threshold'' 𝜹 of 144, i.e., if there are no forks, the Bitcoin canister keeps all blocks around for about one day (at one block every 10 minutes on average). Once a block becomes "difficulty-based 144-stable", the transactions are applied to the UTXO set and the block is discarded.  
All blocks with a stability below the threshold are considered unstable.
 
  
 
==== Bitcoin Canister in Operation ====
 
==== Bitcoin Canister in Operation ====
  
When requesting an update from the Bitcoin adapter, the Bitcoin canister sends a message containing the hashes of all unstable blocks to the Bitcoin adapter, which uses the hashes to determine which blocks the Bitcoin canister is missing, if any.
+
When requesting an update from the Bitcoin adapter, the Bitcoin canister sends a message containing the hashes of all ''unstable blocks'' to the Bitcoin adapter, which uses the hashes to determine which blocks the Bitcoin canister is missing, if any. When receiving blocks and block headers from the Bitcoin adapter, the following validity checks are performed for each block/block header pair:
When receiving blocks and block headers from the Bitcoin adapter, the following validity checks are performed for each block/block header pair:
 
 
* The block header is well-formed, i.e., it can be parsed as a correct block header.
 
* The block header is well-formed, i.e., it can be parsed as a correct block header.
 
* The hash work in the block header is sufficient based on the difficulty target.
 
* The hash work in the block header is sufficient based on the difficulty target.
 
* The block header points to a known predecessor.
 
* The block header points to a known predecessor.
 +
* The timestamp in the block header is greater than the median of the 11 previous blocks.
 +
* The timestamp in the block header is at most two hours in the future with respect to IC time.
 
* The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
 
* The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
 
* The Merkle tree root hash corresponds to the hash in the corresponding block header.
 
* The Merkle tree root hash corresponds to the hash in the corresponding block header.
* All transactions are valid, i.e., the signatures are correct and only unspent outputs are consumed.
 
  
If the verification is successful, the block is added to the list of unstable blocks. Additionally, if a block becomes 𝜹-stable as a result, the UTXO set is updated based on the transaction in this block and the block is discarded.
+
It is important to note that the validity of transactions is '''not''' verified in the Bitcoin canister. The Bitcoin canister relies on the proof of work that goes into the blocks and the verification of the blocks in the Bitcoin network. For a newly discovered block, a regular Bitcoin (full) node therefore provides a higher level of security than the Bitcoin canister, which implies that it is advisable to set the number of confirmations to a reasonably large value to gain confidence in the correctness of the information provided by the Bitcoin canister.
 +
 
 +
If the verification is successful, the block is added to the list of unstable blocks. Additionally, if a block becomes (difficulty-based 144-)stable as a result, the UTXO set is updated based on the transaction in this block and the block is discarded, keeping only the corresponding block header.
 +
 
 +
As mentioned above, the Bitcoin canister may also receive block headers of missing blocks from the Bitcoin adapter. The Bitcoin canister uses this information to determine if it is currently in syncing mode or fully synced with respect to the Bitcoin adapters' views of the Bitcoin blockchain. Concretely, the Bitcoin canister is in the state “synced” if the difference between the maximum height of all block headers and the maximum height of all unstable blocks is at most 2. Otherwise, the canister is in the state “syncing”. The Bitcoin canister only acts on requests if it is in the state “synced”, i.e., all requests are rejected in the state "syncing". This mechanism is meant to ensure that the Bitcoin canister only provides up-to-date information about the Bitcoin blockchain state to prevent Bitcoin dapps from making decisions based on outdated information.
 +
 
 +
The (virtual) management canister exposes the following Bitcoin integration API:
 +
* <span style="font-family: 'Courier New';"><code>bitcoin_get_utxos</code></span>: The function returns the unspent transaction outputs (UTXOs) of a given Bitcoin address.
 +
* <span style="font-family: 'Courier New';"><code>bitcoin_get_balance</code></span>: The function returns the balance of a given Bitcoin address.
 +
* <code>bitcoin_get_block_headers</code>: The function returns the block headers in the given range of heights.
 +
* <span style="font-family: 'Courier New';"><code>bitcoin_send_transaction</code></span>: The function sends the given transaction to the Bitcoin network.
 +
*<span style="font-family: 'Courier New';"><code>bitcoin_get_current_fee_percentiles</code></span>: The function returns the percentiles of the fees, in satoshi per virtual byte, for the last 10,000 transactions.
 +
 
 +
The following address formats are supported:
 +
 
 +
* Pay to public key hash (P2PKH)
 +
* Pay to script hash (P2SH)
 +
* Pay to witness public key hash (P2WPKH)
 +
* Pay to witness script hash (P2WSH)
 +
* Pay to taproot (P2TR)
 +
 
 +
Details about the Bitcoin integration API can be found in the [https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-bitcoin-api Internet Computer specification].
 +
 
 +
In order to reduce the risk of inconsistencies due to forks, confirmations are counted conservatively, using 𝜹-stability (and not difficulty-based 𝜹-stability). The ''stability count'' of a block is defined as the largest 𝜹 so that the block is 𝜹-stable. The number of confirmations for a transaction in a block is defined as the stability count of the block.
 +
 
 +
While this rule may seem complicated, it has several nice properties: If there are no forks, the number of confirmations for each transaction is exactly what one would expect: Once a transaction is in a block, it has one confirmation, if there is a subsequent block, it has two confirmations and so forth. However, if there are multiple competing forks with similar heights, the number of confirmations will remain low for blocks on the competing forks until one fork prevails, at which point the number of confirmations starts to increase.
 +
In short, the rule is meant to ensure that a large number of confirmations, based on the stability count, implies a large probability that the transaction will not be undone even in the presence of competing forks.
 +
 
 +
The following figure shows an example of a chain with two forks. The numbers inside the blocks are the stability counts, which correspond to the number of confirmations for transactions in the blocks. Unlike regular confirmation counts, the stability counts can be negative. Only blocks with a positive stability counts are considered when answering requests.
 +
 
 +
[[File:Forks and stability.png|thumb|center|A chain with two forks and the resulting stability counts (inside the blocks) is shown.|alt=|600x600px]]
  
The Bitcoin canister exposes the following API:
+
When the Bitcoin canister receives an outbound transaction and the transaction passes a basic verification that it can be decoded, the Bitcoin canister forwards the transaction to the Bitcoin adapter as described above.
get_utxos: The function returns the unspent transaction outputs (UTXOs) of a given Bitcoin address.
+
There is no guarantee that the transaction will ever be included in a block. It is up to the issuer of the transaction to maximize the chances to get the transaction into a block by making sure that the transaction is valid and including an appropriate miner fee.
get_balance: The function returns the balance of a given Bitcoin address.
 
send_transaction: The function sends the given transaction to the Bitcoin network.
 
Details about the API can be found on this GitHub page.
 
When answering get_utxos and get_balance calls, which have an optional min_confirmations parameter, the Bitcoin canister considers both the UTXO state as well as all transactions in the unstable blocks that have at least the requested minimum number of confirmations. In other words, after extracting the relevant unspent outputs from the UTXO set, the unstable blocks are parsed to find additional unspent outputs. Moreover, if there are transactions that consume any of the collected outputs, the outputs are dropped as they are considered spent.
 
  
In order to reduce the risk of inconsistencies due to forks, confirmations are counted conservatively, again using 𝜹-stability. We say that the stability count of a block is the largest
+
=== Bitcoin Testnet Release ===
𝜹 so that the block is 𝜹-stable. The process to determine the number of confirmations for transactions is as follows:
 
The largest block height is identified with only a single block at this height.
 
The chain of unstable blocks up to the block identified in the first step is considered, and the number of confirmations for a transaction in a block is defined as the stability count of the block plus 1.
 
  
While this rule may seem complicated, it has several nice properties: If there are no forks, the number of confirmations for each transaction is exactly what one would expect: Once a transaction is in a block, it has one confirmation, if there is a subsequent block, it has two confirmations and so forth. However, if there are multiple competing forks with similar heights, the number of confirmations will remain low until one chain prevails, at which point the number of confirmations start to increase.
+
In summer 2022, the Bitcoin testnet integration was released on the IC. The Testnet Integration is intended to allow engineers to interact with the Bitcoin API on the IC, but only with Bitcoin Testnet and a threshold ECDSA test key. The goal is to allow engineers to build and test their Bitcoin-integrated dApps using a beta running on the IC. This is the next step after the previously-launched developer preview that facilitates dApp development through the community.
In short, the rule is meant to ensure that a large number of confirmations implies a large probability that the transaction will not be undone even in the presence of competing forks.
+
It is strongly advised that engineers do not associate any value with the threshold ECDSA test key as it may be deleted at some point in time and it is running only on regular-size subnet.
  
When the Bitcoin canister receives an outbound transaction and the transaction passes verification checks, it forwards the transaction to the Bitcoin adapter as described above.
+
=== Bitcoin Mainnet Release ===
The Bitcoin canister caches the transaction and periodically resubmits it if the transaction does not appear in a block. The transaction is dropped once it appears in a block or it expires after 24 hours.
 
  
=== Developer Preview ===
+
The Bitcoin integration was released on the IC in the beginning of December 2022, making all Bitcoin integration features available for Bitcoin mainnet.
  
The developer preview released on February 3, 2022, is an early release of the Bitcoin integration functionality. It is intended to be used by developers to start implementing smart contracts against the API and to give feedback so the API can be improved with community feedback towards the final release.
+
==See Also==
The Developer Preview is available only as part of the local development environment (Canister SDK) and does not integrate with the Bitcoin mainnet or testnet. Instead, it runs a local bitcoin node (bitcoind) in regression testing ("regtest") mode that simulates a real Bitcoin network, while being fully controlled by the developer. This is preferable to a Bitcoin network integration for a local development environment due to being better suitable for testing because of the deterministic behaviour of the local Bitcoin node.
+
* '''Code Bitcoin on the Internet Computer: [https://internetcomputer.org/bitcoin-integration/ https://internetcomputer.org/bitcoin-integration]'''
The developer preview release makes all Bitcoin-related logic of the feature available through the APIs get_utxos, get_balance, and send_transaction. However, the integration with the IC protocol stack is simplified: It does not use the custom integration with the IC protocol layers, particularly consensus, but adds an Adapter Shim as external component that hooks up the Adapter to the regular iC protocol stack through query calls and ingress messages. Users of the developer preview need to install the release on top of their local Canister SDK environment and launch it. The Bitcoin canister is exposed as a Wasm canister instead of a virtual canister implemented as part of the replica, much like the management canister, as in the final release.
 

Latest revision as of 08:12, 18 September 2024

Overview

Bitcoin is a decentralized digital currency based on an open-source P2P protocol. Bitcoin uses the unspent transaction output (UTXO) accounting model, i.e., transactions create outputs which are fully consumed when used as inputs for other transactions that create new transaction outputs.

Bitcoin is a payment network without support for smart contracts. Smart contract support for Bitcoin through the Internet Computer adds tremendous value: It leverages the combined strength of the Bitcoin network as the world's digital gold reserve and the Internet Computer as a platform for securely and efficiently executing smart contracts. An example class of applications is decentralized finance (DeFi) built around Bitcoin, which can currently be implemented only with wrapped Bitcoin requiring additional trusted entities. Moreover, Bitcoin can be used to pay for any kind of services on the Internet Computer, which opens up a sheer endless number of application scenarios.

The Internet Computer is integrated with the Bitcoin blockchain to make powerful smart contract functionality available for Bitcoin through a direct, bridgeless, integration of the two blockchains. "Direct" in this context means that no trust assumptions are required other than trust in the correct functioning of the Bitcoin network and the Internet Computer. In other words, there are no additional parties required, such as bridges or other types of intermediaries, resulting in a much cleaner and more secure integration.

This direct integration has the following main features:

  • Canisters can have Bitcoin addresses (and therefore receive and hold bitcoin directly on the Bitcoin blockchain).
  • Canisters can access the balance and UTXO set of Bitcoin addresses.
  • Canisters can access block headers on the Bitcoin blockchain.
  • Canisters can securely sign Bitcoin transactions.
  • Canisters can submit Bitcoin transactions to the Bitcoin network.

The direct, bridgeless, integration relies on a novel threshold ECDSA protocol that enables a subnet to compute ECDSA signatures based on a secret-shared private key upon a canister's request. With this protocol, each canister can "control" a vast number of derivable ECDSA keys and obtain signatures for them, making it possible for canisters to receive, hold, and transfer bitcoin directly on the Bitcoin blockchain in a secure manner. Naturally, a canister must be able to retrieve the UTXOs associated with its Bitcoin addresses. To this end, the Internet Computer pulls in blocks directly from the Bitcoin network. In the following, the underlying architecture of this integration is explored in more detail.

Architecture

This section presents the architecture for the direct integration with the Bitcoin blockchain on a high level. The integration changes and adds components at every layer of the Internet Computer (IC) protocol stack.

A high-level overview of the Bitcoin integration architecture.

The main component is the Bitcoin canister, which runs on a system subnet and exposes the Bitcoin integration endpoints through the virtual management canister interface. The API offers functions to query Bitcoin state (UTXOs, balances, and current transaction fees) and to submit transactions.

In order to serve up-to-date information about the Bitcoin state, Bitcoin blocks must be pulled continuously into the Internet Computer from the Bitcoin network and the set of all UTXOs (referred to as the "UTXO set") updated based on the transaction inputs and outputs contained in the blocks.

The Bitcoin canister maintains a set of recent Bitcoin blocks and the entire UTXO set, which are used together to respond to UTXO and balance queries of canisters. Additionally, it stores the entire list of Bitcoin block headers.

The Bitcoin adapter, an OS-level process external to the replica, connects to multiple Bitcoin nodes chosen randomly using Bitcoin's peer discovery protocol. The Bitcoin adapter maintains a local copy of the whole block header chain as well as a small cache of blocks that it provides to the replica upon request.

In every IC round, the block maker, a core component of the consensus layer, sends a request from the Bitcoin canister to the Bitcoin adapter and gets the response, which is then included in the IC block's payload. More precisely, the Bitcoin canister makes a call to access internal replica APIs to store the request in the replicated state, where it is picked up by the payload builder in the Consensus layer. The payload builder uses interprocess communication to relay the request to the external Bitcoin adapter, which handles the request and returns the result to the payload builder. The payload builder then incorporates the result in the IC block. A request contains hashes of recent block headers for which the Bitcoin canister has the block of transactions as well as the outgoing transactions. The Bitcoin adapter compares the received block hashes against its view of the Bitcoin network: if its cache contains one or more successors of the blocks that the Bitcoin canister has, it returns one or more of these blocks. Furthermore, it adds the transactions received in the request to a queue for outgoing transactions to be submitted asynchronously to the Bitcoin network.

Every IC block is broadcast to the subnet nodes and needs to go through the notarization and finalization process. The notarization process is extended for the Bitcoin integration: Each replica performs a deterministic validity check of the Bitcoin payload contained in the IC block. It is crucial that the block maker propose a block only if it is guaranteed that the block will be successfully validated by all honest replicas as otherwise consensus may not be reached, causing the entire IC block to be dropped.

Once the IC block with the Bitcoin payload has been validated successfully, finalization proceeds without changes. Once the block is finalized, the Bitcoin payload needs to be extracted in the message routing layer and posted to the correct subnet queue for execution. When the Bitcoin payload reaches the execution layer, it gets sent to the Bitcoin canister where the payload is validated and the state of the Bitcoin canister is updated accordingly.

Creating a Bitcoin transaction requires computing one ECDSA signature per UTXO used as transaction input. Canisters can request ECDSA signatures through the threshold ECDSA API that is implemented as part of dedicated chain-key signing subnets. There is one such subnet deployed and, if demand increases, multiple signing subnets may be made available in the future. Figure 1 shows the threshold ECDSA functionality in a simplified manner as part of the Bitcoin-enabled subnet instead of being located on a separate subnet. The threshold ECDSA API makes it possible for a canister to request an ECDSA signature computed jointly by the replicas of the ECDSA subnet based on a secret-shared private key.

Technical Details

As described in the previous section, canisters interact with the Bitcoin canister to retrieve information about the Bitcoin state and send transactions. The Bitcoin canister in turn depends on the Bitcoin adapter, which is the component that interacts with the Bitcoin network. In this section, technical details about the individual components are provided, starting bottom-up with the Bitcoin adapter.

Bitcoin Adapter

The Bitcoin adapter interacts with the Bitcoin network to obtain block headers and blocks, and publish Bitcoin transactions issued by canisters.

Connecting to Bitcoin Nodes

By default, the Bitcoin adapter connects to 5 randomly chosen Bitcoin nodes but the number of connections is configurable. In order to ensure that the Bitcoin adapter of each replica connects to a different random set with high probability, the Bitcoin adapter queries the Bitcoin nodes for addresses until it has received 2000 addresses and randomly chooses nodes from these addresses until 5 connections have been established. Experiments showed that this process results in the Bitcoin adapter of each replica connecting to mostly different addresses.

State

The Bitcoin adapter maintains the following state:

  • All Bitcoin block headers.
  • A cache for Bitcoin blocks, which it expects the Bitcoin canister to request next.
  • A cache for outgoing transactions that are advertised but not transmitted to Bitcoin nodes yet.

Initially, the adapter only has the hard-coded genesis block header and the caches are empty.

Bitcoin Adapter in Operation

When the Bitcoin adapter is started, it connects to Bitcoin nodes and starts pulling in block headers until it is fully synced. For each downloaded block header, the Bitcoin adapter performs the following checks:

  • The block header is well-formed, i.e., it can be parsed as a correct block header.
  • The previous block field points to a locally available block header.
  • The hash work in the block header is sufficient based on the difficulty target.
  • The timestamp in the block header is greater than the median of the 11 previous blocks.

The caches remain empty until requests from the Bitcoin canister are received. Periodically, the Bitcoin canister sends a list of block header hashes of the recent block headers for which it already has the full blocks (containing all transactions). Details on which block header hashes are sent are provided in the section about the Bitcoin canister.

The Bitcoin adapter checks if it has any blocks that the Bitcoin canister is missing and responds with a message containing the missing blocks, prioritizing blocks with a lower height. Multiple blocks can be returned in a single message up to a soft cap of 2 MB, ensuring that at least one Bitcoin block can be returned even if its size exceeds 2 MB. This upper bound implies that only one block is returned for most of the recent blocks whose size is typically over 1 MB. The ability to send multiple blocks in one message is advantageous mainly for the Bitcoin testnet where blocks are usually significantly smaller. In addition to the Bitcoin block(s), the adapter also appends up to 100 block headers of subsequent blocks to its response. The purpose of these block headers is explained in the section about the Bitcoin canister.

If the Bitcoin adapter does not have the missing blocks in its cache, it immediately returns an empty message to prevent an unnecessary delay in the Consensus layer. Having an accurate view on the state of the Bitcoin canister, the Bitcoin adapter then downloads the next missing blocks so that it can put them into a return message in a future request from the Bitcoin canister. Since the Bitcoin adapter does not keep track of transactions, it cannot verify the validity of transactions in received blocks. However, in order to prevent spamming the Bitcoin canister with invalid blocks, it performs a few basic checks:

  • The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
  • The Merkle tree root hash corresponds to the hash in the corresponding block header.


Blocks are dropped from the cache as soon as the received set of block header hashes indicates that the Bitcoin canister has received the blocks.

When the Bitcoin adapter receives outbound transactions, they are placed in the transaction cache and advertised to the Bitcoin network. The transactions are transmitted to the connected Bitcoin peers upon request and removed from the cache after 10 minutes. There is no guarantee that the transactions are ever requested by connected peers.

Bitcoin Canister

As mentioned above, the Bitcoin canister is the main component as it provides access to the Bitcoin integration API.

State

For a certain block height h, defined below, the Bitcoin canister stores the following state:

  • The full UTXO set from genesis up to block height h.
  • The balances of all addresses in the UTXO set.
  • Blocks including their block headers starting from block height h+1.
  • The full history of block headers of stable blocks (the notion of stability is defined below).

Since the Bitcoin canister does not store the full history of transactions, it must decide when it is safe to drop a block, relying only on the information in the UTXO set that it maintains.

Fork Resolution

The Bitcoin canister uses block difficulty for fork resolution to determine the "correct" chain just like Bitcoin. Concretely, the chain with the largest sum of block difficulties is considered the "correct" chain.

Due to the risk of long-running forks, the Bitcoin canister further uses a concept called stability to determine which blocks can be dropped and to count confirmations for transactions. Simply put, a block is considered stable if there is a certain number of subsequent blocks, reducing the risk that the block will be discarded in the future, and the tip of any fork is also at least the same number of blocks behind the tip of the chain containing the block.

More formally, if h(b) denotes the number of predecessor blocks of block b since genesis and d(b) denotes the length of the longest successor path starting at and including block b, stability is defined as follows.

Definition (𝜹-stability): Let B denote the set of locally available blocks.
For a parameter 𝜹>0, it is said that a block b is 𝜹-stable if the following conditions hold:
* d(b) ≥ 𝜹
* ∀ b’ ∈ B \ {b}, h(b’) = h(b): d(b) - d(b’) ≥ 𝜹

Note that the genesis block is always considered stable. Given the latest stable block and a set of unstable blocks, a generalization of 𝜹-stability, dubbed difficulty-based 𝜹-stability, is used to determine when an unstable block becomes stable. Thus, difficulty-based stability is used to define the cut-off block height h mentioned in the description of the state above: h is the largest height with a difficulty-based 𝜹-stable block.

The difference to 𝜹-stability is its use of a difficulty-based depth function dh(b): The depth dh(b) is the sum of the difficulty of block b itself and all successor blocks, divided by the difficulty of the latest stable block.

Note that if all blocks have the same difficulty, then d(b) = dh(b) for every block b.

The Bitcoin canister is configured with a difficulty-based stability threshold 𝜹 of 144, i.e., if there are no forks, the Bitcoin canister keeps all blocks around for about one day (at one block every 10 minutes on average). Once a block becomes "difficulty-based 144-stable", the transactions are applied to the UTXO set and the block is discarded.

Bitcoin Canister in Operation

When requesting an update from the Bitcoin adapter, the Bitcoin canister sends a message containing the hashes of all unstable blocks to the Bitcoin adapter, which uses the hashes to determine which blocks the Bitcoin canister is missing, if any. When receiving blocks and block headers from the Bitcoin adapter, the following validity checks are performed for each block/block header pair:

  • The block header is well-formed, i.e., it can be parsed as a correct block header.
  • The hash work in the block header is sufficient based on the difficulty target.
  • The block header points to a known predecessor.
  • The timestamp in the block header is greater than the median of the 11 previous blocks.
  • The timestamp in the block header is at most two hours in the future with respect to IC time.
  • The block is well-formed, i.e., it can be parsed as a correct Bitcoin block.
  • The Merkle tree root hash corresponds to the hash in the corresponding block header.

It is important to note that the validity of transactions is not verified in the Bitcoin canister. The Bitcoin canister relies on the proof of work that goes into the blocks and the verification of the blocks in the Bitcoin network. For a newly discovered block, a regular Bitcoin (full) node therefore provides a higher level of security than the Bitcoin canister, which implies that it is advisable to set the number of confirmations to a reasonably large value to gain confidence in the correctness of the information provided by the Bitcoin canister.

If the verification is successful, the block is added to the list of unstable blocks. Additionally, if a block becomes (difficulty-based 144-)stable as a result, the UTXO set is updated based on the transaction in this block and the block is discarded, keeping only the corresponding block header.

As mentioned above, the Bitcoin canister may also receive block headers of missing blocks from the Bitcoin adapter. The Bitcoin canister uses this information to determine if it is currently in syncing mode or fully synced with respect to the Bitcoin adapters' views of the Bitcoin blockchain. Concretely, the Bitcoin canister is in the state “synced” if the difference between the maximum height of all block headers and the maximum height of all unstable blocks is at most 2. Otherwise, the canister is in the state “syncing”. The Bitcoin canister only acts on requests if it is in the state “synced”, i.e., all requests are rejected in the state "syncing". This mechanism is meant to ensure that the Bitcoin canister only provides up-to-date information about the Bitcoin blockchain state to prevent Bitcoin dapps from making decisions based on outdated information.

The (virtual) management canister exposes the following Bitcoin integration API:

  • bitcoin_get_utxos: The function returns the unspent transaction outputs (UTXOs) of a given Bitcoin address.
  • bitcoin_get_balance: The function returns the balance of a given Bitcoin address.
  • bitcoin_get_block_headers: The function returns the block headers in the given range of heights.
  • bitcoin_send_transaction: The function sends the given transaction to the Bitcoin network.
  • bitcoin_get_current_fee_percentiles: The function returns the percentiles of the fees, in satoshi per virtual byte, for the last 10,000 transactions.

The following address formats are supported:

  • Pay to public key hash (P2PKH)
  • Pay to script hash (P2SH)
  • Pay to witness public key hash (P2WPKH)
  • Pay to witness script hash (P2WSH)
  • Pay to taproot (P2TR)

Details about the Bitcoin integration API can be found in the Internet Computer specification.

In order to reduce the risk of inconsistencies due to forks, confirmations are counted conservatively, using 𝜹-stability (and not difficulty-based 𝜹-stability). The stability count of a block is defined as the largest 𝜹 so that the block is 𝜹-stable. The number of confirmations for a transaction in a block is defined as the stability count of the block.

While this rule may seem complicated, it has several nice properties: If there are no forks, the number of confirmations for each transaction is exactly what one would expect: Once a transaction is in a block, it has one confirmation, if there is a subsequent block, it has two confirmations and so forth. However, if there are multiple competing forks with similar heights, the number of confirmations will remain low for blocks on the competing forks until one fork prevails, at which point the number of confirmations starts to increase. In short, the rule is meant to ensure that a large number of confirmations, based on the stability count, implies a large probability that the transaction will not be undone even in the presence of competing forks.

The following figure shows an example of a chain with two forks. The numbers inside the blocks are the stability counts, which correspond to the number of confirmations for transactions in the blocks. Unlike regular confirmation counts, the stability counts can be negative. Only blocks with a positive stability counts are considered when answering requests.

A chain with two forks and the resulting stability counts (inside the blocks) is shown.

When the Bitcoin canister receives an outbound transaction and the transaction passes a basic verification that it can be decoded, the Bitcoin canister forwards the transaction to the Bitcoin adapter as described above. There is no guarantee that the transaction will ever be included in a block. It is up to the issuer of the transaction to maximize the chances to get the transaction into a block by making sure that the transaction is valid and including an appropriate miner fee.

Bitcoin Testnet Release

In summer 2022, the Bitcoin testnet integration was released on the IC. The Testnet Integration is intended to allow engineers to interact with the Bitcoin API on the IC, but only with Bitcoin Testnet and a threshold ECDSA test key. The goal is to allow engineers to build and test their Bitcoin-integrated dApps using a beta running on the IC. This is the next step after the previously-launched developer preview that facilitates dApp development through the community. It is strongly advised that engineers do not associate any value with the threshold ECDSA test key as it may be deleted at some point in time and it is running only on regular-size subnet.

Bitcoin Mainnet Release

The Bitcoin integration was released on the IC in the beginning of December 2022, making all Bitcoin integration features available for Bitcoin mainnet.

See Also