How it works · Set up · Settings · What is tested · Known issues
These scripts prepare an Ubuntu machine to run a private XDC network. They install what the build needs, build XDPoSChain, check your network settings and start each node.
Caution
These scripts have not been run end to end. The tests use a stand-in for the node program, so try them on a disposable machine first. See What is tested.
Warning
If you started a node with an older node.sh, stop it. That version opened RPC to every address, including the personal API, with its wallet unlocked by an empty password. Anyone who could reach the port could use that wallet. Treat its private key as exposed, and don't use it again.
flowchart LR
S[setup.sh<br/>installs and builds] --> C[config.py<br/>checks config.yml]
C --> P[Puppeth<br/>you create the genesis]
P --> N[node.sh<br/>starts each node]
| File | Role |
|---|---|
setup.sh |
Installs packages and Go 1.23.12, verifies the download, then builds XDPoSChain v2.7.1 |
config.yml |
Chain name, consensus, block time, masternodes, funding and network ID |
config.py |
Checks the settings and prints them for the other steps |
node.sh |
Imports a wallet, initialises the chain data and starts one node |
| Item | Requirement |
|---|---|
| Operating system | Ubuntu, 64-bit, x86 or ARM |
| Memory | 16 GB |
| Storage | 500 GB minimum |
git clone https://github.com/CoinClubQuincy/PrivateXDCNode_SetupScript.git
cd PrivateXDCNode_SetupScript
# Edit config.yml with your own addresses first
DRY_RUN=1 ./setup.sh # shows every command without running it
./setup.shsetup.sh uses sudo to install packages. It doesn't upgrade or remove anything. It installs Go and XDPoSChain under your home folder, or under INSTALL_DIR if you set it.
Then create the network:
-
Run
python3 config.py summary, and enter those values in~/XDPoSChain/build/bin/puppeth. Puppeth asks its questions interactively, so this step is manual. -
Save the genesis file as
genesis/genesis.json. -
Create a bootnode key and start the bootnode, both with
~/XDPoSChain/build/bin/bootnode. -
Put your settings in
.env, which git ignores:BOOTNODES="enode://your-bootnode-id@your-bootnode-ip:30301" PRIVATE_KEY_1="your-first-node-key"
Then run
chmod 600 .env.node.shruns this file as shell code and won't start if other accounts can read or change it. -
Run
./node.sh 1, then the same for each other node.
The key is only needed the first time a node starts. node.sh creates a random wallet password in .pwd, readable only by you. Keep that file, because the imported wallet needs it.
node.sh starts each node in the background. Logs and the process ID are in nodes/<number>/.
| Node | P2P port | RPC port | WebSocket port |
|---|---|---|---|
| 1 | 30303 | 8545 | 8555 |
| 2 | 30304 | 8546 | 8556 |
RPC and WebSocket listen on 127.0.0.1 unless you set RPC_ADDR. Open only the P2P port to the other nodes.
Each node holds an unlocked wallet, so anyone who can call eth_sendTransaction can spend from it. On any other address, node.sh therefore only offers net, web3 and XDPoS, and you need RPC_API=net,web3,XDPoS in .env. To use eth from another machine, use an SSH tunnel, or a proxy that blocks sending transactions. Put a firewall in front of the port either way.
.env setting |
Default | Meaning |
|---|---|---|
BOOTNODES |
Required | Bootnode enode URLs |
PRIVATE_KEY_<number> |
Required at first start | Wallet key for that node |
RPC_ADDR |
127.0.0.1 |
Address RPC and WebSocket listen on |
RPC_API |
eth,net,web3,XDPoS |
APIs offered. Only net,web3,XDPoS are allowed away from the local machine |
ETHSTATS |
Off | Stats server to report to. It goes on the node's command line, so other accounts on the machine can see its secret in ps |
PROJECT_DIR |
~/XDPoSChain |
Where XDPoSChain was built |
GENESIS_FILE |
./genesis/genesis.json |
Genesis file to start from |
python3 config.py check reports every problem in config.yml. The addresses in the file are samples, so replace them with your own. Nodes ships as zero addresses, which the check refuses until you fill them in.
| Setting | Meaning | Checked |
|---|---|---|
Chain_Name |
Name of the chain | Letters, numbers and underscores |
Consensus |
1 Ethash, 2 Clique, 3 XDPoS | One of the three |
BlockTime |
Seconds between blocks | 1 or more |
EpochReward |
Reward for each epoch | 0 or more |
MasterNode, signers |
Initial masternode and signers | Valid addresses |
blockPerEpoch |
Blocks in each epoch. The default is 900 | 1 or more |
setGap |
Blocks used to prepare the next masternode set | Smaller than blockPerEpoch |
foundationAddress |
Foundation address, whose key you hold | Valid address |
MultiSig-Address, walletConfirmations |
Multisig owners, and how many must confirm | Confirmations can't exceed owners |
swapWallet |
Wallet funded with 55 million XDC | Valid address |
preFund |
Addresses to fund at the start | Valid addresses |
networkID |
ID of your network | Not 50 (mainnet) or 51 (Apothem) |
Total_Nodes, Nodes |
Number of nodes, and their addresses | The count must match |
tests/test_scripts.py has 38 tests and runs in CI on every push, along with ShellCheck. XDC is a small stand-in script in these tests, so no real node runs.
| Tested | Not tested |
|---|---|
Every setting check in config.py |
A real build of XDPoSChain |
| RPC staying private by default, and unsafe APIs being refused | Puppeth, or a genesis file from it |
Keys and stats secrets staying out of the node's environment, and a readable .env being refused |
|
| Keys staying off the command line and out of logs | A real node starting, or nodes finding each other |
| The password file being random and private | Blocks being produced |
| Ports, folders, restarts and failed starts | |
setup.sh steps, stopping at a failed step, and refusing a bad download |
The flags in node.sh were compared with the source and start script of XDPoSChain v2.7.1, but not run against it. To try the whole thing, follow Set up on a fresh Ubuntu virtual machine, and then check that eth_blockNumber rises on 127.0.0.1:8545.
node.shno longer opens RPC to every address, offers thepersonalandadminAPIs, or allows any web origin. The empty wallet password is replaced by a random one.node.shtakes a node number, and no longer has a fixed network ID, a bootnode at a fixed IP address or a stats server login..envmust be private to you, and keys are removed from the environment before the node starts.setup.shno longer runsapt upgrade, removes the installed Go, adds a third-party package source or assumes/home/ubuntu. It stops at the first failed step.- Go 1.15.5 and XDPoSChain v1.4.4 are replaced by Go 1.23.12 and v2.7.1. The Go download is now checked against its SHA-256.
setup.shno longer callsgeth, which it never installed, ornode1.shtonode4.sh, which came from another repository. It no longer installs the faucet, because that step rannpmin the wrong folder.config.pynow checks the settings and is used by the other scripts. Thealiascalls, which had no effect, and a block of unrelated sample data are gone..env,.pwd, keys, logs, node data and the genesis file are now ignored by git.
| Issue | Effect |
|---|---|
| Creating the genesis file is manual | Puppeth is interactive, and config.py summary only prints the values for it |
| Each node holds an unlocked wallet while it runs | Anything on the machine that can reach the local RPC port can spend from it, including through eth_sendTransaction |
.env is run as shell code |
Only put settings in it that you wrote yourself |
.pwd and .env are plain files |
They are private to your account, but anything running as that account can read them |
| The faucet isn't included | The XDC Foundation's backend and frontend are separate, and were last updated in 2022 |
More XDC and EVM projects
| Group | Project | What it is |
|---|---|---|
| Standards | XRC-SHARES | Dividend-paying NFT shares and SPLITS for a DApp |
| Standards | XRCDividendPlus | Dividend-paying XRC-20 token |
| Treasury and finance | Multi-Sig-Treasury | Treasury controlled by tokenized keys |
| Treasury and finance | XRC-Airdrop | Self-run token airdrop |
| Treasury and finance | XRC-Credit | Single-loan credit contract |
| Treasury and finance | XDC-Defi-Instruments | Assets, agreements, forwards, futures and a marketplace |
| Treasury and finance | XRC1155-Equities-Market | Shares, portfolios and a marketplace on ERC-1155 |
| Treasury and finance | NFTOTC | Over-the-counter sale of a token collection |
| Treasury and finance | DAppProxySwap | Currency swaps for a DApp through a fixed router |
| Identity and access | LoginMFAContract | Login with an NFT and a signed second factor |
| Identity and access | PrivateAccessToken | Token access to encrypted off-chain data |
| Identity and access | Delegated_Authority | KYC notary proof of concept |
| Identity and access | EncryptedNFT-Documents | NFTs tied to encrypted off-chain documents |
| Learning and libraries | XDC-LemonadeStand | Workshop DApp built on XRC-SHARES |
| Learning and libraries | Non-Financial-SmartContracts | Games, inventory, keys and on-chain repositories |
| Learning and libraries | ContractLedger | On-chain list of contract addresses |
| Learning and libraries | TimestampConverter | Timestamps to calendar dates in Solidity |
| Tools | XDC_Python_SDK_V1 | Python client for the XDC JSON-RPC API |
| Tools | WebApp_to_XDCPay | Working web app connected to XDCPay |
| Multi-chain | CoinClub_Framework | Python library with an XDC adapter |
| Interfaces | Contract_Interface_Model_Language | Interface documents for smart contracts and APIs |
MIT.