Skip to content

Commit 909c582

Browse files
Merge pull request #960 from dfinity/Add_example_for_block_headers
chore: Add example of using bitcoin_get_block_headers to basic_bitcoin
2 parents 71c7902 + b48003e commit 909c582

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed

rust/basic_bitcoin/README.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ To clone and build the smart contract in **Rust**:
4242
```bash
4343
git clone https://github.com/dfinity/examples
4444
cd examples/rust/basic_bitcoin
45-
cargo build --release --target wasm32-unknown unknown
45+
cargo build --release --target wasm32-unknown-unknown
4646
```
4747

4848
### Acquire cycles to deploy
@@ -214,6 +214,21 @@ it sent to the network. You can track the status of this transaction using a
214214
transaction has at least one confirmation, you should be able to see it
215215
reflected in your current balance.
216216

217+
## Step 6: Retrieving block headers
218+
219+
You can also get a range of Bitcoin block headers by using the `get_block_headers`
220+
endpoint on your canister.
221+
222+
Make the call using the command line. Be sure to replace `10` with your desired start height:
223+
224+
```bash
225+
dfx canister --network=ic call basic_bitcoin get_block_headers "(10: nat32)"
226+
```
227+
or replace `0` and `11` with your desired start and end height respectively:
228+
```bash
229+
dfx canister --network=ic call basic_bitcoin get_block_headers "(0: nat32, 11: nat32)"
230+
```
231+
217232
## Conclusion
218233

219234
In this tutorial, you were able to:

rust/basic_bitcoin/src/basic_bitcoin/basic_bitcoin.did

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ type get_utxos_response = record {
3232
next_page : opt blob;
3333
};
3434

35+
type block_header = blob;
36+
type block_height = nat32;
37+
38+
type get_block_headers_response = record {
39+
tip_height : block_height;
40+
block_headers : vec block_header;
41+
};
42+
3543
service : (network) -> {
3644
"get_p2pkh_address" : () -> (bitcoin_address);
3745

@@ -43,6 +51,8 @@ service : (network) -> {
4351

4452
"get_utxos" : (bitcoin_address) -> (get_utxos_response);
4553

54+
"get_block_headers" : (start_height : block_height, end_height : opt block_height) -> (get_block_headers_response);
55+
4656
"get_current_fee_percentiles" : () -> (vec millisatoshi_per_vbyte);
4757

4858
"send_from_p2pkh" : (

rust/basic_bitcoin/src/basic_bitcoin/src/bitcoin_api.rs

+28
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
use candid::Principal;
12
use ic_cdk::api::management_canister::bitcoin::{
23
bitcoin_get_balance, bitcoin_get_current_fee_percentiles, bitcoin_get_utxos,
34
bitcoin_send_transaction, BitcoinNetwork, GetBalanceRequest, GetCurrentFeePercentilesRequest,
45
GetUtxosRequest, GetUtxosResponse, MillisatoshiPerByte, SendTransactionRequest,
56
};
7+
use crate::{GetBlockHeadersRequest, GetBlockHeadersResponse};
68

79
/// Returns the balance of the given bitcoin address.
810
///
@@ -36,6 +38,31 @@ pub async fn get_utxos(network: BitcoinNetwork, address: String) -> GetUtxosResp
3638
utxos_res.unwrap().0
3739
}
3840

41+
/// Returns the block headers in the given height range.
42+
pub(crate) async fn get_block_headers(network: BitcoinNetwork, start_height: u32, end_height: Option<u32>) -> GetBlockHeadersResponse{
43+
let cycles = match network {
44+
BitcoinNetwork::Mainnet => 10_000_000_000,
45+
BitcoinNetwork::Testnet => 10_000_000_000,
46+
BitcoinNetwork::Regtest => 0,
47+
};
48+
49+
let request = GetBlockHeadersRequest{
50+
start_height,
51+
end_height,
52+
network
53+
};
54+
55+
let res = ic_cdk::api::call::call_with_payment128::<(GetBlockHeadersRequest,), (GetBlockHeadersResponse,)>(
56+
Principal::management_canister(),
57+
"bitcoin_get_block_headers",
58+
(request,),
59+
cycles,
60+
)
61+
.await;
62+
63+
res.unwrap().0
64+
}
65+
3966
/// Returns the 100 fee percentiles measured in millisatoshi/byte.
4067
/// Percentiles are computed from the last 10,000 transactions (if available).
4168
///
@@ -61,3 +88,4 @@ pub async fn send_transaction(network: BitcoinNetwork, transaction: Vec<u8>) {
6188

6289
res.unwrap();
6390
}
91+

rust/basic_bitcoin/src/basic_bitcoin/src/lib.rs

+26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ mod bitcoin_wallet;
33
mod ecdsa_api;
44
mod schnorr_api;
55

6+
use candid::{CandidType, Deserialize};
67
use ic_cdk::api::management_canister::bitcoin::{
78
BitcoinNetwork, GetUtxosResponse, MillisatoshiPerByte,
89
};
@@ -52,6 +53,31 @@ pub async fn get_utxos(address: String) -> GetUtxosResponse {
5253
bitcoin_api::get_utxos(network, address).await
5354
}
5455

56+
pub type Height = u32;
57+
pub type BlockHeader = Vec<u8>;
58+
59+
/// A request for getting the block headers for a given height range.
60+
#[derive(CandidType, Debug, Deserialize, PartialEq, Eq)]
61+
pub struct GetBlockHeadersRequest {
62+
pub start_height: Height,
63+
pub end_height: Option<Height>,
64+
pub network: BitcoinNetwork,
65+
}
66+
67+
/// The response returned for a request for getting the block headers from a given height.
68+
#[derive(CandidType, Debug, Deserialize, PartialEq, Eq, Clone)]
69+
pub struct GetBlockHeadersResponse {
70+
pub tip_height: Height,
71+
pub block_headers: Vec<BlockHeader>,
72+
}
73+
74+
/// Returns the block headers in the given height range.
75+
#[update]
76+
pub async fn get_block_headers(start_height: u32, end_height: Option<u32>) -> GetBlockHeadersResponse{
77+
let network = NETWORK.with(|n| n.get());
78+
bitcoin_api::get_block_headers(network, start_height, end_height).await
79+
}
80+
5581
/// Returns the 100 fee percentiles measured in millisatoshi/byte.
5682
/// Percentiles are computed from the last 10,000 transactions (if available).
5783
#[update]

0 commit comments

Comments
 (0)