diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/bitcoin-checker-canister.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/bitcoin-checker-canister.md deleted file mode 100644 index a3850e2..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/bitcoin-checker-canister.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -learn_hub_id: 45033984570516 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/45033984570516-Bitcoin-Checker-Canister" -learn_hub_title: "Bitcoin Checker Canister" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Bitcoin Checker Canister - -The [Bitcoin checker canister](https://dashboard.internetcomputer.org/canister/oltsj-fqaaa-aaaar-qal5q-cai) provides a useful service to canisters that make use of the [Bitcoin integration](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084) of the Internet Computer: Given any Bitcoin address or transaction, the Bitcoin checker canister checks whether the address or transaction may be associated with illicit activities. - -The following figure shows a high-level overview of how the [ckBTC](https://learn.internetcomputer.org/hc/en-us/articles/44598021228564 "Chain-key Bitcoin") minter interacts with the Bitcoin checker canister. When a user deposits or wishes to withdraw bitcoin, the ckBTC minter sends a request to the Bitcoin checker canister, which in turn checks the involved Bitcoin addresses against the [Specially Designated Nationals (SDN) list](https://sanctionslist.ofac.treas.gov/Home/SdnList) of the [OFAC](https://ofac.treasury.gov/). If there is a hit, the check is considered `Failed`. When receiving the response `Failed`, the actions of the ckBTC minter depend on the type of request. - - * If the user deposited bitcoin, the ckBTC minter refuses to mint ckBTC and quarantines the received bitcoin instead. - * If the user attempted a Bitcoin withdrawal, the ckBTC returns an error and drops the request. - - - -![](https://learn.internetcomputer.org/hc/article_attachments/45033948399764) - -The canister ID of the Bitcoin checker canister is `oltsj-fqaaa-aaaar-qal5q-cai`. - -## Technical Details - -The Bitcoin checker canister stores a copy of the SDN list internally. The list can only be modified by upgrading the Bitcoin checker canister itself, which requires an NNS proposal as the NNS is the only controller of the Bitcoin checker canister. - -The Bitcoin checker canister offers a simple API to other canisters, which is discussed next. The candid file of the Bitcoin checker canister is available [here](https://github.com/dfinity/ic/blob/master/rs/bitcoin/checker/btc_checker_canister.did). - -### Checking Bitcoin Addresses - -The Bitcoin checker canister exposes the endpoint `check_address`, which takes a Bitcoin address in the form of a string as its sole parameter. It is then simply checked if the address is found on the SDN list. Since this is a simple lookup operation, no cycles are charged. - -### Checking Bitcoin Transactions - -The main endpoint to check a Bitcoin transaction is `check_transaction`, which takes the transaction ID as a `blob` as its sole parameter. Given such a transaction ID, the Bitcoin checker canister performs the following steps. - - 1. It uses an [HTTPS outcall](https://learn.internetcomputer.org/hc/en-us/articles/34211194553492) to obtain the (binary) transaction that corresponds to the given transaction ID. - 2. The received transaction is hashed and the result is compared against the transaction ID as they should match. - 3. If there is a match, it makes another HTTPS outcall for each input in the transaction as the inputs themselves are only references to previous transactions with an index that identifies the output that is consumed with the given input. - 4. For each received input transaction, the Bitcoin address is derived that corresponds to the output at the right index. - 5. Each address is looked up in the SDN list. If any address appears on the list, `Failed` is returned. Otherwise, the result is `Passed`. - - - -Since this lookup is expensive due to the (potentially many) HTTPS outcalls, at least **40 billion cycles** must be attached to the call. The actual cost is likely lower, and unused cycles are refunded. - -There is also the `check_transaction_str` endpoint, which is identical to `check_transaction` except for the fact that the transaction ID parameter must be provided as a string. - -Lastly, there is the `check_transaction_query` endpoint, which can be used to check the status of a previous call to `check_transaction` or `check_transaction_str` using a query call. Note that a call to this endpoint does not trigger any HTTPS outcalls, nor is it guaranteed that this endpoint will be maintained in a backwards-compatible manner. - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/bitcoin-integration.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/bitcoin-integration.md deleted file mode 100644 index fbd152d..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/bitcoin-integration.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -learn_hub_id: 34211154520084 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/34211154520084-Bitcoin-Integration" -learn_hub_title: "Bitcoin Integration" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Bitcoin Integration - -The Bitcoin integration on the Internet Computer makes it possible to create Bitcoin smart contracts, that is, smart contracts in the form of canisters running on the Internet Computer that make use of real bitcoin. This integration is made possible through two key components. - -The first component is [chain-key signatures](https://learn.internetcomputer.org/hc/en-us/articles/34209497587732), which enables every canister to obtain [ECDSA](https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm) and [Schnorr](https://en.wikipedia.org/wiki/Schnorr_signature) public keys and get signatures with respect to these keys in a secure manner. Since Bitcoin addresses are tied to ECDSA/Schnorr public keys, having ECDSA/Schnorr public keys on a canister means that the canister can derive its own Bitcoin addresses. Given that the canister can request signatures for any of its public keys using the [IC ECDSA](https://internetcomputer.org/docs/current/references/ic-interface-spec#ic-sign_with_ecdsa) and [IC Schnorr](https://internetcomputer.org/docs/references/ic-interface-spec#ic-sign_with_schnorr) interface, a canister can create Bitcoin transactions with valid signatures that move bitcoins from any of its Bitcoin addresses to any other address. - -The second component is the integration with Bitcoin at the network level. The Internet Computer replicas have the capability to instantiate a so-called _Bitcoin adapter_ , a process external to the replica process. The Bitcoin adapter uses the standard Bitcoin peer-to-peer protocol to get information about the Bitcoin blockchain. At the same time, the Bitcoin adapter communicates with the replica process to learn about the current Bitcoin state inside the replica. If the Bitcoin adapter learns that a Bitcoin block has not been made available to the replica yet, the Bitcoin adapter requests the next missing block from the connected Bitcoin nodes and forwards it to the replica upon receipt. - -Inside the replica, Bitcoin blocks are made available to the _Bitcoin canister_. The Bitcoin canister is a canister running on a system subnet whose purpose is to provide Bitcoin-related functionality to other canisters. In particular, it keeps information about the Bitcoin blockchain state and makes this information accessible to other canisters, such as the balance and unspent transaction outputs (UTXOs) of any Bitcoin address. Additionally, the fees of the most recent Bitcoin transactions that were put into blocks can be requested from the Bitcoin canister as well. The Bitcoin canister also offers the last piece of crucial functionality: It provides an endpoint for canisters to send Bitcoin transactions, which are forwarded to the Bitcoin adapter. The Bitcoin adapter in turn advertises the transactions to its connected Bitcoin peers and transfers the transaction upon request. - -The architecture of the Bitcoin integration is summarized in the following figure: - -![](https://learn.internetcomputer.org/hc/article_attachments/41161561347348) - -The figure depicts the main components: The Bitcoin adapter, which acts as a light-weight Bitcoin client that relays Bitcoin-related information between the replica process (on the left) and the Bitcoin network (on the right), and the Bitcoin canister, which interacts with the Bitcoin adapter to maintain the Bitcoin blockchain state and transfer Bitcoin transactions to the Bitcoin network. - -As mentioned before, the Bitcoin canister offers a low-level API to read from and write to the Bitcoin blockchain. Usage of the Bitcoin integration API is illustrated in the following sample flow: - -![](https://learn.internetcomputer.org/hc/article_attachments/43174436435476) - -In this figure, a canister first requests the balance of some Bitcoin address. This may be an address of the canister itself or any other address. Subsequently, the canister fetches the UTXOs of a Bitcoin address with the goal of crafting a Bitcoin transaction, in which case the Bitcoin address must be associated with a public key for which the canister can request signatures. Next, the canister calls the fee endpoint to get recent fees before building a Bitcoin transaction using some of the UTXOs as inputs. For each input, the IC ECDSA API is called to obtain the required signatures. Note that, if a [Taproot address](https://en.wikipedia.org/wiki/List_of_bitcoin_forks#Taproot) is used, the IC Schnorr API is used instead. In the last step, the transaction is submitted. - -## Additional information - -There are many sources providing additional information about the Bitcoin integration on the Internet Computer: - - * The [developer docs](https://internetcomputer.org/docs/build-on-btc/) are the right starting point for developers who wish to implement Bitcoin smart contracts on the Internet Computer. - * The [Bitcoin canister source code](https://github.com/dfinity/bitcoin-canister) can be found on GitHub, including its [interface specification](https://github.com/dfinity/bitcoin-canister/blob/master/INTERFACE_SPECIFICATION.md). - * A more detailed description of the integration, including the cycles cost of each endpoint, can be found [here](https://internetcomputer.org/docs/references/bitcoin-how-it-works). - * The [scientific paper](https://arxiv.org/pdf/2506.21327) on the Bitcoin integration is the right source for those who wish to learn about the technical details. - - - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-fusion.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-fusion.md deleted file mode 100644 index bbc22e4..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-fusion.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -learn_hub_id: 34329023770260 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/34329023770260-Chain-Fusion" -learn_hub_title: "Chain Fusion" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Chain Fusion - -Chain Fusion technology enables canisters to interact with multiple blockchain networks in a decentralized manner. This allows developers to build application using information from as well as holding and transferring assets on various blockchains, eliminating the need for trusted intermediaries like bridges. - -To make this possible, canisters must be able to - - * sign transactions - - * bi-directionally communicate with other chains - - - - -without a single point of trust. - -To achieve the former, [chain-key signatures](https://learn.internetcomputer.org/hc/en-us/articles/34209497587732) let canisters control addresses on several blockchain networks and sign transactions to transfer their assets to other addresses. - -For the latter, ICP nodes either exchange information with nodes from other blockchain networks natively (see [Bitcoin integration](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084) for more details) or they use HTTPs outcalls to interact with JSON RPC providers for other networks ([Ethereum Integration](https://learn.internetcomputer.org/hc/en-us/articles/34575019947668)). - -Among other applications, these integrations have been used to bring digital token twins to ICP. These twin tokens, called [chain-key tokens](https://learn.internetcomputer.org/hc/en-us/articles/34211397080980), including ckBTC, ckETH, ckUSDC, and ckUSDT, are fully backed by their native tokens and controlled by a canister smart contract. This comes with high security guarantees and lets smart contracts on ICP to hold and transact these tokens at high speed and low cost. - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-key-bitcoin.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-key-bitcoin.md deleted file mode 100644 index a5e57a4..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-key-bitcoin.md +++ /dev/null @@ -1,371 +0,0 @@ ---- -learn_hub_id: 44598021228564 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/44598021228564-Chain-key-Bitcoin" -learn_hub_title: "Chain-key Bitcoin" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Chain-key Bitcoin - -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 when waiting for 6 confirmations) 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](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084 "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 minter waits for 6 confirmations before minting ckBTC and it burns ckBTC before it transfers BTC back to the users. The ckBTC ledger is [ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md) and [ICRC-1](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-1/README.md) 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. - -![](https://learn.internetcomputer.org/hc/article_attachments/44598021222548) - -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](https://github.com/dfinity/bitcoin-canister) to retrieve information about the Bitcoin network state and send Bitcoin transactions. - -The ckBTC minter further interacts with the [Bitcoin checker canister](https://learn.internetcomputer.org/hc/en-us/articles/45033984570516) to run checks against Bitcoin addresses and transactions. These checks are meant to ensure that the ckBTC minter only uses "clean" bitcoins to back the issued ckBTC tokens and to prevent transferring bitcoins to Bitcoin addresses that are considered to be associated with illicit activity. As such, these checks provide an additional layer of security to ckBTC users. - -## Canisters - -Both the [ckBTC ledger](https://dashboard.internetcomputer.org/canister/mxzaz-hqaaa-aaaar-qaada-cai) and the [ckBTC minter](https://dashboard.internetcomputer.org/canister/mqygn-kiaaa-aaaar-qaadq-cai), running on the [pzp6e](https://dashboard.internetcomputer.org/subnet/pzp6e-ekpqk-3c5x7-2h6so-njoeq-mt45d-h3h6c-q3mxf-vpeq5-fk5o7-yae) subnet, are canisters that are controlled by the NNS (specifically, the [NNS root canister](https://dashboard.internetcomputer.org/canister/r7inp-6aaaa-aaaaa-aaabq-cai)). - -### ckBTC Ledger - -The ckBTC ledger, which complies with the [ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md) and [ICRC-1](https://github.com/dfinity/ICRC-1/tree/main/standards/ICRC-1) standards, is responsible for keeping account balances and for transferring ckBTC between accounts. It provides the following functionality: - - * It enables the ckBTC minter to mint and burn ckBTC. - * It enables the transfer of ckBTC among users. - - - -As mentioned above, the transaction fee is 0.0000001 ckBTC, the equivalent of 10 satoshi. The transaction fee is sent to the account with the ckBTC minter as the owner and the subaccount `0xfee`. The **minting account** is the ckBTC minter’s default account; that is, 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 the canister responsible for managing deposited BTC and minting/burning ckBTC based on the amount of deposited BTC. It provides the following functionality: - - * For a certain principal ID and an optional subaccount, it returns a specific Bitcoin address under the ckBTC minter’s control. The ckBTC minter uses P2WPKH (“pay to witness public key hash”) addresses as defined in [BIP-141](https://en.bitcoin.it/wiki/BIP_0141). These addresses are rendered in the Bech32 format as defined in [BIP-173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki). While the ckBTC minter exclusively uses P2WPKH addresses internally, it supports all currently used address formats (P2PKH, P2SH, P2WPKH, P2TR) for retrievals. - * Users can inform the ckBTC minter about bitcoins that were sent to an address controlled by the ckBTC minter. If the balance has increased, the ckBTC minter mints ckBTC for the user associated with the Bitcoin address. - * Users can request to get bitcoins back. The ckBTC minter burns the same amount of ckBTC and transfers the corresponding BTC amount minus fees to the address provided by the user. - - - -The ckBTC minter canister 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.0005 BTC** , or **50,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 currently set to **5 minutes**. - * `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 currently set to **6**. - * `btc_checker_principal`: The principal ID of the Bitcoin checker canister, discussed below. - * `check_fee`: The fee that must be paid when depositing bitcoins to cover the cost in cycles for interacting with the Bitcoin checker canister. It is currently set to **100 satoshi**. - * `utxo_consolidation_threshold`: The minimum number of unspent transaction outputs (UTXOs) to trigger a consolidation. UTXO consolidation is discussed below. - * `max_num_inputs_in_transaction`: The maximum number of inputs that the ckBTC minter uses in a transaction, set to **1000**. - - - -The remaining parameters are self-explanatory and can be found in the [ckBTC minter Candid file](https://github.com/dfinity/ic/blob/master/rs/bitcoin/ckbtc/minter/ckbtc_minter.did). - -The following sections explain how the ckBTC minter manages its internal state. - -#### Addresses - -All Bitcoin addresses that are controlled by the ckBTC minter and have a positive balance are part of the ckBTC minter's state. If the balance of such an address reduces to zero, the address is removed from the state. It can be added back if the balance becomes positive again. - -#### Unspent Transaction Outputs - -Once a new unspent transaction output (UTXO) under the control of the ckBTC minter is discovered (using the `update_balance` function), it is stored internally in a set called `available_utxos` (defined [here](https://github.com/dfinity/ic/blob/2348b094d3d27616ee3f049d3048baa1da8d625a/rs/bitcoin/ckbtc/minter/src/state.rs#L305C14-L305C14) in the source code). - -All discovered UTXOs remain in this set until a Bitcoin transaction is created to spend one or more of them when retrieving bitcoins. When a transaction is created spending some UTXOs, these UTXOs are removed from the set `available_utxos` and inserted in the `used_utxos` field of the `SubmittedBtcTransaction` struct (defined [here](https://github.com/dfinity/ic/blob/70d19f16c17f8f42987a46d473ba27705927cdb7/rs/bitcoin/ckbtc/minter/src/state.rs#L87) in the source code), which is the internal representation of a Bitcoin transaction. - -A UTXO is removed from the ckBTC state when the `SubmittedBtcTransaction` struct that contains the UTXO is removed from the state. - -#### Transactions - -Every transaction that the ckBTC minter creates has an output that sends the ckBTC minter fee plus the transaction change back to its main BTC address (the P2WPKH address derived from its public key with an empty derivation path). - -A transaction can be removed from the cache if the transaction output that belongs to the ckBTC minter appears in the returned list of UTXOs of the ckBTC minter’s main BTC address with at least `min_confirmations=6` confirmations. - -The ckBTC minter may resubmit transactions, making use of Bitcoin’s request by fee (RBF) mechanism as defined in [BIP-125](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki). In the case of ckBTC, a resubmission adds a transaction to the cache that spends exactly the same UTXOs as the transaction it replaces. The only difference is that the BTC amount sent to the user(s) is reduced in order to increase the fee. - -BIP-125 states that at most 100 transactions may be evicted from the mempool, i.e., the fee cannot be increased more than 100 times. Moreover, the fee must be increased at least by the minimum relay fee (see minrelaytxfee [here](https://en.bitcoin.it/wiki/Miner_fees#Relaying)) of 1 satoshi/vbyte. - -For example, if we assume a minimum increase of 200 satoshi (the minimum fee for a basic `segwit` transaction with one input and one output is 192 satoshi and the number per output is always lower than 200 if there are at least as many outputs as inputs), the minimum transfer amount should be at least 20,000 satoshi which equals 0.0002 BTC. When adding a base fee at a large fee rate of 100 satoshi/vbyte and assuming a virtual transaction size of 200 vbyte per output, we get a minimum transfer amount of 0.0004 BTC. Adding a security margin, we get the minimum retrieval amount of 0.0005 BTC that is used for the configuration parameter `retrieve_btc_min_amount`. The RBF flag is set on every transaction to ensure that they can be updated if necessary. - -Transactions with `min_confirmations=6` confirmations or more are considered _finalized_. The ckBTC minter stores information about finalized transactions forever. - -## Converting BTC to ckBTC - -In this section, the process to convert BTC to ckBTC is explained, making use of the ckBTC minter and ckBTC ledger endpoints. - -The first step is for the user to determine the Bitcoin address where the user is supposed to transfer bitcoin for the minting process by calling the `get_btc_address` endpoint. Next, the user transfers the desired BTC amount to this Bitcoin address. - -Once the transaction has `min_confirmations=6` confirmations, the user notifies the ckBTC minter to update the balance of the user's account on the ckBTC ledger by calling the `update_balance` function. The ckBTC minter uses the `bitcoin_get_utxos` endpoint of the Bitcoin canister to retrieve the current list of UTXOs for the Bitcoin address associated with the user. If there are new UTXOs, the ckBTC minter instructs the Bitcoin checker canister to perform a check of the newly discovered UTXOs and then, if the checks are successful, issues a minting transaction to the ckBTC ledger per UTXO, minting the value of the UTXO minus the Bitcoin checker fee into the user’s account. - -Formally, Let `R` denote the set of returned UTXOs. The following pseudo-code illustrates how the UTXOs are processed: - - - for utxo in new_utxos(R): // R = set of returned UTXOs - if utxo.value >= check_fee: - if utxo in checked_utxos: - state = checked_utxos.get(utxo) - else: - state = bitcoin_checker.check_transaction(utxo.transaction_id).await? - if state == passed: - checked_utxos.set(utxo, passed) - if state == passed: - ckbtc_ledger.mint(utxo.value-check_fee, recipient_account).await? - available_utxos.add(utxo) // Add to available UTXOs - checked_utxos.remove(utxo) // Remove from checked UTXOs after minting - else: - add_to_quarantine_list(utxo) - else: - add_to_ignore_list(utxo) - return response with UTXO statuses - - -The function `new_utxos` extracts the newly discovered UTXOs from `R`. Details about this function are provided further below. - -A UTXO is considered if its value is at least `check_fee`. UTXOs with a value lower than this fee are added to an ignore list. The additional state `checked_utxos` is maintained to remember that a UTXO was checked if the state is clean. Once the corresponding amount of ckBTC has been minted, this state can be removed again. If the UTXO does not pass the check, it is moved to a quarantine list instead. - -The function `new_utxos` filters out all UTXOs in the ignore list, the quarantine list, and the set `available_utxos`, as well as the UTXOs in any `used_utxos` list of `SubmittedBtcTransaction` structs. By contrast, the UTXOs in `checked_utxos` are not filtered. - -Note that the implementation uses the map `utxos_state_addresses` instead of the set `available_utxos`. For each address, the map contains all UTXOs, including UTXOs already used in outgoing transactions. It is therefore not necessary to parse all `SubmittedBtcTransaction` structs when using the map because UTXOs that have been used in transactions are already considered. - -UTXOs in the ignore list and quarantine list remain there indefinitely. Mechanisms to enable the owner to transfer the funds in these UTXOs back out may be added in the future. - -## Converting ckBTC to BTC - -The process to convert ckBTC to BTC consists of the following steps: - - 1. Transfer request: The user makes the desired ckBTC amount available to the ckBTC minter and requests a conversion. The destination Bitcoin address undergoes a check by the Bitcoin checker canister. If the check is successful, the request is accepted and put into a queue. - 2. Submission: The ckBTC minter periodically attempts to submit transactions for validated transfer requests. - 3. Finalization: The ckBTC minter periodically checks which transactions went through and finalizes these transactions. - 4. Resubmission: The ckBTC minter can resubmit a transaction that has been pending for at least one day with a higher fee. - - - -The individual parts are discussed in greater detail in the following sections. - -There are two flows to convert ckBTC to BTC. The newer, recommended flow is based on the ICRC-2 standard and requires the user to allow the ckBTC minter to withdraw the desired amount from a user-controlled account by calling `icrc2_approve` on the ckBTC ledger. Subsequently, the user can call the `retrieve_btc_with_approval` endpoint to inform the ckBTC minter about the withdrawal intent. In addition to specifying the withdrawal amount, the Bitcoin address where the withdrawn funds are to be sent must be specified as well. - -The ckBTC minter instructs the Bitcoin checker canister to perform a check against the targeted Bitcoin address using the `check_address` endpoint. If the check is successful, the ckBTC minter deducts the fee from the amount to be retrieved and puts the corresponding retrieval request into a queue and checks the status of the queue on a timer. - -If the oldest request has been in the queue for at least 10 minutes or at least 20 retrieval requests have been accumulated, the ckBTC minter creates a single Bitcoin transaction to serve up to 100 retrieval requests as follows: - - 1. It selects available UTXOs with a total sum of at least the sum in the retrieval requests. - 2. It constructs a Bitcoin transaction with the selected UTXOs as inputs and an output for each retrieval request plus an additional output for the ckBTC minter’s fee and the change. - 3. It uses the Bitcoin canister’s fee API to determine an appropriate fee for the transaction, using the median fee rate. - 4. It distributes the fee evenly among all outputs other than the output for the ckBTC minter’s fee plus change. - 5. For each input of the transaction, the ckBTC minter invokes the threshold ECDSA functionality (calling the `sign_with_ecdsa` function) to obtain the required signatures and puts them into the transaction. - 6. Lastly, it sends the Bitcoin transaction by invoking the `bitcoin_send_transaction` function of the Bitcoin integration API. - - - -The BTC retrieval process is depicted in the following figure. - -![](https://learn.internetcomputer.org/hc/article_attachments/44598026440340) - -Note that the amounts in the transfer to the withdrawal account and the retrieval request need not be the same. The `retrieve_btc_status_v2` endpoint can be used to query the current status of a retrieval request. - -The other, older mechanism, which is not based on ICRC-2, is summarized here briefly for the sake of completeness. Since the ckBTC minter can only burn ckBTC in an account that it controls, the first step is to transfer the amount to be retrieved to the owner-specific _withdrawal account_ under the ckBTC minter’s control. After the user has transferred the desired ckBTC amount to the withdrawal account, the user can call the `retrieve_btc` endpoint, specifying the withdrawal amount and the destination Bitcoin address. The ckBTC minter will then attempt to burn the specified ckBTC amount in the withdrawal account and, if the Bitcoin checker canister indicates that the destination address is clean, record the retrieval request, which is handled on a timer as before. - -The advantage of the ICRC-2-based flow is that the ckBTC amount stays with the user until a request is made to retrieve BTC, i.e., the risk that the funds get stuck in the withdrawal account is removed. - -Looking at the retrieval flow in more detail, the first step is to approve the ckBTC minter to withdraw the desired ckBTC amount from (one of) the user's accounts. To this end, the user calls icrc2_approve on the ckBTC ledger. The required parameters are `spender` and `amount` but there are also several optional parameters such as `from_subaccount`. - -Subsequently, the user can call `retrieve_btc_with_approval` on the ckBTC minter with parameters `address`, specifying the Bitcoin address that should receive the retrieved bitcoins, and `amount` (plus, optionally, `from_subaccount`), which causes the ckBTC minter to attempt to transfer the specified amount from the user's account to the minting account. As defined in ICRC-1, transferring tokens to the minting account constitutes a burn operation. Note that specifying an amount to be retrieved smaller than the minimum retrieval amount (`retrieve_btc_min_amount`) results in an immediate rejection of the request. - -If the burn operation fails, the retrieval process is aborted and an error is returned to the user. If the ckBTC tokens are burned successfully, the ckBTC minter instructs the Bitcoin checker canister to perform a check against the Bitcoin address where funds are supposed to be sent. If this check fails, a task is created internally to reimburse the burned amount to the user and an error is returned. Otherwise, the steps depend on the result: if the result is `Passed`, a task to transfer the amount minus the Bitcoin checker fee to the destination address is created and the user receives the signal that the request was accepted in the form of the block index of the burn operation on the ckBTC ledger. If the result is `Failed`, a task to reimburse the amount _minus the Bitcoin checker fee_ is created and a corresponding error message is returned to the user. - -The following pseudo-code illustrates how the `retrieve_btc_with_approval` endpoint works, given the parameters `amount` and `btc_address`. - - - assert(max(retrieve_btc_min_amount, check_fee) <= amount) - index = ckbtc_ledger.icrc2_transfer_from(user_account, minting_account, amount).await? - result = bitcoin_checker.check_address(btc_address).await - if result = error: - create_reimbursement(amount, index, user_account) - return Error("Failed to perform check") - else: - Ok(state) = result - if state == clean: - create_request(amount-check_fee, index, btc_address) - return index - else: - create_reimbursement(amount-check_fee, index, btc_address) - return Error("Tainted destination address") - - -For each recorded retrieval request, the ckBTC minter stores the following data: - - * `index`: The block index of the burn operation used to burn the ckBTC. Since the block index is unique, it is used as the request ID. - * `amount`: The total amount of tokens to retrieve. This amount must be at least the minimum retrieval amount as defined above. - * `btc_address`: The address where the bitcoins will be sent. - * `received_at`: The timestamp when the request was received (not shown in the pseudo-code). - - - -Pseudo-code for the older `retrieve_btc` endpoint whose retrieval flow is based on the concept of withdrawal accounts is shown here, also requiring the parameters `amount` and `btc_address`. - - - assert(amount >= max(retrieve_btc_min_amount, kyt_fee)) - assert(ckbtc_ledger.balance_of(withdrawal_account).await? >= amount) - state = bitcoin_checker.check_address(btc_address).await? - - if state == clean: - index = ckbtc_ledger.icrc1_transfer(withdrawal_account, minting_account, amount).await? - create_request(amount-check_fee, index, btc_address) - return index - else: - index = ckbtc_ledger.burn(check_fee, withdrawal_account).await? - return Error("Tainted destination address", index) - - -Note that while the `retrieve_btc` endpoint achieves the same result as `retrieve_btc_with_approval`, it works quite differently internally. For example, the check performed by the Bitcoin checker canister happens _before_ the ckBTC tokens are burned. Further note that if the check succeeds but the burn transaction fails (regardless of the result of the check), no fee is charged and the request is rejected, which implies that a subsequent request with the same parameters will result in another call to the Bitcoin checker canister. - -#### Submission - -The ckBTC minter uses the [timer functionality](https://internetcomputer.org/docs/current/developer-docs/backend/periodic-tasks) to initiate Bitcoin transfers. The following steps are carried out periodically: - - 1. Check if there is at least one request that is 10 minutes old or there are at least 20 requests in the pending-requests queue. If not, stop. - 2. Update the balance of the ckBTC minter’s main BTC address (the P2WPKH address derived from its public key with an empty derivation path) using the Bitcoin integration’s `bitcoin_get_utxos` function. Newly discovered UTXOs are added to the set `available_utxos`. - 3. Determine the total amount of bitcoins available, which is the sum of all bitcoins in `available_utxos`. - 4. Call the transfer function with the next batch of requests that can be served given the total amount of available bitcoins. A transaction is created, setting the transaction ID for each request in the batch, and sent to the Bitcoin network. - 5. Every request in this batch is then moved to the unconfirmed-transfers queue. - - - - -As evident from the steps outlined above, the transfer function can handle multiple requests at the same time. Handling multiple requests in a single transaction has several advantages over sending individual transactions: - - 1. Requests can possibly be served more quickly, especially if the ckBTC minter must wait for change to return to its main BTC address. - 2. As the fee for the non-input bytes is shared, the fee per request is slightly lower. - 3. Serving multiple requests at the same time can make denial-of-service attacks where an attacker attempts to drain the pool of usable UTXOs with many small requests harder. - - - -Given this set of requests, the next step is to select UTXOs for the transaction. - -Since UTXOs are always spent entirely, the difference between the sum of bitcoins in the spent UTXOs and the requested amount minus the Bitcoin miner fee must be transferred to a new UTXO as well. As mentioned before, the ckBTC minter uses its main BTC address to accumulate change. - -The transfer function performs the following steps: - - 1. Determine the target `t` of bitcoins that must be transferred out to handle all requests in the given batch. - 2. Select UTXOs for the transaction from the set `available_utxos`. - 3. Build the Bitcoin transaction and compute the Bitcoin miner fee based on current Bitcoin fees using the median fee rate of the return value of `bitcoin_get_current_fee_percentiles` and the (virtual) size of the transaction. The ckBTC minter fee is `146*in + 4*out + 26 satoshi`, where `in` and `out` denote the number of transaction inputs and outputs, respectively. Note that the fee is split evenly among the handled retrieval requests, deducting the same fraction of the total fee from each output that is not returning change and the ckBTC minter fee to the ckBTC minter. - 4. Sign every input using the threshold ECDSA interface. - 5. Submit the transaction using the `bitcoin_send_transaction` endpoint. - 6. Create a transaction record in the form of a `SubmittedBtcTransaction` struct. The UTXOs selected for this transaction are moved from the set `available_utxos` to the `used_utxos` field in the `SubmittedBtcTransaction` struct. - - - -The following UTXO selection algorithm, in pseudo-code, is used: - - - // t = target, A = available_utxos, k = # outputs - // Pre-condition: sum(A) >= t - fn select_utxos(t, A, k) - - fn greedy(t, A): - if t ≤ 0 or |A| = 0: return {} - m := max(A) // The UTXO with the largest value - if m.value < t: - return {m} ∪ greedy(t-m.value, A \ {m}) - else: - return min({a ∊ A | a.value ≥ t}) - - S := greedy(t, A) - A := A \ S - if |A| > UTXOS_COUNT_THRESHOLD: - a := min(A) - while a ≠ Ø and |S| < k: - S := S ∪ {a} - A := A \ {a} - return S - - -The algorithm has the following properties. If there are at most `UTXOS_COUNT_THRESHOLD` (currently set to 1,000) UTXOs, the algorithm greedily chooses the smallest number of UTXOs possible for the given target. If a single UTXO suffices, it uses the UTXO that results in the smallest change. - -If there are more than `UTXOS_COUNT_THRESHOLD` UTXOs, the UTXOs with the smallest values are added to the greedy solution until the number of inputs `k` matches the number of outputs that the transaction produces. Note that a transaction with `k` outputs handles `k-1` retrieval requests as there is always one output that returns the change and fee to the ckBTC minter. - -Once the transaction is sent, the requests are moved to the unconfirmed-transfers queue. - -#### Finalization - -The ckBTC minter uses the timer mechanism to determine the status of sent transactions as well. Specifically, the ckBTC minter periodically wakes up and checks the state of the requests in the unconfirmed-transfers queue. The ckBTC minter checks the UTXOs of its main account to determine which transactions have sufficiently many confirmations. Concretely, If an output returning the ckBTC fee and change is discovered, the corresponding transaction is considered final and is discarded. - -#### Resubmission - -It is possible that it takes a long time for a transaction to be included in a block. If fees increase significantly for some time, a transaction may even be stuck for a long time or dropped entirely. While the ckBTC minter uses a reasonable fee, it may still be necessary to issue a transaction again because burned ckBTC are never returned and UTXOs are never freed and are thus stuck when the transaction spending these UTXOs is stuck. - -The ckBTC minter resubmits a transaction that has not been confirmed within 24 hours. - -If a transaction is replaced, the new transaction uses the same UTXOs as the original transaction but the fee is increased. In other words, the transaction is identical except that the outputs for each user is reduced due to the increased fee. The new fee is the sum of the old transaction fee plus the size of the transaction (in `vbytes`) times the minimum relay fee of 1 satoshi/vbyte plus the ckBTC minter fee again because the ckBTC minter must acquire new signatures and send the new transaction to the Bitcoin canister. - -## Fees - -The ckBTC canisters run on an application subnet and must be self-sustainable. Rather than charging cycles for the endpoints, the ckBTC minter accumulates a surplus of BTC over time. Moreover, every ckBTC transaction increases the ckBTC balance of the ckBTC minter's fee account (i.e., its principal ID plus the `0xfee` subacccount) by **10 satoshi**. In the future, the ckBTC minter will mint ckBTC to get the total ckBTC supply and the BTC amount under the ckBTC minter's control to match. The ckBTC minter can then trade these extra ckBTC tokens for cycles to fuel both the ckBTC minter and ckBTC ledger. - -There is a growing surplus of BTC because it collects a fee when bitcoins are withdrawn. The formula for the ckBTC minter fee when calling `retrieve_btc` is determined as follows: - - * Under the conservative assumption that 1 BTC = 20,000 XDR, 1 billion cycles corresponds to 5 satoshi (because 1 trillion cycles corresponds to 1 XDR). - * The [cost](https://docs.internetcomputer.org/references/t-sigs-how-it-works/#api-fees) to obtain a single EDCSA signature is approximately 26.16 billion cycles on a 34-node subnet, whereas sending a Bitcoin transaction costs 5 billion cycles plus 20 million cycles per byte. - - - -Given these numbers, the cost to sign and send a transaction with `in` inputs and `out` outputs is - - - 26.16b*in + 5b + tx_size*20m cycles - < 26.16b*in + 5b + (149*in + 35*out + 10)*20m cycles - < 29.14b*in +0.7b*out + 5.2b cycles - < 146*in + 4*out + 26 satoshi. - - -The formula `146*in + 4*out + 26` is used to determine the ckBTC minter’s fee in satoshi. Since every transaction has at least two inputs and two outputs, the fee is at least 352 satoshi. - -This conservative pricing strategy is used to subsidize the other endpoints, which are free of charge. Moreover, while the `retrieve_btc_with_approval` endpoint is relatively expensive, the fee is typically still lower than the Bitcoin miner fee. - -As mentioned above, there is also a fee (namely, the Bitcoin checker fee of **100 satoshi**) when converting BTC to ckBTC (but not when converting ckBTC to BTC). - -## UTXO Consolidation - -As more and more bitcoins are deposited, the number of UTXOs that are managed by the ckBTC minter grows. Users tend to deposit bitcoins in small quantities, resulting in many UTXOs that lock small amounts. A consequence of the ckBTC minter managing numerous small UTXOs is that it may not be possible to withdraw a large amount in a single transaction because such a transaction would require spending an exceedingly large number of outputs, which would cause the transaction to be larger than the maximum size of a standard Bitcoin transaction of [100 KB](https://github.com/bitcoin/bitcoin/blob/3c098a8aa0780009c11b66b1a5d488a928629ebf/src/policy/policy.h#L24). In other words, large withdrawals may take longer as they might have to be split up into multiple smaller withdrawals, leading to a poor user experience. - -In order to mitigate the risk of failed withdrawal requests, the ckBTC miner creates _UTXO consolidation transactions:_ As long as the ckBTC minter has more than 10,000 UTXOs, it periodically creates transactions that spend the 1000 smallest outputs that it possesses, creating 2 new outputs each locking half of the sum of the bitcoins in the inputs minus the network fee. Initially, a consolidation transaction is created once per day, and the frequency is later reduced to once per week. 1000 inputs are used as it is large enough a number to reduce the total number of managed UTXOs quickly but small enough to generate standard Bitcoin transactions. It is a technical detail why 2 outputs are created as opposed to a single one: More of the existing code can be reused for consolidation transactions as every other transaction created by the ckBTC minter has at least 2 outputs, one for the user requesting a withdrawal and one for the change that goes back to the ckBTC minter. - -In contrast to transactions triggered by withdrawal requests, the ckBTC minter triggers UTXO consolidation transactions and therefore must pay for them itself. The ckBTC minter uses the funds accumulated in its fee collector account, i.e., its `0xfee` subaccount. Since the ckBTC minter is using its own funds, it is still always guaranteed that 1 ckBTC is backed by (at least) 1 BTC. - -## ckBTC Minter API - -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. - * `get_known_utxos` (query): Returns the UTXOs associated with the given account (principal ID-subaccount pair) that the ckBTC minter knows. - * `update_balance`: Instructs the ckBTC minter to check the balance of a Bitcoin address and mint ckBTC into the account of the owner. - * `estimate_withdrawal_fee`: Returns a current estimate for the fee to be paid when retrieving a certain BTC amount. - * `get_deposit_fee` (query): Returns the fee charged when minting ckBTC. This fee currently corresponds to `check_fee`. - * `get_withdrawal_account`: Returns a specific ckBTC account where the owner must transfer ckBTC before being able to retrieve BTC. - * `retrieve_btc_with_approval`: Instructs the ckBTC minter to burn a certain ckBTC amount and send the corresponding BTC amount, minus fees, to a provided Bitcoin address. - * `retrieve_btc`: Serves the same purpose as `retrieve_btc_with_approval` but requires the user to first deposit ckBTC in a specific subaccount of the ckBTC minter. - * `retrieve_btc_status_v2` (query): Returns the status of a previous `retrieve_btc` or `retrieve_btc_with_approval` call. - * `retrieve_btc_status_v2_by_account` (query): Provides the status of all recent `retrieve_btc` or `retrieve_btc_with_approval` calls associated with the provided account. - * `retrieve_btc_status` (query): Serves the same purpose as `retrieve_btc_status_v2` but returns less status information. This endpoint is considered _deprecated_. - * `get_minter_info` (query): Returns information about the ckBTC minter itself. - * `get_canister_status`: Returns canister status information. - * `get_events` (query): Returns a set of events for debugging purposes. - - - -## Additional information - - * [Bitcoin integration](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084) - * [ckBTC developer documentation](https://docs.internetcomputer.org/defi/chain-key-tokens/ckbtc/overview) - - - -#### - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-key-tokens.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-key-tokens.md deleted file mode 100644 index ebb9630..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/chain-key-tokens.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -learn_hub_id: 34211397080980 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/34211397080980-Chain-Key-Tokens" -learn_hub_title: "Chain-Key Tokens" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Chain-Key Tokens - -One important way to extend the utility of a token is to bring it from one blockchain to another one. In traditional blockchain architectures, this is mostly accomplished through wrapping. More decentralized (and secure) alternatives to wrapping exist and can replace it: Meet [chain-key cryptography](https://learn.internetcomputer.org/hc/en-us/articles/34209486239252) and chain-key tokens! - -A wrapped token represents an underlying asset, which is typically native on a different blockchain than the wrapped token. For example, a wrapped Bitcoin token represents real bitcoin but is a different token available on a different chain, for example, on the Ethereum blockchain. Traditional wrapping always involves intermediaries that need to be trusted. - -A more secure alternative to wrapping tokens is to use advanced threshold cryptography to obtain chain-key tokens. As an example, chain-key Bitcoin (ckBTC), the first major chain-key token on ICP, is 1:1 backed with real bitcoin held 100% on chain by a smart contract. It can be considered a Bitcoin _twin_ on the Internet Computer that features low transaction fees and latency and high throughput, similar in its properties to a Bitcoin Layer 2. - -## Traditional wrapped tokens - -In traditional blockchain architectures, token wrapping involves an off-chain trusted intermediary and a token ledger smart contract. A user who wants to have a specific token, say a wrapped Bitcoin token, sends tokens of the underlying asset, such as bitcoin, to the intermediary. The intermediary, once it has confirmed the transfer of the underlying token on the token’s native blockchain, keeps the received tokens in custody and instructs the token ledger to create, or mint, the same amount of wrapped tokens that it has received of the underlying token. Minting increases the supply of the wrapped token. The newly minted wrapped tokens can then be used on the blockchain where the wrapped token was minted. - -If a user wants to redeem wrapped tokens for the underlying asset, this again involves the intermediary: The user sends the wrapped token to an address controlled by the intermediary and makes an unwrap request. The intermediary removes the amount of received wrapped tokens from the wrapped token’s supply and returns the corresponding amount of underlying tokens to the user on the blockchain that natively hosts the underlying asset. - -Regular users can just use the wrapped tokens and normally need not bother with the wrapping and unwrapping themselves. Thus, wrapped tokens are convenient for most users and as easy to use as any native token on the same blockchain. - -This traditional off-chain approach of wrapping works well from a functional perspective, but has the major drawback of involving an intermediary whose integrity is crucial for the security of the wrapping and unwrapping of the token. The main problem is that the intermediary can get compromised, for example, hacked, defrauded by an insider, or go out of business, which may result in a total loss of the underlying tokens in the worst case. Strategies such as multi-signature schemes with keys held by multiple parties to try to decentralize the intermediary can provide some mitigation but do not change the fact that wrapping is done by an off-chain entity or group of entities. In short, this architecture is not fully decentralized. There is another potential risk regarding the backing of the wrapped token: Ideally, a wrapped token is always backed 1:1 by the underlying token. In practice, however, the intermediary can use the tokens held in custody to create profit, for example, by using them for risky investments. In the worst case, if things go wrong, this can lead to the loss of tokens and a depegging of the wrapped token. - -Overall, this traditional way of implementing wrapped tokens is not desirable for reasons of security, risk, and its inherent centralized nature. - -## Chain-key tokens - -Chain-key tokens, such as ckBTC, are an advanced cryptography-based replacement for wrapped tokens offering stronger security and decentralization: With chain-key tokens, all operations are performed completely on chain by smart contracts, without involving any off-chain intermediaries. This eliminates the security risks and centralization concerns when using a traditional wrapping approach with an intermediary. Replacing wrapping with on-chain operations require a few key building blocks, in particular, a decentralized interaction between the two blockchains must be possible. - -Chain-key tokens implement the [ICRC-1 and ICRC-2 token standards](https://github.com/dfinity/ICRC-1/tree/main) so that they can be easily integrated by on-chain services, for example, wallets and DEXs. - -## Architecture - -The architecture of any chain-key token on ICP uses the following building blocks as its foundation: - - 1. Some form of decentralized integration with the blockchain that hosts the underlying token. This integration must allow canisters on ICP to query balances of addresses of the underlying token on its native chain as well as send transactions to the underlying chain. - 2. A chain-key implementation of the signature scheme used for signing transactions on the blockchain hosting the underlying asset must be available. For example, Bitcoin and Ethereum require ECDSA signatures. This functionality makes it possible to sign transactions for the chain of the underlying token fully on chain without involving an intermediary. - - - -ICP has been integrated with the Bitcoin network using a [direct integration at the network level](https://learn.internetcomputer.org/hc/en-us/articles/34209531762324). The integration with Ethereum uses multiple JSON-RPC providers accessed via [HTTPS outcalls](hc/en-us/articles/01JJC9PGK13GHY6C1S0D2TQ58Z) and helper smart contracts deployed on Ethereum. - -A chain-key token is typically implemented using a set of canisters: - - 1. A **minter** canister is responsible for creating and removing supply of the chain-key token based on the inflow and outflow of the underlying token. It keeps the underlying tokens in on-chain custody, ensuring a 1:1 backing of the chain-key token with the underlying asset. It must be possible for any user to verify that the total supply of the chain-key token does not exceed the minter’s balance of the underlying asset. - 2. A **ledger** canister keeps track of all the balances and handles all transfers of the chain-key token. As mentioned above, this canister must adhere to the ICRC-1 and ICRC-2 token standards. - 3. An **index** canister is used to look up ledger data such as the status of a transaction or the transaction history. - 4. Optionally, one or more **archive** canisters to hold a backup copy of past transactions. - - - -## Creating chain-key tokens from underlying tokens - -When a user wishes to obtain chain-key tokens for some underlying tokens, they send the underlying tokens to an address or contract on the origin blockchain controlled by the minter. Once the minter learns about the deposit, it will then instruct the ledger to mint the corresponding number of chain-key tokens for the user. - -The minter may learn about the deposit in different ways. The user may inform the minter about the deposit directly by calling an endpoint on the minter. This is the approach used for chain-key Bitcoin. The claim that tokens have been deposited to a certain address is verified by retrieving the current set of unspent outputs of that address. In the case of chain-key Ether (ckETH) and chain-key ERC-20 (ckERC20) tokens, deposits are made to a helper smart contract on Ethereum. The minter learns about deposits by periodically querying the event logs on the helper smart contract. - -## Redeeming chain-key tokens for underlying tokens - -A chain-key token can circulate on the ICP as long as needed. There is no need to frequently bring in and transfer out underlying tokens, and normally there is no need for most users to do this themselves. However, a user may want to redeem chain-key tokens they hold at some point to receive the underlying asset. To this end, the user must first approve the minter to withdraw at least the desired amount of chain-key tokens from the user’s account (using the approval mechanism defined in [ICRC-2](https://github.com/dfinity/ICRC-1/blob/main/standards/ICRC-2/README.md)). Note that, depending on the chain-key token, more than one approval may be needed. For example, since ERC-20 transactions on Ethereum cost gas, a fee in ckETH must be paid to cover the gas fee in ETH. The user must therefore approve the ckETH minter to withdraw some of the user’s ckETH for the gas fee as well as the minter of the targeted ckERC20 token for the actual withdrawal. - -After the chain-key tokens have been burned, that is, removed from the supply, the minter creates a transaction to transfer the same amount of underlying tokens, possibly minus a fee, from its custody to the user-specified address. The minter uses the chain-key signing functionality available on the Internet Computer to sign the transaction in a decentralized and secure manner. For example, threshold ECDSA signing is used for chain-key tokens where the underlying token can be transferred using ECDSA signatures, which is the case, for example, for Bitcoin, ETH, and tokens on Ethereum. - -Lastly, the signed transaction must be transferred to the blockchain hosting the underying token. The direct integration with Bitcoin makes this step simple as the Internet Computer itself offers the functionality to transmit Bitcoin transactions. For EVM-based chains, this step can be accomplished by sending the transaction to JSON-RPC providers using HTTPS outcalls. - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/dogecoin-integration.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/dogecoin-integration.md deleted file mode 100644 index b7875de..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/dogecoin-integration.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -learn_hub_id: 46782835018516 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/46782835018516-Dogecoin-Integration" -learn_hub_title: "Dogecoin Integration" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Dogecoin Integration - -The [Dogecoin](https://dogecoin.com/) integration on the Internet Computer makes it possible to create Dogecoin smart contracts, that is, smart contracts in the form of canisters running on the Internet Computer that make use of real dogecoin. - -This integration heavily reuses the [Bitcoin integration](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084) since Dogecoin is a Bitcoin fork. Just like the Bitcoin integration, the Dogecoin integration consists of two main components. It also uses a dedicated process, called the _Dogecoin adapter_ , that interacts with the Dogecoin network directly. The current state of the Dogecoin blockchain is maintained in the [Dogecoin canister](https://github.com/dfinity/dogecoin-canister), which also manages all communication with the Dogecoin adapter. The high-level architecture is depicted in the following diagram. - -![](https://learn.internetcomputer.org/hc/article_attachments/46782851378068) - -More information including technical details can be found on the [Bitcoin integration](https://learn.internetcomputer.org/hc/en-us/articles/34211154520084) page. Information on how to get started with the Dogecoin integration can be found [here](https://dfinity.github.io/dogecoin-canister/). - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/ethereum-integration.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/ethereum-integration.md deleted file mode 100644 index 44def67..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/ethereum-integration.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -learn_hub_id: 34575019947668 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/34575019947668-Ethereum-Integration" -learn_hub_title: "Ethereum Integration" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Ethereum Integration - -Canister smart contracts on ICP can directly interact with the Ethereum network and other networks that are using the Ethereum Virtual Machine (EVM), such as Polygon and Avalanche. This integration is possible thanks to ICP's HTTPS outcalls and chain-key signatures, which allow Ethereum state to be queried and Ethereum transactions to be signed and submitted by canisters. - - * [HTTPS outcalls:](https://learn.internetcomputer.org/hc/en-us/articles/34211194553492) To query information from Ethereum and other EVM networks, HTTPS outcalls are used. HTTPS outcalls can obtain information from external sources. In this integration, they're used to obtain data from JSON-RPC services by querying Ethereum's transactions, addresses, and block information. To facilitate JSON-RPC calls, the [EVM RPC canister](https://learn.internetcomputer.org/hc/en-us/articles/45550731488916) provides an API endpoint that canisters can use. - - * [Chain-key signatures for ECDSA:](https://learn.internetcomputer.org/hc/en-us/articles/34209497587732) A canister can have an Ethereum address and sign transactions for that address in a secure and decentralized way using chain-key cryptography. This allows canisters to hold Ethereum natively. Messages sent by the smart contract can be signed in this way, enabling calling any smart contract on Ethereum from the canister. - - - -The main components are depicted in the following figure. - -### ![](https://learn.internetcomputer.org/hc/article_attachments/34575033443348) - -This functionality also forms the basis for EVM-based [chain-key tokens](https://learn.internetcomputer.org/hc/en-us/articles/34211397080980), like ckETH, ckUSDC, and many more. - -## Additional Resources - -[Blog article](https://medium.com/dfinity/icp-ethereum-how-icps-evm-rpc-canister-connects-the-networks-b57909efecf6) - -[Developer docs on EVM RPC canister](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/evm-rpc/overview) - - - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/evm-rpc-canister.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/evm-rpc-canister.md deleted file mode 100644 index 5465939..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/evm-rpc-canister.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -learn_hub_id: 45550731488916 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/45550731488916-EVM-RPC-Canister" -learn_hub_title: "EVM RPC Canister" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# EVM RPC Canister - -The [EVM RPC Canister](https://github.com/internet-computer-protocol/evm-rpc-canister) is a canister that enables the communication between canisters on the Internet Computer and smart contracts on Ethereum and other EVM (Ethereum Virtual Machine) blockchains. - -Canisters can send requests to the EVM RPC Canister, which forwards the request to multiple JSON-RPC services using [HTTPS outcalls](https://learn.internetcomputer.org/hc/en-us/articles/34211194553492) and returns a response to the canister that sent the request. As such, the EVM RPC canister acts as a gateway for canisters to communicate with and query information from EVM-compatible chains. It provides endpoints that ICP developers can use to interact with Ethereum smart contracts and ensures that the responses received from the Ethereum network are secure and immediately useful within a canister. - -## Architecture - -The following figure depicts the involved components and their interactions at a high level. - -![](https://learn.internetcomputer.org/hc/article_attachments/45550731486996) - -The EVM RPC Canister accepts requests from canisters and interacts with JSON-RPC providers via HTTPS outcalls to obtain data from and submit data to Ethereum or other EVM-based blockchains. Multiple JSON-RPC providers are queried to ensure that the response does not come from a single centralized party: The HTTPs outcalls mechanism guarantees that at least 2/3 of the subnet's nodes agree on the response obtained from the server. Once the response is validated, it is sent to the canister that originated the request. - -For Candid-RPC methods such as `eth_getTransactionReceipt`, the EVM RPC canister sends the same request to at least three different RPC providers by default and compares the results. If there are discrepancies, the caller receives a set of inconsistent results to handle them in a way that makes sense for the use case. Instead of relying on the default, the caller can specify the total number of providers to be queried or even list the concrete providers of choice. Moreover, the caller can also set a minimum number of providers that must return the same (non-error) result. Currently, the following JSON-RPC providers are supported: [CloudFlare](https://www.cloudflare.com/), [Alchemy](https://www.alchemy.com/), [Ankr](https://www.ankr.com/), and [BlockPI](https://blockpi.io/). - -Beyond the Ethereum blockchain, this canister also has partial support for [Polygon](https://polygon.technology/), [Avalanche](https://www.avax.network/), and other popular EVM networks. - -The EVM RPC is controlled by the [Network Nervous System DAO](https://learn.internetcomputer.org/hc/en-us/articles/33692645961236), i.e., its functionality cannot be changed by a single entity. Together, these mechanisms ensure that no trust in additional parties (bridges or oracles) are necessary for the caller canister to send transactions and to condition executions on Ethereum state. - -Detailed information about the available endpoints and code samples can be found in the [developer docs](https://internetcomputer.org/docs/current/developer-docs/multi-chain/ethereum/evm-rpc/overview). - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/exchange-rate-canister.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/exchange-rate-canister.md deleted file mode 100644 index 786e287..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/exchange-rate-canister.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -learn_hub_id: 45038506066452 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/45038506066452-Exchange-Rate-Canister" -learn_hub_title: "Exchange Rate Canister" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# Exchange Rate Canister - -The exchange rate canister (XRC) is a canister running on the [uzr34 system subnet](https://dashboard.internetcomputer.org/subnet/uzr34-akd3s-xrdag-3ql62-ocgoh-ld2ao-tamcv-54e7j-krwgb-2gm4z-oqe) that provides exchange rates to requesting canisters. A request comprises a base asset, a quote asset, and an optional (UNIX epoch) timestamp. The base and quote asset can be any combination of cryptocurrency and fiat currency assets, for example, BTC/ICP, ICP/USD, or USD/EUR. The timestamp parameter makes it possible to request historic rates. If no timestamp is provided in the request, the rate for the current time is returned. - -The XRC constitutes an on-chain oracle for exchange rates, which is particularly useful for DeFi applications but can further add value to any application that requires exchange rate information. - -The cycle minting canister of the [NNS](https://learn.internetcomputer.org/hc/en-us/articles/33692645961236) makes use of the XRC to obtain up-to-date ICP/XDR rates, which it requires for the conversion of ICP to cycles. - -## Usage - -The canister ID of the XRC is `uf6dk-hyaaa-aaaaq-qaaaq-cai`. A request of the form - - - type GetExchangeRateRequest = record { - base_asset: Asset; - quote_asset: Asset; - timestamp: opt nat64; - }; - - -can be sent to the XRC, which replies with the following result: - - - type GetExchangeRateResult = variant { - Ok: ExchangeRate; - Err: ExchangeRateError; - }; - - -An `Asset` is a record consisting of a symbol (for example, "ICP") and a class (either `Cryptocurrency` or `FiatCurrency`). The full candid file can be found [here](https://github.com/dfinity/exchange-rate-canister/blob/main/src/xrc/xrc.did). The optional timestamp in the request must be a UNIX timestamp in seconds when provided. If no timestamp is provided, the timestamp corresponding to the start of the current minute is used. Note that the granularity for requests is 1 minute, so seconds in a timestamp are ignored. - -It is further worth nothing that some exchanges may not always have exchange rates available for the current minute. Depending on the use case, it may be advisable to use the start of the previous minute to increase the chance to get a response based on rates collected from all queried exchanges. - -For every request, **1B cycles** need to be sent along, otherwise an `ExchangeRateError::NotEnoughCycles` error is returned. The actual cost of the call depends on two factors, the requested asset types and the state of the internal exchange rate cache, as follows: - - * If the request can be served from the cache, the actual cost is 20M cycles. - * If both assets are fiat currencies, the cost is 20M cycles as well. - * If one of the assets is a fiat currency or the cryptocurrency USDT, the cost is 260M cycles. - * If both assets are cryptocurrencies, the cost is 500M cycles. - - - -The remaining cycles are returned to the requesting canister. Note that at least 1M cycles are charged even in case of an error in order to mitigate the risk of a denial-of-service attack. - -## Technical Details - -The following figure depicts the work flow when receiving a request. - -[![](https://learn.internetcomputer.org/hc/article_attachments/45038716591124)](https://wiki.internetcomputer.org/wiki/File:XRC_Flow_Diagram.png) - -After receiving a request (step 1), the exchange rate for each cryptocurrency asset in the request with respect to the quote asset USDT is queried (for the timestamp in the request) from all supported exchanges using [HTTPS outcalls](https://learn.internetcomputer.org/hc/en-us/articles/34211194553492 "HTTPS outcalls") if this rate is not already cached (step 2). If a rate can be computed based on the query results received from the exchanges, it is inserted in the cache and returned to the requesting canister (step 3). The _median rate_ of all received rates is returned as it is not susceptible to outliers (unlike, for example, the average rate). - -If a cryptocurrency/cryptocurrency base-quote pair B/Q was requested, the B/Q rate is derived from the queried B/USDT and Q/USDT rates: First, the Q/USDT rates are inverted to get the USDT/Q rates. Second, the cross product of the B/USDT and USDT/Q rates is computed. Lastly, the median of these rates is returned as the B/Q rate. The motivation for using the cross product is that it contains every B/Q rate that can be derived from the given B/USDT and USDT/Q rates. The median rate is chosen as it is less susceptible to outliers than using, for example, the average. - -The XRC queries daily foreign exchange (forex) rates from forex data providers automatically on a fixed schedule. Furthermore, the XRC queries multiple stablecoin rates automatically to derive the USD/USDT rate as follows. Given SC1/USDT, SC2/USDT, ... rates for a set of stablecoins SC1, SC2, ..., it uses the median of these rates as the USD/USDT rate. This rule is based on the assumption that at least half of the stablecoins in the set keep their peg to USD at any time, in which case the median rate is an adequate estimate for the USD/USDT rate. Given the USD/USDT rate and the forex rates for fiat currencies other than USD, the requested rate can be computed for the case when one or more assets in the request are fiat currencies. - -Since more requests to exchanges are required for cryptocurrency/cryptocurrency pairs, more cycles are charged for such requests. - -As indicated in the figure above, the response to a successful request contains metadata in addition to the rate. The metadata contains the following fields: - - * `decimals`: The rate is returned as a scaled 64-bit integer. The scaling factor is 10 to the power of `decimals`. - * `base_asset_num_received_rates`: The number of received rates for the base asset from all queried exchanges. - * `base_asset_num_queried_sources`: The number of queried exchanges for the base asset. - * `quote_asset_num_received_rates`: The number of received rates for the quote asset from all queried exchanges. - * `quote_asset_num_queried_sources`: The number of queried exchanges for the quote asset. - * `standard_deviation`: The standard deviation of all received rates for this request. Note that the standard deviation is scaled by the same factor as the rate itself. - * `forex_timestamp`: The timestamp of the beginning of the day for which the forex rates were retrieved, if any. - - - -This additional information can be used to determine the trustworthiness of the received rate, for example by checking the number of rates that went into the computation of the rate and the standard deviation. If the XRC receives largely inconsistent rates from exchanges, it returns an `ExchangeRateError::InconsistentRatesReceived` itself. - diff --git a/.migration/learn-hub/how-does-icp-work/chain-fusion/sol-rpc-canister.md b/.migration/learn-hub/how-does-icp-work/chain-fusion/sol-rpc-canister.md deleted file mode 100644 index f9ce81b..0000000 --- a/.migration/learn-hub/how-does-icp-work/chain-fusion/sol-rpc-canister.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -learn_hub_id: 46782465439764 -learn_hub_url: "https://learn.internetcomputer.org/hc/en-us/articles/46782465439764-SOL-RPC-Canister" -learn_hub_title: "SOL RPC Canister" -learn_hub_section: "Chain Fusion" -learn_hub_category: "How does ICP work?" -migrated: false ---- - -# SOL RPC Canister - -The [SOL RPC canister](https://github.com/dfinity/sol-rpc-canister) is a canister that enables the communication between canisters on the Internet Computer and smart contracts on the [Solana](https://solana.com/) blockchains. - -Canisters can send requests to the SOL RPC Canister, which forwards the request to multiple JSON-RPC services using [HTTPS outcalls](https://learn.internetcomputer.org/hc/en-us/articles/34211194553492) and returns a response to the canister that sent the request. - -# Architecture - -The following figure depicts the involved components and their interactions at a high level. - -![](https://learn.internetcomputer.org/hc/article_attachments/46782497345940) - -The SOL RPC Canister accepts requests from canisters and interacts with JSON-RPC providers via HTTPS outcalls to obtain data from and submit data to Solana. Multiple JSON-RPC providers are queried to ensure that the response does not come from a single centralized party. At the same time, this mechanism guarantees that there is no single point of failure. Currently, the following JSON-RPC providers are supported: [Alchemy](https://www.alchemy.com/), [Ankr](https://www.ankr.com/), [Chainstack](https://chainstack.com/), [dRPC](https://drpc.org/), [Helius](https://www.helius.dev/), and [PublicNode](https://publicnode.com/). - -The SOL RPC is controlled by the [Network Nervous System DAO](https://learn.internetcomputer.org/hc/en-us/articles/33692645961236), i.e., its functionality cannot be changed by a single entity. Together, these mechanisms ensure that no trust in additional parties (bridges or oracles) are necessary for the caller canister to send transactions and to condition executions on Solana state. - -A [code sample](https://github.com/dfinity/sol-rpc-canister/tree/main/examples/basic_solana) showing how to use the SOL RPC canister can be found in the [SOL RPC canister repository](https://github.com/dfinity/sol-rpc-canister/). - diff --git a/docs/concepts/chain-fusion/bitcoin.md b/docs/concepts/chain-fusion/bitcoin.md new file mode 100644 index 0000000..6b1cb74 --- /dev/null +++ b/docs/concepts/chain-fusion/bitcoin.md @@ -0,0 +1,96 @@ +--- +title: "Bitcoin Integration" +description: "How ICP connects to Bitcoin natively: the adapter, the Bitcoin canister, the checker canister, and ckBTC" +--- + +ICP's Bitcoin integration lets canisters hold Bitcoin addresses, query balances and UTXOs, and sign and broadcast Bitcoin transactions, all without bridges or custodians. This page covers the protocol architecture: the Bitcoin adapter, the Bitcoin canister, the Bitcoin checker canister, and chain-key Bitcoin (ckBTC). + +## Architecture + +The integration has two layers: + +**Protocol layer.** ICP nodes run a _Bitcoin adapter_, a process separate from the replica that speaks the Bitcoin peer-to-peer protocol. The adapter connects to Bitcoin nodes, downloads blocks, and relays pending transactions. It keeps the replica informed about the latest Bitcoin state. Inside the replica, the _Bitcoin canister_ (a canister running on a dedicated system subnet) processes blocks from the adapter, maintains the UTXO set for all Bitcoin addresses, and exposes a low-level API to other canisters. + +**Signing layer.** Each canister can derive its own Bitcoin addresses through [chain-key signatures](../chain-key-cryptography.md). Because Bitcoin addresses are tied to ECDSA or Schnorr public keys, and the protocol can produce threshold signatures for those keys, a canister can authorize Bitcoin transactions without any node ever holding the full private key. + +Together, these two layers give a canister the ability to receive bitcoin, check its balance, construct transactions, sign them, and broadcast them to the Bitcoin network. + +## Bitcoin canister API + +The Bitcoin canister exposes three main endpoints accessible through the management canister: + +- `bitcoin_get_balance`: returns the balance of any Bitcoin address. +- `bitcoin_get_utxos`: returns the unspent transaction outputs (UTXOs) for a given address. This is the primary input when constructing a Bitcoin transaction. +- `bitcoin_get_current_fee_percentiles`: returns recent fee rates so a canister can estimate an appropriate miner fee. +- `bitcoin_send_transaction`: broadcasts a signed transaction to the Bitcoin network via the adapter. + +A typical flow for a canister spending bitcoin is: fetch UTXOs for its address, select inputs, build the transaction, call `sign_with_ecdsa` (or `sign_with_schnorr` for Taproot) for each input, then call `bitcoin_send_transaction`. + +## Bitcoin checker canister + +The Bitcoin checker canister (`oltsj-fqaaa-aaaar-qal5q-cai`) screens Bitcoin addresses and transactions against the [OFAC Specially Designated Nationals (SDN) list](https://sanctionslist.ofac.treas.gov/Home/SdnList). It is used by ckBTC and any canister that wants to avoid handling funds associated with sanctioned activity. + +Two primary endpoints are available: + +- `check_address`: checks a single Bitcoin address against the SDN list. This is a simple lookup with no cycle cost. +- `check_transaction`: checks all input addresses of a transaction. The canister fetches the transaction and each of its inputs via HTTPS outcalls, derives the input addresses, and checks each one against the SDN list. Because of the HTTPS outcalls, at least 40 billion cycles must be attached; unused cycles are refunded. `check_transaction_str` accepts the transaction ID as a string instead of a blob. + +Both endpoints return `Passed` or `Failed`. The canister itself is controlled by the NNS, so its SDN list can only be updated via a governance proposal. + +## Chain-key Bitcoin (ckBTC) + +ckBTC is a token on ICP backed 1:1 by real bitcoin. 1 ckBTC can always be redeemed for 1 BTC and vice versa. Unlike wrapped tokens, ckBTC relies on no third-party custodian: the bitcoin is held by a canister-controlled address on the Bitcoin network, and the minting and burning happen entirely onchain. + +ckBTC transactions settle in seconds and cost a fraction of a satoshi, making it practical for high-frequency or low-value transfers that would be uneconomical on Bitcoin directly. + +### Canisters + +Two canisters run on the [pzp6e subnet](https://dashboard.internetcomputer.org/subnet/pzp6e-ekpqk-3c5x7-2h6so-njoeq-mt45d-h3h6c-q3mxf-vpeez-fez7a-iae), both controlled by the NNS root canister: + +| Canister | ID | +|----------|-----| +| ckBTC minter | `mqygn-kiaaa-aaaar-qaadq-cai` | +| ckBTC ledger | `mxzaz-hqaaa-aaaar-qaada-cai` | + +The **ledger** is an ICRC-1/ICRC-2 compliant token ledger. It records all ckBTC balances and handles transfers. The transfer fee is 0.0000001 ckBTC (10 satoshi), sent to the minter's fee subaccount. + +The **minter** manages the BTC side: it controls Bitcoin addresses, tracks UTXOs, triggers minting when deposits arrive, and signs and submits Bitcoin transactions when users withdraw. + +### Converting BTC to ckBTC + +1. The user calls `get_btc_address` on the minter to receive a deposit address (a P2WPKH address) tied to their principal. +2. The user sends bitcoin to that address on the Bitcoin network. +3. After 6 confirmations, the user calls `update_balance` on the minter. +4. The minter fetches UTXOs for the deposit address via `bitcoin_get_utxos` and checks each new UTXO with the Bitcoin checker canister. UTXOs that pass the check are minted as ckBTC into the user's ledger account (minus the 100-satoshi checker fee). UTXOs that fail the check are quarantined. + +The 6-confirmation requirement protects against Bitcoin chain reorganizations. + +### Converting ckBTC to BTC + +The recommended flow uses ICRC-2 approval: + +1. The user calls `icrc2_approve` on the ckBTC ledger, authorizing the minter to withdraw the desired amount. +2. The user calls `retrieve_btc_with_approval` on the minter, specifying the amount and destination Bitcoin address. +3. The minter checks the destination address with the Bitcoin checker canister. If it passes, the minter burns the ckBTC from the user's account and queues a Bitcoin withdrawal. +4. The minter periodically batches pending requests: it selects UTXOs, builds a Bitcoin transaction, signs each input using threshold ECDSA, and submits via `bitcoin_send_transaction`. + +Requests are batched to reduce Bitcoin miner fees: if at least 20 requests accumulate or the oldest request is 10 minutes old, the minter creates a single transaction serving up to 100 requests. + +The minimum withdrawal amount is 0.0005 BTC (50,000 satoshi) to ensure the fee remains proportionally small. + +### Minter fee + +The minter fee for a withdrawal transaction is `146 × inputs + 4 × outputs + 26` satoshi. This formula covers the cost of threshold ECDSA signatures and transaction broadcasting. The fee is split among all outputs in a batch transaction. + +### UTXO consolidation + +As deposits accumulate, the minter manages a growing set of UTXOs. Too many small UTXOs can make large withdrawals impossible (a Bitcoin transaction is limited to 100 KB). When the UTXO count exceeds 10,000, the minter periodically creates _consolidation transactions_ that merge the 1,000 smallest UTXOs into 2 new outputs, funded from the minter's fee account. + +## Next steps + +- [Bitcoin guide](../../guides/chain-fusion/bitcoin.md): build Bitcoin transactions from a canister +- [Dogecoin integration](dogecoin.md): Bitcoin fork integration using the same architecture +- [Chain Fusion overview](index.md): integration patterns and supported chains +- [Chain-key cryptography](../chain-key-cryptography.md): threshold ECDSA and Schnorr signing + + diff --git a/docs/concepts/chain-fusion/chain-key-tokens.md b/docs/concepts/chain-fusion/chain-key-tokens.md new file mode 100644 index 0000000..6d60217 --- /dev/null +++ b/docs/concepts/chain-fusion/chain-key-tokens.md @@ -0,0 +1,69 @@ +--- +title: "Chain-Key Tokens" +description: "Trustless 1:1 representations of external blockchain assets on ICP" +--- + +Chain-key tokens are ICP tokens backed 1:1 by assets native to another blockchain. ckBTC represents bitcoin, ckETH represents ether, ckUSDC represents USDC on Ethereum, and so on. Each token is fully backed by the underlying asset (held in a canister-controlled address on the origin chain), and all minting and burning happens entirely onchain, with no third-party custodian. + +## Why chain-key tokens instead of wrapped tokens + +Traditional wrapped tokens depend on an off-chain custodian that holds the underlying asset and instructs a token contract to mint or burn the wrapped version. If the custodian is compromised, hacked, or goes out of business, the backing can be lost entirely. Additionally, nothing prevents a dishonest custodian from using the custodied assets for other purposes, risking a depeg. + +Chain-key tokens eliminate the custodian. The underlying assets are held by a minter canister at a blockchain address derived from a chain-key key, an address no single party controls. Minting and burning are triggered by verifiable onchain events (confirmed Bitcoin UTXOs, Ethereum event logs), and the minter signs withdrawal transactions using threshold cryptography distributed across a subnet's nodes. + +## Architecture + +Every chain-key token uses a set of canisters: + +1. **Minter**: manages the underlying asset on the origin chain. It controls the deposit address (or Ethereum helper contract), detects incoming deposits, instructs the ledger to mint tokens, and signs and submits withdrawals when tokens are burned. +2. **Ledger**: an ICRC-1/ICRC-2 compliant token ledger. It records all balances and executes mint, burn, and transfer operations. +3. **Index**: provides indexed access to ledger transactions, enabling efficient lookup of an account's transaction history. +4. **Archive** (optional): stores historical transaction data that has been offloaded from the ledger to keep it compact. + +All canisters in a chain-key token system are controlled by the NNS, making the token governance fully decentralized. + +## Minting (getting chain-key tokens) + +The minting process differs slightly by chain: + +**Bitcoin-based tokens (ckBTC, ckDOGE).** The user requests a deposit address from the minter. This is a chain-key ECDSA address controlled by the minter. The user sends the underlying asset to this address on the Bitcoin or Dogecoin network. Once the transaction reaches the required confirmation threshold (6 confirmations for ckBTC), the user calls `update_balance` on the minter. The minter verifies the deposit via the Bitcoin canister and mints the corresponding amount on the ledger. + +**EVM-based tokens (ckETH, ckERC20).** A helper smart contract deployed on Ethereum receives deposits. When a user sends ETH or an ERC-20 token to the helper contract, it emits an event. The minter periodically queries these event logs via the [EVM RPC canister](ethereum.md) and mints the corresponding chain-key tokens on the ICP ledger. + +## Burning (redeeming underlying assets) + +All chain-key token redemptions use ICRC-2 approval: + +1. The user calls `icrc2_approve` on the ledger to authorize the minter to withdraw the desired amount. +2. The user calls the minter's withdrawal endpoint (for example, `retrieve_btc_with_approval` for ckBTC). +3. The minter burns the chain-key tokens from the user's account. +4. The minter constructs a transaction on the origin chain, signs it using chain-key cryptography (threshold ECDSA for Bitcoin and Ethereum; threshold Ed25519 for Solana), and submits it. + +For EVM-based tokens, the gas fee on Ethereum must be covered. ckETH acts as the fee currency: when redeeming ckERC20 tokens, the user also approves a small ckETH amount to cover the Ethereum gas cost. + +## Chain-key token security + +The security of a chain-key token rests on two properties: + +- **Supply bound.** The minter never mints more chain-key tokens than the underlying assets it controls. The total ckBTC supply, for example, is always at most equal to the BTC held at minter-controlled Bitcoin addresses. +- **Threshold custody.** The minter's private key is never held by a single party. Withdrawal transactions are signed collectively by the subnet nodes through the chain-key protocol, so a single compromised node cannot authorize unauthorized withdrawals. + +## Deployed tokens + +| Token | Underlying | Origin chain | Integration method | +|-------|------------|--------------|-------------------| +| ckBTC | BTC | Bitcoin | Direct | +| ckETH | ETH | Ethereum | EVM RPC canister | +| ckERC20 (ckUSDC, ckUSDT, ...) | ERC-20 tokens | Ethereum | EVM RPC canister | +| ckSOL | SOL | Solana | SOL RPC canister | +| ckDOGE | DOGE | Dogecoin | Direct | + +## Next steps + +- [Bitcoin integration](bitcoin.md): ckBTC minter and ledger in detail +- [Ethereum integration](ethereum.md): ckETH and ckERC20 architecture +- [Chain Fusion overview](index.md): the full landscape of ICP cross-chain capabilities +- [Chain-key tokens guide](../../guides/digital-assets/chain-key-tokens.md): how to integrate chain-key tokens into an application +- [Chain-key cryptography](../chain-key-cryptography.md): the threshold signing that makes chain-key tokens possible + + diff --git a/docs/concepts/chain-fusion/dogecoin.md b/docs/concepts/chain-fusion/dogecoin.md new file mode 100644 index 0000000..0e733a2 --- /dev/null +++ b/docs/concepts/chain-fusion/dogecoin.md @@ -0,0 +1,24 @@ +--- +title: "Dogecoin Integration" +description: "How ICP connects to Dogecoin using the same architecture as the Bitcoin integration" +--- + +ICP supports a native Dogecoin integration that works the same way as the [Bitcoin integration](bitcoin.md). Because Dogecoin is a Bitcoin fork, it reuses the same two-component architecture: a dedicated adapter that communicates with the Dogecoin network, and a Dogecoin canister that maintains the current chain state and exposes a query-and-send API to other canisters. + +## Architecture + +The _Dogecoin adapter_ is a process that runs alongside the ICP replica on each node. It speaks the Dogecoin peer-to-peer protocol, syncs blocks from the Dogecoin network, and relays transactions. The _Dogecoin canister_ ([source](https://github.com/dfinity/dogecoin-canister)) is a canister running on a system subnet that consumes blocks from the adapter, maintains the UTXO set, and exposes endpoints for balance queries, UTXO retrieval, fee estimation, and transaction submission. + +Canister-controlled Dogecoin addresses are derived from chain-key ECDSA public keys, just as in the Bitcoin integration. Transactions are signed using the management canister's `sign_with_ecdsa` API and broadcast to the Dogecoin network through the adapter. + +## Chain-key DOGE (ckDOGE) + +ckDOGE is the chain-key token representing Dogecoin on ICP, backed 1:1 by real DOGE held in a canister-controlled address. The minter-plus-ledger architecture is the same as [ckBTC](bitcoin.md#chain-key-bitcoin-ckbtc): users deposit DOGE to a minter-controlled address, the minter mints ckDOGE on the ledger, and withdrawals trigger an onchain Dogecoin transaction signed with threshold ECDSA. + +## Next steps + +- [Bitcoin integration](bitcoin.md): detailed description of the shared adapter and canister architecture +- [Dogecoin canister documentation](https://dfinity.github.io/dogecoin-canister/) +- [Chain Fusion overview](index.md): integration patterns and supported chains + + diff --git a/docs/concepts/chain-fusion/ethereum.md b/docs/concepts/chain-fusion/ethereum.md new file mode 100644 index 0000000..3a0a462 --- /dev/null +++ b/docs/concepts/chain-fusion/ethereum.md @@ -0,0 +1,64 @@ +--- +title: "Ethereum Integration" +description: "How ICP connects to Ethereum and EVM chains: HTTPS outcalls, chain-key ECDSA, and the EVM RPC canister" +--- + +Canisters on ICP can interact with Ethereum and any EVM-compatible chain (Polygon, Avalanche, Arbitrum, Base, Optimism, and others) without bridges or trusted intermediaries. The integration combines two ICP capabilities: [HTTPS outcalls](../https-outcalls.md) to read chain state and [chain-key ECDSA signatures](../chain-key-cryptography.md) to authorize transactions. + +## How it works + +**Reading Ethereum state.** Canisters query Ethereum via JSON-RPC, the same API used by standard Ethereum clients. Because HTTPS outcalls involve all subnet replicas independently fetching the URL and reaching consensus on the response, the result has strong integrity guarantees. Rather than making raw HTTPS outcalls directly, most canisters use the EVM RPC canister, which provides a typed Candid interface and handles multi-provider redundancy automatically. + +**Signing Ethereum transactions.** Each canister can derive an Ethereum address from its chain-key ECDSA public key. To authorize a transaction, the canister calls `sign_with_ecdsa` on the management canister, receives a threshold signature produced by the subnet nodes collectively, and includes the signature in the serialized transaction before submitting it. + +**Submitting Ethereum transactions.** The signed transaction is submitted via the EVM RPC canister's `eth_sendRawTransaction` endpoint, which relays it to multiple JSON-RPC providers for broadcast. + +This flow (query, sign, submit) lets canisters call any Ethereum smart contract, hold ETH or ERC-20 tokens, and participate in DeFi protocols entirely from onchain ICP code. + +## EVM RPC canister + +The EVM RPC canister (`7hfb6-caaaa-aaaar-qadga-cai`) is a system-level canister that acts as a gateway between ICP canisters and Ethereum JSON-RPC APIs. It is controlled by the NNS, so its behavior cannot be changed by any single party. + +### Multi-provider architecture + +For each Candid-RPC method (such as `eth_getTransactionReceipt` or `eth_getBlockByNumber`), the EVM RPC canister sends the request to at least three independent JSON-RPC providers by default and compares the results. Supported providers include [CloudFlare](https://www.cloudflare.com/), [Alchemy](https://www.alchemy.com/), [Ankr](https://www.ankr.com/), and [BlockPI](https://blockpi.io/). + +Results are returned in one of two forms: + +- **Consistent**: all queried providers returned the same result. This is the expected case for finalized data. +- **Inconsistent**: providers returned different results. The caller receives the full set of results and can decide how to handle the discrepancy (for example, by waiting for more confirmations or querying additional providers). + +Callers can override the defaults: specifying a different number of providers, listing concrete providers to use, or setting a minimum agreement threshold. + +### Available methods + +The EVM RPC canister supports the standard JSON-RPC Ethereum API, including: + +- `eth_getBlockByNumber`, `eth_getBlockByHash`: block data +- `eth_getTransactionCount`, `eth_getTransactionByHash`, `eth_getTransactionReceipt`: transaction data +- `eth_getLogs`: event logs (used to detect deposits for chain-key tokens) +- `eth_feeHistory`, `eth_gasPrice`: fee estimation +- `eth_sendRawTransaction`: broadcast a signed transaction +- `eth_call`: call a smart contract read function + +Beyond Ethereum mainnet, the canister also has partial support for Polygon, Avalanche, and other popular EVM networks. + +## Chain-key Ether and ERC-20 tokens + +ckETH and ckERC20 tokens (such as ckUSDC and ckUSDT) are chain-key tokens backed 1:1 by assets on Ethereum. They follow the same architecture as ckBTC (a minter canister plus an ICRC-1/ICRC-2 ledger canister) but use a different deposit mechanism. + +**Deposits.** Because ICP cannot observe Ethereum state directly (unlike Bitcoin, which uses a native adapter), ckETH uses a helper smart contract deployed on Ethereum. Users send ETH or ERC-20 tokens to this helper contract, which emits an event. The ckETH minter periodically queries the event log via the EVM RPC canister to discover deposits and mints the corresponding chain-key tokens. + +**Withdrawals.** The user approves the minter to burn their chain-key tokens (via ICRC-2), then calls the withdrawal endpoint. The minter burns the tokens, signs an Ethereum transaction using chain-key ECDSA, and submits it via the EVM RPC canister. + +For a full description of chain-key token architecture, see [Chain-key tokens](chain-key-tokens.md). + +## Next steps + +- [Ethereum guide](../../guides/chain-fusion/ethereum.md): code examples for reading state and sending transactions +- [Chain Fusion overview](index.md): integration patterns and supported chains +- [HTTPS outcalls](../https-outcalls.md): how canisters reach external HTTP endpoints +- [Chain-key cryptography](../chain-key-cryptography.md): threshold ECDSA signing +- [Chain-key tokens](chain-key-tokens.md): ckETH and ckERC20 architecture + + diff --git a/docs/concepts/chain-fusion/exchange-rate-canister.md b/docs/concepts/chain-fusion/exchange-rate-canister.md new file mode 100644 index 0000000..17ff002 --- /dev/null +++ b/docs/concepts/chain-fusion/exchange-rate-canister.md @@ -0,0 +1,56 @@ +--- +title: "Exchange Rate Canister" +description: "On-chain oracle for cryptocurrency and fiat exchange rates" +--- + +The exchange rate canister (XRC) is a system canister running on the [uzr34 system subnet](https://dashboard.internetcomputer.org/subnet/uzr34-akd3s-xrdag-3ql62-ocgoh-ld2ao-tamcv-54e7j-krwgb-2gm4z-oqe) that provides exchange rates to other canisters. It serves as an onchain oracle for asset prices, querying external exchanges via [HTTPS outcalls](../https-outcalls.md) and returning the median rate across all responses. + +The canister ID is `uf6dk-hyaaa-aaaaq-qaaaq-cai`. + +The NNS cycle minting canister uses the XRC to obtain up-to-date ICP/XDR rates, which it needs to convert ICP to cycles. + +## Requesting a rate + +A request takes the form: + +```candid +type GetExchangeRateRequest = record { + base_asset: Asset; + quote_asset: Asset; + timestamp: opt nat64; +}; +``` + +An `Asset` is a record with a symbol (for example, `"ICP"` or `"USD"`) and a class (`Cryptocurrency` or `FiatCurrency`). The base and quote assets can be any combination of cryptocurrency and fiat currency, for example `BTC/ICP`, `ICP/USD`, or `USD/EUR`. + +The optional `timestamp` is a Unix timestamp in seconds with 1-minute granularity (seconds are ignored). If omitted, the rate for the current minute is returned. To improve reliability, using the start of the previous minute is advisable, since some exchanges may not yet have data for the current minute. + +The response is a `GetExchangeRateResult` variant (`Ok: ExchangeRate` or `Err: ExchangeRateError`). A successful response includes the rate as a scaled 64-bit integer, plus metadata: the `decimals` field (divide the rate by 10^`decimals` to get the human-readable price), the number of sources queried and rates received for each asset, the standard deviation, and the forex timestamp if applicable. + +## Cycle cost + +Every request must include **1 billion cycles**. The actual cost depends on the request type: + +| Request type | Actual cost | +|---|---| +| Served from cache, or both assets are fiat | 20M cycles | +| One asset is fiat or USDT | 260M cycles | +| Both assets are cryptocurrencies | 500M cycles | + +Unused cycles are refunded. At least 1M cycles are charged even on error, to prevent denial-of-service attacks. + +## How rates are computed + +When a cryptocurrency rate is not cached, the XRC queries all supported exchanges using HTTPS outcalls to get the asset's price against USDT. It then takes the **median** of all received rates, making the result resistant to outliers. For a cryptocurrency/cryptocurrency pair like BTC/ICP, the XRC derives the rate from independent BTC/USDT and ICP/USDT rates using a cross-product approach before taking the median. + +For fiat currencies, the XRC downloads daily forex rates from forex data providers on a fixed schedule. USD/USDT is derived by taking the median of rates for several stablecoins against USDT, based on the assumption that at least half of the included stablecoins maintain their USD peg at any given time. + +If the XRC receives largely inconsistent rates from exchanges, it returns an `ExchangeRateError::InconsistentRatesReceived` error. + +## Next steps + +- [Chain Fusion overview](index.md): integration patterns and supported chains +- [HTTPS outcalls](../https-outcalls.md): how the XRC fetches external data +- [XRC Candid interface](https://github.com/dfinity/exchange-rate-canister/blob/main/src/xrc/xrc.did) + + diff --git a/docs/concepts/chain-fusion.md b/docs/concepts/chain-fusion/index.md similarity index 72% rename from docs/concepts/chain-fusion.md rename to docs/concepts/chain-fusion/index.md index a746c8f..a4675e4 100644 --- a/docs/concepts/chain-fusion.md +++ b/docs/concepts/chain-fusion/index.md @@ -7,7 +7,7 @@ sidebar: Chain Fusion is ICP's approach to cross-chain interoperability. Instead of relying on bridges or oracles, canisters interact with other blockchains directly: they can read state, hold assets, and sign and submit transactions on Bitcoin, Ethereum, Solana, and dozens of other chains. All of this runs onchain with the same trust assumptions as the Internet Computer itself. -The foundation is [chain-key cryptography](chain-key-cryptography.md). Each canister can derive keys for external signature schemes (ECDSA and Schnorr) and request threshold signatures from the protocol. This means a canister can control a Bitcoin address, an Ethereum account, or a Solana wallet: without any single node ever holding the private key. +The foundation is [chain-key cryptography](../chain-key-cryptography.md). Each canister can derive keys for external signature schemes (ECDSA and Schnorr) and request threshold signatures from the protocol. This means a canister can control a Bitcoin address, an Ethereum account, or a Solana wallet: without any single node ever holding the private key. ## Why Chain Fusion matters @@ -16,9 +16,9 @@ Most cross-chain solutions introduce a trusted intermediary: a bridge, a multisi A canister interacting with Bitcoin or Ethereum has no external dependency beyond the target chain itself. The signing happens inside the protocol through a threshold cryptographic ceremony distributed across subnet nodes. This gives developers several advantages: - **No bridges.** Canisters hold assets directly on external chains. There is no wrapped token that can depeg, no bridge contract that can be exploited. -- **No oracles.** Canisters can read external chain state themselves: either through a direct protocol integration (Bitcoin) or by querying RPC providers via [HTTPS outcalls](https-outcalls.md). -- **Full autonomy.** Canisters can schedule cross-chain actions using [timers](../guides/backends/timers.md), enabling use cases like automated trading, periodic liquidations, or cronjob services: all without external triggers. -- **Familiar UX.** Because ICP has low-cost computation and [canisters pay for their own cycles](cycles.md), users can interact with cross-chain apps through a standard browser without installing a wallet. +- **No oracles.** Canisters can read external chain state themselves: either through a direct protocol integration (Bitcoin) or by querying RPC providers via [HTTPS outcalls](../https-outcalls.md). +- **Full autonomy.** Canisters can schedule cross-chain actions using [timers](../../guides/backends/timers.md), enabling use cases like automated trading, periodic liquidations, or cronjob services: all without external triggers. +- **Familiar UX.** Because ICP has low-cost computation and [canisters pay for their own cycles](../cycles.md), users can interact with cross-chain apps through a standard browser without installing a wallet. ## How it works @@ -36,7 +36,7 @@ Two schemes are available: | Threshold Schnorr (`bip340secp256k1`) | Bitcoin Taproot, Ordinals | | Threshold Schnorr (`ed25519`) | Solana, TON, Polkadot, Cardano, NEAR, Stellar | -See [Chain-key cryptography](chain-key-cryptography.md) for details on the threshold signing protocols, key derivation, and deployed keys. +See [Chain-key cryptography](../chain-key-cryptography.md) for details on the threshold signing protocols, key derivation, and deployed keys. ### 2. Reading external chain state @@ -44,7 +44,7 @@ A canister needs to read the state of an external chain to verify events, check - **Direct integration.** The protocol runs a native adapter that connects to the external chain's peer-to-peer network. Bitcoin uses this model: ICP nodes run a Bitcoin adapter that syncs blocks directly, so canisters can query UTXOs and submit transactions through the management canister's Bitcoin API without any intermediary. -- **RPC integration.** For chains without a direct integration, canisters use [HTTPS outcalls](https-outcalls.md) to query RPC providers. The EVM RPC canister (`7hfb6-caaaa-aaaar-qadga-cai`) provides a typed Candid interface for Ethereum and EVM-compatible chains. It sends each request to at least three independent RPC providers and returns either a `Consistent` result (all providers agree) or an `Inconsistent` result that the caller can handle. Solana has a similar dedicated canister (SOL RPC). For other chains, canisters can make raw HTTPS outcalls to any JSON-RPC endpoint. +- **RPC integration.** For chains without a direct integration, canisters use [HTTPS outcalls](../https-outcalls.md) to query RPC providers. The EVM RPC canister (`7hfb6-caaaa-aaaar-qadga-cai`) provides a typed Candid interface for Ethereum and EVM-compatible chains. It sends each request to at least three independent RPC providers and returns either a `Consistent` result (all providers agree) or an `Inconsistent` result that the caller can handle. Solana has a similar dedicated canister (SOL RPC). For other chains, canisters can make raw HTTPS outcalls to any JSON-RPC endpoint. ### 3. Submitting transactions @@ -70,9 +70,9 @@ Direct integration provides the strongest trust guarantees. The only assumption Chain-key tokens are digital twins of native assets from other blockchains (for example, ckBTC for Bitcoin and ckETH for Ethereum). Each token is backed 1:1 by the native asset, which is held in a canister-controlled address on the source chain. Minting and burning happen entirely onchain. No bridge, no custodian. -These tokens implement the [ICRC-2](../guides/digital-assets/ledgers.md) token standard, so they can be transferred and traded within the ICP ecosystem with the same speed and cost as any other ICP token. When a user wants to redeem the underlying asset, the minter canister signs and submits a withdrawal transaction on the source chain. +These tokens implement the [ICRC-2](../../guides/digital-assets/ledgers.md) token standard, so they can be transferred and traded within the ICP ecosystem with the same speed and cost as any other ICP token. When a user wants to redeem the underlying asset, the minter canister signs and submits a withdrawal transaction on the source chain. -For details on integrating with chain-key tokens, see the [Chain-key tokens guide](../guides/digital-assets/chain-key-tokens.md). +For details on chain-key token architecture, see [Chain-key tokens](chain-key-tokens.md). For integration guides, see the [Chain-key tokens guide](../../guides/digital-assets/chain-key-tokens.md). ## Supported chains @@ -101,10 +101,10 @@ This is not exhaustive. If a chain uses a supported signature scheme and has RPC Several reusable canisters and protocol APIs are available for building Chain Fusion applications: -- **Bitcoin API.** The management canister exposes `bitcoin_get_utxos`, `bitcoin_get_balance`, and `bitcoin_send_transaction`: a direct protocol-level integration with no intermediary. See [Bitcoin integration](../guides/chain-fusion/bitcoin.md). -- **EVM RPC canister** (`7hfb6-caaaa-aaaar-qadga-cai`). A canister providing a typed Candid interface for Ethereum and EVM-compatible chains. Queries multiple RPC providers and returns consensus results. See [Ethereum integration](../guides/chain-fusion/ethereum.md). -- **SOL RPC canister.** A similar canister for Solana, providing typed access to Solana's JSON-RPC API. See [Solana integration](../guides/chain-fusion/solana.md). -- **Chain-key tokens.** Minter and ledger canisters that implement ckBTC, ckETH, and ckERC20: trustless 1:1 representations of external assets on ICP. See [Chain-key tokens](../guides/digital-assets/chain-key-tokens.md). +- **Bitcoin API.** The management canister exposes `bitcoin_get_utxos`, `bitcoin_get_balance`, and `bitcoin_send_transaction`: a direct protocol-level integration with no intermediary. See [Bitcoin integration](bitcoin.md) and the [Bitcoin guide](../../guides/chain-fusion/bitcoin.md). +- **EVM RPC canister** (`7hfb6-caaaa-aaaar-qadga-cai`). A canister providing a typed Candid interface for Ethereum and EVM-compatible chains. Queries multiple RPC providers and returns consensus results. See [Ethereum integration](ethereum.md) and the [Ethereum guide](../../guides/chain-fusion/ethereum.md). +- **SOL RPC canister.** A similar canister for Solana, providing typed access to Solana's JSON-RPC API. See [Solana integration](solana.md) and the [Solana guide](../../guides/chain-fusion/solana.md). +- **Chain-key tokens.** Minter and ledger canisters that implement ckBTC, ckETH, and ckERC20: trustless 1:1 representations of external assets on ICP. See [Chain-key tokens](chain-key-tokens.md) and the [integration guide](../../guides/digital-assets/chain-key-tokens.md). - **Chain Fusion Signer.** A reusable canister that exposes threshold signature APIs directly to web apps and CLI users, with cycle payments via ICRC-2 approval. [OISY Wallet](https://oisy.com) is a prominent production example: a multichain wallet built on ICP that uses the Chain Fusion Signer to manage keys for Bitcoin, Ethereum, and other chains. See the [chain-fusion-signer repository](https://github.com/dfinity/chain-fusion-signer). ## Example use cases @@ -119,10 +119,14 @@ Chain Fusion enables application patterns that are difficult or impossible with ## Next steps -- [Bitcoin integration](../guides/chain-fusion/bitcoin.md): build with BTC on ICP -- [Ethereum integration](../guides/chain-fusion/ethereum.md): interact with Ethereum and EVM chains -- [Chain-key tokens](../guides/digital-assets/chain-key-tokens.md): ckBTC, ckETH, and ckERC20 -- [Chain-key cryptography](chain-key-cryptography.md): the threshold signing protocols behind Chain Fusion -- [HTTPS outcalls](https-outcalls.md): make HTTP requests from canisters - - +- [Bitcoin integration](bitcoin.md): how the Bitcoin adapter and ckBTC work +- [Ethereum integration](ethereum.md): Ethereum, EVM chains, and the EVM RPC canister +- [Solana integration](solana.md): the SOL RPC canister +- [Chain-key tokens](chain-key-tokens.md): architecture of trustless cross-chain tokens +- [Exchange rate canister](exchange-rate-canister.md): onchain oracle for asset prices +- [Bitcoin guide](../../guides/chain-fusion/bitcoin.md): build with BTC on ICP +- [Ethereum guide](../../guides/chain-fusion/ethereum.md): interact with Ethereum and EVM chains +- [Chain-key cryptography](../chain-key-cryptography.md): the threshold signing protocols behind Chain Fusion +- [HTTPS outcalls](../https-outcalls.md): make HTTP requests from canisters + + diff --git a/docs/concepts/chain-fusion/solana.md b/docs/concepts/chain-fusion/solana.md new file mode 100644 index 0000000..5ea4a3d --- /dev/null +++ b/docs/concepts/chain-fusion/solana.md @@ -0,0 +1,31 @@ +--- +title: "Solana Integration" +description: "How canisters interact with Solana via the SOL RPC canister" +--- + +Canisters on ICP can query and interact with the Solana network through the SOL RPC canister. The architecture mirrors the [Ethereum integration](ethereum.md): [HTTPS outcalls](../https-outcalls.md) are used to query Solana's JSON-RPC API, and [chain-key Schnorr signatures (Ed25519)](../chain-key-cryptography.md) enable canisters to sign Solana transactions. + +## SOL RPC canister + +The [SOL RPC canister](https://github.com/dfinity/sol-rpc-canister) is a system-level canister that acts as a gateway between ICP canisters and Solana's JSON-RPC API. Like the EVM RPC canister, it is controlled by the NNS and uses multiple independent JSON-RPC providers to ensure responses are not sourced from a single centralized party. + +Supported providers include [Alchemy](https://www.alchemy.com/), [Ankr](https://www.ankr.com/), [Chainstack](https://chainstack.com/), [dRPC](https://drpc.org/), [Helius](https://www.helius.dev/), and [PublicNode](https://publicnode.com/). + +Each request is forwarded to multiple providers. If providers return consistent results, that response is passed back to the calling canister. The NNS controls which providers are registered and how the canister behaves, so no single entity can alter its operation. + +## Signing Solana transactions + +Solana uses Ed25519 signatures. Canisters can derive Ed25519 public keys and request threshold Schnorr signatures via the management canister's `schnorr_public_key` and `sign_with_schnorr` API (using the `ed25519` algorithm variant). This gives each canister its own Solana wallet address, with signing performed collectively by subnet nodes without reconstructing the private key. + +## Chain-key SOL (ckSOL) + +ckSOL is the chain-key token representing SOL on ICP. Like ckETH, it is backed 1:1 by SOL held in a canister-controlled Solana address. The minter canister monitors Solana deposits via the SOL RPC canister and mints ICRC-1/ICRC-2 compliant ckSOL tokens on ICP. Withdrawals follow the same pattern: burn ckSOL, sign a Solana transfer using chain-key Ed25519, and broadcast via the SOL RPC canister. + +## Next steps + +- [Solana guide](../../guides/chain-fusion/solana.md): code examples for interacting with Solana +- [Chain Fusion overview](index.md): integration patterns and supported chains +- [Ethereum integration](ethereum.md): the EVM RPC canister for comparison +- [Chain-key cryptography](../chain-key-cryptography.md): Ed25519 threshold Schnorr signing + + diff --git a/docs/concepts/chain-key-cryptography.md b/docs/concepts/chain-key-cryptography.md index bcc916d..a91e419 100644 --- a/docs/concepts/chain-key-cryptography.md +++ b/docs/concepts/chain-key-cryptography.md @@ -16,7 +16,7 @@ This design has several consequences for developers: - **Fast verification.** Clients verify subnet responses with a single public key check. There is no need to download block headers or maintain a light client. - **Certified data.** Canisters can set certified variables that the subnet signs at each block. Query responses that include these certificates are cryptographically authenticated, bridging the gap between fast queries and trusted updates. See [Certified variables](../guides/backends/certified-variables.md). - **Verifiable randomness.** The threshold BLS scheme produces unique signatures: for a given message and key, only one valid signature exists. ICP exploits this property to generate unpredictable, unbiased random numbers that canisters can consume. See [Verifiable randomness](verifiable-randomness.md). -- **Cross-chain signing.** Canisters can request threshold ECDSA and Schnorr signatures, giving them the ability to control addresses and sign transactions on external blockchains. This is the foundation of [Chain Fusion](chain-fusion.md). +- **Cross-chain signing.** Canisters can request threshold ECDSA and Schnorr signatures, giving them the ability to control addresses and sign transactions on external blockchains. This is the foundation of [Chain Fusion](chain-fusion/index.md). ## Core protocols @@ -91,7 +91,7 @@ For signing costs, see [Cycles costs](../references/cycles-costs.md). ## Supported chains -Any blockchain whose transaction authentication uses ECDSA (secp256k1) or Schnorr signatures (BIP340 over secp256k1, or Ed25519) can be integrated with ICP through chain-key signatures. For the full list of supported chains with integration methods and chain-key tokens, see [Chain Fusion: Supported chains](chain-fusion.md#supported-chains). +Any blockchain whose transaction authentication uses ECDSA (secp256k1) or Schnorr signatures (BIP340 over secp256k1, or Ed25519) can be integrated with ICP through chain-key signatures. For the full list of supported chains with integration methods and chain-key tokens, see [Chain Fusion: Supported chains](chain-fusion/index.md#supported-chains). ## Chain evolution @@ -103,7 +103,7 @@ For more on how upgrades work at the protocol level, see the [Chain Evolution](h ## Next steps -- [Chain Fusion](chain-fusion.md): how canisters use chain-key signatures to interact with other blockchains +- [Chain Fusion](chain-fusion/index.md): how canisters use chain-key signatures to interact with other blockchains - [Ethereum integration](../guides/chain-fusion/ethereum.md): using threshold ECDSA with Ethereum and EVM chains - [VetKeys](vetkeys.md): a related cryptographic primitive for onchain encryption - [Management canister reference](../references/management-canister.md): the threshold signing API diff --git a/docs/concepts/index.md b/docs/concepts/index.md index 8944cc1..9d44dbb 100644 --- a/docs/concepts/index.md +++ b/docs/concepts/index.md @@ -24,7 +24,7 @@ Understand the ideas behind the Internet Computer before you build on it. These ## Cryptography and cross-chain - **[Chain-Key Cryptography](chain-key-cryptography.md)**: Threshold signatures that enable cross-chain integration, fast finality, and chain evolution. -- **[Chain Fusion](chain-fusion.md)**: How ICP connects to Bitcoin, Ethereum, Solana, and other blockchains natively. +- **[Chain Fusion](chain-fusion/index.md)**: How ICP connects to Bitcoin, Ethereum, Solana, and other blockchains natively. - **[VetKeys](vetkeys.md)**: Verifiable encrypted threshold key derivation for onchain encryption and secret management. ## Trust and governance diff --git a/docs/getting-started/choose-your-path.md b/docs/getting-started/choose-your-path.md index b7c5af0..39de84a 100644 --- a/docs/getting-started/choose-your-path.md +++ b/docs/getting-started/choose-your-path.md @@ -70,7 +70,7 @@ Here is how Ethereum concepts map to ICP: | Fee (user pays) | [Cycles](../concepts/cycles.md) (canister pays) | Users interact for free; developers fund computation | | No HTTP serving | Built-in HTTP serving | Canisters serve web pages directly | | Offchain storage (IPFS, etc.) | Onchain stable memory | Up to 500 GiB per canister, no external storage needed | -| Bridges / oracles | [Chain-key signing](../concepts/chain-fusion.md), [HTTPS outcalls](../guides/backends/https-outcalls.md) | Canisters sign transactions on other chains natively; HTTPS outcalls fetch external data without oracles | +| Bridges / oracles | [Chain-key signing](../concepts/chain-fusion/index.md), [HTTPS outcalls](../guides/backends/https-outcalls.md) | Canisters sign transactions on other chains natively; HTTPS outcalls fetch external data without oracles | | Immutable by default | Upgradeable by default | Canisters can be upgraded while preserving state | The biggest shift: on Ethereum, smart contracts are minimal programs that rely on offchain infrastructure. On ICP, a canister can be an entire application (frontend, backend, database, and scheduled jobs) all onchain. diff --git a/docs/guides/chain-fusion/bitcoin.mdx b/docs/guides/chain-fusion/bitcoin.mdx index 8eaeb48..2a64c01 100644 --- a/docs/guides/chain-fusion/bitcoin.mdx +++ b/docs/guides/chain-fusion/bitcoin.mdx @@ -1172,7 +1172,7 @@ docker stop bitcoind && docker rm bitcoind ## Next steps -- [Chain fusion overview](../../concepts/chain-fusion.md): understand how ICP integrates with external blockchains +- [Chain fusion overview](../../concepts/chain-fusion/index.md): understand how ICP integrates with external blockchains - [Chain-key cryptography](../../concepts/chain-key-cryptography.md): learn how threshold ECDSA and Schnorr signatures work - [Chain-key tokens](../digital-assets/chain-key-tokens.md): explore ckBTC, ckETH, and other chain-key tokens - [Ethereum integration](ethereum.md): apply similar patterns for Ethereum diff --git a/docs/guides/chain-fusion/dogecoin.md b/docs/guides/chain-fusion/dogecoin.md index df73100..9e6f227 100644 --- a/docs/guides/chain-fusion/dogecoin.md +++ b/docs/guides/chain-fusion/dogecoin.md @@ -177,7 +177,7 @@ Minter -> DOGE: send DOGE to doge_address ## Next steps -- [Chain fusion overview](../../concepts/chain-fusion.md): understand how ICP integrates with external blockchains +- [Chain fusion overview](../../concepts/chain-fusion/index.md): understand how ICP integrates with external blockchains - [Bitcoin integration](bitcoin.md): the same UTXO-based integration with complete code examples - [Chain-key cryptography](../../concepts/chain-key-cryptography.md): how threshold ECDSA signatures work - [Chain-key tokens](../digital-assets/chain-key-tokens.md): ckBTC, ckETH, and upcoming ckDOGE diff --git a/docs/guides/chain-fusion/ethereum.mdx b/docs/guides/chain-fusion/ethereum.mdx index 9014bda..88c6c34 100644 --- a/docs/guides/chain-fusion/ethereum.mdx +++ b/docs/guides/chain-fusion/ethereum.mdx @@ -9,7 +9,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ICP canisters can read data from Ethereum and other EVM-compatible chains, sign transactions with threshold ECDSA, and submit them onchain: all without bridges, oracles, or external signers. This guide covers the EVM RPC canister, which handles JSON-RPC calls to Ethereum nodes on your behalf. -For a conceptual overview of how ICP connects to other blockchains, see [Chain Fusion](../../concepts/chain-fusion.md). +For a conceptual overview of how ICP connects to other blockchains, see [Chain Fusion](../../concepts/chain-fusion/index.md). ## How it works @@ -719,7 +719,7 @@ ic-cdk = "0.20" - [Bitcoin integration](bitcoin.md): similar patterns for BTC using the Bitcoin API - [Chain-key tokens](../digital-assets/chain-key-tokens.md): learn about ckETH and other chain-key tokens backed 1:1 by native assets -- [Chain Fusion concepts](../../concepts/chain-fusion.md): understand how ICP connects to external blockchains +- [Chain Fusion concepts](../../concepts/chain-fusion/index.md): understand how ICP connects to external blockchains - [HTTPS outcalls](../backends/https-outcalls.md): the underlying mechanism the EVM RPC canister uses - [basic_ethereum example](https://github.com/dfinity/examples/tree/master/rust/basic_ethereum): complete end-to-end Rust example with address generation, signing, and transaction submission - [EVM RPC canister source](https://github.com/dfinity/evm-rpc-canister): canister source code and Candid interface diff --git a/docs/guides/chain-fusion/solana.mdx b/docs/guides/chain-fusion/solana.mdx index ad64fa5..7e71a54 100644 --- a/docs/guides/chain-fusion/solana.mdx +++ b/docs/guides/chain-fusion/solana.mdx @@ -9,7 +9,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components'; ICP canisters can interact directly with the Solana network: read account balances, query transaction history, and sign and submit transactions: all without bridges, oracles, or external signers. This guide covers the SOL RPC canister for querying Solana and threshold Ed25519 signatures for signing Solana transactions. -For a conceptual overview of how ICP connects to other blockchains, see [Chain Fusion](../../concepts/chain-fusion.md). +For a conceptual overview of how ICP connects to other blockchains, see [Chain Fusion](../../concepts/chain-fusion/index.md). ## How it works @@ -397,6 +397,6 @@ Follow the [SOL RPC canister repository](https://github.com/dfinity/sol-rpc-cani - [Bitcoin integration](bitcoin.md): direct protocol-level BTC integration - [Ethereum integration](ethereum.md): EVM RPC canister, similar JSON-RPC pattern - [HTTPS outcalls](../backends/https-outcalls.md): the mechanism underlying the SOL RPC canister -- [Chain Fusion concepts](../../concepts/chain-fusion.md): how ICP connects to other blockchains +- [Chain Fusion concepts](../../concepts/chain-fusion/index.md): how ICP connects to other blockchains {/* Upstream: informed by dfinity/portal (docs/building-apps/chain-fusion/solana/overview.mdx; dfinity/cdk-rs) ic-cdk/src/management_canister.rs, ic-management-canister-types/src/lib.rs; dfinity/examples: rust/basic_solana/README.md */}