Delegating with the Casper Client
This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.
Prerequisites
- You meet all prerequisites listed here, including having a valid
node-address
and the Casper command-line client - You have previously installed a smart contract to a Casper network
- Acquiring a Validator's Public Key
Acquiring a Validator's Public Key
This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the delegation request.
Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process.
The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set.
Sending the Delegation Request
There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the delegate
entry point from the system auction contract. The second method involves building the delegate.wasm
from the casper-node
repository and installing it on the network.
We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.
The minimum amount to delegate is 500 CSPR (500,000,000,000 motes).
Method 1: Delegating with the System Auction Contract
This method calls the existing delegate
entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.
casper-client put-deploy \
--node-address <HOST:PORT> \
--secret-key <PATH> \
--chain-name <CHAIN_NAME> \
--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
--session-hash <SESSION_HASH> \
--session-entry-point delegate \
--session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
--session-arg "amount:u512='<AMOUNT_TO_DELEGATE>'" \
--session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
node-address
- An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777secret-key
- The file name containing the secret key of the account paying for the Deploychain-name
- The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-testpayment-amount
- The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1session-hash
- Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
- Testnet:
hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
- Mainnet:
hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
session-entry-point
- Name of the entry point that will be used when calling the contract
The delegate
entry point expects three arguments:
validator
: The hexadecimal public key of the validator receiving the delegated tokensamount
: The number of tokens to be delegateddelegator
: The hexadecimal public key of the account delegating tokens to a validator. This key must match the secret key that signs the delegation
The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.
Calling the delegate
entry point on the auction contract has a fixed cost of 2.5 CSPR.
Example:
This example shows an account delegating 500 CSPR:
casper-client put-deploy \
--node-address http://65.21.75.254:7777 \
--chain-name casper-test \
--secret-key ~/KEYS/secret_key.pem \
--payment-amount 2500000000 \
--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
--session-entry-point delegate \
--session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
--session-arg "amount:u512='500000000000'" \
--session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"
Next, confirm the delegation.
Method 2: Delegating with Compiled Wasm
Another way to send a delegation is to compile the delegate.wasm
and send it to the network via a deploy. Here are the steps to compile the contract yourself.
Building the delegation Wasm
Obtain the delegate.wasm
by cloning the casper-node repository.
git clone https://github.com/casper-network/casper-node
Prepare the Rust environment and then build the contracts using the Makefile provided in the repository.
cd casper-node
make setup-rs
make build-contracts-rs
Once you build the contracts, you can use the delegate.wasm
to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: target/wasm32-unknown-unknown/release/
.
ls target/wasm32-unknown-unknown/release/delegate.wasm
Sending the delegation request
In this example, we use the Casper client to send a deploy containing the delegate.wasm
to the network to initiate the delegation process.
casper-client put-deploy \
--node-address <HOST:PORT> \
--secret-key <PATH> \
--chain-name <CHAIN_NAME> \
--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
--session-path <PATH_TO_WASM>/delegate.wasm \
--session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
--session-arg "amount:u512='<AMOUNT_TO_DELEGATE>'" \
--session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
node-address
- An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777secret-key
- The file name containing the secret key of the account paying for the Deploychain-name
- The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-testpayment-amount
- The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1session-path
- The path to where thedelegate.wasm
is located
The delegate
entry point expects three arguments:
validator
: The hexadecimal public key of the validator receiving the delegated tokensamount
: The number of tokens to be delegateddelegator
: The hexadecimal public key of the account delegating tokens to a validator. This key must match the secret key that signs the delegation
The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.
Example:
This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the delegate entry point.
casper-client put-deploy \
--node-address http://65.21.75.254:7777 \
--chain-name casper-test \
--secret-key ~/KEYS/secret_key.pem \
--payment-amount 20000000000 \
--session-path ~/delegate.wasm \
--session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
--session-arg "amount:u512='500000000000'" \
--session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"
Next, confirm the delegation.
Confirming the Delegation
A Casper network maintains an auction where validators bid on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:
- Your delegation is part of the bid to the auction
- The validator is part of the active validator set
Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:
casper-client get-auction-info \
--node-address http://<peer-ip-address>:7777
Request fields:
node-address
- An IP address of a node on the network
The get-auction-info
call will return all the bids currently in the auction contract and the list of active validators for 4
future eras from the present era.
Below is a sample output:
"bids": [
{
"bid": {
"bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",
"delegation_rate": 1,
"delegators": [
{
"bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",
"delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",
"public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",
"staked_amount": "1"
},
{
"bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",
"delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",
"public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",
"staked_amount": "478473232415318176495746923"
}
],
"inactive": false,
"staked_amount": "493754513995516852173468935"
},
"public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"
},
The delegation request has been processed successfully if your public key and associated amount appear in the bid
data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status.
Checking Validator Status
The auction maintains a field called era_validators
, which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the PublicKeys
of the active validators for that era, along with their stake in the network.
If a validator is part of the set, its public key will be in the era_validators
field as part of the Auction
data structure. We can use the Casper command-line client to create an RPC request to obtain auction information and assert that the selected validator is part of the active validator set.
casper-client get-auction-info \
--node-address http://<peer-ip-address>:7777
Request fields:
node-address
- An IP address of a node on the network
Important Response fields:
In the response, check the "auction_state"."era_validators"
structure, which should contain the public key of the selected validator for the era in which the validator will be active.
Below is an example of the era_validators
structure:
"block_height":105,
"era_validators":[
{
"era_id":9,
"validator_weights":[
{
"public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",
"weight":"648151805935226166098427654"
},
{
"public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",
"weight":"648151805938466925128109996"
},
{
"public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",
"weight":"648151805935226166098427656"
},
{
"public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",
"weight":"648151805938466925128109998"
},
{
"public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",
"weight":"648151805938466925128110000"
}
]
},
In the above example, we see the public keys of the active validators in Era 9
.
Note: Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request.