Run Mainnet Node
NOTE: Ensure you meet the prerequisites before running a Node.
Run a Mainnet Unit Zero node by following the steps:
Prerequisites
Hardware: Ensure you have 4 CPU cores, 8 GB RAM, and 250+ GB SSD.
Account: Create a Waves Account wallet in Mainnet.
Docker: Install the software.
Waves Blockchain Data:
Download blockchain_last.tar via the link.
Or see other blockchain synchronization options.
UNIT0 Chaindata
Download op-geth-chaindata.tar via the link.
Optional. For Mining Only.:
WAVES: Obtain a minimum of 0.005 WAVES tokens to cover the transaction fee.
NOTE: The Consensus Client invokes the Chain Contract on behalf of your account. If your account has a verifier, it must permit such transactions.
Lease: Delegate a minimum of 20,000 WAVES to your account.
Google Chrome: Install the browser to ensure compatibility with the Waves Dapp UI.
Step 1: Configure Node
Create the main directory and go to it:
mkdir main cd main
NOTE: Ensure you have the read and write access to the directory.
In the
main
directory, create the subdirectories:mkdir -p data/{secrets,waves,op-geth}
In the
data/waves
subdirectory, unpack theblockchain_last.tar
archive.In the
data/op-geth
subdirectory, unpack theop-geth-chaindata.tar
archive.Generate a node key and a JWT secret:
NOTE: You can re-use existing secrets if you ran besu previously.
mkdir -p data/secrets openssl rand -hex 32 | tr -d "\n" > data/secrets/p2p-key openssl rand -hex 32 | tr -d "\n" > data/secrets/jwtsecret
In the
main
directory:Create the
waves.conf
file and paste the code block into it:WARNING: You must:
Insert your Mainnet account's seed converted to a base58-encoded byte array.
Set a password as a string.
Specify your server's static IP address. If your server does not have a static IP address, remove the
declared-address
line.
NOTE:
execution-client-address
has changed to"http://op-geth:8551"
.waves { blockchain.type = MAINNET extensions = [ units.ConsensusClient ] wallet { seed = <YOUR-BASE58-ENCODED-SEED> password = <YOUR-PASSWORD-AS-STRING> file = null } network { port = 6868 declared-address = "<YOUR_SERVER_IP_ADDRESS>:6868" # Example: 11.22.33.44:6868. } rest-api.bind-address = "0.0.0.0" } units { defaults { jwt-secret-file = /etc/secrets/jwtsecret } chains = [{ chain-contract = 3PKgN8rfmvF7hK7RWJbpvkh59e1pQkUzero execution-client-address = "http://op-geth:8551" network { port = 6865 known-peers = [ "mainnet-htz-fsn1-1.unit0.dev:6865" "mainnet-htz-hel1-1.unit0.dev:6865" "mainnet-htz-hel1-12.wavesnodes.com:6865" ] declared-address = "<YOUR_SERVER_IP_ADDRESS>:6865" # Example: 11.22.33.44:6865. } mining-enable = yes # Set to `no` to run a validating node that doesn't mine. }] }
Create the
genesis.json
file and paste the code block into it:{ "alloc": { "0x0000000000000000000000000000000000006a7e": { "code": "0x60806040526004361061006e575f3560e01c806396f396c31161004c57806396f396c3146100e3578063c4a4326d14610105578063e984df0e1461011d578063fccc281314610131575f80fd5b806339dd5d1b146100725780637157405a146100b957806378338413146100ce575b5f80fd5b34801561007d575f80fd5b506100a161008c36600461059e565b5f6020819052908152604090205461ffff1681565b60405161ffff90911681526020015b60405180910390f35b3480156100c4575f80fd5b506100a161040081565b6100e16100dc3660046105b5565b61015c565b005b3480156100ee575f80fd5b506100f761044e565b6040519081526020016100b0565b348015610110575f80fd5b506100f76402540be40081565b348015610128575f80fd5b506100f7610468565b34801561013c575f80fd5b506101445f81565b6040516001600160a01b0390911681526020016100b0565b61016c6402540be40060016105fc565b34101561017834610478565b61019061018b6402540be40060016105fc565b610478565b6040516020016101a1929190610630565b604051602081830303815290604052906101d75760405162461bcd60e51b81526004016101ce9190610688565b60405180910390fd5b506101ef6402540be400677fffffffffffffff6105fc565b3411156101fb34610478565b61021561018b6402540be400677fffffffffffffff6105fc565b6040516020016102269291906106bd565b604051602081830303815290604052906102535760405162461bcd60e51b81526004016101ce9190610688565b50435f8181526020819052604090205461ffff166104009081119061027790610478565b604051602001610287919061070c565b604051602081830303815290604052906102b45760405162461bcd60e51b81526004016101ce9190610688565b505f818152602081905260408120805461ffff16916102d283610786565b91906101000a81548161ffff021916908361ffff160217905550505f6402540be400346102ff91906107a6565b9050346103116402540be400836105fc565b1461031b34610478565b6103296402540be400610478565b60405160200161033a9291906107c5565b604051602081830303815290604052906103675760405162461bcd60e51b81526004016101ce9190610688565b506040515f90819034908281818185825af1925050503d805f81146103a7576040519150601f19603f3d011682016040523d82523d5f602084013e6103ac565b606091505b50509050806103fd5760405162461bcd60e51b815260206004820152601e60248201527f4661696c656420746f2073656e6420746f206275726e2061646472657373000060448201526064016101ce565b604080516bffffffffffffffffffffffff1986168152600784900b60208201527ffeadaf04de8d7c2594453835b9a93b747e20e7a09a7fdb9280579a6dbaf131a8910160405180910390a150505050565b6104656402540be400677fffffffffffffff6105fc565b81565b6104656402540be40060016105fc565b6060815f0361049e5750506040805180820190915260018152600360fc1b602082015290565b815f5b81156104c757806104b181610814565b91506104c09050600a836107a6565b91506104a1565b5f8167ffffffffffffffff8111156104e1576104e161082c565b6040519080825280601f01601f19166020018201604052801561050b576020820181803683370190505b509050815b851561059557610521600182610840565b90505f61052f600a886107a6565b61053a90600a6105fc565b6105449088610840565b61054f906030610853565b90505f8160f81b90508084848151811061056b5761056b61086c565b60200101906001600160f81b03191690815f1a90535061058c600a896107a6565b97505050610510565b50949350505050565b5f602082840312156105ae575f80fd5b5035919050565b5f602082840312156105c5575f80fd5b81356bffffffffffffffffffffffff19811681146105e1575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610613576106136105e8565b92915050565b5f81518060208401855e5f93019283525090919050565b6a029b2b73a103b30b63ab2960ad1b81525f61064f600b830185610619565b7f206d7573742062652067726561746572206f7220657175616c20746f20000000815261067f601d820185610619565b95945050505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b6a029b2b73a103b30b63ab2960ad1b81525f6106dc600b830185610619565b7f206d757374206265206c657373206f7220657175616c20746f20000000000000815261067f601a820185610619565b7f4d6178207472616e7366657273206c696d6974206f662000000000000000000081525f61073d6017830184610619565b7f207265616368656420696e207468697320626c6f636b2e2054727920746f207381527232b732103a3930b739b332b9399030b3b0b4b760691b60208201526033019392505050565b5f61ffff821661ffff810361079d5761079d6105e8565b60010192915050565b5f826107c057634e487b7160e01b5f52601260045260245ffd5b500490565b6a029b2b73a103b30b63ab2960ad1b81525f6107e4600b830185610619565b7f206d7573742062652061206d756c7469706c65206f6620000000000000000000815261067f6017820185610619565b5f60018201610825576108256105e8565b5060010190565b634e487b7160e01b5f52604160045260245ffd5b81810381811115610613576106136105e8565b60ff8181168382160190811115610613576106136105e8565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220106399f534da089226c14e2f183f8421d059a924c65c97d7e4f3e931c54fe1bb64736f6c634300081a0033", "balance": "0x0" } }, "baseFeePerGas": "0x3b9aca00", "blobGasUsed": null, "coinbase": "0x0000000000000000000000000000000000000000", "config": { "chainId": 88811, "arrowGlacierBlock": 0, "berlinBlock": 0, "byzantiumBlock": 0, "cancunTime": 0, "constantinopleBlock": 0, "daoForkBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "ethash": {}, "grayGlacierBlock": 0, "homesteadBlock": 0, "istanbulBlock": 0, "londonBlock": 0, "muirGlacierBlock": 0, "petersburgBlock": 0, "shanghaiTime": 0, "terminalTotalDifficulty": 0, "terminalTotalDifficultyPassed": true, "blobSchedule": { "cancun": { "target": 3, "max": 6, "baseFeeUpdateFraction": 3338477 }, "prague": { "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 } } }, "difficulty": "0x0", "excessBlobGas": null, "extraData": "0x", "gasLimit": "0x989680", "gasUsed": "0x0", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0", "number": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "timestamp": "0x6720960b" }
Create the
peers.toml
file and paste the code block into it:[Node.P2P] BootstrapNodes = [ "enode://02718d9a9c6f829c14ea3fd143e526130c70ae43956682cd234046ec932b1c21ca321c484bbb6aa766322ee7e0089d3405747f31d156ec0d67cd80482aede5d7@81.82.238.146:30301", "enode://02884ba9163fe92e1aa5a940a050d12c7d857fed092e43d242ebb63472a3e16e77d3b626d50ad790ed454e0e93607ba7ccebd5ac8423d5745df5066708709ac9@185.241.151.12:30303", "enode://153a16432e725691d50dae6b0700faf4c3a1b92bd6584ea707ca184f9e6732b6a9360ef86ac5b35a0858d6ef5e408c96eadb070ddea230c1f8ea7bec54613fb9@135.181.178.5:30303", "enode://1937134aff8287fddfc80d2583c9218521b15719dc7782ec85322493b973d02a76edf23ad30657f2d827e04a573e8a5bb2a0052a696a960365c2f13e69cbc0f3@95.216.152.163:30303", "enode://5355b769f711ab1951c788d664d0ccbf4bc989013ea3a4f419ab01d9930b524956be65442fa4b72e7de9c470ceeac796235fb198ad9ef49dab559139f17282e2@38.242.222.27:30303", "enode://6b534a07943cbca55d6dff834cac2c77f3e82895f51b25fa8cca1689b5cc0921f68453165fa5c736e55e4c61d0b73795445ed2099c09008358805467d07d2066@81.82.238.146:30302", "enode://85389460716e3e3247b51139de2f11f1b886c7eb3dc849e2e9673447c81922f9955b2d271834cae9c1625e69f7805e2c89362d4dd8cb0ca972668d7262252790@63.250.53.184:30303", "enode://b232ad7ca7bd6156e1adaa28ee0d064f3d973a67c0ad507a1b9dc32b3d64b307c754bc48c274aa96852f0041c2f85792681495e21f5baa62f06d3db8097af258@142.132.251.180:30303", "enode://ded10bb464eea90d2a61ab7fef15531dca698845d93f7fc191a5383c22b09de282982872515f398ae527d300c2d5324bae61199dbb354843e6792f2d13b87880@172.104.241.53:30303", "enode://e15d6f32cddc2a8e69885fc5c445b8ca7bafd91e9a7a834e89ed688150aa55df20fc7ff14d1fc5dd1e266c2b6a2f9dc75b1d6ed5f80ac71cb27f6ba8af12ba4b@213.238.172.133:30303", "enode://e8f7dbec4b146ef0ed1852cd05e3c0654f78a5784a7584f45bc0073bf6206d55764600b586148dfca42bd711c1c1bc02cb20abb2210320f830f003aacf074396@95.217.59.114:30303", "enode://edab526402907ccbbdf51950f09b964d9ebc1b51e1a9a1dca44fdaf823d85f84e513e95503f1e4d9e4e90355674819d52e46b014e054da5f199d5406ae6a5e22@185.31.163.22:30303" ] BootstrapNodesV5 = [] StaticNodes = [ "enode://02718d9a9c6f829c14ea3fd143e526130c70ae43956682cd234046ec932b1c21ca321c484bbb6aa766322ee7e0089d3405747f31d156ec0d67cd80482aede5d7@81.82.238.146:30301", "enode://02884ba9163fe92e1aa5a940a050d12c7d857fed092e43d242ebb63472a3e16e77d3b626d50ad790ed454e0e93607ba7ccebd5ac8423d5745df5066708709ac9@185.241.151.12:30303", "enode://153a16432e725691d50dae6b0700faf4c3a1b92bd6584ea707ca184f9e6732b6a9360ef86ac5b35a0858d6ef5e408c96eadb070ddea230c1f8ea7bec54613fb9@135.181.178.5:30303", "enode://1937134aff8287fddfc80d2583c9218521b15719dc7782ec85322493b973d02a76edf23ad30657f2d827e04a573e8a5bb2a0052a696a960365c2f13e69cbc0f3@95.216.152.163:30303", "enode://5355b769f711ab1951c788d664d0ccbf4bc989013ea3a4f419ab01d9930b524956be65442fa4b72e7de9c470ceeac796235fb198ad9ef49dab559139f17282e2@38.242.222.27:30303", "enode://6b534a07943cbca55d6dff834cac2c77f3e82895f51b25fa8cca1689b5cc0921f68453165fa5c736e55e4c61d0b73795445ed2099c09008358805467d07d2066@81.82.238.146:30302", "enode://85389460716e3e3247b51139de2f11f1b886c7eb3dc849e2e9673447c81922f9955b2d271834cae9c1625e69f7805e2c89362d4dd8cb0ca972668d7262252790@63.250.53.184:30303", "enode://b232ad7ca7bd6156e1adaa28ee0d064f3d973a67c0ad507a1b9dc32b3d64b307c754bc48c274aa96852f0041c2f85792681495e21f5baa62f06d3db8097af258@142.132.251.180:30303", "enode://ded10bb464eea90d2a61ab7fef15531dca698845d93f7fc191a5383c22b09de282982872515f398ae527d300c2d5324bae61199dbb354843e6792f2d13b87880@172.104.241.53:30303", "enode://e15d6f32cddc2a8e69885fc5c445b8ca7bafd91e9a7a834e89ed688150aa55df20fc7ff14d1fc5dd1e266c2b6a2f9dc75b1d6ed5f80ac71cb27f6ba8af12ba4b@213.238.172.133:30303", "enode://e8f7dbec4b146ef0ed1852cd05e3c0654f78a5784a7584f45bc0073bf6206d55764600b586148dfca42bd711c1c1bc02cb20abb2210320f830f003aacf074396@95.217.59.114:30303", "enode://edab526402907ccbbdf51950f09b964d9ebc1b51e1a9a1dca44fdaf823d85f84e513e95503f1e4d9e4e90355674819d52e46b014e054da5f199d5406ae6a5e22@185.31.163.22:30303" ]
Create the docker-compose.yml file and paste the code block into it:
services: op-geth: container_name: op-geth image: ghcr.io/unitsnetwork/op-geth:v1.101503.1-simulate-fixes stop_grace_period: 5m entrypoint: /bin/sh -c command: - | if [ ! -d /root/.ethereum/geth/chaindata ] ; then geth init /tmp/genesis.json else echo geth already initialized fi exec geth \ --config=/etc/peers.toml \ --syncmode=full \ --verbosity=4 \ --http \ --http.addr=0.0.0.0 \ --http.vhosts=* \ --http.api=eth,web3,txpool,net,debug,engine \ --http.corsdomain=* \ --ws \ --ws.addr=0.0.0.0 \ --ws.api=eth,web3,txpool,net,debug \ --ws.rpcprefix=/ \ --ws.origins=* \ --authrpc.addr=0.0.0.0 \ --authrpc.vhosts=* \ --authrpc.jwtsecret=/etc/secrets/jwtsecret \ --nodekey=/etc/secrets/p2p-key \ --log.file=/root/logs/op-geth.log \ --log.format=terminal \ --log.rotate \ --log.compress \ --log.maxbackups=100 \ --log.maxsize=1024 logging: driver: local options: max-size: 1g max-file: 5 healthcheck: test: 'wget -qO /dev/null --header "content-type: application/json" --post-data {\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1} http://127.0.0.1:8545' interval: 5s timeout: 1s retries: 10 environment: GETH_BOOTNODES: "" GETH_NAT: extip:<YOUR_SERVER_IP_ADDRESS> # Example: extip:11.22.33.44. If your server does not have an external IP, set value to `any`, e.g. `GETH_NAT: any` ports: - '30303:30303/tcp' - '30303:30303/udp' volumes: - ./data/secrets:/etc/secrets:ro - ./data/op-geth:/root/.ethereum/chaindata - ./genesis.json:/tmp/genesis.json:ro - ./peers.toml:/etc/peers.toml:ro - ./logs/op-geth:/root/logs waves-node: container_name: waves-node image: ghcr.io/unitsnetwork/consensus-client:mainnet restart: unless-stopped stop_grace_period: 5m ports: - "6865:6865" - "6868:6868" - "127.0.0.1:6869:6869" volumes: - ./data/secrets:/etc/secrets:ro - ./data/waves:/var/lib/waves/data - ./waves.conf:/etc/waves/waves.conf:ro - ./logs/waves:/var/log/waves
Manual Updates
Note that newer images are not pulled when container restarts, neither for the consensus client, nor for op-geth. Automatic pulls have not been enabled to prevent newer incompatible images from being pulled unexpectedly.
You can run the following command to check which version of the consensus client you're running:
docker inspect ghcr.io/unitsnetwork/consensus-client:mainnet | grep revision
Sample output:
❯ docker inspect ghcr.io/unitsnetwork/consensus-client:mainnet | grep revision
"org.opencontainers.image.revision": "e94e576e19ec50f1dc7e0b8d716b6d01344ad781",
e94e576e19ec50f1dc7e0b8d716b6d01344ad781
is git commit hash the image was built from. This hash can be useful for debugging purposes.
Step 2: Launch Node
WARNING: Docker and UFW have a known incompatibility. This issue makes it impossible to map a container's port to a host port (e.g.,
'8545:8545'
) and restrict external access using UFW at the same time.In the docker-compose.yml file, execution client JSON-RPC port (8545) and Waves node's HTTP API port (6869) are mapped to the host's local address: 127.0.0.1:8545:8545 and 127.0.0.1:6869:6869. This configuration ensures the endpoints are accessible only to consumers running locally on the host machine.
If you need to allow access from external addresses, adjust the port mappings to 8545:8545 and 6869:6869. Alternatively, consider using a reverse proxy like nginx for controlled access.
Launch your node via the command:
docker compose up -d
NOTE: The Execution chain is synced with the network log indicates that the Consensus Client is synchronized with the network.
Step 3 (Optional): Start Mining
Go to the Waves dApp page.
In the header of the page, click Sign in. The Connect a wallet to get started window will open.
The “Sign in” button in the header of the Waves dApp page In the Connect a wallet to get started window, select one of the sign-in options:
Sign in with Keeper.
Sign in with Exchange(Seed).
Sign in with Exchange(Email).
Sign in with Metamask.
The sign-in options in the “Connect a wallet to get started” window
The wallet extension will open.
In the wallet extension, sign in to your node account.
In the join block:
In the rewardAddressHex field, enter your account address.
LIMITATIONS: The data field accepts input only in string format.
Click Invoke.
NOTE: The transaction fee is 0.005 WAVES.
A node account adddress entered Confirm the transaction in your wallet. Nodes chosen for block creation receive epoch rewards. Learn more about block generation probability.
NOTE: If you need help, contact us via our Developer chat for assistance.
Last updated