Follow the steps below to deploy your copy of the ledger canister to a local replica.
-
Get a pre-built Ledger canister module and Candid interface files.
export IC_VERSION=a7058d009494bea7e1d898a3dd7b525922979039 curl -o ledger.wasm.gz https://download.dfinity.systems/ic/${IC_VERSION}/canisters/ledger-canister_notify-method.wasm.gz gunzip ledger.wasm.gz curl -o ledger.private.did https://raw.githubusercontent.com/dfinity/ic/${IC_VERSION}/rs/rosetta-api/ledger.did curl -o ledger.public.did https://raw.githubusercontent.com/dfinity/ic/${IC_VERSION}/rs/rosetta-api/ledger_canister/ledger.did
The IC_VERSION
variable is a commit hash from the http://github.com/dfinity/ic repository. -
Make sure you use a recent version of DFX. If you don’t have DFX installed, follow instructions on https://smartcontracts.org/ to install it.
-
If you don’t have a DFX project yet, follow these instructions to create a new DFX project: https://smartcontracts.org/docs/developers-guide/cli-reference/dfx-new.html
-
Copy the file you obtained at the first step (
ledger.wasm
,ledger.private.did
,ledger.public.did
) into the root of your project. -
Add the following canister definition to the
dfx.json
file in your project:{ "canisters": { "ledger": { "type": "custom", "wasm": "ledger.wasm", "candid": "ledger.private.did" } } }
-
Start a local replica.
dfx start --background
-
Create a new identity that will work as a minting account:
dfx identity new minter dfx identity use minter export MINT_ACC=$(dfx ledger account-id)
Transfers from the minting account will create
Mint
transactions. Transfers to the minting account will createBurn
transactions. -
Switch back to your default identity and record its ledger account identifier.
dfx identity use default export LEDGER_ACC=$(dfx ledger account-id)
-
Deploy the ledger canister to your network.
dfx deploy ledger --argument '(record {minting_account = "'${MINT_ACC}'"; initial_values = vec { record { "'${LEDGER_ACC}'"; record { e8s=100_000_000_000 } }; }; send_whitelist = vec {}})'
Example 1. Deploying with archivingIf you want to setup the ledger in a way that matches the production deployment, you should deploy it with archiving enabled. In this setup, the ledger canister dynamically creates new canisters to store old blocks. We recommend using this setup if you are planning to exercise the interface for fetching blocks.
Obtain the principal of the identity you use for development. This principal will be the controller of archive canisters.
dfx identity use default export ARCHIVE_CONTROLLER=$(dfx identity get-principal)
Deploy the ledger canister with archiving options:
dfx deploy ledger --argument '(record {minting_account = "'${MINT_ACC}'"; initial_values = vec { record { "'${LEDGER_ACC}'"; record { e8s=100_000_000_000 } }; }; send_whitelist = vec {}; archive_options = opt record { trigger_threshold = 2000; num_blocks_to_archive = 1000; controller_id = principal "'${ARCHIVE_CONTROLLER}'" }})'
You may want to set
trigger_threshold
andnum_blocks_to_archive
options to low values (e.g., 10 and 5) to trigger archivation after only a few blocks. -
Update the canister definition in the
dfx.json
file to use the public Candid interface:{ "canisters": { "ledger": { "type": "custom", "wasm": "ledger.wasm", - "candid": "ledger.private.did" + "candid": "ledger.public.did" } } }
-
Check that the Ledger canister is healthy. Execute the following command:
dfx canister call ledger account_balance '(record { account = '$(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$LEDGER_ACC'")]) + "}")')' })'
The output should look like the following:
(record { e8s = 100_000_000_000 : nat64 })
Your local ICP ledger canister is up and running now. You can now deploy other canisters that need to communicate with the ledger canister.