Introduction
Welcome to Namada's docs!
About Namada
Namada is a Proof-of-Stake layer 1 protocol for asset-agnostic, interchain privacy. Namada is Anoma's first fractal instance and is currently being developed by Heliax, a public goods lab.
Key innovations include:
- ZCash-like transfers for any assets (fungible and non-fungible)
- Rewarded usage of privacy as a public good
- Interoperability with Ethereum via a custom bridge with trust-minimisation
- Vertically integrated user interfaces
Overview of features
- Proof-of-Stake with governance to secure and evolve Namada
- Fast-finality BFT with 4-second blocks
- Near-zero fees
- Trustless 2-way Ethereum bridge via IBC implementation on ETH
- IBC bridges to chains that already speak IBC (all Cosmos chains)
- MASP
- Convert Circuit (shielded set rewards)
- A reference interface
- Ledger application
For high-level introductions, we recommend:
- Article: Introducing Namada: Shielded Transfers with Any Assets
- Article: What is Namada?
- Talks & Podcasts
To learn more about the protocol, we recommend the following in-depth resources:
About this documentation
This book is written using mdBook, the source can be found in the Namada repository.
Contributions to the contents and the structure of this book should be made via pull requests.
Quickstart - How to run a validator on Namada
About this guide
This guide is for those interested in operating a Namada validator node and assumes basic knowledge of the terminal and how commands are used.
- Comments start with
#
:
# this is a comment make sure you read them!
- Sample outputs start with an arrow:
➜ this is an example command line output useful for comparing
Installing Namada
See the installation guide for details on installing the Namada binaries. Commands in this guide will assume you have the Namada binaries (namada
, namadan
, namadaw
, namadac
) on your $PATH.
A simple way to add these binaries to one's path is to run
cp namada/target/release/namada* /usr/local/bin/
Joining a network
See the testnets page for details of how to join a testnet. The rest of this guide will assume you have joined a testnet chain using the namadac utils join-network
command.
Run a ledger node
We recommend this step with tmux, which allows the node to keep running without needing the terminal to be open indefinitely. If not, skip to the subsequent step.
tmux
# inside the tmux/or not
namada ledger
# can detach the tmux (Ctrl-B then D)
For a more verbose output, one can run
export NAMADA_TM_STDOUT='true'
namada ledger
This should sync your node to the ledger and will take a while (depending on your computer). Subsequent commands (generating an account, etc.) are unlikely to work until it is fully synced. Enquire the current block height with other participants to make sure you are synced in order to proceed.
Account
Accounts on Namada are divided into two subcategories:
- Implicit accounts (all use the same Validity Predicate)
- Established accounts (can use a chosen Validity Predicate)
In order to make transactions on Namada, an account is required, and an implicit account can be created easily.
An implicit account can be generated from the commands described below
namadaw address gen \
--alias example-implicit
➜ Enter encryption password:
Successfully added a key and an address with alias: "example-implicit"
An implicit account with alias "example-implicit" has now been successfully generated and stored locally in the wallet.
It is possible to derive an Established Account through submitting a transaction, signing it with the key for the implicit account. Note that this transaction, as with any transaction on Namada, will consume "gas", and will require a positive balance of NAM tokens.
To initialize an account operator on-chain under the alias "example-established":
namadac init-account \
--source example-implicit \
--public-key example-implicit \
--alias example-established
➜ Jan 06 22:22:19.864 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
Enter decryption password:
Last committed epoch: 22386
Transaction added to mempool: Response { code: Ok, data: Data([]), log: Log("Mempool validation passed"), hash: transaction::Hash(9193C2B2C56AAB1B081B18DA0FBBD4B26C5EF7CEE4B35812ECCB1CC1D1443C45) }
Transaction applied with result: {
"info": "Transaction is valid. Gas used: 6080310; Changed keys: #atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw/?, #atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw/ed25519_pk; VPs result: ",
"height": "650627",
"hash": "4FCCBCE5D4335C3A265B5CF22D5B8999451715F8146EB13194711B5EC70B612A",
"code": "0",
"gas_used": "6080310",
"initialized_accounts": [
"atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw"
]
}
The transaction initialized 1 new account
➜ Added alias example-established for address atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw
The "faucet" is a native established account on Namada that is willing to give a maximum of 1000 tokens to any user at request. Let's transfer ourselves 1000 NAM
from the faucet with the same alias using:
namadac transfer \
--source faucet \
--target example-established \
--token NAM \
--amount 1000 \
--signer example-implicit
➜ Jan 06 22:24:32.926 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
➜ Looking-up public key of atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw from the ledger...
Enter decryption password:
Last committed epoch: 22388
Transaction added to mempool: Response { code: Ok, data: Data([]), log: Log("Mempool validation passed"), hash: transaction::Hash(3A5CA1790FDF5150EF1478DE1E3B2D2F7189B0E5D396176E5E5BFC7A37C58D00) }
Transaction applied with result: {
"info": "Transaction is valid. Gas used: 1504228; Changed keys: #atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5/balance/#atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw, #atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5/balance/#atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3; VPs result: Accepted: atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw, atest1v4ehgw36gc6yxvpjxccyzvphxycrxw2xxsuyydesxgcnjs3cg9znwv3cxgmnj32yxy6rssf5tcqjm3, atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5;",
"height": "650706",
"hash": "26AAE9D79F62EE8E62108D8D7689F4FFF12EA613AF29C7D4CDBEA999C28C6224",
"code": "0",
"gas_used": "1504228",
"initialized_accounts": []
}
To query the balance of your account "example-established":
namadac balance \
--owner example-established
Setting up the validator node
Initialize a validator account under any alias - in this example, "example-validator":
namadac init-validator \
--alias example-validator \
--source example-established
➜ Jan 06 22:26:29.927 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
Generating validator account key...
You will be asked to enter encryption passwords to generate a validator account key, consensus key and a staking reward account key. After entering the encryption password and a decryption password for the "example-established" account's key, the transaction should be added to the mempool and applied in a future block.
➜ Transaction added to mempool: Response { code: Ok, data: Data([]), log: Log("Mempool validation passed"), hash: transaction::Hash(F61D3D73CE7EFCC2021940A75B713C499D4942F820F6EC0F7924B70E7F2E751A) }
Transaction applied with result: {
"info": "Transaction is valid. Gas used: 15139451; Changed keys: #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/voting_power, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/staking_reward_address, #atest1v4ehgw36xppnjsjzx4ryxs2zgc6nx33hxpq5zve4g5u5xdjpgfz5xv2pg3ryy3zrxyenssfcxn02yg/ed25519_pk, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/total_deltas, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/state, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/consensus_key, #atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/?, #atest1v4ehgw36xppnjsjzx4ryxs2zgc6nx33hxpq5zve4g5u5xdjpgfz5xv2pg3ryy3zrxyenssfcxn02yg/?, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator_set, #atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/ed25519_pk, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/address_raw_hash/DB3D27BF31382E6250C06119C3FDF4672BB3DF5A; VPs result: Accepted: atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7;",
"height": "650779",
"hash": "3B6AA8F3E6F1951E21703CABA4CCD24F82F6D5C38674041A7AAA1B7227B1E6B8",
"code": "0",
"gas_used": "15139451",
"initialized_accounts": [
"atest1v4ehgw36xppnjsjzx4ryxs2zgc6nx33hxpq5zve4g5u5xdjpgfz5xv2pg3ryy3zrxyenssfcxn02yg",
"atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd"
]
}
Added alias example-validator for address atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd.
Added alias example-validator-rewards for address atest1v4ehgw36xppnjsjzx4ryxs2zgc6nx33hxpq5zve4g5u5xdjpgfz5xv2pg3ryy3zrxyenssfcxn02yg.
The validator's addresses and keys were stored in the wallet:
Validator address "example-validator"
Staking reward address "example-validator-rewards"
Validator account key "example-validator-key"
Consensus key "example-validator-consensus-key"
Staking reward key "example-validator-rewards-key"
The ledger node has been setup to use this validator's address and consensus key.
Once the init-validator
transaction is applied in the block and the on-chain generated validator's address is stored in your wallet, you MUST restart the namada ledger
node to start the node as a validator that you've just created.
When you restart the node, you might notice log message "This node is not a validator" from Tendermint. This is expected, because your validator doesn't yet have any stake in the PoS system.
We will now add some stake to your validator account.
Transfer 1000 NAM to your validator account ("example-validator"):
namadac transfer \
--source example-established \
--target example-validator \
--token NAM \
--amount 1000
➜ Jan 06 22:28:17.624 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
Looking-up public key of atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw from the ledger...
Enter decryption password:
Last committed epoch: 22392
Transaction added to mempool: Response { code: Ok, data: Data([]), log: Log("Mempool validation passed"), hash: transaction::Hash(7FD43C7573B4A62E24DBB6C99EE6C7A107DF01CC5F947517B91742E6324AE58D) }
Transaction applied with result: {
"info": "Transaction is valid. Gas used: 1989091; Changed keys: #atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5/balance/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd, #atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5/balance/#atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw; VPs result: Accepted: atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd, atest1v4ehgw36ggmyzwp5g9prgsekgsu5y32z8ycnsvpeggcnys35gv65yvzxg3zrjwphgcu5gde4lvmstw, atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5;",
"height": "650842",
"hash": "D251AAB5D4CD9471DB4E11DA09DEF0F15E2A3EC95EE0EE2C76766839FC352394",
"code": "0",
"gas_used": "1989091",
"initialized_accounts": []
}
Bond the 1000 NAM to "example-validator" using:
namadac bond \
--validator example-validator \
--amount 1000
➜ Jan 06 22:29:08.903 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
Looking-up public key of atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd from the ledger...
Enter decryption password:
Last committed epoch: 22393
Transaction added to mempool: Response { code: Ok, data: Data([]), log: Log("Mempool validation passed"), hash: transaction::Hash(2B814FE404F6F1D8C07CC3A51AA3038C193810251B9C50107B79698ED15A4EDC) }
Transaction applied with result: {
"info": "Transaction is valid. Gas used: 3734939; Changed keys: #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/total_deltas, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/total_voting_power, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator_set, #atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5/balance/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd, #atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5/balance/#atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/validator/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/voting_power, #atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7/bond/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd/#atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd; VPs result: Accepted: atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd, atest1v9hx7w362pex7mmxyphkvgznw3skkefqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqq8ylv7, atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5;",
"height": "650869",
"hash": "14F5C67D27E2F9695EA40ABEA2DEC69F5B0FFEF5DFD7CB7D0FC397CC8A618BA8",
"code": "0",
"gas_used": "3734939",
"initialized_accounts": []
}
Check your bond:
namadac bonds \
--validator example-validator
➜ Jan 06 22:30:42.798 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
Last committed epoch: 22394
Self-bonds:
Active from epoch 22395: Δ 1000
Bonds total: 1000
Check the voting power - this will be 0 until the active-from epoch is reached (in this case 22395
):
namadac voting-power \
--validator example-validator
➜ Jan 06 22:31:24.908 INFO namada_apps::cli::context: Chain ID: namada-testnet-1.2.bf0181d9f7e0
Last committed epoch: 22395
Validator atest1v4ehgw36g3prx3pjxapyvve3xvury3fkxg6nqsesxccnzw2rxdryg335xcmnysjzxdzyvd2pamfmwd is active, voting power: 1
Total voting power: 44
Note that with the above command, you can also specify --epoch
argument to check a future epoch.
Congratulations, you have set up a validator node!
User Guide
Welcome to Namada's user guide!
This guide will teach you how to install, operate and interact with the Namada ledger node, the client, and the wallet.
Install Namada
Namada can be installed through the following methods:
The hardware requirements for installing and running a Namada full node can be found here
Hardware Requirements
This section covers the minimum and recommended hardware requirements for engaging with Namada as a validator node.
Validator Requirements
Hardware | Minimal Specifications |
---|---|
CPU | x86_64 or arm64 processor with at least 4 physical cores (must support AVX/SSE instruction set) |
RAM | 8GB DDR4 |
Storage | at least 500GB SSD (NVMe SSD is recommended. HDD will also work.) |
User Requirements
Hardware | Minimal Specifications |
---|---|
CPU | x86_64 or arm64 processor with at least 2 physical cores (must support AVX/SSE instruction set) |
RAM | 2GB DDR4 |
Storage | at least 100GB SSD (NVMe SSD is recommended. HDD will also work.) |
From Source
If you'd like to install Namada from source you will have to install some dependencies first: Rust, Git, Clang, OpenSSL and LLVM.
First, install Rust by following the instructions from the official page.
At the end of the installation, make sure that Cargo's bin directory ($HOME/.cargo/bin) is available on your PATH environment variable. You can either restart your shell or run source $HOME/.cargo/env
to continue.
If you already have Rust installed, make sure you're using the latest version by running:
rustup update
Then, install the remaining dependencies.
Ubuntu: running the following command should install everything needed:
sudo apt-get install -y make git-core libssl-dev pkg-config libclang-12-dev build-essential
Mac: installing the Xcode command line tools should provide you with almost everything you need:
xcode-select --install
Now that you have all the required dependencies installed, you can clone the source code from the Namada repository and build it with:
git clone https://github.com/anoma/namada.git
cd namada
make install
During internal and private testnets, checkout the latest testnet branch using git checkout $NAMADA_TESTNET_BRANCH
.
From Binaries
Prebuilt binaries might not be available for a specific release or architecture, in this case you have to build from source.
Installing Tendermint
Namada binaries require a unique fork of Tendermint from Heliax. Please follow these instructions.
Installing GLIBC
Finally, you should have GLIBC v2.29
or higher.
MacOS: the system-provided glibc should be recent enough.
Ubuntu 20.04: this is installed by default and you don't have to do anything more.
Ubuntu 18.04: glibc has v2.27
by default which is lower than the required version to run Namada. We recommend to directly install from source or upgrade to Ubuntu 19.04, instead of updating glibc to the required version, since the latter way can be a messy and tedious task. In case, updating glibc would interest you this website gives you the steps to build the package from source.
Downloading the binaries
Now that you have all dependencies installed, you can download the latest binary release from our releases page by choosing the appropriate architecture.
Placing the binaries onto $PATH
For ubuntu and mac machines, the following command should work for placing namada into path
Once inside the directory containing the binaries:
sudo cp ./namada* /usr/local/bin/
From Docker
The Namada docker image can be found here
Installing Tendermint
Start by exporting the variable
export TM_HASH=v0.1.4-abciplus
Install the heliaxdev/tendermint fork
git clone https://github.com/heliaxdev/tendermint && cd tendermint && git checkout $TM_HASH
make build
The above requires that golang is correctly installed with the correct $PATH setup
- In linux, this can be resolved by
sudo snap install go --channel=1.18/stable --classic
- Copy both the namada and tendermint binaries to somewhere on $PATH (or uselol the relative paths)
- This step may or may not be necessary
- namada binaries can be found in
/target/release
- tendermint is in
build/tendermint
In a linux based terminal, one can use the following command in order to copy the tendermint
binaries to $PATH
sudo cp ./build/tendermint $HOME/go/bin/
`
Overview of binaries
This guide assumes that the Namada binaries are installed and available on path. These are:
namada
: The main binary that can be used to interact with all the components of Namadanamadan
: The ledger nodenamadac
: The clientnamadaw
: The wallet
The main binary namada
has sub-commands for all of the other binaries:
namada client = namadac
namada node = namadan
namada wallet = namadaw
To explore the command-line interface, add --help
argument at any sub-command level to find out any possible sub-commands and/or arguments.
Adding binaries to path
The binaries should be added to $PATH
from the make install
command. However, if this for some reason did not work, a solution may be to copy the binaries from namada/target/release
to home/$USER/.local/bin/
for example:
sudo cp namada/target/release/namada* /home/alice/.local/bin/
The Namada Ledger
To start a local Namada ledger node, run:
namada ledger
Note: You need to have joined a network before you start the ledger. It throws an error if no network has been configured.
The node will attempt to connect to the persistent validator nodes and other peers in the network, and synchronize to the latest block.
By default, the ledger will store its configuration and state in the .namada
directory relative to the current working directory. You can use the --base-dir
CLI global argument or NAMADA_BASE_DIR
environment variable to change it.
The ledger also needs access to the built WASM files that are used in the genesis block. These files are included in release and shouldn't be modified, otherwise your node will fail with a consensus error on the genesis block. By default, these are expected to be in the wasm
directory, relative to the current working directory. This can also be set with the --wasm-dir
CLI global argument, NAMADA_WASM_DIR
environment variable or the configuration file.
The ledger configuration is stored in .namada/{chain_id}/config.toml
(with
default --base-dir
). It is created when you join the network. You can modify
that file to change the configuration of your node. All values can also be set
via environment variables. Names of the recognized environment variables are
derived from the configuration keys by: uppercase every letter of the key,
insert .
or __
for each nested value and prepend NAMADA_
. For example,
option p2p_pex
in [ledger.tendermint]
can be set by
NAMADA_LEDGER__TENDERMINT__P2P_PEX=true|false
or
NAMADA_LEDGER.TENDERMINT.P2P_PEX=true|false
in the environment (Note: only the
double underscore form can be used in Bash, because Bash doesn't allow dots in
environment variable names).
Namada Wallet Guide
This document describes the different wallet concepts and options that are available to users of Namada who want to be able to send, receive and interact with NAM tokens on the Namada blockchain.
Check out the different options to generate a wallet:
An introduction to Namada Addresses
The purpose of the Namada wallet is to provide a user-interface to store and manage both keys and addresses. In this context, keys are (potentially) very large integers that have some meaning on an eliptic curve. Keys are the fundamental building blocks for accounts on Namada. Keys come in the form of pairs (secret and public), can be used to derive the account address (first 40 chars of the SHA256 hash of the public key).
All accounts in Namada have a unique address, exactly one Validity Predicate and optionally any additional data in its dynamic storage sub-space.
There are currently 3 types of account addresses:
- Implicit (not fully supported yet): An implicit account is derived from your keypair and can be used to authorize certain transactions from the account. They can be used as recipients of transactions even if the account has not been used on-chain before.
- Established: Used for accounts that allow the deployment of custom validation logic. These must be created on-chain via a transaction (e.g. initialize an account. The address is generated on-chain and is not known until the transaction is applied (the user provides randomness).
- Internal: Special internal accounts, such as protocol parameters account, PoS and IBC.
Manage keypairs
Namada uses ed25519 keypairs for signing cryptographic operations on the blockchain.
To manage your keys, various sub-commands are available under:
namada wallet key
Generate a keypair
It is possible to generate keys using the CLI. By doing so, an implicit account address is also derived in the process and added to storage.
namada wallet key gen --alias my-key
The derived implicit address shares the same my-key
alias. The previous command has the same effect as namada wallet address gen --alias my-key
.
List all known keys
namada wallet key list
Manage addresses
To manage addresses, similar to keys, various sub-commands are available:
namada wallet address
Generate an implicit address
namada wallet address gen --alias my-account
Note that this will also generate and save a key from which the address was derived and save it under the same my-account
alias. Thus, this command has the same effect as namada wallet key gen --alias my-account
.
List all known addresses
namada wallet address list
File System Wallet
By default, the Namada Wallet is stored under .namada/{chain_id}/wallet.toml
where keys are stored encrypted. You can change the default base directory path with --base-dir
and you can allow the storage of unencrypted keypairs with the flag --unsafe-dont-encrypt
.
If the wallet doesn't already exist, it will be created for you as soon as you run a command that tries to access the wallet. A newly created wallet will be pre-loaded with some internal addresses like pos
, pos_slash_pool
, masp
and more.
Currently, the Namada client can load the password via:
- Stdin: the client will prompt for a password.
- Env variable: by exporting a ENV variable called
NAMADA_WALLET_PASSWORD
with value of the actual password. - File: by exporting an ENV variable called
NAMADA_WALLET_PASSWORD_FILE
with value containing the path to a file containing the password.
Web Wallet
The Web Wallet for Namada is currently in closed beta.
Paper Wallet
At the moment, the Namada CLI doesn't provide a Paper Wallet.
Hardware Wallet
The Ledger Hardware Wallet is currently in development.
Send and Receive NAM tokens
In Namada, tokens are implemented as accounts with the Token Validity Predicate. It checks that its total supply is preserved in any transaction that uses this token. Your wallet will be pre-loaded with some token addresses that are initialized in the genesis block.
Initialize an established account
If you already have a key in your wallet, you can skip this step. Otherwise, generate a new keypair now.
Then, send a transaction to initialize your new established account and save its address with the alias my-new-acc
. The my-key
public key will be written into the account's storage for authorizing future transactions. We also sign this transaction with my-key
.
namada client init-account \
--alias my-new-acc \
--public-key my-key \
--source my-key
Once this transaction has been applied, the client will automatically see the new address created by the transaction and add it to your Wallet with the chosen alias my-new-acc
.
This command uses the prebuilt User Validity Predicate.
Send a Payment
To submit a regular token transfer from your account to the validator-1
address:
namada client transfer \
--source my-new-acc \
--target validator-1 \
--token NAM \
--amount 10
This command will attempt to find and use the key of the source address to sign the transaction.
See your balance
To query token balances for a specific token and/or owner:
namada client balance --token NAM --owner my-new-acc
For any client command that submits a transaction (init-account
, transfer
, tx
, update
and PoS transactions), you can use the --dry-run
flag to simulate the transaction being applied in the block and see what would be the result.
See every known addresses' balance
You can see the token's addresses known by the client when you query all tokens balances:
namada client balance
Fees on Namada
In order to settle the market for Namada blockspace demand, fees are coupled with transactions. In order for any namada transaction to be considered valid, the correct corresponding fee must be paid. All fees are paid in the native token NAM. The exact fee is set by governance.
How fees are paid
Fees on Namada are paid by the implicit address corresponding to the --signer
of the transaction. This means that in the transaction
namada client transfer \
--source my-new-acc \
--target validator-1 \
--token NAM \
--amount 10 \
--signer my-key
the account associated with my-key
will be required to pay the fee. This means that even though my-new-account
may have a positive NAM balance, my-key
will need to have the associated NAM in order to pay the transaction fee.
For testnet purposes, we recommend using the faucet to source NAM for transaction fees.
Shielded transfers
In Namada, shielded transfers are enabled by the Multi-Asset Shielded Pool (MASP). The MASP is a zero-knowledge circuit (zk-SNARK) that extends the Zcash Sapling circuit to add support for sending arbitrary assets. All assets in the pool share the same anonymity set, this means that the more transactions are issued to MASP, the stronger are the privacity guarantees.
Using MASP
If you are familiar with Zcash, the set of interactions you can execute with the MASP are similar:
- Shielding transfers: transparent to shielded addresses
- Shielded transfers: shielded to shielded addresses
- Deshielding transfers: shielded to transparent addresses
- A Spending Key is a type of private key that allows any user in possession of it to spend the balance of the associated address. For shielded addresses, possessing the Spending Key also allows the user to view the address’ balance and transaction data.
- A Viewing Key allows any user in possession of it to view and disclose transaction details. It is derived from the Spending Key and hold the same alias.
Shielding transfers
To try out shielded transfers, you first need to be in possession of a transparent account with some token balance.
Create your transparent account
Generate an implicit account:
namadaw address gen --alias [your-implicit-account-alias]
Then, create an established account on-chain using the implicit account you've just generated:
namadac init-account \
--source [your-implicit-account-alias] \
--public-key [your-implicit-account-alias] \
--alias [your-established-account-alias]
Get tokens from the Testnet Faucet
The testnet tokens which the faucet can provide you have the aliases NAM
,
BTC
, ETH
, DOT
, Schnitzel
, Apfel
, and Kartoffel
. The faucet
will transfer these in increments of 1000 maximum at a time.
namadac transfer \
--token btc \
--amount 1000 \
--source faucet \
--target [your-established-account-alias] \
--signer [your-implicit-account-alias]
Now that you have a transparent account with some tokens, you can generate a Spending Key to hold your shielded balances.
Generate your Spending Key
You can randomly generate a new Spending Key with:
namadaw masp gen-key --alias [your-spending-key-alias]
Create a new payment address
To create a payment address from your Spending key, use:
namadaw masp gen-addr \
--key [your-spending-key-alias] \
--alias [your-payment-address-alias]
This command will generate a different payment address each time you run it. Payment addresses can be reused or discarded as you like, and any relationship between addresses cannot be deciphered by any user without the spending key.
Send your shielding transfer
Once you have a payment address, transfer a balance from your transparent account to your shielded account with something like:
namadac transfer \
--source [your-established-account-alias] \
--target [your-payment-address-alias] \
--token btc \
--amount 100
View your balance
Once this transfer has been broadcasted, validated, and executed on the blockchain, you can view your Spending Key's balance:
namadac balance --owner [your-spending-key-alias]
Shielded transfers
Now that you have a shielded balance, it can be transferred to a another shielded address:
namadac transfer \
--source [your-spending-key-alias] \
--target [some-payment-address] \
--token btc \
--amount 50 \
--signer [your-implicit-account-alias]
Deshielding tranfers
You can also transfer back your balance to a transparent account:
namadac transfer \
--source [your-spending-key-alias] \
--target [some-transparent-address-alias] \
--token btc \
--amount 50 \
--signer [your-implicit-account-alias]
Shielded Address/Key Generation
Spending Key Generation
When the client generates a spending key, it automatically derives a viewing key for it. The spending key acts as the "source" of any transfer from any shielded address derived from it. The viewing key is able to determine the total unspent notes that the spending key is authorized to spend.
Payment Address Generation
Payment addresses can be derived from both spending keys as well as viewing keys. The payment address acts as a destination address in which any tokens received by this address is spendable by the corresponding spending key. Only the payment address's spending key and viewing key are able to spend and view the payment address's balance, respectively. Below are examples of how payment addresses can be generated:
namadaw masp gen-addr --alias my-pa1 --key my-sk
namadaw masp gen-addr --alias my-pa2 --key my-vk
Manual Key/Address Addition
It is also possible to manually add spending keys, viewining keys, and payment addresses in their raw form. This is demonstrated by the commands below.
namadaw masp add --alias my-sk --value xsktest1qqqqqqqqqqqqqq9v0sls5r5de7njx8ehu49pqgmqr9ygelg87l5x8y4s9r0pjlvu69au6gn3su5ewneas486hdccyayx32hxvt64p3d0hfuprpgcgv2q9gdx3jvxrn02f0nnp3jtdd6f5vwscfuyum083cvfv4jun75ak5sdgrm2pthzj3sflxc0jx0edrakx3vdcngrfjmru8ywkguru8mxss2uuqxdlglaz6undx5h8w7g70t2es850g48xzdkqay5qs0yw06rtxcvedhsv
namadaw masp add --alias my-vk --value xfvktest1qqqqqqqqqqqqqqpagte43rsza46v55dlz8cffahv0fnr6eqacvnrkyuf9lmndgal7erg38awgq60r259csg3lxeeyy5355f5nj3ywpeqgd2guqd73uxz46645d0ayt9em88wflka0vsrq29u47x55psw93ly80lvftzdr5ccrzuuedtf6fala4r4nnazm9y9hq5yu6pq24arjskmpv4mdgfn3spffxxv8ugvym36kmnj45jcvvmm227vqjm5fq8882yhjsq97p7xrwqt7n63v
namadaw masp add --alias my-pa --value patest10qy6fuwef9leccl6dfm7wwlyd336x4y32hz62cnrvlrl6r5yk0jnw80kus33x34a5peg2xc4csn
Making Shielded Transactions
Shielding Transactions
In order to shield tokens from a transparent address, the user must first generate a shielded payment address in which the user holds the spending key for. It is then possible to make a transfer from the transparent address to the newly created shielded payment address. Once this process is completed, the new tokens are now considered "shielded". The gas fee is charged to the source address that makes the transfer to the shielded payment address. Shielding tokens can be done as following:
namadac transfer --source Bertha --amount 50 --token BTC --target my-pa
Unshielding Transactions
"Unshielding" is the process of transferring token balances from the shielded set to the transparent one. When the user makes a transfer from a shielded account (using the corresponding spending key) to a transparent account, the newly transferred funds are considered "unshielded". The gas fee is charged to the signer's address (which should default to the target address). Once the transaction is complete, the spending key will no longer be able to spend the transferred amount. Below is an example of how an unshielding transaction is performed:
namadac transfer --target Bertha --amount 45 --token BTC --source my-sk
Shielded Transactions
Shielded transfers are made from one shielded account to another. From a user perspective, this is almost equivalent to a transparent-transparent token transfer, except the gas fee is paid by the signer of the transaction. The command for performing a shielded transfer is given below:
namadac transfer --source my-sk --amount 5 --token BTC --target your-pa
Viewing Shielded Balances
The viewing key that is derived from a spending key allows any user holding that key to view the balances attached to corresponding spending key. It is possible to use this viewing key to either decipher the full balance of the corresponding viewing key or query a subset of them.
namadac balance
namadac balance --owner my-key
namadac balance --owner my-key --token BTC
namadac balance --token BTC
Listing Shielded Keys/Addresses
The wallet is able to list all the spending keys, viewing keys, and payment addresses that it stores. Below are examples of how the wallet's storage can be queried:
namadaw masp list-keys
namadaw masp list-keys --unsafe-show-secret
namadaw masp list-keys --unsafe-show-secret --decrypt
namadaw masp list-addrs
Finding Shielded Keys/Addresses
The wallet is able to find any spending key, viewing key or payment address when given its alias. Below are examples of how the wallet's storage can be queried:
namadaw masp find --alias my-alias
namadaw masp find --alias my-alias --unsafe-show-secret
🔏 Interacting with the Cubic Proof-of-Stake system
The Namada Proof of Stake system uses the NAM token as the staking token. It features delegation to any number of validators and customizable validator validity predicates.
PoS Validity Predicate
The PoS system is implemented as an account with the PoS Validity Predicate that governs the rules of the system. You can find its address in your wallet:
namada wallet address find --alias PoS
Epochs
The system relies on the concept of epochs. An epoch is a range of consecutive blocks identified by consecutive natural numbers. Each epoch lasts a minimum duration and includes a minimum number of blocks since the beginning of the last epoch. These are defined by protocol parameters.
To query the current epoch:
namada client epoch
Delegating (Staking)
You can delegate to any number of validators at any time. When you delegate tokens, the delegation won't count towards the validator's stake (which in turn determines its voting power) until the beginning of epoch n + 2
in the current epoch n
(the literal 2
is set by PoS parameter pipeline_len
). The delegated amount of tokens will be deducted from your account immediately, and will be credited to the PoS system's account.
To submit a delegation that bonds tokens from the source address to a validator with alias validator-1
:
namada client bond \
--source my-new-acc \
--validator validator-1 \
--amount 12.34
You can query your delegations:
namada client bonds --owner my-new-acc
The result of this query will inform the epoch from which your delegations will be active.
Because the PoS system is just an account, you can query its balance, which is the sum of all staked tokens:
namada client balance --owner PoS
Slashes
Should a validator exhibit punishable behavior, the delegations towards this validator are also liable for slashing. Only the delegations that were active in the epoch in which the fault occurred will be slashed by the slash rate of the fault type. If any of your delegations have been slashed, this will be displayed in the bonds
query. You can also find all the slashes applied with:
namada client slashes
Unbonding
While your tokens are being delegated, they are locked-in the PoS system and hence are not liquid until you withdraw them. To do that, you first need to send a transaction to “unbond” your tokens. You can unbond any amount, up to the sum of all your delegations to the given validator, even before they become active.
To submit an unbonding of a delegation of tokens from a source address to the validator:
namada client unbond \
--source my-new-acc \
--validator validator-1 \
--amount 1.2
When you unbond tokens, you won't be able to withdraw them immediately. Instead, tokens unbonded in the epoch n
will be withdrawable starting from the epoch n + 6
(the literal 6
is set by PoS parameter unbonding_len
). After you unbond some tokens, you will be able to see when you can withdraw them via bonds
query:
namada client bonds --owner my-new-acc
When the chain reaches the epoch in which you can withdraw the tokens (or anytime after), you can submit a withdrawal of unbonded delegation of tokens back to your account:
namada client withdraw \
--source my-new-acc \
--validator validator-1
Upon success, the withdrawn tokens will be credited back your account and debited from the PoS system.
Validators' Voting Power
To see all validators and their voting power, which is exactly equal to the amount of staked NAM tokens from their self-bonds and delegations, you can query:
namada client bonded-stake
With this command, you can specify --epoch
to find the voting powers at some future epoch. Note that only the voting powers for the current and the next epoch are final.
📒 PoS Validators
Generate a validator account
To register a new validator account, run:
namada client init-validator \
--alias my-validator \
--source my-new-acc \
--commission-rate <commission-rate>
--max-commission-rate-change <max-commission-rate-change>
The commission rate charged by the validator for delegation rewards and the maximum change per epoch in the commission rate charged by the validator for delegation rewards. Both are expressed as a decimal between 0 and 1. Staking rewards are not yet implemented.
This command will generate the keys required for running a validator:
- Consensus key, which is used in signing blocks in Tendermint.
- Validator account key for signing transactions on the validator account, such as token self-bonding, unbonding and withdrawal, validator keys, validity predicate, state and metadata updates.
Then, it submits a transaction to the ledger that generates the new validator account with established address, which can be used to receive new delegations.
The keys and the alias of the address will be saved in your wallet. Your local ledger node will also be setup to run this validator, you just have to shut it down with e.g. Ctrl + C
, then start it again with the same command:
namada ledger
The ledger will then use the validator consensus key to sign blocks, should your validator account acquire enough voting power to be included in the active validator set. The size of the active validator set is limited to 128
(the limit is set by the PoS max_validator_slots
parameter).
Note that the balance of NAM tokens that is in your validator account does not count towards your validator's stake and voting power:
namada client balance --owner my-validator --token NAM
That is, the balance of your account's address is a regular liquid balance that you can transfer using your validator account key, depending on the rules of the validator account's validity predicate. The default validity predicate allows you to transfer it with a signed transaction and/or stake it in the PoS system.
Self-bonding
You can submit a self-bonding transaction of tokens from a validator account to the PoS system with:
namada client bond \
--validator my-validator \
--amount 3.3
Determine your voting power
A validator's voting power is determined by the sum of all their active self-bonds and delegations of tokens, with slashes applied, if any.
The same rules apply to delegations. When you self-bond tokens, the bonded amount won't count towards your validator's stake (which in turn determines your power) until the beginning of epoch n + 2
in the current epoch n
. The bonded amount of tokens will be deducted from the validator's account immediately and will be credited to the PoS system's account.
While your tokens are being self-bonded, they are locked-in the PoS system and hence are not liquid until you withdraw them. To do that, you first need to send a transaction to “unbond” your tokens. You can unbond any amount, up to the sum of all your self-bonds, even before they become active.
Self-unbonding
To submit an unbonding of self-bonded tokens from your validator:
namada client unbond \
--validator my-validator \
--amount 0.3
Again, when you unbond tokens, you won't be able to withdraw them immediately. Instead, tokens unbonded in the epoch n
will be withdrawable starting from the epoch n + 6
. After you unbond some tokens, you will be able to see when you can withdraw them via bonds
query:
namada client bonds --validator my-validator
When the chain reaches the epoch in which you can withdraw the tokens (or anytime after), you can submit a withdrawal of unbonded tokens back to your validator account:
namada client withdraw --validator my-validator
Governance
The Namada governance mechanism gives users the possibility to upgrade the protocol dynamically.
There are two different mechanism to create a proposal:
- On-chain proposals: Proposal is voted on and tallied on-chain. This can optionally include proposal code to be executed if the proposal is accepted.
- Off-chain proposals
On-chain proposals
Create a proposal
Assuming you have an account with at least 500 NAM token (in this example we are going to use my-new-acc
), lets get the corresponding address
namada wallet address find --alias `my-new-acc`
Now, we need to create a json file proposal.json
holding the content of our proposal. Copy the below text into a json file.
{
"content": {
"title": "Proposal title",
"authors": "email@proposal.n",
"discussions-to": "www.github.com/anoma/aip/1",
"created": "2022-03-10T08:54:37Z",
"license": "MIT",
"abstract": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros. Nullam sed ex justo. Ut at placerat ipsum, sit amet rhoncus libero. Sed blandit non purus non suscipit. Phasellus sed quam nec augue bibendum bibendum ut vitae urna. Sed odio diam, ornare nec sapien eget, congue viverra enim.",
"motivation": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices.",
"details": "Ut convallis eleifend orci vel venenatis. Duis vulputate metus in lacus sollicitudin vestibulum. Suspendisse vel velit ac est consectetur feugiat nec ac urna. Ut faucibus ex nec dictum fermentum. Morbi aliquet purus at sollicitudin ultrices. Quisque viverra varius cursus. Praesent sed mauris gravida, pharetra turpis non, gravida eros.",
"requires": "2"
},
"author": "TODO",
"voting_start_epoch": 3,
"voting_end_epoch": 6,
"grace_epoch": 12,
"proposal_code_path": "./wasm_for_tests/tx_no_op.wasm"
}
You should change the value of:
Author
field with the address ofmy-new-acc
.voting_start_epoch
with a future epoch (must be a multiple of 3) for which you want the voting to beginvoting_end_epoch
with an epoch greater thanvoting_start_epoch
, a multiple of 3, and by which no further votes will be acceptedgrace_epoch
with an epoch greater thanvoting_end_epoch
+ 6, in which the proposal, if passed, will come into effectproposal_code_path
with the absolute path of the wasm file to execute (or remove the field completely)
As soon as your proposal.json
file is ready, you can submit the proposal with (making sure to be in the same directory as the proposal.json
file):
namada client init-proposal --data-path proposal.json
The transaction should have been accepted. You can query all the proposals with:
namada client query-proposal
or a single proposal with
namada client query-proposal --proposal-id 0
where 0
is the proposal id.
Vote a proposal
Only validators and delegators can vote. Assuming you have a validator or a delegator account (in this example we are going to use validator
), you can send a vote with the following command:
namada client vote-proposal \
--proposal-id 0 \
--vote yay \
--signer validator
where --vote
can be either yay
or nay
.
Check the result
As soon as the ledger reaches the epoch defined in the json as voting_end_epoch
, no votes will be accepted. The code definied in proposal_code
json field will be executed at the beginning of grace_epoch
epoch. You can use the following commands to check the status of a proposal:
namada client query-proposal --proposal-id 0
or to just check the result:
namada client query-proposal-result --proposal-id 0
Off-chain proposals
If for any reason issuing an on-chain proposal is not adequate to your needs, you still have the option to create an off-chain proposal.
Create proposal
Create the same json file as in the on-chain proposal and use the following command:
namada client init-proposal \
--data-path proposal.json \
--offline
This command will create a proposal
file same directory where the command was launched.
Vote on proposal
To vote on an offline proposal use the following command:
namada client vote-proposal --data-path proposal \
--vote yay \
--signer validator \
--offline
This command will create a proposal-vote-${address}
file (where address is the --signer
address).
Tally off-chain proposal
To compute the tally for an offline proposal we need to collect
proposal
file (must have this name)- all the
proposal-vote-${address}
files
All those files will have to be in a folder (lets call it offline-proposal
).
Now you can use the following command:
namada client query-proposal-result \
--offline \
--data-path `offline-proposal`
which will tell you the proposal result.
Using IBC with Namada
This document describes using the inter-blockchain communication (IBC) protocol with Namada. This documentation covers being able to create connections through IBC as well as setting up local instances of Namada for testing purposes.
Warning
This feature is currently in development. Expect the unexpected.
This document will cover three essential steps for using IBC with Namada
The below is intended for those that wish to conduct IBC message transfers between two Namada chains. There is of course the cabablitiy to do this between any two IBC compatible chains (such as a cosmos chain). In this case, it is necessary to have a node of both the destination and the source chain running in order to make any package transfers. Below, we discuss first how to enable this connection between two pre-existing chains by Hermes, and second setting up 2 Namada local instances or joining two pre-existing Namada instances for this purpose.
Setup Hermes
Hermes is an IBC relayer to relay packets between chains(instances). We have our Hermes supporting Namada instances. Before packet relay, we need the following step to configure and start Hermes.
- Make Hermes config file
- Create IBC client/connection/channel between instances
- Run Hermes
Make Hermes config file
One essential piece of the puzzle is to create a config.toml
file that describes what connections will be set up that the relayer will be responsible for.
export HERMES_CONFIG="<choose path for hermes config>/config.toml"
touch $HERMES_CONFIG
If you don't specify the file path, ~/.hermes/config.toml
is read as default.
You can find an example of the config file here. Essentially, you change only the chain IDs, the RPC addresses, and the key names in the config file for Namada. If you don't have nodes, please set up nodes manually or through our scripts.
The path to the config file, which is is saved in the variable $HERMES_CONFIG
will be useful later.
Interpreting the toml
Each chain configuration is specified under the [[chains]]
object.
These are the pieces of this puzzle you want to keep your :eyes: on:
chains.id
is the name of the chainchains.rpc_address
specifies the port that the channel is communicating through, and will be the argument for theledger_address
of Namada when interacting with the ledger (will become clearer later)- Make sure to change the IP address to the IP address of your local machine that is running this node!
chains.key_name
specifies the key of the signer who signs a transaction from the relayer. The key should be generated before starting the relayer.
Create IBC client/connection/channel between instances
Hermes CLI has commands to create them. Before the creation, a node of each instance should be running.
Install Hermes
Before conducting any IBC operations, we build Heliax's Hermes fork from source.
export COMMIT="470137e845b997228f9bcda8eec8bc02bd0be6da"
git clone git@github.com:heliaxdev/ibc-rs.git
git checkout $COMMIT
cd ibc-rs
cargo build --release --bin hermes
export IBC_RS=$(pwd) # if needed
Check the binary:
./target/release/hermes --version
It is recommended to now add hermes to $PATH
such that it is callable without any pre-fixes.
For ubuntu users, this can be achieved by
cp ./target/release/hermes /usr/local/bin/
`
Create IBC channel
The "create channel" command (below) creates not only the IBC channel but also the necessary IBC client connection.
hermes -c $HERMES_CONFIG \
create channel $CHAIN_A_ID \
--chain-b $CHAIN_B_ID \
--port-a transfer \
--port-b transfer \
--new-client-connection
This command will ask you with the following message. You can continue with y
.
to re-use a pre-existing connection. [y/n]
When the creation has been completed, you can see the channel IDs. For example, the following text shows that a channel with ID 7
has been created on Chain A namada-test.0a4c6786dbda39f786
, and a channel with ID 12
has been created on Chain B namada-test.647287156defa8728c
. You will need the channel IDs for a transfer over IBC. It means that you have to specify channel-7
as a channel ID (The prefix channel-
is always required) for a transfer from Chain A to Chain B. Also, you have to specify channel-12
as a channel ID for a transfer from Chain B to Chain A.
Success: Channel {
ordering: Unordered,
a_side: ChannelSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "namada-test.0a4c6786dbda39f786",
version: 0,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-0",
),
connection_id: ConnectionId(
"connection-3",
),
port_id: PortId(
"transfer",
),
channel_id: Some(
ChannelId(
7,
),
),
version: None,
},
b_side: ChannelSide {
chain: BaseChainHandle {
chain_id: ChainId {
id: "namada-test.647287156defa8728c",
version: 0,
},
runtime_sender: Sender { .. },
},
client_id: ClientId(
"07-tendermint-1",
),
connection_id: ConnectionId(
"connection-2",
),
port_id: PortId(
"transfer",
),
channel_id: Some(
ChannelId(
12,
),
),
version: None,
},
connection_delay: 0ns,
}
Run Hermes
Once you run Hermes, it monitors instances via the nodes and relays packets according to monitored events.
hermes -c $HERMES_CONFIG start
Setup nodes for Namada instances
We need a node for each instance to be monitored by Hermes. In this document, we will set up two local nodes for two instances. But, of course, the node doesn't have to be on the same machine as Hermes.
We will explain for two cases:
- Set up nodes to join existing Namada instances
- Set up local Namada instances for testing purposes
Before running the following scripts, you have to build Namada and wasm.
git clone git@github.com:anoma/namada.git
cd namada
git checkout v0.12.2
make build-release
make build-wasm-scripts
export NAMADA_DIR=$(pwd) # if needed
You can use scripts in our Hermes branch to setup these nodes automatically.
Set up nodes to join existing Namada instances
The script join-namada.sh
will set up two nodes for two instances, copy necessary files for Hermes, and make an account for Hermes on each ledger. Also, it will make a Hermes' config file config_for_namada.toml
in the ibc-rs
directory.
The script requires the Namada directory path and chain IDs.
git clone git@github.com:heliaxdev/ibc-rs.git
git checkout $COMMIT # The branch is the same as our Hermes
cd ibc-rs
./scripts/join-namada.sh $NAMADA_DIR $CHAIN_ID_A $CHAIN_ID_B
You need to wait to sync each node with the corresponding instance.
And, you have to transfer NAM token to the relayer account (the script will make an alias relayer
) from the faucet or others on each instance because the fee for IBC transactions should be charged. For example, the following command transfers NAM from the faucet for namada-a instance which is created by the script. You can refer to here about --base-dir
and --ledger-address
.
${NAMADA_DIR}/target/release/namadac transfer \
--base-dir ${IBC_RS}/data/namada-a/.namada \
--source faucet \
--target relayer \
--token nam \
--amount 1000 \
--signer relayer \
--ledger-address 127.0.0.1:26657
After the sync, you can create the channel and start Hermes as we explain above.
# create a channel
hermes -c $HERMES_CONFIG \
create channel $CHAIN_A_ID \
--chain-b $CHAIN_B_ID \
--port-a transfer \
--port-b transfer \
--new-client-connection
# Run Hermes
hermes -c $HERMES_CONFIG start
Each node data and configuration files are in ${IBC_RS}/data/namada-*/.namada
.
In order to close any ledgers setup by the script, one can run
killall namadan
Set up local Namada instances
The script setup-namada.sh
will set up two instances with one validator node, copy necessary files for Hermes, and make an account for Hermes on each ledger. Also, it will make a Hermes' config file config_for_namada.toml
in the ibc-rs
directory.
git clone git@github.com:heliaxdev/ibc-rs.git
git checkout $COMMIT # The branch is the same as our Hermes
cd ibc-rs
./scripts/setup-namada.sh $NAMADA_DIR $CHAIN_ID_A $CHAIN_ID_B
In this case, we don't have to wait for sync. If the relayer account on each instance has enough balance, you can create a channel and start Hermes immediately as we explain above. You find these chain IDs of the instances in the config file config_for_namada.toml
. One can run grep "id" ${HERMES_CONFIG}
.
# create a channel
hermes -c $HERMES_CONFIG \
create channel $CHAIN_A_ID \
--chain-b $CHAIN_B_ID \
--port-a transfer \
--port-b transfer \
--new-client-connection
# Run Hermes
hermes -c $HERMES_CONFIG start
Each node data and configuration files are in ibc-rs/data/namada-*/.namada
.
In order to close any ledgers setup by the script, one can run
killall namadan
Transferring assets over IBC
This will make transfers across chains by Namada CLI. This assumes that a channel has been created and Hermes is running with the proper config.
In order to do this by Namada's ibc-transfer
command, we will need to know the base-dir
and ledger-address
of each instance (and other transfer parameters).
base-dir
is the base directory of each node. If you have used the script, the direcotry is ${IBC_RS}/data/namada-*/.namada
.
ledger-address
is rpc_addr
in the relevant hermes' config files.
One can run grep "rpc_addr" ${HERMES_CONFIG}
.
For the local node ONLY
To find your ledger address for Chain A, you can run the following command
export BASE_DIR_A = "${IBC_RS}/data/namada-a/.namada"
export LEDGER_ADDRESS_A = "$(grep "rpc_address" ${BASE_DIR_A}/${CHAIN_A_ID}/setup/validator-0/.namada/${CHAIN_A_ID}/config.toml)"
`
And then the channel ID for this chain will depend on the order in which one created the channel. Since we have only opened one channel, the channel-id
is channel-0
, but as more are created, these increase by index incremented by 1. Please refer to here.
So one can go ahead and run
export CHANNEL_ID = "channel-0"
Such transfers from Chain A can be achieved by
namadac --base-dir ${BASE_DIR_A}
ibc-transfer \
--amount ${AMOUNT} \
--source ${SOURCE_ALIAS} \
--receiver ${RECEIVER_RAW_ADDRESS} \
--token ${TOKEN_ALIAS} \
--channel-id ${CHANNEL_ID} \
--ledger-address ${LEDGER_ADDRESS_A}
Where the above variables in ${VARIABLE}
must be substituted with appropriate values. The raw address of the receiver can be found by namadaw --base-dir ${BASE_DIR_B} address find --alias ${RECEIVER}
.
E.g
namadac --base-dir ${BASE_DIR_A}
ibc-transfer \
--amount 100 \
--source albert \
--receiver atest1d9khqw36g56nqwpkgezrvvejg3p5xv2z8y6nydehxprygvp5g4znj3phxfpyv3pcgcunws2x0wwa76 \
--token nam \
--channel-id channel-0 \
--ledger-address 127.0.0.1:27657
Namada Testnets
For more context read:
Namada protocol versions
A testnet might deploy different versions of the Namada protocol. To see in-detail what each protocol version includes, refer to the Github changelog, which specifies what changes have been made in between versions.
Report a bug
If you find a bug, please submit an issue with the bug
issue template.
How to join a Namada testnet
- Environment setup
- Pre-genesis validator
- Running your genesis validator
- Running a full node
- Becoming a validator post-genesis
Latest Testnet
The Namada public testnet is permissionless, anyone can join without the authorisation of a centralised party. Expect frequent upgrades (every two weeks).
-
Most recent upgrade:
- From date: 25th of January 2023
- Namada protocol version:
v0.13.3
- Tendermint version:
v0.1.4-abciplus
- CHAIN_ID:
public-testnet-2.1.4014f207f6d
Due to a bug, we released a hotfix. This must be installed and applied before
18:00:00 UTC
. In order to apply it, follow these steps. -
Most recent testnet:
- From date: 24th of January 2023
- Namada protocol version:
v0.13.2
- Tendermint version:
v0.1.4-abciplus
- CHAIN_ID:
public-testnet-2.1.4014f207f6d
Testnet History Timeline
- Namada public testnet 2.1:
- From date: 17th of January 2023
- Namada protocol version:
v0.13.1-hardfork
(hardfork) - Tendermint version:
v0.1.4-abciplus
- CHAIN_ID:
public-testnet-2.0.2feaf2d718c
The above hardfork was meant to take effect on Block Height 37370
, but some issues arose. You can read more here.
-
Namada public testnet 2.0:
- From date: 12th of January 2023
- Namada protocol version:
v0.13.0
- Tendermint version:
v0.1.4-abciplus
- CHAIN_ID:
public-testnet-2.0.2feaf2d718c
-
Namada public testnet 1.1:
- From date: 2nd of January 2023
- Namada protocol version:
v0.12.2
-
Namada public testnet 1:
- Namada protocol version:
v0.12.0
- Tendermint version:
v0.1.4-abciplus
- Genesis time: 20th of December 2022 at 17:00 UTC
- CHAIN_ID:
public-testnet-1.0.05ab4adb9db
- Namada protocol version:
Block explorer
The block explorer is currently in development. The latest version can be found at namada.world
Community
For questions or feedback, feel free to post or comment on Reddit or Github. Don't forget to follow Namada on Twitter for testnet relevant updates and to join Discord for questions and support for validators.
1) Environment setup
If you don't want to build Namada from source you can install Namada from binaries
Export the following variables:
export NAMADA_TAG=v0.13.3
export TM_HASH=v0.1.4-abciplus
Installing Namada
- Clone namada repository and build binaries
git clone https://github.com/anoma/namada && cd namada && git checkout $NAMADA_TAG
- Build binaries
make build-release
- There may be some additional requirements you may have to install (linux):
sudo apt-get update -y sudo apt-get install build-essential make pkg-config libssl-dev libclang-dev -y curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- There may be some additional requirements you may have to install (linux):
Installing Tendermint
- Install the heliaxdev/tendermint fork
The above requires that golang is correctly installed with the correct $PATH setupgit clone https://github.com/heliaxdev/tendermint && cd tendermint && git checkout $TM_HASH make build
- In linux, this can be resolved by
sudo snap install go --channel=1.18/stable --classic
- Copy both the namada and tendermint binaries to somewhere on $PATH (or uselol the relative paths)
- This step may or may not be necessary
- namada binaries can be found in
/target/release
- tendermint is in
build/tendermint
Check ports
- Open ports on your machine:
- 26656
- 26657
- To check if ports are open you can setup a simple server and curl the port from another host
- Inside the namada folder, run
{ printf 'HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n' "$(wc -c < namada)"; cat namada; } | nc -l $PORT`
- From another host run one of the two commands:
nmap $IP -p$PORT
curl $IP:$PORT >/dev/null
Verifying your installation
- Make sure you are using the correct tendermint version
tendermint version
should output0.1.4-abciplus
- Make sure you are using the correct Namada version
namada --version
should outputNamada v0.13.3
2) Generate pre-genesis validator setup
-
Create a pre-genesis file inside the
namada
repository.cd namada export ALIAS="CHOOSE_A_NAME_FOR_YOUR_VALIDATOR" export PUBLIC_IP="LAPTOP_OR_SERVER_IP" namada client utils init-genesis-validator --alias $ALIAS --max-commission-rate-change 0.01 --commission-rate 0.05 --net-address $PUBLIC_IP:26656
- Expect the message
Pre-genesis TOML written to .namada/pre-genesis/[your-alias]/validator.toml
- Expect the message
- This will generate a folder inside
namada/.namada
.cat namada/.namada/pre-genesis/$ALIAS/validator.toml
2.1) Submitting the config
If you want to be a genesis validator for the testnet, please make a pull request to https://github.com/anoma/namada-testnets adding your validator.toml file to the relevant directory (e.g. namada-public-testnet-2
for the second public testnet), renaming it to $alias.toml
. e.g. if you chose your alias to be "bertha", submit the file with the name bertha.toml
. You can see what an example PR looks like here.
2.2) Wait for the CHAIN_ID
Wait until corresponding CHAIN_ID
has been distributed.
3) (OPTIONAL) Reset your validator node
- You can skip to 3.1 if you don't need to reset the ledger state
- This is the right time to save any logs file you want to share with us!
- Save your
pre-genesis
folder in the ledger base directorymkdir backup-pregenesis && cp -r .namada/pre-genesis backup-pregenesis/
- Delete ledger base directory (WARNING: THIS WILL ALSO DELETE YOUR VALIDATOR KEYS, DO NOT RUN UNLESS YOU'VE BACKED IT UP)
rm -rf .namada
- Check that namada and tendermint binaries are correct (see step 1)
- If you have you are a genesis validator from the previous testnet continue with the instructions below otherwise go to step
3.1
- Create a
.namada
foldermkdir .namada
mkdir .namada/pre-genesis
- Copy the backuped file back to
.namada/pre-genesis
foldercp -r backup-pregenesis/* .namada/pre-genesis/
3.1) Run your node as a genesis validator
- Wait for the genesis file to be ready,
CHAIN_ID
. - Join the network with the
CHAIN_ID
export CHAIN_ID="public-testnet-2.1.4014f207f6d" namada client utils join-network \ --chain-id $CHAIN_ID --genesis-validator $ALIAS
- Start your node and sync
NAMADA_TM_STDOUT=true namada node ledger run
- if you want more logs
NAMADA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run
- if you want to save logs to a file
TIMESTAMP=$(date +%s)
NAMADA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run &> logs-${TIMESTAMP}.txt
tail -f -n 20 logs-${TIMESTAMP}.txt
(in another shell)
- If started correctly you should see a the following log:
[<timestamp>] This node is a validator ...
4) Run your full node as a user
- Wait for the genesis file to be ready, you will receive a
$CHAIN_ID
. - Join the network with the
CHAIN_ID
export CHAIN_ID="public-testnet-2.1.4014f207f6d"
namada client utils join-network --chain-id $CHAIN_ID
- Start your node and sync
NAMADA_TM_STDOUT=true namada node ledger run
- if you want more logs
NAMADA_LOG=debug ANOMA_TM_STDOUT=true namada node ledger run
- if you want to save logs to a file
TIMESTAMP=$(date +%s)
ANOMA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run &> logs-${TIMESTAMP}.txt
tail -f -n 20 logs-${TIMESTAMP}.txt
(in another shell)
5) Become a validator post genesis
After genesis, you can still join the network as a user and become a validator through self-bonding.
After following step 4), create a user account through the following command
namada wallet address gen --alias my-account
Now choose a name for your validator:
export VALIDATOR_ALIAS="your-validator-name"
A validator account requires additional keys compared to a user account, so start by initialising a validator account:
namada client init-validator \
--alias $VALIDATOR_ALIAS \
--source my-account \
--commission-rate <enter-your-commission-rate> \
--max-commission-rate-change <enter-decimal-rate>
Then ensure you have enough NAM in order to self bond. Each voting power requires 1000 NAM, and you must be in the top 120 validators in terms of voting-power in order to become an active validator. You can see other validators' voting power through:
namada client bonded-stake
Faucet
In order to gain more NAM, the following command can be run:
namadac transfer \
--token NAM \
--amount 1000 \
--source faucet \
--target $VALIDATOR_ALIAS \
--signer $VALIDATOR_ALIAS
Note: A maximum amount of 1000 NAM can be sourced from the faucet per transaction, so to get more, run this multiple times
namada client bond \
--validator $VALIDATOR_ALIAS \
--amount <enter-amount>
The PoW Solution on Namada
In order to combat the "costlessness of blockspace" problem with a testnet, and hence prevent DOS attacks as a result, when a Namada account does not have the required fees to pay for a transaction, the user must complete a Proof of Work challenge. The difficulty of this challenge is a parameter set by governance, and will dictate the (average) computational expenditure needed in order to complete the challenge.
In order to avoid having to complete endless Proof of Work challenges, we recommend using the faucet to fund the implicit account as one of a user's first transactions:
namada client transfer \
--source faucet \
--target my-key \
--token NAM \
--amount 1000 \
--signer my-key
which will allow my-key
to sign future transactions and pay for any further fees.
The PoW Faucet
The Faucet on Namada will always require users to complete a PoW challenge, regardless of the balance of the implicit account.
Upgrades
This page covers all installation steps required by various upgrades to testnets.
Latest Upgrade
Hotfix for Testnet public-testnet-2.1.4014f207f6d
25/01/2023
At around 06:15 UTC 25/01/2023, a validator with very little stake was scheduled to become part of the active validator set. From this tx, we discovered a conversion bug between the Namada state machine and Tendermint, which lead to a crash in the node. A patch was released v0.13.3 in order to deal with this issue.
In order to successfully update your node, please follow the below steps:
- Validators need to stop their node (
^c
) - Upgrade their version to v0.13.3
- Restart their node with the following
--time
argument:
NAMADA_TM_STDOUT=true namadan ledger run --time 2023-01-25T21:00:00Z
23/01/2023
A new testnet was released before the fortnightly testnet release schedule due to the below hardfork not working as intended. Follow the steps in setting up a new testnet
Hardfork v0.13.1
This hardfork is set to be instantiated at block height 37370
, which is predicted to occur at around 17.00 UTC on 18/01/2023.
Requirements to do before 17.00 UTC 18/01/2023
In order to install this upgrade, a user or validator must
-
Download the binaries or install them from source
-
Ensure the versions are correct, such that
<PATH_TO_BINARY>/namada --version
isv0.13.1-hardfork
-
Interrupt the
namada ledger
by the interrupt command^C
-
Install the binaries onto
$PATH
(this depends on your machine). This must be done after interrupting the ledger, as otherwise an error is likely to be thrown. -
As soon as possible, restart the ledger by running
NAMADA_TM_STDOUT=true namada node ledger run
The ledger will then update correctly at the correct height. In order to ensure a smooth fork, please do this as soon as possible.
Troubleshooting
This document addresses common issues users on Namada have faced, and what to do to resolve them.
Installing Namada from source
Not enough RAM
Building binaries locally is a computationally heavy task and will put your computer to the test. The compilation usually requires at least 16 GB of RAM and depending on the optimisation of your machine, could require slightly more (for some machines slightly less). For this reason, compilation can sometimes fail and will require.
The error src/apps/namada lib could not compile due to previous errors. Exited with exit code:
is a common error that can sometimes mean your computer ran out of memory when compiling. To resolve this, I have found closing all other applications and recompiling once or twice will do the trick. Otherwise more RAM will be needed.
Compiling for the first time
Compilation errors due to missing library installations when building the binaries for the first time can be a common problem.
Linker "CC" not found
If one runs into the error
Entering directory '/root/namada/wasm/wasm_source'
RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown --target-dir 'target' --features tx_bond && \
cp "./target/wasm32-unknown-unknown/release/namada_wasm.wasm" ../tx_bond.wasm
Compiling proc-macro2 v1.0.46
Compiling quote v1.0.21
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: could not compile `quote` due to previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `proc-macro2` due to previous error
It may be resolved by running
sudo apt install build-essential
Another solution can sometimes be installing libcland-dev
. This can be achieved through:
sudo apt-get update -y
sudo apt-get install -y libclang-dev
WASM32-unknown-unknown
Another issue the compiler may run into is that it cannot find the wasm32-unknown-unknown target.
error[E0463]: can't find crate for `core`
|
= note: the `wasm32-unknown-unknown` target may not be installed
= help: consider downloading the target with `rustup target add wasm32-unknown-unknown`
error[E0463]: can't find crate for `compiler_builtins`
For more information about this error, try `rustc --explain E0463`.
error: could not compile `cfg-if` due to 2 previous errors
This issue can be resolved by running
rustup target add wasm32-unknown-unknown
(Yes the name of the target is wasm32-unknown-unknown
. This is not the compiler unable to tell which version/release it is).
Validator Troubleshooting
Missed pre-genesis
If you missed setting up as a validator pre-genesis, this means you must set up to become one post-genesis. It is not possible to add pre-genesis validators once the chain has been launched (as by definition). Instead, any full-node can become a validator through self-bonding NAM tokens.
Tendermint
When facing tendermint issues as a validator, the most common cause of the issue is that we are running the wrong version of tendermint. Keep an eye on the testnet docs here
Note that the common debug statement Error reconnecting to peers
does not mean that your node is not working properly. Instead, it means there exists at least one validator on the network not working properly. To check whether this is a problem on your end, note the block height and see if it corresponds to the blockheight at https://namada.world
Namada FAQ
Q: How do I join as a validator post-genesis?
A: Joining as a validator post genesis can be done following these instructions
Q: How do I use the Faucet?
A: The faucet can be used to get a various list of tokens from the following command:
namadac transfer \
--token NAM \
--amount 1000 \
--source faucet \
--target [your-established-account-alias] \
--signer [your-established-account-alias]
Q: Where can I see the available tokens on the Faucet?
A: The following list of tokens are available to withdraw from the faucet:
NAM, DOT, ETH, BTC
There are a few more, but we leave it to you as a challenge to find out which these are :thinking_face:
HINT: namadac balance
Q: How do I use the Ethereum Bridge?
A: The Ethereum Bridge is not yet implemented as of 0.12.0. Keep an eye on the Changelog :eyes: to see when it will be officially released.
Q: How can I make an IBC transfer?
A: Same as Ethereum Bridge, so keep an eye on the Changelog!
Q: What requirements do I need to be a User/Validator on Namada
A: See hardware requirements
In order to build binaries from source, at least 16GB RAM will be required