Skip to content

Commit

Permalink
Merge pull request #960 from dfinity/Add_example_for_block_headers
Browse files Browse the repository at this point in the history
chore: Add example of using bitcoin_get_block_headers to basic_bitcoin
  • Loading branch information
dragoljub-duric authored Aug 28, 2024
2 parents 71c7902 + b48003e commit 909c582
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
17 changes: 16 additions & 1 deletion rust/basic_bitcoin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ To clone and build the smart contract in **Rust**:
```bash
git clone https://github.com/dfinity/examples
cd examples/rust/basic_bitcoin
cargo build --release --target wasm32-unknown unknown
cargo build --release --target wasm32-unknown-unknown
```

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

## Step 6: Retrieving block headers

You can also get a range of Bitcoin block headers by using the `get_block_headers`
endpoint on your canister.

Make the call using the command line. Be sure to replace `10` with your desired start height:

```bash
dfx canister --network=ic call basic_bitcoin get_block_headers "(10: nat32)"
```
or replace `0` and `11` with your desired start and end height respectively:
```bash
dfx canister --network=ic call basic_bitcoin get_block_headers "(0: nat32, 11: nat32)"
```

## Conclusion

In this tutorial, you were able to:
Expand Down
10 changes: 10 additions & 0 deletions rust/basic_bitcoin/src/basic_bitcoin/basic_bitcoin.did
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ type get_utxos_response = record {
next_page : opt blob;
};

type block_header = blob;
type block_height = nat32;

type get_block_headers_response = record {
tip_height : block_height;
block_headers : vec block_header;
};

service : (network) -> {
"get_p2pkh_address" : () -> (bitcoin_address);

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

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

"get_block_headers" : (start_height : block_height, end_height : opt block_height) -> (get_block_headers_response);

"get_current_fee_percentiles" : () -> (vec millisatoshi_per_vbyte);

"send_from_p2pkh" : (
Expand Down
28 changes: 28 additions & 0 deletions rust/basic_bitcoin/src/basic_bitcoin/src/bitcoin_api.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use candid::Principal;
use ic_cdk::api::management_canister::bitcoin::{
bitcoin_get_balance, bitcoin_get_current_fee_percentiles, bitcoin_get_utxos,
bitcoin_send_transaction, BitcoinNetwork, GetBalanceRequest, GetCurrentFeePercentilesRequest,
GetUtxosRequest, GetUtxosResponse, MillisatoshiPerByte, SendTransactionRequest,
};
use crate::{GetBlockHeadersRequest, GetBlockHeadersResponse};

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

/// Returns the block headers in the given height range.
pub(crate) async fn get_block_headers(network: BitcoinNetwork, start_height: u32, end_height: Option<u32>) -> GetBlockHeadersResponse{
let cycles = match network {
BitcoinNetwork::Mainnet => 10_000_000_000,
BitcoinNetwork::Testnet => 10_000_000_000,
BitcoinNetwork::Regtest => 0,
};

let request = GetBlockHeadersRequest{
start_height,
end_height,
network
};

let res = ic_cdk::api::call::call_with_payment128::<(GetBlockHeadersRequest,), (GetBlockHeadersResponse,)>(
Principal::management_canister(),
"bitcoin_get_block_headers",
(request,),
cycles,
)
.await;

res.unwrap().0
}

/// Returns the 100 fee percentiles measured in millisatoshi/byte.
/// Percentiles are computed from the last 10,000 transactions (if available).
///
Expand All @@ -61,3 +88,4 @@ pub async fn send_transaction(network: BitcoinNetwork, transaction: Vec<u8>) {

res.unwrap();
}

26 changes: 26 additions & 0 deletions rust/basic_bitcoin/src/basic_bitcoin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod bitcoin_wallet;
mod ecdsa_api;
mod schnorr_api;

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

pub type Height = u32;
pub type BlockHeader = Vec<u8>;

/// A request for getting the block headers for a given height range.
#[derive(CandidType, Debug, Deserialize, PartialEq, Eq)]
pub struct GetBlockHeadersRequest {
pub start_height: Height,
pub end_height: Option<Height>,
pub network: BitcoinNetwork,
}

/// The response returned for a request for getting the block headers from a given height.
#[derive(CandidType, Debug, Deserialize, PartialEq, Eq, Clone)]
pub struct GetBlockHeadersResponse {
pub tip_height: Height,
pub block_headers: Vec<BlockHeader>,
}

/// Returns the block headers in the given height range.
#[update]
pub async fn get_block_headers(start_height: u32, end_height: Option<u32>) -> GetBlockHeadersResponse{
let network = NETWORK.with(|n| n.get());
bitcoin_api::get_block_headers(network, start_height, end_height).await
}

/// Returns the 100 fee percentiles measured in millisatoshi/byte.
/// Percentiles are computed from the last 10,000 transactions (if available).
#[update]
Expand Down

0 comments on commit 909c582

Please sign in to comment.