├── .gitignore ├── README.md ├── docker-ctn ├── .dockerignore ├── Dockerfile ├── Nnodes │ ├── init-network.sh │ └── script1.js └── netstat │ ├── init-netstat.sh │ └── netstatconf.sh ├── netstat_desktop.png └── vagrant-vm ├── Nnodes ├── init-network.sh └── script1.js ├── Vagrantfile ├── bootstrap.sh └── netstat ├── init-netstat.sh └── netstatconf.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled source # 2 | ################### 3 | *.com 4 | *.class 5 | *.dll 6 | *.exe 7 | *.o 8 | *.so 9 | 10 | # Packages # 11 | ############ 12 | # it's better to unpack these files and commit the raw source 13 | # git has its own built in compression methods 14 | *.7z 15 | *.dmg 16 | *.gz 17 | *.iso 18 | *.jar 19 | *.rar 20 | *.tar 21 | *.zip 22 | 23 | # Logs and databases # 24 | ###################### 25 | *.log 26 | *.sql 27 | *.sqlite 28 | 29 | # OS generated files # 30 | ###################### 31 | .DS_Store 32 | .DS_Store? 33 | ._* 34 | .Spotlight-V100 35 | .Trashes 36 | ehthumbs.db 37 | Thumbs.db 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # private-networks-deployment-scripts 2 | This repository contains out-of-the-box deployment scripts for ethereum private PoA networks. 3 | There are 2 sandboxes - vagrant virtual machine and docker container setups, both can be used to create dev environment, initiate and run a private network. 4 | Puppeth network manager is used to create new network and generate genesis file. 5 | 6 | **The goal** is to create 'out-of-box', 'one-click' solution for setting up new private ethereum network. 7 | 8 | 9 | In progress: 10 | 11 | * Test, test, test ... 12 | * Find out why docker is so slow 13 | * Add netstat 14 | * Use only 1 folder with init-network.sh, try to avoid duplication. 15 | 16 | 17 | ## Running vagrant VM 18 | 19 | In the top level directory: 20 | 21 | $ cd vagrant-vm 22 | $ vagrant up 23 | $ vagrant ssh 24 | $ sudo -i 25 | $ cd /home/ubuntu/Nnodes/ 26 | $ ./init-network.sh 27 | 28 | Script will ask you to define a name of future network, amount of nodes, password for each node... 29 | 30 | 31 | ## Running docker container 32 | 33 | In the top level directory: 34 | 35 | $ cd /home/Nnodes/docker-ctn 36 | $ docker build -t $CONTAINER_NAME . 37 | $ docker run -p 3000:3000 --name $CONTAINER_INSTANCE_NAME -i -t $CONTAINER_NAME 38 | $ cd /home/Nnodes 39 | $ ./init-network.sh 40 | 41 | To connect to node console via IPC, please type 42 | 43 | $ geth attach ipc:nodes/NODE_NUM/geth.ipc 44 | 45 | ## Ethereum netstat 46 | 47 | Additionally you can run an ether netstat to see your PoA network information. 48 | 49 | In the 'Nnodes' directory: 50 | 51 | $ cd netstat 52 | $ ./init-netstat.sh 53 | 54 | If network successfully started, you will see something like this on http://localhost:3000 55 | ![Created network information](https://github.com/ConsenSys/private-networks-deployment-scripts/blob/master/netstat_desktop.png) 56 | 57 | Please make sure port 3000 is free. 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /docker-ctn/.dockerignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Consensys/private-networks-deployment-scripts/f0172bb3b13ce931c361a5b2ad7ba006334b958a/docker-ctn/.dockerignore -------------------------------------------------------------------------------- /docker-ctn/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | 4 | RUN apt-get update && \ 5 | apt-get install -y \ 6 | build-essential \ 7 | git \ 8 | libdb-dev \ 9 | libsodium-dev \ 10 | libtinfo-dev \ 11 | sysvbanner \ 12 | unzip \ 13 | wget \ 14 | wrk \ 15 | zlib1g-dev 16 | 17 | 18 | ENV GOREL go1.7.3.linux-amd64.tar.gz 19 | ENV PATH $PATH:/usr/local/go/bin 20 | 21 | RUN wget -q https://storage.googleapis.com/golang/$GOREL && \ 22 | tar xfz $GOREL && \ 23 | mv go /usr/local/go && \ 24 | rm -f $GOREL 25 | 26 | RUN apt-get update && \ 27 | apt-get install -y --no-install-recommends software-properties-common && \ 28 | add-apt-repository ppa:ethereum/ethereum && \ 29 | apt-get update 30 | 31 | # Install add-apt-repository 32 | RUN apt-get install -y build-essential unzip libdb-dev libleveldb-dev libsodium-dev zlib1g-dev libtinfo-dev solc sysvbanner wrk \ 33 | git python dstat ntp nodejs solc ethereum npm software-properties-common vim 34 | 35 | RUN mkdir -p /home/Nnodes 36 | ADD Nnodes /home/Nnodes 37 | 38 | RUN mkdir -p /home/netstat 39 | ADD netstat /home/netstat 40 | #RUN cd /home/Nnodes 41 | 42 | # Temporary useful tools 43 | #RUN apt-get update && \ 44 | # apt-get install -y iputils-ping net-tools vim 45 | 46 | #SET netstat repositories 47 | RUN cd /home/netstat && \ 48 | git clone https://github.com/cubedro/eth-netstats && \ 49 | cd eth-netstats && \ 50 | npm install && \ 51 | npm install -g grunt-cli && \ 52 | ln -s /usr/bin/nodejs /usr/bin/node && \ 53 | grunt && \ 54 | cd ../ && \ 55 | git clone https://github.com/cubedro/eth-net-intelligence-api && \ 56 | cd eth-net-intelligence-api && \ 57 | npm install && \ 58 | npm install -g pm2 && \ 59 | cd ../../ 60 | 61 | 62 | EXPOSE 3000 63 | 64 | -------------------------------------------------------------------------------- /docker-ctn/Nnodes/init-network.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "[*] Init private PoA network" 4 | 5 | echo "[*] Enter a name of your private network" 6 | read network_name 7 | 8 | NETWORK_DIR=${network_name}_network 9 | NETWORK_GENESIS_FILE=${network_name}_genesis.json 10 | 11 | #Clean up previous network 12 | #TODO instead of deleting move to back folder 13 | rm -rf $NETWORK_DIR 14 | mkdir $NETWORK_DIR 15 | cd $NETWORK_DIR 16 | mkdir logs 17 | 18 | echo "[*] Enter number of nodes" 19 | read num 20 | 21 | echo "[*] Creating ${num} nodes" 22 | 23 | for ((i = 1; i <= $num; i++)) { 24 | geth --datadir nodes/node$i account new 25 | ACCOUNTS[$i]=`geth account list --keystore nodes/node$i/keystore | sed 's/^[^{]*{\([^{}]*\)}.*/\1/'` 26 | # echo "[*] New accouunt = ${ACCOUNTS[$i]}" 27 | } 28 | 29 | #Create PUPPETH_ARG 30 | PUPPETH_ARG="$network_name\n2\n2\n10\n" 31 | 32 | for _ in `seq 1 2`; 33 | do 34 | for ((i = 1; i <= $num; i++)) { 35 | PUPPETH_ARG+="${ACCOUNTS[$i]}\n" 36 | } 37 | PUPPETH_ARG+="\n" 38 | done 39 | 40 | #GENERATE RANDOM ID for the network 41 | PUPPETH_ARG+="\n" 42 | 43 | #ADD SOMETHING FUN INTO A BLOCK 44 | PUPPETH_ARG+="\n" 45 | 46 | #GENERATE GENESIS FILE 47 | PUPPETH_ARG+="2\n2\n$NETWORK_GENESIS_FILE\n" 48 | 49 | #echo "[*] PUPPETH_ARG = $PUPPETH_ARG" 50 | 51 | #CALL puppeth network manager and pass arguments 52 | printf $PUPPETH_ARG | puppeth &> logs/puppeth_output.log 53 | 54 | #GLOBAL_ARGS="--mine --rpc --rpcaddr 0.0.0.0 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3" 55 | GLOBAL_ARGS="--mine --rpc --rpcaddr 0.0.0.0" 56 | RPC_START_PORT=22000 57 | START_PORT=21000 58 | 59 | #INIT and START network nodes 60 | for ((i = 1; i <=$num; i++)) { 61 | echo "[*] Init node $i" 62 | geth --datadir nodes/node$i init $NETWORK_GENESIS_FILE &>> logs/node$i.log 63 | echo "[*] Start node $i" 64 | echo "[*] Type password for $i node" 65 | read -s password 66 | echo $password > password$i.txt 67 | geth --datadir nodes/node$i $GLOBAL_ARGS --unlock ${ACCOUNTS[$i]} --password password$i.txt \ 68 | --rpcport $(($RPC_START_PORT + $i - 2)) --port $(($START_PORT + $i - 1)) &>> logs/node$i.log & 69 | #rm -rf password$i.txt 70 | } 71 | echo "[*] Setting up network, please wait ..." 72 | sleep 10 73 | 74 | #WAIT A BIT MORE FOR NODES TO START 75 | for ((i = 1; i <= $num; i++)) { 76 | if [ ! -e "nodes/node$i/geth.ipc" ]; then 77 | sleep 2 78 | fi 79 | } 80 | 81 | #Create file of enodes 82 | ENODES_FILE=enodes_list.txt 83 | rm -rf $ENODES_FILE 84 | for ((i = 1; i <= $num; i++)) { 85 | if [ -e "nodes/node$i/geth.ipc" ]; then 86 | echo "[*] Directory found for node $i" 87 | geth --exec 'admin.nodeInfo.enode' attach nodes/node$i/geth.ipc >> $ENODES_FILE 88 | else "[*] Please check node $i, there is something wrong with it" 89 | fi 90 | } 91 | 92 | #ADD PEERS 93 | for ((i = 1; i <= $num; i++)) { 94 | if [ -e "nodes/node$i/geth.ipc" ]; then 95 | echo "[*] Add peers for node $i" 96 | OWNED_ENODE=`geth --exec 'admin.nodeInfo.enode' attach nodes/node$i/geth.ipc` 97 | #echo "Owned enode = $OWNED_ENODE" 98 | while read line; do 99 | if [ $OWNED_ENODE != $line ]; then 100 | geth --exec "admin.addPeer($line)" attach nodes/node$i/geth.ipc >> "nodes_add_res.txt" 101 | fi 102 | done < $ENODES_FILE 103 | fi 104 | } 105 | 106 | #RUN SMART CONTRACT 107 | echo "[*] Sending first transaction" 108 | geth --exec 'loadScript("../script1.js")' attach nodes/node1/geth.ipc 109 | 110 | echo "[*] To stop network, please type exit" 111 | read val 112 | COMMAND=`echo $val | tr '[:upper:]' '[:lower:]'` 113 | if [ $COMMAND == 'exit' ]; then 114 | pkill geth > /dev/null 2>&1 115 | for ((i = 1; i <=$num; i++)) { 116 | rm -rf password$i.txt 117 | } 118 | echo "[*] Bye!" 119 | fi 120 | 121 | cd ../ 122 | -------------------------------------------------------------------------------- /docker-ctn/Nnodes/script1.js: -------------------------------------------------------------------------------- 1 | a = eth.accounts[0] 2 | web3.eth.defaultAccount = a; 3 | 4 | // abi and bytecode generated from simplestorage.sol: 5 | // > solcjs --bin --abi simplestorage.sol 6 | var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"payable":false,"type":"constructor"}]; 7 | 8 | var bytecode = "0x6060604052341561000f57600080fd5b604051602080610149833981016040528080519060200190919050505b806000819055505b505b610104806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632a1afcd914605157806360fe47b11460775780636d4ce63c146097575b600080fd5b3415605b57600080fd5b606160bd565b6040518082815260200191505060405180910390f35b3415608157600080fd5b6095600480803590602001909190505060c3565b005b341560a157600080fd5b60a760ce565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b6000805490505b905600a165627a7a72305820d5851baab720bba574474de3d09dbeaabc674a15f4dd93b974908476542c23f00029"; 9 | 10 | var simpleContract = web3.eth.contract(abi); 11 | var simple = simpleContract.new(42, {from:web3.eth.accounts[0], data: bytecode, gas: 0x47b760, privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="]}, function(e, contract) { 12 | if (e) { 13 | console.log("err creating contract", e); 14 | } else { 15 | if (!contract.address) { 16 | console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); 17 | } else { 18 | console.log("Contract mined! Address: " + contract.address); 19 | console.log(contract); 20 | } 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /docker-ctn/netstat/init-netstat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "[*] Enter number of nodes in the network" 4 | read num 5 | 6 | NET_SECRET="random_secret" 7 | 8 | #INIT NETSTAT 9 | cd /home/netstat 10 | cd eth-netstats 11 | (WS_SECRET=$NET_SECRET npm start &) 12 | cd ../ 13 | 14 | 15 | cd eth-net-intelligence-api 16 | bash ../netstatconf.sh $num node http://localhost:3000 $NET_SECRET > app.json 17 | (pm2 start app.json &) 18 | open http://localhost:3000 19 | cd ../../ 20 | 21 | -------------------------------------------------------------------------------- /docker-ctn/netstat/netstatconf.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # bash intelligence 3 | 4 | # sets up a eth-net-intelligence app.json for a local ethereum network cluster of nodes 5 | # - is the number of clusters 6 | # - is a prefix for the node names as will appear in the listing 7 | # - is the eth-netstats server 8 | # - is the eth-netstats secret 9 | # 10 | 11 | # open http://localhost:3301 12 | 13 | N=$1 14 | shift 15 | name_prefix=$1 16 | shift 17 | ws_server=$1 18 | shift 19 | ws_secret=$1 20 | shift 21 | 22 | echo -e "[" 23 | 24 | for ((i=0;i logs/puppeth_output.log 53 | 54 | #GLOBAL_ARGS="--mine --rpc --rpcaddr 0.0.0.0 --rpcapi admin,db,eth,debug,miner,net,shh,txpool,personal,web3" 55 | GLOBAL_ARGS="--mine --rpc --rpcaddr 0.0.0.0" 56 | RPC_START_PORT=8100 57 | START_PORT=30300 58 | 59 | #INIT and START network nodes 60 | for ((i = 1; i <=$num; i++)) { 61 | echo "[*] Init node $i" 62 | geth --datadir nodes/node$i init $NETWORK_GENESIS_FILE &>> logs/node$i.log 63 | echo "[*] Start node $i" 64 | echo "[*] Type password for $i node" 65 | read -s password 66 | echo $password > password$i.txt 67 | geth --datadir nodes/node$i $GLOBAL_ARGS --unlock ${ACCOUNTS[$i]} --password password$i.txt \ 68 | --rpcport $(($RPC_START_PORT + $i - 2)) --port $(($START_PORT + $i - 1)) &>> logs/node$i.log & 69 | #rm -rf password$i.txt 70 | } 71 | echo "[*] Setting up network, please wait ..." 72 | sleep 10 73 | 74 | #WAIT A BIT MORE FOR NODES TO START 75 | for ((i = 1; i <= $num; i++)) { 76 | if [ ! -e "nodes/node$i/geth.ipc" ]; then 77 | sleep 2 78 | fi 79 | } 80 | 81 | #Create file of enodes 82 | ENODES_FILE=enodes_list.txt 83 | rm -rf $ENODES_FILE 84 | for ((i = 1; i <= $num; i++)) { 85 | if [ -e "nodes/node$i/geth.ipc" ]; then 86 | echo "[*] Directory found for node $i" 87 | geth --exec 'admin.nodeInfo.enode' attach nodes/node$i/geth.ipc >> $ENODES_FILE 88 | else "[*] Please check node $i, there is something wrong with it" 89 | fi 90 | } 91 | 92 | #ADD PEERS 93 | for ((i = 1; i <= $num; i++)) { 94 | if [ -e "nodes/node$i/geth.ipc" ]; then 95 | echo "[*] Add peers for node $i" 96 | OWNED_ENODE=`geth --exec 'admin.nodeInfo.enode' attach nodes/node$i/geth.ipc` 97 | #echo "Owned enode = $OWNED_ENODE" 98 | while read line; do 99 | if [ $OWNED_ENODE != $line ]; then 100 | geth --exec "admin.addPeer($line)" attach nodes/node$i/geth.ipc >> "nodes_add_res.txt" 101 | fi 102 | done < $ENODES_FILE 103 | fi 104 | } 105 | 106 | #RUN SMART CONTRACT 107 | echo "[*] Sending first transaction" 108 | geth --exec 'loadScript("../script1.js")' attach nodes/node1/geth.ipc 109 | 110 | echo "[*] To stop network, please type exit" 111 | read val 112 | COMMAND=`echo $val | tr '[:upper:]' '[:lower:]'` 113 | if [ $COMMAND == 'exit' ]; then 114 | pkill geth > /dev/null 2>&1 115 | for ((i = 1; i <=$num; i++)) { 116 | rm -rf password$i.txt 117 | } 118 | echo "[*] Bye!" 119 | fi 120 | 121 | cd ../ 122 | -------------------------------------------------------------------------------- /vagrant-vm/Nnodes/script1.js: -------------------------------------------------------------------------------- 1 | a = eth.accounts[0] 2 | web3.eth.defaultAccount = a; 3 | 4 | // abi and bytecode generated from simplestorage.sol: 5 | // > solcjs --bin --abi simplestorage.sol 6 | var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"payable":false,"type":"constructor"}]; 7 | 8 | var bytecode = "0x6060604052341561000f57600080fd5b604051602080610149833981016040528080519060200190919050505b806000819055505b505b610104806100456000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632a1afcd914605157806360fe47b11460775780636d4ce63c146097575b600080fd5b3415605b57600080fd5b606160bd565b6040518082815260200191505060405180910390f35b3415608157600080fd5b6095600480803590602001909190505060c3565b005b341560a157600080fd5b60a760ce565b6040518082815260200191505060405180910390f35b60005481565b806000819055505b50565b6000805490505b905600a165627a7a72305820d5851baab720bba574474de3d09dbeaabc674a15f4dd93b974908476542c23f00029"; 9 | 10 | var simpleContract = web3.eth.contract(abi); 11 | var simple = simpleContract.new(42, {from:web3.eth.accounts[0], data: bytecode, gas: 0x47b760, privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="]}, function(e, contract) { 12 | if (e) { 13 | console.log("err creating contract", e); 14 | } else { 15 | if (!contract.address) { 16 | console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined..."); 17 | } else { 18 | console.log("Contract mined! Address: " + contract.address); 19 | console.log(contract); 20 | } 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /vagrant-vm/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure(2) do |config| 2 | config.vm.box = "ubuntu/xenial64" 3 | config.vm.provision :shell, path: "bootstrap.sh" 4 | config.vm.network "forwarded_port", guest: 3000, host: 3000 5 | config.vm.provider "virtualbox" do |v| 6 | v.memory = 4096 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /vagrant-vm/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu -o pipefail 3 | 4 | # install build deps 5 | add-apt-repository ppa:ethereum/ethereum 6 | apt-get update 7 | apt-get install -y build-essential unzip libdb-dev libleveldb-dev libsodium-dev zlib1g-dev libtinfo-dev solc sysvbanner wrk \ 8 | git python dstat ntp nodejs solc ethereum npm 9 | 10 | 11 | # For custom build config 12 | #sudo npm install -g node-gyp truffle@3.4.11 \ 13 | # truffle-default-builder ether-pudding rimraf web3@0.20.2 \ 14 | # ethereumjs-testrpc@6.0.3 q 15 | 16 | 17 | # install golang 18 | GOREL=go1.7.3.linux-amd64.tar.gz 19 | wget -q https://storage.googleapis.com/golang/$GOREL 20 | tar xfz $GOREL 21 | mv go /usr/local/go 22 | rm -f $GOREL 23 | PATH=$PATH:/usr/local/go/bin 24 | echo 'PATH=$PATH:/usr/local/go/bin' >> /home/ubuntu/.bashrc 25 | 26 | # install Porosity 27 | wget -q https://github.com/jpmorganchase/quorum/releases/download/v1.2.0/porosity 28 | mv porosity /usr/local/bin && chmod 0755 /usr/local/bin/porosity 29 | 30 | # copy examples 31 | cp -r /vagrant/Nnodes /home/ubuntu/Nnodes 32 | cp -r /vagrant/netstat /home/ubuntu/netstat 33 | 34 | #SET netstat repositories 35 | cd /home/ubuntu/netstat 36 | git clone https://github.com/cubedro/eth-netstats 37 | cd eth-netstats 38 | npm install 39 | npm install -g grunt-cli 40 | ln -s /usr/bin/nodejs /usr/bin/node 41 | grunt 42 | cd ../ 43 | 44 | git clone https://github.com/cubedro/eth-net-intelligence-api 45 | cd eth-net-intelligence-api 46 | npm install 47 | npm install -g pm2 48 | cd ../../ 49 | 50 | #chown -R ubuntu:ubuntu /home/ubuntu/7nodes 51 | 52 | # done! 53 | banner "Consensys" 54 | echo 55 | echo 'The Consensys vagrant instance has been provisioned' 56 | echo "Use 'vagrant ssh' to open a terminal, 'vagrant suspend' to stop the instance, and 'vagrant destroy' to remove it." 57 | -------------------------------------------------------------------------------- /vagrant-vm/netstat/init-netstat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "[*] Enter number of nodes in the network" 4 | read num 5 | 6 | NET_SECRET="random_secret" 7 | 8 | #INIT NETSTAT 9 | cd /home/ubuntu/netstat 10 | cd eth-netstats 11 | (WS_SECRET=$NET_SECRET npm start &) 12 | cd ../ 13 | 14 | 15 | cd eth-net-intelligence-api 16 | bash ../netstatconf.sh $num node http://localhost:3000 $NET_SECRET > app.json 17 | (pm2 start app.json &) 18 | open http://localhost:3000 19 | cd ../../ 20 | 21 | -------------------------------------------------------------------------------- /vagrant-vm/netstat/netstatconf.sh: -------------------------------------------------------------------------------- 1 | # !/bin/bash 2 | # bash intelligence 3 | 4 | # sets up a eth-net-intelligence app.json for a local ethereum network cluster of nodes 5 | # - is the number of clusters 6 | # - is a prefix for the node names as will appear in the listing 7 | # - is the eth-netstats server 8 | # - is the eth-netstats secret 9 | # 10 | 11 | # open http://localhost:3301 12 | 13 | N=$1 14 | shift 15 | name_prefix=$1 16 | shift 17 | ws_server=$1 18 | shift 19 | ws_secret=$1 20 | shift 21 | 22 | echo -e "[" 23 | 24 | for ((i=0;i