Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Interact with Dogecoin from a smart contract on the Internet Computer

Introduction

Work In Progress

🚧 The developer documentation is under construction.

The Build on Dogecoin book is intended for developers to explain how smart contracts on the Internet Computer, often referred as canisters, can interact with the Dogecoin blockchain.

Background

To interact with the Dogecoin blockchain, your canister will make use of the following:

  • Dogecoin canister: Think of it as your decentralized gateway to reach the Dogecoin blockchain. This canister provides an API that can be used by others to query information about the network state, e.g., UTXOs, block information, or the balance of any Dogecoin address; and to send a signed transaction to the network.

  • Threshold ECDSA: A canister can have a secret key that is stored in a secure and decentralized manner using chain-key cryptography (several such keys can be computed by key derivation). Messages sent by the canister can be signed using this key, enabling the canister to send signed transactions to Dogecoin.

Getting Started

First, set up your development environment. Then, to build smart contracts interacting with the Dogecoin blockchain, you will need to know how to

  • Generate a Dogecoin address. Dogecoin addresses are necessary for your dapp to sign transactions and hold assets like DOGE. An ICP smart contract can have multiple addresses.

  • Create a Dogecoin transaction. Dogecoin transactions spend unspent transaction outputs (UTXOs) and create new UTXOs. A UTXO is the output of a Dogecoin transaction. It exists until it is used as the input of another transaction.

  • Sign the transaction using one of the supported threshold signature APIs. All inputs of a transaction must be signed before the transaction can be submitted to the Dogecoin network.

  • Submit the transaction by sending a request to the Dogecoin API that specifies the blob of the transaction and the target Dogecoin network (mainnet or testnet4).

  • Read information from the Dogecoin network, such as transaction details or address balances.

Developer Environment

To develop Dogecoin applications to be deployed on ICP, your local developer environment will need to include:

  • Necessary tools and packages for the language you’d like to build your dapp in:

    • The Rust toolchain for installing Rust packages and compiling Rust code.

    • The IC SDK for creating, deploying, and managing smart contracts.

  • A local Dogecoin testnet.

  • A local instance of the Dogecoin canister.

  • An ICP smart contract project.

Install tooling

Rust toolchain

Before developing DOGE applications in Rust, you will need to install the Rust toolchain, including:

IC SDK

The IC SDK includes a CLI tool called dfx that is used for creating, managing, and deploying dapps on ICP. You can install it natively on macOS and Linux; however, Windows users will need to set up WSL 2 before installing the IC SDK.

Learn more about installing the IC SDK

Create or download an example project

To set up and test your local Dogecoin testnet, you will need a smart contract that implements methods that call the local Dogecoin canister.

Create a new project using dfx new my_project or check out the examples that already implements basic methods for calling the Dogecoin canister.

Info

Popular libraries like Rust's bitcoin crate and Motoko's bitcoin package can be used within ICP smart contracts.

Create a local Dogecoin testnet (regtest) with dogecoind

It is recommended that developers set up a local Dogecoin testnet on their machine, as it allows them to mine blocks quickly and at will, which facilitates testing various cases without having to rely on the Dogecoin testnet or the Dogecoin mainnet. Alternatively, you can test dapps using the Dogecoin testnet or mainnet through the ICP Dogecoin API. Both workflows are detailed below.

A local Dogecoin testnet deployed on your computer operates in "regression testing mode," or regtest mode. Regtest mode is used to instantly create a new, private blockchain with the configuration of a testnet. However, there is one key difference: regtest mode enables the developer to have complete control over the environment, including determining when blocks are created. This allows you to test and iterate faster than relying on the Dogecoin testnet or mainnet.

Example for a Linux machine:

# Download the binary
curl -L -O https://github.com/dogecoin/dogecoin/releases/download/v1.14.9/dogecoin-1.14.9-x86_64-linux-gnu.tar.gz

# Unpack
tar -xvf dogecoin-1.14.9-x86_64-linux-gnu.tar.gz

# Add binaries to the PATH environment variable
export PATH="$(pwd)/dogecoin-1.14.9/bin:$PATH"

Note

There are currently no released binary for Mac OS X.

This should be created in the project folder root. This allows you to run different local Dogecoin testing networks for different projects.

mkdir dogecoin_data
cat > dogecoin.conf <<EOF
regtest=1
txindex=1
rpcuser=ic-doge-integration
rpcpassword=QPQiNaph19FqUsCrBRN0FII7lyM26B51fAMeBQzCb-E=
rpcauth=ic-doge-integration:cdf2741387f3a12438f69092f0fdad8e\$62081498c98bee09a0dce2b30671123fa561932992ce377585e8e08bb0c11dfa
EOF

Explanation of settings:

  • regtest=1: Enables Dogecoin’s regression test mode for local blockchain testing.

  • txindex=1: Maintains a full transaction index to support lookups by transaction ID.

  • rpcuser=ic-btc-integration: Sets a default username for JSON-RPC authentication.

  • rpcpassword=QPQ…b-E=: Sets the password for JSON-RPC authentication.

  • rpcauth=ic-btc-integration:cdf…dfa: Uses an alternative authentication method for RPC, combining the username and a salted hash.

Find more details about dogecoin.conf settings in the Dogecoin Core Daemon documentation.

dogecoind -conf=$(pwd)/dogecoin.conf -datadir=$(pwd)/dogecoin_data --port=18444

This command assumes that port 18444 on your machine is available. If it isn't, change the specified port accordingly.

Starting dfx with Dogecoin support

TODO XC-527: add support for Regtest

Using Dogecoin Regtest

TODO XC-527: add support for Regtest

Dogecoin API Endpoints

To be able to reach the Dogecoin network, your smart contract needs to target one of the available endpoints on the Dogecoin canister.

Dogecoin Canister

Testnet?

Dogecoin testnet is not supported.

Available Endpoints

See the Dogecoin canister interface specification for more details.

dogecoin_get_utxos

Returns UTXOs for a Dogecoin address. UTXOs can be filtered by minimum confirmations (min_confirmations, which may be at most 144) or via a page reference.

dogecoin_get_utxos_query

Used to query dogecoin_get_utxos. Since this is a query call, it returns quickly but results are not trustworthy.

dogecoin_get_balance

Returns the balance of a Dogecoin address in koinus. Takes an optional argument of min_confirmations.

dogecoin_get_balance_query

Used to query dogecoin_get_balance. Since this is a query call, it returns quickly but results are not trustworthy.

dogecoin_get_current_fee_percentiles

Returns fee percentiles (in millikoinus/byte) from the most recent 10_000 Dogecoin transactions.

dogecoin_get_block_headers

Returns raw block headers for a given range of heights.

dogecoin_send_transaction

Sends a raw Dogecoin transaction to the network after validation.

Cycles Cost

The costs of API calls in cycles and USD for the Dogecoin Mainnet APIs are presented in the following tables. As a general principle for the Dogecoin API, some API calls must have a minimum number of cycles attached to them, as indicated in the column Minimum cycles to send with call. Cycles not consumed by the call are returned to the caller. Requiring a relatively large minimum number of cycles makes it possible to change the pricing of API calls without breaking existing smart contracts when the Dogecoin subnet grows in terms of its replication factor in the future. The call for submitting a Dogecoin transaction to the Dogecoin network does not require extra cycles to be attached as the charged cost is independent of the replication factor of the subnet.

The cost per API call in USD uses the USD/XDR exchange rate of May 22, 2025 ($1.354820 USD).

Dogecoin Mainnet

TransactionDescriptionPrice (Cycles)Price (USD)Minimum cycles to send with call
Dogecoin UTXO set for an addressFor retrieving the UTXO set for a Dogecoin address (dogecoin_get_utxos)50_000_000 + 1 cycle per Wasm instruction$0.00006774 + Wasm instruction cost10_000_000_000
Dogecoin fee percentilesFor obtaining the fee percentiles of the most recent transactions (dogecoin_get_current_fee_percentiles)10_000_000$0.00001355100_000_000
Dogecoin balance for an addressFor retrieving the balance of a given Dogecoin address (dogecoin_get_balance)10_000_000$0.00001355100_000_000
Dogecoin transaction submissionFor submitting a Dogecoin transaction to the Dogecoin network, per transaction (dogecoin_send_transaction)5_000_000_000$0.00677N/A
Dogecoin transaction payloadFor submitting a Dogecoin transaction to the Dogecoin network, per byte of payload (dogecoin_send_transaction)20_000_000$0.00002710N/A
Dogecoin block headersFor retrieving the block headers in specified range (dogecoin_get_block_headers)50_000_000 + 1 cycle per Wasm instruction$0.00006774 + Wasm instruction cost10_000_000_000

Note

Fees for calling the dogecoin_get_utxos and dogecoin_get_block_headers endpoints depend on the number of Wasm instructions that the Dogecoin canister consumes when processing the requests to ensure fair charging.

Dogecoin Transactions

Generating a Dogecoin address

TODO XC-464: integrate snippet from basic_dogecoin example.

This is just a dummy example to see how inserting code snippet is rendered

#![allow(unused)]
fn main() {
#[update]
pub async fn get_p2pkh_address() -> String {
    let ctx = BTC_CONTEXT.with(|ctx| ctx.get());

    // Unique derivation paths are used for every address type generated, to ensure
    // each address has its own unique key pair.
    let derivation_path = DerivationPath::p2pkh(0, 0);

    // Get the ECDSA public key of this smart contract at the given derivation path
    let public_key = get_ecdsa_public_key(&ctx, derivation_path.to_vec_u8_path()).await;

    // Convert the public key to the format used by the Bitcoin library
    let public_key = PublicKey::from_slice(&public_key).unwrap();

    // Generate a legacy P2PKH address from the public key.
    // The address encoding (Base58) depends on the network type.
    Address::p2pkh(public_key, ctx.bitcoin_network).to_string()
}
}

Creating Dogecoin Transactions

TODO XC-464: integrate snippet from basic_dogecoin example.

Signing Transactions

TODO XC-464: integrate snippet from basic_dogecoin example.

Submitting Transactions

TODO XC-464: integrate snippet from basic_dogecoin example.

Reading the Dogecoin State

TODO XC-464: integrate snippet from basic_dogecoin example.