Some developers may want to deploy their own BitShares blockchain locally for governance, and speed reasons. This section explains how to prepare the private testnet environment and what steps to take to be a block producing node (witness node).

For the private testnet, you MUST create and set up own genesis file and also, set parameters’ values into a database configuration file (config.ini). You should not connect to the mainnet nor the public testnet.

Let’s get started, open a new command line interface (CLI) window and go to a directory you want to download the testnet branch files. And run the following command lines. In this example, you create a bitshares-testnet directory.

After you download a testnet branch files in a bitshares-testnet directory, let’s build the programs. Run the following commands. This command will create two program files (witness_node and cli_wallet).

cmake.make

You will find the compiled program files in the below folders.

program name

directory and folder

witness_node

../bitshares-testnet/programs/witness_node/

cli_wallet

../bitshares-testnet/programs/cli_wallet/

The above installation steps are the same with the public testnet installation.

The genesis file is the initial state of the network. We want to create a subdirectory named genesis and create a file within it named my-genesis.json. In the private testnet, we have to generate each active and owner private key. Here is a sample private testnet genesis file template, copy and past into your my-genesis.json file.

The chain ID is a hash of the genesis state. All transaction signatures are only valid for a single chain ID. So editing the genesis file will change your chain ID, and make you unable to sync with all existing chains (unless one of them has exactly the same genesis file you do).

For testing purposes, the --dbg-init-key option will allow you to quickly create a new chain against any genesis file, by replacing the witnesses’ block production keys.

Default Genesis

The graphene code base has a default genesis block integrated that has all witnesses, committee members and funds and a single account called nathan available from a single private key:

Deleting caches will reset all cmake variables, so if you have used instructions like build-ubuntu which tells you to set other cmake variables, you will have to add those variables to the cmake line above.

Tip

Embedding the genesis copies the entire content of genesis.json into the witness_node binary, and additionally copies the chain ID into the cli_wallet binary. Embedded genesis allows the following simplifications to the subsequent instructions:

You do not need to specify the my-genesis.json file on the witness node command line, or in the witness node configuration file.

You do not need to specify the chain ID on the cli_wallet command line when starting a new wallet.

Embedded genesis is a feature designed to make life easier for consumers of pre-compiled binaries, in exchange for slight, optional complication of the process for producing binaries.

witness_node startup will create a witness_node_data_dir as a default data directory. And you will find a configuration config.ini file in the data directory.

Note

If you want to use a different folder name and directory for the data, you have to use --data-dir option in a startup command line and set your data directory folder path, every time when you start the witness_node. Otherwise, the witness_node_data_dir folder and another config.ini file will be created (if it’s not existed) and the witness_node will use the data directory.

# Endpoint for P2P node to listen onp2p-endpoint=127.0.0.1:11010# Endpoint for websocket RPC to listen onrpc-endpoint=127.0.0.1:11011###--> For Private Testnet, add a seed node of your own# P2P nodes to connect to on startup (may specify multiple times)# seed_node =###--> For Private Testnet, this value set needs to overwrite default checkpoint.checkpoint=[]# Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints.## checkpoint = ["22668518", "0159e4e600cb149e22ef960442ca331159914617"]# File to read Genesis State fromgenesis-json=genesis/my-genesis.json# ==============================================================================# witness plugin options# ==============================================================================# Enable block production, even if the chain is stale.enable-stale-production=false# Percent of witnesses (0-100) that must be participating in order to produce blocks# required-participation = 33# If start a private testnet with the default number 33, the node won't produce blocks####--> For Private testnet, set 0required-participation=0###--> For Private Testnet, set own key pairs# Tuple of [PublicKey, WIF private key] (may specify multiple times)private-key=["-- generated key --","5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"]# ID of witness controlled by this node (e.g. "1.6.5", quotes are required, may specify multiple times)# witness-id =witness-id="1.6.1"witness-id="1.6.2"witness-id="1.6.3"witness-id="1.6.4"witness-id="1.6.5"witness-id="1.6.6"witness-id="1.6.7"witness-id="1.6.8"witness-id="1.6.9"witness-id="1.6.10"witness-id="1.6.11"

This authorizes the witness_node to produce blocks on behalf of the listed witness-id’s, and specifies the private key needed to sign those blocks. Normally each witness would be on a different node, but for the purposes of this testnet, we will start out with all witnesses signing blocks on a single node.

Note

It’s important to activate a 2/3 majority of the witnesses defined in the genesis file.

If you want to use a different folder name and directory for the data, you have to use --data-dir in a startup command line and set your data directory folder path, every time you start the witnesses-node. Otherwise, the witness_node_data_dir folder will be created and be used to generate a default config.ini file to start the witness_node!!

Note

We did not set --genesis-jsonmy-genesis.json in a command line above. Because we set the genesis file name my-genesis.json for the private testnet in a configuration config.ini file.

The --enable-stale-production flag tells the witness_node to produce on a chain with zero blocks or very old blocks. We specify the --enable-stale-production parameter on the command line as we will not normally need it (although it can also be specified in the configuration file).

(When we started a witness_node for a short time to create a data directory, we also obtained a chain ID.)

The chain ID (i.g., blockchain id) is a hash of the genesis state. All transaction signatures are only valid for a single chain ID. So editing the genesis file will change your chain ID, and make you unable to sync with all existing chains (unless one of them has exactly the same genesis file you do).

For testing purposes, the --dbg-init-key option will allow you to quickly create a new chain against any genesis file, by replacing the witnesses’ block production keys.

Important

Each wallet is specifically associated with a single chain, specified by its chain ID. This is to protect the user from (e.g., unintentionally) using a testnet wallet on the real chain.

The chain ID is printed at witness node startup. It can also be obtained by using the API to query a running witness node with the get_chain_properties API call:

We are now ready to connect a new wallet to your private testnet witness node. You must specify a chain ID and server. Keep your witness node running. Open another Command Prompt window run this command (a blank username and password will suffice):

Make sure to replace the above chain ID (i.e., blockchain id) cf307110d0...36aa74b with your chain ID reported by your witness_node. The chain-id passed to the CLI-wallet needs to match the id generated and used by the witnessnode.

--server-rpc-endpoint - The port number is how you defined (opened) --rpc-endpoint for the witness_node.

If you receive the new>>> prompt, it means your wallet has been executed successfully.

nathan happens to be the account name defined in the genesis file. If you had edited your my-genesies.json file just after it was created, you could have put a different name there. Also, note that 5KQwrPbwdL...P79zkvFD3 is the private key defined in the config.ini file.

Now we have the private key imported into the wallet but still no funds assocciated with it. Funds are stored in genesis balance objects. These funds can be claimed, with no fee, using the import_balance command:

As a result, we have one account (named nathan) imported into the wallet and this account is well funded with BTS as we have claimed the funds stored in the genesis file. You can view this account information and the balance by using the below commands:

We will now create another account (named alpha) so that we can transfer funds back and forth between nathan and alpha.

Creating a new account is always done by using an existing account - we need it because someone (i.e. the registrar) has to fund the registration fee. Also, there is the requirement for the registrar account to have a lifetime member (LTM) status. Therefore we need to upgrade the account nathan to LTM, before we can proceed with creating other accounts.

upgrade_account nathan true
get_account nathan

In the response, next to membership_expiration_date you should see 1969-12-31T23:59:59. If you get 1970-01-01T00:00:00 something is wrong and nathan has not been successfully upgraded.

We can now register an account by using nathan as registrar. But first we need to generate the public key for the new account. We do it by using the suggest_brain_key command.

If you want to set up a second node (with the same genesis file) and connect it to the first node by using the p2p-endpoint of the first node as the seed-node for the second. The below are example settings.