Set Up a Private Casper Network
Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.
Prerequisitesβ
Follow these guides to set up the required environment and user accounts.
- Setting up the Casper client
- Setting up the client for interacting with the network
- Setting up an account
Step 1. Setting up a Validator Nodeβ
A Casper node is a physical or virtual device participating in the Casper network. You need to set up several validator nodes on your private network. An operator who has won an auction bid will be a validator for the private network.
Use the below guides to set up and manage validator nodes.
- Casper node setup - GitHub guide: A guide to configuring a system with the new Rust node to operate within a network.
- Basic node setup tutorial: A guide on using the
casper-node-launcher
, generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes. - Set up Mainnet and Testnet validator nodes: A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes.
Use these FAQ collections for tips and details for validators.
Step 2. Setting up the Directoryβ
Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes.
- Go through the file location section to understand how directories are created and managed in a Casper private network.
- Refer to the setting up a new network guide to identify the required configuration files to set up a genesis block.
Step 3. Configuring the Genesis Blockβ
A Casper private network contains a different set of configurations when compared to the public network. The chainspec.toml
file contains the required configurations for the genesis process in a private network.
You should add the configuration options below to the chainspec.toml
file inside the private network directory.
Unrestricted transfers configurationβ
This option disables unrestricted transfers between regular accounts. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators.
[core]
allow_unrestricted_transfers = false
In contrast, users in the public network can freely transfer funds to different accounts.
A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:
[core]
allow_unrestricted_transfers = false
compute_rewards = false
allow_auction_bids = false
refund_handling = { type = "refund", refund_ratio = [1, 1] }
fee_handling = { type = "accumulate" }
administrators = ["ADMIN_PUBLIC_KEY"]
Refund handling configurationβ
This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user.
A refund_ratio
is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the refund_ratio
is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user.
[core]
refund_handling = { type = "refund", refund_ratio = [1, 1] }
After deducting the gas fee, the distribution of the remaining payment amount is handled based on the fee_handling configuration.
The default configuration for a public chain, including the Casper Mainet, looks like this:
[core]
refund_handling = { type = "refund", refund_ratio = [0, 100] }
The refund variant with refund_ratio
of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return.
Fee handling configurationβ
This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed.
Set up the configuration as below:
[core]
fee_handling = { type = "pay_to_proposer" }
The fee_handling
configuration has three variations:
pay_to_proposer
: The rest of the payment amount after deducing the gas fee from a refund is paid to the block's proposer.burn
: The tokens paid are burned, and the total supply is reduced.accumulate
: The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled.
Auction behavior configurationβ
A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set.
Use the configuration below to limit the auction validators:
[core]
allow_auction_bids = false
Other configurations related to the auction:
allow_auction_bids
- if this option is set to false thenadd_bid
anddelegate
options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to anAuctionBidsDisabled
error.core.compute_rewards
- if this option is set to false, then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids.
In a public network, allow_auction_bid
is set to true, which allows bidding for new entries and validator nodes.
Step 4. Configuring the Administrator Accountsβ
An administrator is mandatory for a private network since it manages all the other validator accounts. There should be at least one administrator account configured within a network to operate it as a private network
. You can create new administrators and rotate the validator set in a single configuration update. The operator must first ensure the global_state.toml
file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only the administrator accounts can hold and distribute token balances.
Configuring administrator accountsβ
Use this configuration option in the chainspec.toml
to add administrator accounts to the private network:
[core]
administrators = ["NEW_ACCOUNT_PUBLIC_KEY"]
Note: Regular accounts are not allowed to manage their associated keys on a private network.
Generating new administrator accountsβ
Use the command below to generate new administrator accounts in your private network. This generates the contents of a global_state.toml
with the entries required to create new administrator accounts at the upgrade point.
global-state-update-gen \
generate-admins --data-dir $DATA_DIR/global_state \
--state-hash $STATE_ROOT_HASH \
--admin $PUBLIC_KEY_HEX, $BALANCE
NEW_PUBLIC_KEY
- Public key of the administrator in a hex format.NEW_BALANCE
- Balance for the administratorβs main purse.DATA_DIR
- Path to the global state directory.STATE_ROOT_HASH
- State root hash, taken from the latest block before an upgrade.
Managing accounts and smart contractsβ
Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in Casper node's private chain control management file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key.
Use this command to generate these contracts:
make build-contracts-rs
Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:
- To disable a contract: Execute the
disable_contract.wasm
withcontract_hash
andcontract_package_hash
as parameters. - To enable a contract: Execute the
enable_contract.wasm
withcontract_hash
andcontract_package_hash
as parameters. - To disable an account: Execute
set_action_thresholds.wasm
with argumentdeploy_threshold:u8='255'
andkey_management_threshold:u8='0'
. - To enable an account: Execute
set_action_thresholds.wasm
withdeploy_threshold:u8='1'
set to 1 andkey_management_threshold:u8='0'
.
Step 5. Starting the Casper Nodeβ
After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:
sudo systemctl start casper-node-launcher
Refer to the Casper node setup GitHub guide to know more details about configuring a new node to operate within a network.
Additionally, refer to the casper-node-launcher to check whether the installed node binaries match the installed configurations by comparing the version numbers.
Step 6. Rotating the Validator Accountsβ
You need to go through setting up a validator node guide before starting this section.
Use this command to create content in the global_state.toml
file to rotate the validator set. Specify all the current validators, their stakes, and new accounts.
global-state-update-gen \
validators --data-dir $DATA_DIR/global_state \
--state-hash $STATE_ROOT_HASH \
βvalidator $PUBLIC_KEY_HEX,$STAKE,$OPTIONAL_DELEGATION_RATE
To rotate the validators set, perform a network upgrade with a global_state.toml
with new entries generated by the global-state-update-gen
command.
You can find more details on enabling new validators in the joining a running network guide. The guide explains how to join the network and provide additional security to the system.
Step 7. Testing the Private Networkβ
We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer.
Sample configuration filesβ
Here are sample configurations that can be adapted for testing:
- A chainspec template that is specific to the customer's private chain.
- An accounts template with one administrator in the
administrators
settings.
Specifying IP addressesβ
Here is an example set of IP addresses in use:
http://18.224.190.213:7777
http://18.188.11.97:7777
http://18.188.206.170:7777
http://18.116.201.114:7777
Setting up the nodeβ
Set up the node address, chain name, and the administrator's secret key.
export NODE_ADDR=http://18.224.190.213:7777
export CHAIN_NAME="private-test"
This testing example will also use an alice/secret_key.pem
file, a secret key generated through the keys generation process. Alice is a regular user in this testing example.
Funding Alice's accountβ
The following command transfers tokens to Alice's account.
casper-client \
transfer \
-n $NODE_ADDR \
--chain-name $CHAIN_NAME \
--secret-key admin/secret_key.pem \
--session-account=$(<admin/public_key_hex) \
--target-account=$(<alice/public_key_hex) \
--amount=100000000000 \
--payment-amount=3000000000 \
--transfer-id=123
To check the account information, use this command:
casper-client get-account-info -n $NODE_ADDR
--public-key alice/public_key.pem
Adding a bid as Aliceβ
The following command attempts to add an auction bid on the network. It should return ApiError::AuctionError(AuctionBidsDisabled) [64559]
.
casper-client \
put-deploy \
-n $NODE_ADDR \
--chain-name $CHAIN_NAME \
--secret-key alice/secret_key.pem \
--session-path add_bid.wasm \
--payment-amount 5000000000 \
--session-arg "public_key:public_key='$(<alice/public_key_hex)'" \
--session-arg "amount:u512='10000'" \
--session-arg "delegation_rate:u8='5'"
# Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"
We should get a similar error for the delegate entry point.
Disabling Alice's accountβ
The following command disables Alice's account. In this case, executing deploys with Alice's account will not be successful.
casper-client \
put-deploy \
-n $NODE_ADDR \
--chain-name $CHAIN_NAME \
--secret-key admin/secret_key.pem \
--session-account=alice/public_key_hex
--session-path set_action_thresholds.wasm \
--payment-amount=2500000000 \
--session-arg "key_management_threshold:u8='0'" \
--session-arg "deploy_threshold:u8='1'"
Enabling Alice's accountβ
The following command enables Alice's account. In this case, executing deploys with Alice's account will be successful.
casper-client \
put-deploy \
-n $NODE_ADDR \
--chain-name $CHAIN_NAME \
--secret-key admin/secret_key.pem \
--session-account=alice/public_key_hex
--session-path set_action_thresholds.wasm \
--payment-amount=2500000000 \
--session-arg "key_management_threshold:u8='255'" \
--session-arg "deploy_threshold:u8='255'"
Enabling a contractβ
The following command enables a contract using its hash.
casper-client \
put-deploy \
-n $NODE_ADDR \
--chain-name $CHAIN_NAME \
--secret-key admin/secret_key.pem \
--session-account=$(<alice/public_key_hex) \
--session-path enable_contract.wasm \
--payment-amount 3000000000 \
--session-arg "contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'" \
--session-arg "contract_hash:account_hash='account-hash-$CONTRACT_HASH'"
Disabling a contractβ
The following command disables a contract using its hash. Executing this contract using CONTRACT_HASH
again should fail.
casper-client \
put-deploy \
-n $NODE_ADDR \
--chain-name $CHAIN_NAME \
--secret-key admin/secret_key.pem \
--session-account=$(<alice/public_key_hex) \
--session-path disable_contract.wasm \
--payment-amount 3000000000 \
--session-arg "contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'" \
--session-arg "contract_hash:account_hash='account-hash-$CONTRACT_HASH'"
Alice needs a container access key for the contract package in her named keys.
Verifying seigniorage allocationsβ
Seigniorage allocations should be zero at each switch block. This is the related configuration:
[core]
compute_rewards = false
Validator stakes should not increase on each switch block. Run this command to verify this:
casper-client get-era-info -n $NODE_ADDR -b 153
The total supply shouldn't increase, and the validator's stakes should remain the same.
Rotating validatorsβ
The following command rotates the validator set. Perform a network upgrade with a global_state.toml
with the new entries generated by the global-state-update-gen
command.
global-state-update-gen validators \
--data-dir $DATA_DIR \
--state-hash $STATE_ROOT_HASH \
--validator NEW_PUBLIC_KEY,NEW_STAKE \
--validator NEW_PUBLIC_KEY2,NEW_STAKE2
Adding new administratorsβ
The following command produces the administrator content in the global_state.toml
file.
global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH
Remember that new administrators can be created, and the validator set can also be rotated in a single update.
The chainspec.toml
file should contain the following entries that include new administrators as well as existing ones for an upgrade:
[core]
administrators = ["NEW_PUBLIC_KEY"]
After this step, the private network would be ready for use.