Direct Integration with Bitcoin

Thanks so much for the frequent updates. I believe the community doesn’t mind delays provided we are kept in the loop. We appreciate you guys working so hard!


Hi, I have seen a paper you helped edit that said that ICOracle token (trading on the ic.lighthouse dex) will be needed for the Bitcoin smart contracts. Is this true or false.

Thanks for the updates Dieter!

Given the new index and the multiplier effect of that on the memory used, how long do you anticipate the 48GB will be able to hold the Bitcoin state until stable memory limits will need to be bumped again?

Also, instead of holding all of the state in a single canister and scaling vertically against hardware limitations, why not shard it horizontally? Imagining we get the new composite queries feature sooner rather than later and the Bitcoin integration is on its own subnet, wouldn’t this both help work around some of the current memory limitations and also improve the load scalability of the Bitcoin integration since the request load isn’t all then hitting a single canister?

We’ve now gone from having just 8GB of stable memory for over a year to then 32GB and now 48GB pretty quickly, which is exciting but also makes me wonder if using the full 32GB and 48GB has been tested thoroughly to ensure there isn’t much performance degradation.

Back in April, I asked,

What makes the team feel confident that vertically scaling the Bitcoin integration within a single canister is still the right long-term architectural decision?


Do you happen to know if we have to do anything special in our code to take advantage of 32GB or is it just included without any changes. Currently using mo:base/HashMap

You would need to use stable memory directly, so ExperimentalStableMemory | Internet Computer Home. If you have more questions I think Motoko stable memory in 2022 would be a great place to ask.


That’s a great question. We thought it was the right way to go for now. Scaling out to multiple canisters has advantages (more memory, can run concurrently) and disadvantages (clearly more complex to deal with multiple canisters). So we start with the simpler approach, and can always transition to a multi-canister approach in the future.

Note that the UTXO set doesn’t grow super quickly | Charts - Unspent Transaction Outputs. In the last 3 years, it grew from 64M UTXOs to 85M, and we plan to grow the stable memory further, so I don’t think the single canister approach will be a problem any time soon, if ever.


Thanks for the updates Dieter!:pray:t2::heart:

could you please expand on what IDKG key rotation does?

1 Like

All t-ecdsa addresses are new, why do we need to store historical utxos on chain? Just the related utxos would be sufficient

The Bitcoin canister, which tracks the UTXO set, does not know which addresses all the user canisters created and gave out. A user canister can create a deposit address in canister code and hand it out to a some other user who can then make a deposit into that address. Then the user canister later wants to be able to ask the Bitcoin canister about the balance in that address. If the Bitcoin canister did not have the entire UTXO set then it would not be able to answer. The addresses that user canisters create cannot be foreseen as they are chosen from a practically unbounded hierarchical address space.


How about notifying the Bitcoin Canister to cache the related utxo like light client

Seems to make for unnecessarily complicated programming and possibly even serious limitation. If a notification is required then the canister code can not directly answer a call with a deposit address. It has to do a round trip through the Bitcoin canister first, adding latency. If we notify the Bitcoin canister about an address only later then there is a race condition. Does the notification come in first or the deposit? If the latter then the deposit would get missed. Unless the Bitcoin canister gets a feature to query UTXOs that were created in the past from other Bitcoin nodes, which now complicates its code. It now has to be able to process Merkle proofs and the Bitcoin adapter has to get a new feature to make those queries. It just seems to get really messy. The serious limitation could be if deposit address are created outside (externally, off-chain), e.g. in frontend code or even in scenarios that are entirely offline, which are possible with HD-derivation. Then there is no way to notify the Bitcoin canister.

Notification also open an attack vector on the Bitcoin canister. I can now ask the Bitcoin canister to track millions of address that I never actually use.


Gotu. So how about only calculating the utxo for new addresses of the btc network. Considering snapshoting all existing addresses in a set, and only cache utxo for newly generated addresses. That would still cut all pre existing utxos

Good idea. I think that could work. Or could have worked if that path had been chosen earlier. From where the implementation stands now the fastet way to launch is propably not touching that aspect anymore and increasing the stable memory size instead (my guess, I can’t speak for the team that is working on it).

A different aspect: over time I would certainly like to see the Bitcoin integration move into the opposite direction and store the entire Bitcoin blockchain, i.e. all historical transaction including spent outputs. Could be spread over multiple canisters. Then we would have a block explorer running on chain which is something that doesn’t exist in the world. There simply are no decentralized block explorers, hence there are no trustless block explorers right now. Likewise, there are no trustless Bitcoin full nodes that SPV nodes can connect to. A decentralized Bitcoin full node on the IC would be hugely beneficial for the Bitcoin ecosystem. For example, for smartcards or IoT devices accepting Bitcoin. They can then just validate a single signature created by the IC subnet instead of having to validate Merkle proofs and proof-of-work header segments.


See the threshold ECDSA forum thread

1 Like

That Bitcoin to/from ckBTC demo in the Global R&D Meeting just now was fantastic. Does anyone know who gave that presentation, or where the demo code lives? I’m looking to integrate payments into my grant project at this exact moment and that code would be incredibly helpful!

The demo I’m talking about is the ckBTC Minting Demo hosted on the IC here, that lets you convert Bitcoin to/from ckBTC, which can be transferred easily/cheaply/quickly throughout the IC.


Glad you liked the demo! The canister code is ic/rs/bitcoin/ckbtc at master · dfinity/ic · GitHub, I don’t think the front end is checked in as it’s just for the demo, but I guess the backend is what you’re most interested in?


I’m definitely interested most in the backend. But it looks like I might need to learn Rust; the rest of my codebase is in Motoko and that’s where my experience lies. Any chance there will be a Motoko version of demo code? Or am I wrong when thinking that I would need to implement all the backend code you linked to in my own canisters, and maybe it’s just a public canister on the IC somewhere that I would be interacting with, or maybe a library I could import with Vessel?

Either way, frontend code would be handy to see the usage of the backend canister during all the operations shown in the demo.


Hi @mymikemiller, I am the one who gave the demo. Really happy to hear that you liked it :slight_smile:
If you want I can make a repo with the frontend code, it’s a react app. It may be a good starting point if you want to understand how to interact with the minter and the ledger.
If don’t know rust you can still interact with the minter using minter.did. You just have to know the canister id and the did interface to interact with another canister from your canister. But probably that taking a look at the code will help you to understand.
We will probably not make a motoko version any soon. I will try to see where is the best place to share my code and keep you up to date.


Fantastic demo, @0rions! If I’m interpreting you correctly, I ought to be able to import your ic-ckbtc-minter canister by specifying its IC cid in an Actor’s constructor like this, which also currently requires me to duplicate the canister’s interface (i.e. there’s no way to specify the .did file you linked to and have it infer the interface from that), then use its public functions like any of my local canisters, right? I’ve never imported a canister from the IC.

I believe that means I will need to provide my own implementation for local development since local canisters can’t access IC canisters, and I could do that by compiling my own local canister from your above-linked Rust source, or at least by making a mock canister with the same interface as described here.

The cid I would pass to the constructor when creating the ic-ckbtc-minter Actor is not the cid in the url you listed in the demo, waaaa-aaaag-qazsa-cai, though, since that’s the cid for the frontend, right? What’s the cid for the backend canister where the backend functions live?

1 Like