You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This example demonstrates how to deploy a smart contract on the Internet Computer that can receive and send Bitcoin, including support for legacy (P2PKH), SegWit (P2WPKH), and Taproot (P2TR) address types.
3
+
This example demonstrates how to deploy a smart contract on the Internet Computer that can receive and send bitcoin, including support for legacy (P2PKH), SegWit (P2WPKH), and Taproot (P2TR) address types.
4
+
5
+
This example also includes examples of how to work with Bitcoin assets such as Ordinals, Runes, and BRC-20 tokens.
6
+
7
+
## Table of contents
8
+
9
+
-[Architecture](#architecture)
10
+
-[Prerequisites](#prerequisites)
11
+
-[Building and deploying the smart contract](#building-and-deploying-the-smart-contract)
-[x] On macOS, an `llvm` version that supports the `wasm32-unknown-unknown` target is required. This is because the Rust `bitcoin` library relies on the `secp256k1-sys` crate, which requires `llvm` to build. The default `llvm` version provided by XCode does not meet this requirement. Instead, install the [Homebrew version](https://formulae.brew.sh/formula/llvm), using `brew install llvm`.
-[x] On macOS, an `llvm` version that supports the `wasm32-unknown-unknown` target is required. This is because the Rust `bitcoin` library relies on the `secp256k1-sys` crate, which requires `llvm` to build. The default `llvm` version provided by XCode does not meet this requirement. Instead, install the [Homebrew version](https://formulae.brew.sh/formula/llvm), using `brew install llvm`.
21
40
22
41
## Building and deploying the smart contract
23
42
@@ -30,20 +49,24 @@ cd examples/rust/basic_bitcoin
30
49
31
50
### 2. Start the ICP execution environment
32
51
52
+
Open a terminal window (terminal 1) and run the following:
-`dfx deploy` tells the command line interface to `deploy` the smart contract.
54
77
-`--argument '(variant { regtest })'` passes the argument `regtest` to initialize the smart contract, telling it to connect to the local Bitcoin regtest network.
55
78
56
-
57
-
Your smart contract is live and ready to use! You can interact with it using either the command line or using the Candid UI, which is the link you see in the terminal.
79
+
Your smart contract is live and ready to use! You can interact with it using either the command line or the Candid UI (the link you see in the terminal).
58
80
59
81
> [!NOTE]
60
82
> You can also interact with a pre-deployed version of the `basic_bitcoin` example running on the IC mainnet and configured to interact with Bitcoin **testnet4**.
61
-
>
83
+
>
62
84
> Access the Candid UI of the example: https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.icp0.io/?id=vvha6-7qaaa-aaaap-ahodq-cai
> Newly mined bitcoin, like those you created with the above `bitcoin-cli` command cannot be spent until 100 additional blocks have been added to the chain. To make your bitcoin spendable, create 100 additional blocks. Choose one of the smart contract addresses as receiver of the block reward or use any valid bitcoin dummy address.
127
-
>
148
+
> Newly mined bitcoin, like those you created with the above `bitcoin-cli` command, cannot be spent until 100 additional blocks have been added to the chain. To make your bitcoin spendable, create 100 additional blocks. Choose one of the smart contract addresses as receiver of the block reward or use any valid Bitcoin dummy address.
This calls `bitcoin_get_block_headers`, useful for validating blockchains or light client logic.
166
+
This calls `bitcoin_get_block_headers`, which is useful for blockchain validation or light client logic.
167
+
168
+
## Bitcoin assets
169
+
170
+
Bitcoin's scripting capabilities enable various digital assets beyond simple transfers. This example demonstrates how to create and interact with three major Bitcoin asset protocols from an ICP smart contract:
171
+
172
+
-**Ordinals**: Inscribe arbitrary data onto individual satoshis
173
+
-**Runes**: Create fungible tokens using `OP_RETURN` outputs
174
+
-**BRC-20**: Build fungible tokens on top of Ordinals using JSON
175
+
176
+
### Prerequisites for Bitcoin assets
177
+
178
+
All Bitcoin assets rely on off-chain indexing since the Bitcoin protocol doesn't natively support querying these assets. The `ord` CLI tool is the standard indexer for Bitcoin assets like Ordinals and Runes.
179
+
180
+
Install `ord` using a package manager. For example, on macOS:
181
+
182
+
```bash
183
+
brew install ord
184
+
```
185
+
186
+
For other platforms, see the [ord repository](https://github.com/ordinals/ord) for installation instructions.
187
+
188
+
> [!NOTE]
189
+
> This repository includes a [default ord config file](./ord.yaml) that matches the also provided [bitcoin config file](./bitcoin.conf).
190
+
191
+
> [!IMPORTANT]
192
+
> **Bitcoin Configuration**: To work with Bitcoin assets, make sure bitcoind is configured to accept non-standard transactions by including this setting in your `bitcoin.conf`:
193
+
>
194
+
> ```
195
+
> acceptnonstdtxn=1
196
+
> ```
197
+
198
+
## Inscribe an Ordinal
199
+
200
+
[Ordinals](https://ordinals.com) is a protocol that allows inscribing arbitrary data (text, images, etc.) onto individual satoshis, creating unique digital artifacts on Bitcoin. Each inscription is permanently stored in the Bitcoin blockchain using a two-transaction commit/reveal process.
201
+
202
+
### Step-by-step process:
203
+
204
+
1. **Start the ord server** to index transactions:
205
+
```bash
206
+
ord --config-dir . server
207
+
```
208
+
209
+
2.**Get a Taproot address** for funding the inscription:
The function returns the reveal transaction ID. Your inscription is now permanently stored on Bitcoin and can be viewed using ord or other Ordinals explorers. The default address of the local `ord` server is `http://127.0.0.1:80/`.
230
+
231
+
## Etch a Rune
232
+
233
+
[Runes](https://docs.ordinals.com/runes.html) is a fungible token protocol that embeds token metadata directly into Bitcoin transactions using `OP_RETURN` outputs. Unlike Ordinals, Runes are created in a single transaction and support standard fungible token operations.
234
+
235
+
### Step-by-step process:
236
+
237
+
1.**Start the ord server** to track Rune balances:
The Rune is now etched with 1_000_000 tokens minted to your address. The tokens can be transferred using standard Bitcoin transactions with Runestone data.
268
+
269
+
## Deploy a BRC-20 token
270
+
271
+
[BRC-20](https://domo-2.gitbook.io/brc-20-experiment/) is a token standard built on top of Ordinals that uses structured JSON payloads to create fungible tokens. BRC-20 tokens follow the same inscription process as Ordinals but with standardized JSON formats.
272
+
273
+
### Step-by-step process:
274
+
275
+
1.**Start the ord server** to index BRC-20 inscriptions:
276
+
```bash
277
+
ord --config-dir . server
278
+
```
279
+
280
+
2.**Get a Taproot address** for the token deployment:
The deployment inscription contains JSON metadata that BRC-20 indexers use to track token balances and transfers. Additional mint and transfer operations require separate inscriptions following the BRC-20 protocol.
306
+
307
+
To view the deployed BRC-20 token, use the local `ord` explorer at `http://127.0.0.1:80/`.
308
+
145
309
146
310
## Notes on implementation
147
311
148
-
- Keys are derived using structured derivation paths according to BIP-32.
149
-
- Key caching is used to avoid repeated calls to `get_ecdsa_public_key` and `get_schnorr_public_key`.
150
-
- Transactions are assembled and signed manually, ensuring maximum flexibility in construction and fee estimation.
151
-
- When _testing_ on mainnet, the [chain-key testing canister](https://github.com/dfinity/chainkey-testing-canister) can be used to save on costs for calling the threshold signing APIs for signing the BTC transactions.
312
+
This example implements several important patterns for Bitcoin integration:
313
+
314
+
-**Derivation paths**: Keys are derived using structured derivation paths according to BIP-32, ensuring reproducible key generation.
315
+
-**Key caching**: Optimization is used to avoid repeated calls to `get_ecdsa_public_key` and `get_schnorr_public_key`.
316
+
-**Manual transaction construction**: Transactions are assembled and signed manually, ensuring maximum flexibility in construction and fee estimation.
317
+
-**Cost optimization**: When testing on mainnet, the [chain-key testing canister](https://github.com/dfinity/chainkey-testing-canister) can be used to save on costs for calling the threshold signing APIs.
318
+
-**Asset protocols**: Bitcoin assets (Ordinals, Runes, BRC-20) demonstrate advanced scripting capabilities and witness data usage.
152
319
153
320
## Security considerations and best practices
154
321
322
+
This example is provided for educational purposes and is not production-ready. It is important to consider security implications when developing applications that interact with Bitcoin or other cryptocurrencies. The code has **not been audited** and may contain vulnerabilities or security issues.
323
+
155
324
If you base your application on this example, we recommend you familiarize yourself with and adhere to the [security best practices](https://internetcomputer.org/docs/current/references/security/) for developing on the Internet Computer. This example may not implement all the best practices.
156
325
157
326
For example, the following aspects are particularly relevant for this app:
0 commit comments