diff --git a/.gitignore b/.gitignore index 373f742e68a960c3bfe08a94edc371ef95903a8f..d94a031649a960be7963f2ea78a5f2842aa45053 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ */lastseen -*/node* */status cache */cache -network5445/contracts/* +network*/node +network*/bootnode +network*/contracts/* diff --git a/README.md b/README.md index e3ccd343d0390618587ec358ee6b45e2db5a6a35..1480bb6b9b0679e4d8c3ec34e1b9b85fd1b49e13 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,53 @@ # Blockchain Federal Argentina -## TEST NETWORK - -## Official URL: https://gitlab.bfa.ar/blockchain/nucleo - -1. Install geth - - For Debian read doc/compiling-geth-on-debian.txt - - For Ubuntu read doc/installing-geth-on-ubuntu.txt -2. `sudo apt install jq ncurses-bin curl` -3. `git clone https://github.com/rlegene/bfa.git` -4. `source ${HOME}/bfa/bin` - - You can include this line in your .bash_profile if you want. - - It is perfectly safe to source it multiple times. -5. Install this crontab: `@reboot bfa/bin/cron.sh` - - If you are running a sealer you MUST do this. -6. run `start.sh`. This will start synchronizing and probably takes at least an hour. -7. Change your node's settings with `syncmode.sh` + +## Website: https://www.bfa.ar/ +## Repo: https://gitlab.bfa.ar/blockchain/nucleo.git + +1. Install `git` + - as root: `apt install git` +2. Clone the official BFA repository + - `git clone https://gitlab.bfa.ar/blockchain/nucleo.git bfa` +3. Run the installation script. This will change settings on your system. If you are worried (you should be?), then you could run this step by step manually. + - as root: `bfa/bin/installbfa.sh` + You will see a lot of warnings when installing web3. This seems to be "normal". Ignoring those errors seems not to cause problems. +4. Switch to user `bfa` + - as root: `su - bfa` +5. Start synchronizing. Synchronizing can take a while. (This script is automatically run at system restart.) + - as bfa: `start.sh` +7. Monitor the logs with `bfalog.sh`. Press CTRL-C at any time to stop the `tail -f`. +8. Change your node's settings with `admin.sh syncmode` - Do this before you have synced too much in the step before, as it might remove all your downloaded chain data and restart synchronizing the chain. -8. Wait for it to finish synchronizing. -9. Run `maymine.sh` to update your configuration (detects if you are allowed to seal/mine or not). -10. Get some Ether from someone. Once you have some, you can try: - - Create your contract (there is already one deployed, but you can "overwrite" it with your own) - - Type lines of text into `tsa-insert.sh` (end with ctrl-D) -11. Free things to do with the BFA: - - Verify that the checksum has been seen with `tsa-verify.sh "<yourtexthere>"` - - If the text can not be found, it is because your insert transaction still isn't in the blockchain. Wait a bit and try again. - - Try the basic `explorer.sh`. It follows "latest" by default, but you can specify a block number as argument, e.g. `explorer.sh 0` to see genesis (block 0). - - Try out `walker.pl` -12. Install node.js so you can do better scripts locally: - `sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 68576280` - `sudo apt-add-repository "deb https://deb.nodesource.com/node_7.x $(lsb_release -sc) main"` - `sudo apt-get update` - `sudo apt-get install nodejs` - `npm init -y` - `npm install web3` - -There are other "interesting" programs in the bin/ and src/ directories. +9. Wait for it to finish synchronizing. +10. Run `maymine.sh` to update your configuration (detects if you are allowed to seal/mine or not). You can run this as often as you wish. If you try to mine/seal but is not allowed, your log will show errors (but no harm done). +11. Simple super basic tools (more actual proof of concepts, to inspire programmers): + - `explorer.sh` : It follows "latest" by default, but you can specify a block number as argument, e.g. `explorer.sh 0` to see genesis (block 0). + - `walker.pl` : Also takes a blocknumber to start from. Keeps waiting for new blocks. + +There are other "interesting" programs in the bin/ and src/ directories, but for developers, probably the `dev` branch is more interesting. ## start.sh -requires: **geth** -Starts a node on the 5445 BFA test net. Creates a genesis.json if you don't have one already. -One is already included in this package, which will allow you to connect to the existing BFA testnet. +Starts a node for you on the BFA Ethereum net. ## attach.sh -request: **geth** -Connects you to your running local geth. +Connects you to the CLI of your running local geth (fails if it is not already running). ## compile.and.deploy.contract -requires: **geth**, **solc**, **jq** -Compiles and deploys a contract to the blockchain. A local "node1" must already be running and synchronized. +Compiles and deploys a contract to the blockchain. A local account must already have ether to pay for the tx. Argument 1 is the filename of the contract to compile. Example: `compile.and.deploy.contract src/TimestampAuthority.sol` -## tsa-insert.sh -requires: **geth** - -Inserts the checksum of a text into the TSA. - -## tsa-verify.sh -requires: **geth** - -Returns the first blocknumber where the SHA256 checksum of a text was seen. The timestamp can then be found in the block (with `explorer.sh` for instance). - ## explorer.sh -requires: **curl**, **jq**, **tput** _(ncurses-bin)_, _(curl)_ Simple script to look at blocks -## src/TimeStampAuthority.sol - -The initial Timestamp service. - ## walker.pl -requires: **geth**, **perl**, __(libjson-perl)__ + +Shows one line per block being sealed in the network, then waits for the next block. ## rewind.sh @@ -94,3 +65,19 @@ the output from `geth` into `log.sh`, so we still can read the log. ## sendether.sh If you wish to give someone Ether, this script might be useful. + +## MasterDistiller.js + +Manages a deployed Distiller contract. It'll show registered users and their +set "allowance". + +## sealeradd.sh / sealerrem.sh + +When a sealer operator votes to promote or demote a sealer, this script +does most of the typing. Takes a single argument, being the account number +of the sealer which is being voted for. + +## monitor.sh + +This is being run every minute from `cron.sh`. It will update a file +in `network/status` showing very basic network information. diff --git a/bin/admin.sh b/bin/admin.sh new file mode 100755 index 0000000000000000000000000000000000000000..035393395b9f6e5d827deffb2b881085b737ff7f --- /dev/null +++ b/bin/admin.sh @@ -0,0 +1,130 @@ +#!/bin/bash +# Robert Martin-Legene <robert@nic.ar> + +if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi +source ${BFAHOME}/bin/libbfa.sh || exit 1 + +defaultsyncmode="fast" + +function modefilter +{ + case "$mode" in + "full"|"fast"|"light") + ;; + *) + echo "Unsupported mode." + mode="" + return + ;; + esac + true +} + +function admin_syncmode +{ + echo "Available synchronization modes:" + echo " full : verify all blocks and all transactions since genesis (most secure)" + echo " fast : verify all blocks but not all transactions (faster than full, but less certain)" + echo " light: Makes this node into a light node which downloads almost" + echo " nothing, but relies on fast and full nodes in the network" + echo " to answer it's requests. This is the fastest and uses least" + echo " local resources, but outsources all trust to another node." + echo "Default mode is fast, because for many, it is a healthy compromise" + echo "between speed and paranoia. You can change the setting, according to" + echo "your needs." + + mode=$( cat ${BFANODEDIR}/syncmode 2>/dev/null || true ) + mode=${mode:-${defaultsyncmode}} + orgmode=$mode + modefilter + echo "Your current mode is set to ${mode}" + killed=0 + mode= + + echo + while [ -z "${mode}" ] + do + read -p "Which mode do you wish? : " mode + modefilter + done + echo "Remembering your choice." + echo $mode > ${BFANODEDIR}/syncmode + if [ "$orgmode" = "fast" -a "$mode" = "full" ] + then + echo "You increased your paranoia level. The proper thing to do now," + echo "would be to delete your version of what you synchronized with" + echo "fast mode, and revalidate everything in the entire blockchain." + echo "This probably takes quite a long time and also requires downloading" + echo "all blocks from the entire blockchain again." + yesno n "Do you wish to delete all downloaded blocks and resynchronize?" + if [ "$REPLY" = "y" ] + then + if [ -r "${BFANODEDIR}/geth.pid" ] + then + pid=$( cat ${BFANODEDIR}/geth.pid ) + kill -0 $pid 2>/dev/null && + echo "Killing running geth." && + killed=1 + while ! kill $pid 2>/dev/null + do + sleep 1 + done + fi + rm -fr ${BFANODEDIR}/geth/chainstate ${BFANODEDIR}/geth/lightchainstate + geth --cache 0 --datadir ${BFANODEDIR} init ${BFAHOME}/src/genesis.json + test $killed -eq 1 && + echo && + echo "The startup.sh should restart your geth shortly." + fi + else + echo "No further action taken." + fi +} + +function admin_bootnode +{ + keyfile=${BFANETWORKDIR}/bootnode/key + echo "Only very few wants to actually run a boot node." + echo "If you have a keyfile for a bootnode, then you will" + echo "automatically start one, when restarting your system." + if [ -f $keyfile ] + then + echo "You are set up to run a boot node." + echo "Deleting your bootnode keyfile disables your bootnode." + yesno n "Do you want to delete your bootnode keyfile?" + if [ "$REPLY" = "y" ] + then + rm $keyfile + fi + pidfile=${BFANETWORKDIR}/bootnode/pid + if [ -r $pidfile ] + then + pid=`cat $pidfile` + kill -0 $pid && + echo "Terminating your bootnode." && + kill `cat $pidfile` || + true + fi + else + echo "You are not set up to run a boot node." + yesno n "Do you want to create a keyfile for a bootnode?" + if [ "$REPLY" = "y" ] + then + bootnode -genkey $keyfile + fi + echo "You can now start your bootnode by running start.sh" + fi +} + +case "$1" in + bootnode) + admin_bootnode + ;; + syncmode) + admin_syncmode + ;; + *) + echo Usage: `basename $0` "{bootnode|syncmode}" + trap '' ERR + exit 1 +esac diff --git a/bin/bfalog.sh b/bin/bfalog.sh index 69701e18e3be634005fd28e595aaaed6d058161c..e387b0d02c8ee73e384f0798ab983f58fd53d777 100755 --- a/bin/bfalog.sh +++ b/bin/bfalog.sh @@ -4,5 +4,4 @@ if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi source ${BFAHOME}/bin/libbfa.sh || exit 1 -bfaconfig node exec tail -n 100 -F ${BFANODEDIR}/log diff --git a/bin/checkreceipt.sh b/bin/checkreceipt.sh deleted file mode 100755 index d58cdacf06b7be943da04622008631857f41ec35..0000000000000000000000000000000000000000 --- a/bin/checkreceipt.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 - -geth_exec "eth.getTransactionReceipt(\"$1\");" < /dev/null diff --git a/bin/compile.and.deploy.contract b/bin/compile.and.deploy.contract index 9b5c967fb0f692ebf22abeb3e52266195c206637..bb1d8abe2fe0d1fd8d0485062ea8c44b117f6592 100755 --- a/bin/compile.and.deploy.contract +++ b/bin/compile.and.deploy.contract @@ -32,7 +32,7 @@ var address = rcpt.contractAddress var pubcontract = mycontract.at(address) console.log( pubcontract.address ) EOT - echo '*** Creating contract. Please stand by.' + echo '*** Creating contract. Be patient.' outfile=$( mktemp ) cleanup "$outfile" geth_exec_file $js > $outfile @@ -65,6 +65,5 @@ contractname=${filename%%.sol} contractname=${contractname##*/} contractname=${contractname##contract.} contractname=${contractname%.*} -bfaconfig max prereq jq solc geth create diff --git a/bin/cron.sh b/bin/cron.sh index e1f8ca4b2ab16b5f263554635cc3dbfd8cfebdac..50a0b0ad669253b9e806284b01d57aa52916ad94 100755 --- a/bin/cron.sh +++ b/bin/cron.sh @@ -8,13 +8,4 @@ exec < /dev/null > bfa-cron-output.log 2>&1 # Go to script bin, 'cause we expect to find $BFAHOME/bin/env there cd `dirname $0` source ./env -( - ./start.sh & - # Yes, we wait 60 seconds after starting the server. - # If you don't want to wait, kill the sleep.. the || true - # will capture the ERR trap. - while sleep 60 || true - do - ./monitor.sh - done & -) +./start.sh diff --git a/bin/env b/bin/env index 2139b8492cfa7cc8b1fb1db458bc2c8b657b5cc1..da600287e68bddb6ffc6c0ac67593c8e2b3eac49 100644 --- a/bin/env +++ b/bin/env @@ -1,4 +1,4 @@ export BFAHOME=${HOME}/bfa -export BFANETWORKDIR="${BFAHOME}/network5445" -export BFANETWORKID=5445 -PATH=${PATH}:${BFAHOME}/bin +export BFANETWORKID=47525974938 +export BFANETWORKDIR="${BFAHOME}/network" +PATH=${PATH}:${BFAHOME}/bin:${HOME}/bin diff --git a/bin/explorer.sh b/bin/explorer.sh index 10b69ea870ada6706cd75b3d35bdbef8569bb9e8..a343b885b9713c9b3d4f907f89dc81813d87c0f4 100755 --- a/bin/explorer.sh +++ b/bin/explorer.sh @@ -4,7 +4,6 @@ if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi source ${BFAHOME}/bin/libbfa.sh || exit 1 -bfaconfig max prereq tput curl cd "${BFANETWORKDIR}" width=$( tput cols ) diff --git a/bin/installbfa.sh b/bin/installbfa.sh new file mode 100755 index 0000000000000000000000000000000000000000..bc467f09b2db07acd0faf62fd8b4055add5ebeab --- /dev/null +++ b/bin/installbfa.sh @@ -0,0 +1,193 @@ +#!/bin/bash + +NODEJSPGP=0x68576280 + +# /root often does not have enough space, so we create a directory in /home +# for building, which we hope has more space. +NEW=/home/root/new + +trap 'exit 1' ERR +set -o errtrace +# Be verbose +set -e + +if [ `id -u` -ne 0 ] +then + echo "We are not root, but we need to be. Trying sudo now." + exec sudo $0 +fi + +function info +{ + echo + echo '***' + echo "*** $@" + echo '***' +} + +# For getting a recent nodejs +function nodejsinstall +{ + info nodejs + # Nodejs software repository PGP key + if [ `apt-key export ${NODEJSPGP} 2>&1 | wc -l` -le 50 ] + then + info Adding nodejs software repository PGP key + apt-key adv --keyserver keyserver.ubuntu.com --recv ${NODEJSPGP} + fi + local file=/etc/apt/sources.list.d/nodesource.list + if [ ! -r "$file" ] + then + info Adding nodejs repository to apt sources. + echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -sc) main" > $file + info And now updating the software package list. + apt update + fi + # nodejs also provides npm + aptinstall nodejs +} + +function web3install +{ + ( + cd ~bfa + test -r package.json || + info Initialising nodejs. && + sudo --set-home -u bfa npm init -y + ) + # nodejs package(s) that we need. + echo 'require("web3")' | sudo --set-home -u bfa nodejs 2>/dev/null && return + info Installing nodejs module: web3 "(will show many warnings)" + sudo --set-home -u bfa npm install web3 +} + +function golanginstall +{ + if [ ! -d /usr/local/go ] + then + info Downloading package of go binaries. + mkdir -p ${NEW} + cd ${NEW} + local arch= + case "$(uname -m)" in + x86_64) + arch=amd64 + ;; + *) + echo Do not know how to help you. >&2 + exit 1 + ;; + esac + + #Download go*.linux-${ARCH}.tar.gz from https://golang.org/dl/ + golangurl=$( + curl -f https://golang.org/dl/ 2>/dev/null | + grep linux-${arch}.tar.gz | + grep downloadBox | + sed 's/.*href="//;s/".*//' | + head -1 + ) + name=$( basename $golangurl ) + if [ -r "$name" ] + then + # If we have the download, check if it is corrupt + tar -ztf "$name" >/dev/null 2>&1 || + rm -f "$name" + fi + if [ ! -r "$name" ] + then + curl -f -O $golangurl || + rm -f "$name" + fi + # Integrity checking the archive + tar -xzf "$name" + info Unpacking $name into /usr/local + tar -C /usr/local -xzf go*.tar.gz + fi + PATH=${PATH}:/usr/local/go/bin +} + +function gethinstall +{ + mkdir -p ${NEW} + cd ${NEW} + info Download geth source code. + test -d go-ethereum || + git clone https://github.com/ethereum/go-ethereum + cd ${NEW}/go-ethereum + info Running git pull to ensure that the local go-ethereum repo is up-to-date. + git pull + # + cd ${NEW}/go-ethereum + info Compiling geth + make all && + echo Ignore that last line, if it tells you to run geth now. + mkdir -p ~bfa/bin + cp -vp ${NEW}/go-ethereum/build/bin/{geth,bootnode,abigen,ethkey,puppeth,rlpdump,wnode,swarm,swarm-smoke} ~bfa/bin/ + chown -R bfa:bfa ~bfa +} + +function aptinstall +{ + for pkg in $* + do + # consider apt install --install-suggests if you are masochist + dpkg --verify $pkg 2>/dev/null || + ( + info Installing $pkg + apt -y install $pkg + ) + done +} + +function usersetup +{ + if ! id bfa >/dev/null 2>&1 + then + info Adding required user \"bfa\" + adduser --disabled-password --gecos 'Blockchain Federal Argentina' bfa + fi + cd ~bfa + # cloning if not done already + if [ ! -d ~bfa/bfa ] + then + git clone https://gitlab.bfa.ar/blockchain/nucleo.git bfa + fi + # updating + cd ~bfa/bfa + git pull + # + cd ~bfa + if expand < .bashrc | grep -Evq 'source .*bfa/bin/env' + then + info Adding to automatically source \~bfa/bfa/bin/env via .bashrc + echo 'source ~/bfa/bin/env' >> .bashrc + fi + mkdir -p ~bfa/bfa/network +} + +function cronit +{ + if [ $( ( crontab -u bfa -l 2>/dev/null || true ) | grep -E 'bfa/bin/cron.sh$' | wc -l ) -eq 0 ] + then + info Install crontab to start automatically upon reboot + (( crontab -u bfa -l 2>/dev/null || true ) ; echo '@reboot bfa/bin/cron.sh' ) | crontab -u bfa - + fi +} + +function welcome +{ + info "(re)log in as user bfa" +} + + +# development tools +aptinstall dirmngr apt-transport-https curl git curl build-essential sudo +aptinstall jq libjson-perl libwww-perl +usersetup +nodejsinstall +web3install +golanginstall +gethinstall +cronit +welcome diff --git a/bin/libbfa.js b/bin/libbfa.js index c542be6aefd3aed27b67c7a90d03e6f8ba6b464c..25d17a96d67e792e64d67c50a76dbc7b46395ee0 100644 --- a/bin/libbfa.js +++ b/bin/libbfa.js @@ -5,117 +5,41 @@ module.exports = class Libbfa constructor() { this.fs = require('fs'); this.Web3 = require('web3'); - this._account(); - } - - fatal( txt ) - { - console.log( txt ); - process.exit( 1 ); - } - - _home() - { - if ( this.home != undefined ) - return; - if ( process.env.BFAHOME == undefined ) + // + // BFAHOME + if ( undefined == process.env.BFAHOME ) fatal( "$BFAHOME not set. Did you source bfa/bin/env ?" ); - this.home = process.env.BFAHOME; - } - - _getnetworkid() - { - if ( this.networkid != undefined ) - return; - this._home(); - if ( process.env.BFANETWORKID == undefined ) + // BFANETWORKID + if ( undefined == process.env.BFANETWORKID ) + process.env.BFANETWORKID= 47525974938; + // BFANETWORKDIR + if ( undefined == process.env.BFANETWORKDIR ) + process.env.BFANETWORKDIR = process.env.BFAHOME + '/network'; + // BFANODEDIR + if ( undefined == process.env.BFANODEDIR ) + process.env.BFANODEDIR = this.networkdir + "/node"; + // ACCOUNT + if ( undefined == process.env.BFAACCOUNT ) { - var netw = new Array(); - this.fs.readdirSync( this.home ).forEach( function(file){ - if ( file.startWith('network') ) - netw.push( 0 + file.substring(7) ); + var files = new Array(); + this.fs.readdirSync( process.env.BFANODEDIR + '/keystore' ).forEach( function(filename) { + if ( filename.includes('--') ) + files.push( filename ); }); - if ( netw.length == 0 ) - fatal( "Can't determine your network ID." ); - netw.sort(); - process.env.BFANETWORKID= - this.networkid = netw[0]; + // found none? + if ( files.length == 0 ) + fatal( "Found no accounts in your keystore." ); + files.sort(); + process.env.BFAACCOUNT = '0x' + files[0].replace( /^.*--/, '' ); } - else - this.networkid = process.env.BFANETWORKID; - } - - _networkdir() - { - if ( this.networkdir != undefined ) - return; - this._getnetworkid(); - if ( process.env.BFANETWORKDIR == undefined ) - process.env.BFANETWORKDIR = - this.networkdir = process.env.BFAHOME + '/network' + process.env.BFANETWORKID; - else - this.networkdir = process.env.BFANETWORKDIR; - } - - _nodedir() - { - if ( this.nodedir != undefined ) - return; - this._networkdir(); - if ( this.networkdir == undefined ) - return; - if ( process.env.BFANODEDIR == undefined ) - { - var dirs = new Array(); - //var fs = this.fs; - var nwdir = this.networkdir; - this.fs.readdirSync( this.networkdir ).forEach( - function findnodedirs(f1) { - var name1 = [nwdir,f1].join('/'); - var fs = require('fs'); - if ( fs.statSync( name1 ).isDirectory() ) - { - fs.readdirSync( name1 ).forEach( - function lookforkeystores(f2) { - var name2 = [nwdir,f1,f2].join('/'); - if (f2 == "keystore" && fs.statSync( name2 ).isDirectory() ) - { - dirs.push( name1 ); - } - } - ) - } - } - ); - if ( dirs.length == 0 ) - return; - dirs.sort(); - process.env.BFANODEDIR = - this.nodedir = dirs[0]; - } - else - this.nodedir = process.env.BFANODEDIR; - this.netport = Number.parseInt( this.fs.readFileSync( this.nodedir + '/netport' ) ); - this.rpcport = Number.parseInt( this.fs.readFileSync( this.nodedir + '/rpcport' ) ); - } - - _account() - { - this._nodedir(); - if ( this.acct != undefined ) - return; - if ( process.env.BFANODEDIR == undefined ) - return; - var files = new Array(); - this.fs.readdirSync( process.env.BFANODEDIR + '/keystore' ).forEach( function(filename) { - if ( filename.includes('--') ) - files.push( filename ); - }); - // found none? - if ( files.length == 0 ) - return; - files.sort(); - this.account = '0x' + files[0].replace( /^.*--/, '' ); + // + this.home = process.env.BFAHOME; + this.networkid = process.env.BFANETWORKID; + this.networkdir = process.env.BFANETWORKDIR; + this.nodedir = process.env.BFANODEDIR; + this.netport = Number.parseInt( this.setfromfile( this.nodedir+'/netport', 30303 ); + this.rpcport = Number.parseInt( this.setfromfile( this.nodedir+'/rpcport', 8545 ); + this.account = process.env.BFAACCOUNT; } contract(w3, name) @@ -123,18 +47,24 @@ module.exports = class Libbfa this._networkdir(); var contractdir = [ this.networkdir, 'contracts', name ].join('/'); var contractaddress = this.fs.realpathSync( contractdir ).replace(/^.*\//, ''); - if ( contractaddress == undefined ) + if ( undefined == contractaddress ) return; var abistr = this.fs.readFileSync( contractdir + '/abi' ).toString(); - if ( abistr == undefined ) + if ( undefined == abistr ) return; var abi = JSON.parse( abistr ); - if ( abi == undefined ) + if ( undefined == abi ) return; var c = new w3.eth.Contract( abi, contractaddress ); c.abi = abi; c.contractaddress = contractaddress; - return c; + return c; + } + + fatal( txt ) + { + console.log( txt ); + process.exit( 1 ); } newweb3() @@ -159,4 +89,11 @@ module.exports = class Libbfa isAddr(n) { return n.length == 42 && n.substring(0,2) == "0x"; } + + setfromfile( filename, defval ) + { + if ( this.fs.statSync( filename ).isFile() ) + return this.fs.readFileSync( filename ); + return defval; + } } diff --git a/bin/libbfa.sh b/bin/libbfa.sh index f949c4943e649ec41a63e825c5a2503bb790a920..7a635eb8864762bc6b1ac206fbf4ec08c815b214 100644 --- a/bin/libbfa.sh +++ b/bin/libbfa.sh @@ -2,7 +2,7 @@ # 20180626 Robert Martin-Legene <robert@nic.ar> trap "echo Argh! ; exit 1" ERR -set -e -o errtrace +set -o errtrace function fatal() { @@ -10,15 +10,31 @@ function fatal() exit 1 } -trap "fatal Argh!" ERR +function errtrap +{ + fatal "${ERRTEXT:-Argh!}" +} + +trap errtrap ERR test -n "$BASH_VERSION" || fatal "This file must be source(d) from bash." test "$( caller 2>/dev/null | awk '{print $1}' )" != "0" || fatal "This file must be source(d), not executed." -function stderr +function yesno { - echo "$@" >&2 + local defreply=${1,,} + local yn=Yn + test "$defreply" = "n" && + yn=yN + shift + REPLY= + read -p "$* [${yn}]: " -n 1 -e + REPLY=${REPLY,,} + if [ "$REPLY" != "y" -a "$REPLY" != "n" ] + then + REPLY=$defreply + fi } function cleanup @@ -34,23 +50,12 @@ function cleanup function geth_attach { - bfaconfig node -# local cat=cat -# if echo $- | grep -q x -# then -# cat="tee /dev/tty |" -# fi -# $cat | geth --cache 0 "$@" attach ipc:${BFANODEDIR}/geth.ipc } function geth_exec_file { test -r "$1" - if echo $- | grep -q x && [ -t 1 ] - then - sed "s/^/input: /" "$1" - fi geth_attach --exec "loadScript(\"$1\")" </dev/null } @@ -62,7 +67,6 @@ function geth_exec function geth_rpc { - bfaconfig node local cmd=$1 test -n "$cmd" local params= @@ -75,7 +79,7 @@ function geth_rpc params="${params}${1}," shift done - # Eat the last command and add a ] + # Eat the last comma and add a ] params=${params/%,/]} fi local json=$( @@ -95,155 +99,21 @@ function geth_rpc echo "$json" | jq .result } -function getnetworkid -{ - test -n "${BFANETWORKID}" && - return - local dir="${BFANETWORKDIR}" - for dir in $( ls -1d "${BFAHOME}"/* | sort --version-sort ) - do - if [ -d "${dir}" ] - then - local base=$( basename "${dir}" ) - base=$( echo "${base}" | grep -E '^network[0-9]+$' ) || true - if [ -n "${base:7}" ] - then - BFANETWORKID=${base:7} - return - fi - fi - done -} - -function networkdir -{ - test -n "${BFAHOME}" -a -d "${BFAHOME}" || - fatal "\$BFAHOME in your environment must point to a directory." - # If no BFANETWORKDIR variable has been set, we will try to guess - # the network directory based on the directory we are in. - if [ -z "${BFANETWORKDIR}" ] - then - BFANETWORKDIR=$( - ls -1d "${BFAHOME}"/* | - grep -qE '/network[0-9]+$' | - sort --version-sort | - head -1 - ) - fi - test -n "${BFANETWORKDIR}" -a ! -d "${BFANETWORKDIR}" && - fatal "\$BFANETWORKDIR (\"${BFANETWORKDIR}\") not found." - if [ -z "${BFANETWORKDIR}" -o ! -d "${BFANETWORKDIR}" ] - then - local num=0 - while [ $num -lt 9876 ] - do - num=$(( $RANDOM * $RANDOM )) - done - stderr "I can not find your BFANETWORKDIR." - stderr "Consider running: mkdir ${BFAHOME}/network${num} or set BFANETWORKDIR in ${BFAHOME}/bin/env" - exit 1 - fi - getnetworkid - gen_genesis -} - -function nodedir -{ - networkdir - # set defaults - if [ -z "$BFANODEDIR" ] - then - # If there is no nodedir found, use the first node we - # find in the networkdir - BFANODEDIR=$( - ls -1d "${BFANETWORKDIR}"/*/keystore 2>/dev/null | - sort --version-sort | - head -1 - ) - if [ -z "${BFANODEDIR}" ] - then - BFANODEDIR="${BFANETWORKDIR}/node1" - echo "No node directories found. Initialising a new node." - geth --datadir ${BFANODEDIR} init ${BFAHOME}/src/genesis.json - else - # Get rid of the "keystore" label - BFANODEDIR=$( dirname $BFANODEDIR ) - fi - fi - test -n "${BFANODEDIR}" || - fatal "Unable to guess \$BFANODEDIR . Consider setting it explicitly in ${BFAHOME}/bin/env" - test -d "${BFANODEDIR}" || - fatal "$BFANODEDIR is not a directory." - test -d "${BFANODEDIR}/geth/chaindata" || - fatal "Node is not initialised. Consider running: geth --datadir $BFANODEDIR init ${BFAHOME}/src/genesis.json" - # Support migrating from "former" setups - if [ -r "${BFANODEDIR}/port" -a ! -r "${BFANODEDIR}/netport" ] - then - mv "${BFANODEDIR}/port" "${BFANODEDIR}/netport" - fi - # - test -r "${BFANODEDIR}/netport" || - echo $(( $RANDOM / 2 + 12345 )) > ${BFANODEDIR}/netport - netport=$( cat ${BFANODEDIR}/netport ) - test $? = 0 - test -r "${BFANODEDIR}/rpcport" || - echo $(( $RANDOM / 2 + 12345 )) > ${BFANODEDIR}/rpcport - rpcport=$( cat ${BFANODEDIR}/rpcport ) -} - function extradata { - account # something uniqueish ## find default interface - local def_if=$( ( ip -4 route show ; ip -6 route show ) | expand | sed -ne '/^default /{s/ */ /g;s/^.* dev //;s/ .*//;p;q}' ) - local mymac=$( ip link show ${def_if} | sed -ne '/link\|ether/{s/^.*link.ether //;s/ .*//;s/://g;p;q}' ) + local def_if=$( + ( ip -4 route show ; ip -6 route show ) | + expand | + sed -ne '/^default /{s/ */ /g;s/^.* dev //;s/ .*//;p;q}' + ) + local mymac=$( + ip link show ${def_if} | + sed -ne '/link\|ether/{s/^.*link.ether //;s/ .*//;s/://g;p;q}' + ) # - echo -n "${account:0:19}.${mymac:0:12}" -} - -function account -{ - nodedir - if [ -z "$account" ] - then - test -d "${BFANODEDIR}/keystore" - account=$( - ls -1dl "${BFANODEDIR}"/keystore/*--* 2>/dev/null | - head -1 | - sed 's/.*--//' - ) - fi - if [ -z "$account" ] - then - echo "No accounts found. Creating a new one (they are free)." - geth --datadir ${BFANODEDIR} --password /dev/null account new - if [ -n "$loop_protection" ] - then - fatal "Loop detected." - fi - loop_protection=1 - account - fi - unset loop_protection -} - -function bfaconfig -{ - case "$1" in - network) - networkdir - ;; - node) - nodedir - ;; - account|max) - account - ;; - *) - fatal "Unknown bfaconfig request" - ;; - esac + echo -n "${BFAACCOUNT:0:19}.${mymac:0:12}" } function prereq @@ -261,57 +131,8 @@ function prereq test $err -eq 0 } -function gen_genesis -{ - local genesis="${BFAHOME}/src/genesis.json" - test -e "${genesis}" && - return - bfaconfig account - local zero4="0000" - local zero8="${zero4}${zero4}" - local zero16="${zero8}${zero8}" - local zero20="${zero16}${zero4}" - local zero32="${zero16}${zero16}" - local zero40="${zero20}${zero20}" - local zero60="${zero40}${zero20}" - local zero64="${zero32}${zero32}" - local zero128="${zero64}${zero64}" - local zero130="${zero128}00" - local nodes=$account - local timestamp=$( printf '0x%08x' $( date +%s ) ) - local vanity_Blockchain="426c6f636b636861696e" - local vanity_Federal="4665646572616c" - local vanity_Argentina="417267656e74696e61" - local vanity_NIC="4e4943" - local vanity="${vanity_Blockchain}20${vanity_Federal}20${vanity_Argentina}20${vanity_NIC}" - ## Make sure vanity is exactly 64 characters - vanity="${vanity}${zero64}" - vanity="${vanity:0:64}" - echo -n "$vanity" | grep -Evq '[^0-9a-fA-F]' - cat <<-EOCONF > ${genesis} - { - "config": { - "chainId": ${BFANETWORKID}, - "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 4, - "eip150Hash": "0x${zero64}", - "clique": { "period": 15, "epoch": 30000 } - }, - "nonce": "0x0000000000000000", - "timestamp": "${timestamp}", - "extraData": "0x${vanity}${account}${zero130}", - "gasUsed": "0x0", "gasLimit": "0xffeeddcc", "difficulty": "0x1", - "number": "0x0", - "mixHash": "0x${zero64}", - "coinbase": "0x${zero40}", - "parentHash": "0x${zero64}", - "alloc": { "${account}": { "balance": "0x200${zero60}" } } - } - EOCONF -} - function contract { - bfaconfig network local contract="${BFANETWORKDIR}/contracts/${1}" local realdir=$( realpath "${contract}" ) test -r "${realdir}" @@ -341,3 +162,55 @@ function contractSendTx echo "contract.${func}.sendTransaction(${args} {from: eth.accounts[0], gas: 1000000} )" } +############### +# bfainit # +test -n "${BFAHOME}" -a \ + -d "${BFAHOME}" || + fatal "\$BFAHOME in your environment must point to a directory." +# +# BFANETWORKID +test -n "${BFANETWORKID}" || BFANETWORKID=47525974938 +# +# BFANETWORKDIR +test -n "${BFANETWORKDIR}" || BFANETWORKDIR="${BFAHOME}/network" +mkdir -p "${BFANETWORKDIR}" +test -d "${BFANETWORKDIR}" || fatal "\$BFANETWORKDIR (\"${BFANETWORKDIR}\") not found." +# +# BFANODEDIR +test -n "$BFANODEDIR" || BFANODEDIR="${BFANETWORKDIR}/node" +if [ ! -d "${BFANODEDIR}" -o ! -d "${BFANODEDIR}/geth/chaindata" ] +then + echo "Node is not initialised. Initialising with BFA genesis." + geth --cache 0 --datadir "${BFANODEDIR}" init "${BFAHOME}/src/genesis.json" +fi +# +# netport +netport=30303 +if [ -r "${BFANODEDIR}/netport" ] +then + netport=$( cat ${BFANODEDIR}/netport ) + test $? = 0 +fi +# +# rpcport +rpcport=8545 +if [ -r "${BFANODEDIR}/rpcport" ] +then + rpcport=$( cat ${BFANODEDIR}/rpcport ) + test $? = 0 +fi +# +# BFAACCOUNT +if [ -z "$BFAACCOUNT" ] +then + if ! ls -1d ${BFANODEDIR}/keystore/*--* >/dev/null 2>&1 + then + echo "No accounts found. Creating a new one (they are free)." + geth --cache 0 --datadir ${BFANODEDIR} --password /dev/null account new + fi + BFAACCOUNT=$( + ls -1d "${BFANODEDIR}"/keystore/*--* 2>/dev/null | + head -1 | + sed 's/.*--//' + ) +fi diff --git a/bin/maymine.sh b/bin/maymine.sh index 594455c6220e8b2eb7551334f33ab929fbbce830..ca5daa6d7a68bc00a5e1304dfdb3bda6c7c570bf 100755 --- a/bin/maymine.sh +++ b/bin/maymine.sh @@ -4,7 +4,6 @@ if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi source ${BFAHOME}/bin/libbfa.sh || exit 1 -bfaconfig node res=$( geth_exec_file "${BFAHOME}/src/maymine.js" ) if [ "$res" = "true" ] diff --git a/bin/monitor.sh b/bin/monitor.sh index ab3f83f8221acd9c26d359ebb9690c80a3004d33..478e9cbae740d0551e4d888d3afa018265c2dfb7 100755 --- a/bin/monitor.sh +++ b/bin/monitor.sh @@ -2,23 +2,14 @@ if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi source ${BFAHOME}/bin/libbfa.sh || exit 1 +ERRTEXT="Monitoring failed" function json_query { - cmd=$1 - params=$2 - if [ -n "$params" ] - then - params=",\"parameters\":[$2]" - fi - json=$( - curl -s -H 'Content-type: application/json' -X POST --data "{\"jsonrpc\":\"2.0\",\"method\":\"${cmd}\"${params},\"id\":1}" http://127.0.0.1:$rpcport - ) -} - -function json_err -{ - echo "$json" | jq -r '.result' + local ERRTEXT="Monitoring RPC failed" + trap '' ERR + json=$( geth_rpc $* ) + trap errtrap ERR } function json_arraylength @@ -26,14 +17,9 @@ function json_arraylength jq -r length } -function json_result -{ - echo "$json" | jq -r '.result' -} - -bfaconfig node json_query admin_peers -numpeers=$( json_result | json_arraylength ) +test -n "${json}" || exit 0 +numpeers=$( echo $json | json_arraylength ) statusfile=$( mktemp ) cleanup "${statusfile}" chmod 644 "${statusfile}" @@ -43,7 +29,7 @@ echo "total-peer-count: ${numpeers}" >> ${statusfile} peercount=0 for idx in $( seq 0 $(( $numpeers - 1 )) ) do - eth=$( echo "$json" | jq -r .result[$idx].protocols.eth ) + eth=$( echo "$json" | jq -r .[$idx].protocols.eth ) if [ "$eth" = "handshake" ] then continue @@ -51,11 +37,11 @@ do #echo -n "$idx: "; echo "$eth" | jq -c remoteid=$( echo "$json" | - jq -r .result[$idx].id + jq -r .[$idx].id ) remoteaddress=$( echo "$json" | - jq -r .result[$idx].network.remoteAddress + jq -r .[$idx].network.remoteAddress ) remoteip=$( echo "$remoteaddress" | diff --git a/bin/numpending.sh b/bin/numpending.sh deleted file mode 100755 index cd77368f44364e85c31ad97b613c7a9abcf0616f..0000000000000000000000000000000000000000 --- a/bin/numpending.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 - -echo txpool.status.pending | geth_attach | grep -Ev '^> $' | tail -1 -exit - - -function json_query -{ - cmd=$1 - params=$2 - if [ -n "$params" ] - then - params=",\"parameters\":[$2]" - fi - json=$( - curl -s -H 'Content-type: application/json' -X POST --data "{\"jsonrpc\":\"2.0\",\"method\":\"${cmd}\"${params},\"id\":1}" http://127.0.0.1:$rpcport - ) -} - -bfaconfig node -json_query web3j_txpool -echo $json | jq -exit - diff --git a/bin/start.sh b/bin/start.sh index be39a51ee53e94b046def0d93a9cea23f062c2e0..c82e603ca261cf01ff823868a63c23cf140d5fae 100755 --- a/bin/start.sh +++ b/bin/start.sh @@ -3,27 +3,28 @@ if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi source ${BFAHOME}/bin/libbfa.sh || exit 1 -bootnodeid=6c81b38551fec2f1142b58ed65137cc1b7dfdc7b35bc556ef26604c41e30fcdeb12212b3c19913584f71dc7bf87d76cd67fa523e96996c0f148390fb76fdc5f7 -bootnodev6=2800:40:1:6::135 -bootnodev4=200.68.65.135 -bootnodeport=5445 -bootnodes="enode://${bootnodeid}@[$bootnodev6]:${bootnodeport},enode://${bootnodeid}@[$bootnodev4]:${bootnodeport}" - -bfaconfig max +bootNICv4="enode://59ae768ecdee632e0daceccb6f71b215392eba89230d626573f2fb4e9c0786c9a661027ab7343820ca63d96fe48ffd81ed1bf6e4d512f0ba50ec072c9efd9e4e@[200.108.146.101]:30301" +bootUNCv4="enode://82b66b13d7addcf9ffe1e4e972a105f6ccf50557161c4a0978a5d9ce595ababde609ea8a49897ae89b1d41e90551cb2e9241363238593e950ca68bd5af7c24d6@[200.16.28.28]:30301" +bootnodes="${bootUNCv4},${bootNICv4}" function accountlist { local accts= - for file in ${BFANODEDIR}/keystore/*--* + local filename + for filename in ${BFANODEDIR}/keystore/*--* do - if [ -r "$file" ] + if [ -r "$filename" -a ${#filename} -ge 40 ] then - acct=$( echo $file | sed 's/^.*--//' ) + acct=${filename:$(( ${#filename} - 40 ))} accts="${accts},${acct}" fi done - # strip first comma - echo "--password /dev/null --unlock ${accts:1}" + # strip leading comma + accts=${accts#,} + if [ ${#accts} -ge 40 ] + then + echo "--password /dev/null --unlock ${accts}" + fi } # touch the "miner" file if you are authorized to mine @@ -46,44 +47,109 @@ function getsyncmode echo "--syncmode ${syncmode}" } +test -n "${BFAACCOUNT}" || + fatal "No account defined." -# Start the miner. -( - flock --nonblock --exclusive 9 || exit 1 - if [ -t 1 ] - then - echo Logging everything to ${BFANODEDIR}/log - echo Consider running: tail -n 1000 -F ${BFANODEDIR}/log - fi - while : - do - echo - echo '***' - echo - # (re)configure parameters (you never know if they changed) - flexargs="$( accountlist) $( getminer ) $( getsyncmode ) --extradata $( extradata )" - set -x - geth \ - --datadir ${BFANODEDIR} \ - --networkid $BFANETWORKID \ - --bootnodes "${bootnodes}" \ - --rpc \ - --rpcport $rpcport \ - --rpcapi "eth,net,web3,admin,clique,miner,personal" \ - --port $netport \ - --nousb \ - --txpool.nolocals \ - --txpool.accountslots 128 \ - --txpool.globalslots 32768 \ - --txpool.accountqueue 512 \ - --txpool.globalqueue 8192 \ - --gcmode archive \ - --cache 512 \ - --verbosity 3 \ - ${flexargs} & - set +x - echo $! > ${BFANODEDIR}/geth.pid - wait - sleep 60 - done 2>&1 | ${BFAHOME}/bin/log.sh ${BFANODEDIR}/log & -) 9>> ${BFANODEDIR}/geth.pid + +function startbootnode +{ + local ERRTEXT="bootnode section failed" + local keyfile=${BFANETWORKDIR}/bootnode/key + local pidfile=${BFANETWORKDIR}/bootnode/bootnode.pid + which bootnode >/dev/null 2>&1 || return 0 + test -r $keyfile || return 0 + ( + flock --nonblock --exclusive 9 || ( + echo "A bootnode is already running." + false + ) || exit + if [ -t 1 ] + then + echo Starting bootnode. + fi + while : + do + echo + echo '***' + echo + bootnode --nodekey $keyfile & + echo $! > $pidfile + wait + sleep 60 + done 2>&1 | ${BFAHOME}/bin/log.sh ${BFANETWORKDIR}/bootnode/log & + ) 9>> $pidfile +} + +function startmonitor +{ + local ERRTEXT="monitor section failed" + local pidfile=${BFANETWORKDIR}/monitor.pid + ( + flock --nonblock --exclusive 9 || ( + echo "A monitor is already running." + false + ) || exit + if [ -t 1 ] + then + echo Running monitor every 60 seconds. + fi + while : + do + monitor.sh & + echo $! > $pidfile + wait + sleep 60 + done & + ) 9>> $pidfile +} + +function startgeth +{ + # Start the node. + local ERRTEXT="geth section failed" + which geth >/dev/null 2>&1 || return 0 + ( + flock --nonblock --exclusive 9 || ( + echo "A geth is already running." + false + ) || exit 1 + echo ${BASHPID} > ${BFANODEDIR}/start-loop.pid + if [ -t 1 ] + then + echo Starting geth + echo Logging everything to ${BFANODEDIR}/log + echo Consider running: tail -n 1000 -F ${BFANODEDIR}/log + fi + while : + do + ERRTEXT="geth" + echo + echo '***' + echo + # (re)configure parameters (you never know if they changed) + flexargs="$( accountlist) $( getminer ) $( getsyncmode ) --extradata $( extradata )" + set -x + geth \ + --datadir ${BFANODEDIR} \ + --networkid ${BFANETWORKID} \ + --bootnodes "${bootnodes}" \ + --rpc \ + --rpcport $rpcport \ + --rpcapi "eth,net,web3,admin,clique,miner,personal" \ + --port $netport \ + --nousb \ + --gcmode archive \ + --cache 512 \ + --verbosity ${BFAVERBOSITY:-3} \ + ${flexargs} & + set +x + echo $! > ${BFANODEDIR}/geth.pid + wait + sleep 60 + done 2>&1 | ${BFAHOME}/bin/log.sh ${BFANODEDIR}/log & + ) 9>> ${BFANODEDIR}/start-loop.pid +} + +startgeth +startbootnode +startmonitor diff --git a/bin/syncmode.sh b/bin/syncmode.sh deleted file mode 100755 index 009d260899f968f030e86c503a46ec7bc4c8d9bf..0000000000000000000000000000000000000000 --- a/bin/syncmode.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# Robert Martin-Legene <robert@nic.ar> - -if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 - -defaultmode="fast" - -echo "Available synchronization modes:" -echo " full : verify all blocks and all transactions since genesis (most secure)" -echo " fast : verify all blocks but not all transactions (faster than full, but less certain)" -echo " light: Makes this node into a light node which downloads almost" -echo " nothing, but relies on fast and full nodes in the network" -echo " to answer it's requests. This is the fastest and uses least" -echo " local resources, but outsources all trust to another node." -echo "Default mode is fast, because for many, it is a healthy compromise" -echo "between speed and paranoia. You can change the setting, according to" -echo "your needs." - -function modefilter -{ - case "$mode" in - "full"|"fast"|"light") - ;; - *) - echo "Unsupported mode." - mode="" - return - ;; - esac - true -} - -bfaconfig node -mode=$( cat ${BFANODEDIR}/syncmode 2>/dev/null || true ) -mode=${mode:-${defaultmode}} -orgmode=$mode -modefilter -echo "Your current mode is set to ${mode}" -killed=0 -mode= - -echo -while [ -z "${mode}" ] -do - read -p "Which mode do you wish? : " mode - modefilter -done -echo $mode > ${BFANODEDIR}/syncmode -if [ "$orgmode" = "fast" -a "$mode" = "full" ] -then - echo "You increased your paranoia level. The proper thing to do now," - echo "would be to delete your version of what you synchronized with" - echo "fast mode, and revalidate everything in the entire blockchain." - echo "This probably takes quite a long time and also requires downloading" - echo "all blocks from the entire blockchain again." - REPLY= - while [ "$REPLY" != "y" -a "$REPLY" != "n" ] - do - read -p "Do you wish to delete all downloaded blocks and resynchronize? [yn]: " - REPLY=${REPLY,,} - done - if [ "$REPLY" = "y" ] - then - if [ -r "${BFANODEDIR}/geth.pid" ] - then - local pid=$( cat ${BFANODEDIR}/geth.pid ) - kill -0 $pid 2>/dev/null && - echo "Killing running geth." && - killed=1 - while ! kill $pid 2>/dev/null - do - sleep 1 - done - fi - rm -fr ${BFANODEDIR}/geth/chainstate ${BFANODEDIR}/geth/lightchainstate - geth --cache 0 --datadir ${BFANODEDIR} init ${BFAHOME}/src/genesis.json - test $killed -eq 1 && - echo && - echo "The startup.sh should restart your geth shortly." - fi -fi diff --git a/bin/transactors.pl b/bin/transactors.pl deleted file mode 100755 index d5018b0a1aa1db91e731d40400da6583f0ebc233..0000000000000000000000000000000000000000 --- a/bin/transactors.pl +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -use warnings; -use IO::File; -use Math::BigInt; -use Carp; -$Carp::Verbose = 1; - -die "\$BFAHOME not set. Did you source bfa/bin/env ?\n" - unless exists $ENV{BFAHOME}; -chdir "$ENV{BFAHOME}" or die $!; - -package tools; -my $rpcport; -my $ua = LWP::UserAgent->new; - -sub new -{ - my $class = shift; - return bless {@_}, ref $class || $class; -} - -sub wait -{ - my $i = ++$_[0]->{'wait'}; - printf "%s%c[D", substr('|/-\\', $i%4, 1), 27; - sleep 1; -} - -sub cat($) -{ - my ($filename) = @_; - my $fh = IO::File->new($filename) or return; - return join('', $fh->getlines); -} - -sub hex2string($) -{ - my ($msg)=@_; - my $txt = ''; - while ($msg ne '') - { - my $i=hex( substr($msg,0,2) ); - my $c='.'; - $c=chr($i) if $i >= 32 and $i <= 127; - $txt .= $c; - $msg=substr $msg, 2; - } - return $txt; -} - -sub rpcreq -{ - my ( $opname, @params ) = @_; - if ( not defined $rpcport ) - { - $rpcport = tools::cat "$ENV{BFAHOME}/network5445/node1/rpcport" or die; - } - my $req = HTTP::Request->new( POST => "http://127.0.0.1:$rpcport" ); - $req->content_type('application/json'); - my $extra = scalar @params - ? sprintf(qq(,\"params\":[%s]), join(',', @params)) - : ''; - $req->content( qq({"jsonrpc":"2.0","method":"${opname}"${extra},"id":1})); - my $res = $ua->request($req); - die $res->status_line - unless $res->is_success; - return $res->content; -} - -package balance; -use JSON; - -sub new -{ - my ($class, $acct, $at) = @_; - my $self = bless {}, ref $class || $class; - $self->get( $acct, $at ) if defined $acct; - return $self; -} - -sub acct -{ - my ($self, $acct) = @_; - if ( defined $acct ) - { - $acct = '0x'.$acct if $acct !~ /^0x/; - $self->{'_acct'} = $acct; - } - return unless exists $self->{'_acct'}; - return $self->{'_acct'}; -} - -sub at -{ - my ($self, $at) = @_; - $self->{'_at'} = $at if defined $at; - return sprintf('0x%x', $self->{'_at'}) if exists $self->{'_at'}; - return 'latest'; -} - -sub get -{ - my ($self, $acct, $at) = @_; - $self->acct($acct) if defined $acct; - $self->at($at) if defined $at; - my @params = ( sprintf(qq("%s","%s"),$self->acct,$self->at) ); - my $content = tools::rpcreq( 'eth_getBalance', @params ); - my $json; - eval { $json = decode_json( $content ) }; - my $error = error->new( $content ); - if ( $error ) - { - my $msg = ''; - return 'NOTFOUND' if $error->message =~ /^missing trie node /; - die join(' * ', @params, $content); - return; - } - die if not exists $json->{'result'}; - die if not defined $json->{'result'}; - return Math::BigInt->from_hex( $json->{'result'} ); -} - - -package error; -use JSON; - -sub new -{ - my ($class, $json_in) = @_; - my $json; - eval { $json = decode_json( $json_in ) }; - return unless defined $json; - return unless exists $json->{'error'}; - my $self = bless { - '_code' => undef, - '_message' => undef, - }, ref $class || $class; - $self->code( $json->{'error'}->{'code'} ) if exists $json->{'error'}->{'code'}; - $self->message( $json->{'error'}->{'message'} ) if exists $json->{'error'}->{'message'}; - return $self; -} - -sub code -{ - my ( $self, $val ) = @_; - $self->{'_code'} = $val if scalar @_ > 1; - return $self->{'_code'}; -} - -sub message -{ - my ( $self, $val ) = @_; - $self->{'_message'} = $val if scalar @_ > 1; - return $self->{'_message'}; -} - -package block; -use LWP; -use JSON; - -sub new -{ - my ( $class, $json_raw ) = @_; - return unless defined $json_raw; - return if $json_raw eq ''; - my $self = bless {}, ref $class || $class; - $self->{'json_raw'} = $json_raw; - eval { $self->{'json'} = decode_json( $json_raw ) }; - return if $@; - $self->error( error->new($json_raw) ); - return $self; -} - -sub error -{ - return if not exists $_[0]->{'error'}; - return $_[0]->{'error'}; -} - - -sub json -{ - return unless exists $_[0]->{'json'}; - return $_[0]->{'json'}; -} - -sub result -{ - return unless exists $_[0]->{'json'}->{'result'}; - return $_[0]->{'json'}->{'result'}; -} - -sub number -{ - return if not exists $_[0]->result->{'number'}; - return hex( $_[0]->result->{'number'} ); -} - -sub timestamp -{ - return if not exists $_[0]->result->{'timestamp'}; - return hex( $_[0]->result->{'timestamp'} ); -} - -sub miner -{ - return if not exists $_[0]->result->{'miner'}; - return $_[0]->result->{'miner'}; -} - -sub get($;$) -{ - my ($number) = @_; - $number = sprintf('0x%x', $number) if $number ne 'earliest'; - my $cachefile = "cache/block.$number"; - my $content = tools::rpcreq( 'eth_getBlockByNumber', qq("$number"), "true"); - my $block = block->new( $content ); - return if not defined $block; - return if not exists $block->{'json'}; - die $block->error->message - if $block->error; - return if not $block->result; - return $block; -} - -sub tx { - my ($self) = @_; - return $self->result->{'transactions'}; -} - -package main; - -my $number = shift || 'earliest'; -my $_rcpts; - -sub rcpt -{ - return 0 if exists $_rcpts->{$_[0]}; - $_rcpts->{$_[0]} = 1; - return 1; -} - -while ( 1 ) -{ - my $block = block::get($number); - exit 0 if not defined $block; -use Data::Dumper; print Dumper( $block->result ); -die $block->miner; - rcpt( $block->miner ); - my $txref = $block->tx; - for my $tx (@$txref) - { - my $from = $tx->{'from'}; - my $to = $tx->{'to'}; - my $value = $tx->{'value'}; - next if $value eq '0x0'; - printf "%s\n", $to if rcpt( $to ); - } - $number = $block->number + 1; -} diff --git a/bin/tsa-insert.sh b/bin/tsa-insert.sh deleted file mode 100755 index 1509e6d23d20aa04fae6bb23b086e9b15f6be112..0000000000000000000000000000000000000000 --- a/bin/tsa-insert.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 - -contract="TimeStampAuthority" -contract=${BFANETWORKDIR}/contracts/${contract} -contract=$( realpath "${contract}" ) -test -r "${contract}" -basecontract=$( basename "${contract}" ) -test -n "${basecontract}" -abi=$( cat ${BFANETWORKDIR}/contracts/${basecontract}/abi ) -test -n "${abi}" -hashes= -while read -p : -do - sum=$( echo -n "$REPLY" | sha256sum | cut -c -64 ) - echo $sum - hashes="$hashes,web3.toDecimal(\"0x$sum\")" -done -hashes="${hashes:1}" -echo $hashes -js=$( mktemp ) -cleanup "$js" -cat > $js <<EOT -var mycontract = eth.contract(${abi}) -var thecontract = mycontract.at("${basecontract}") -console.log( thecontract.put.sendTransaction( [${hashes}], {from: eth.accounts[0], gas: 1000000} ) ) -EOT -out=$( mktemp ) -cleanup "$out" -geth_exec_file "${js}" > ${out} -if [ ` wc -l < ${out} ` = 2 -a ` tail -1 < ${out} ` = "true" ] -then - trans=` head -1 < ${out} ` - echo "Sent checksum(s) in transaction ${trans}." -else - ( - cat ${js} - echo - echo ' ***' - echo - cat ${out} - ) >&2 - exit 1 -fi diff --git a/bin/tsa-verify.sh b/bin/tsa-verify.sh deleted file mode 100755 index c2a055d51e67b879f3d9b5ab781d70683ba0304d..0000000000000000000000000000000000000000 --- a/bin/tsa-verify.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 - -contract="TimeStampAuthority" -contract=${BFANETWORKDIR}/contracts/${contract} -contract=$( realpath "${contract}" ) -test -r "${contract}" -basecontract=$( basename "${contract}" ) -test -n "${basecontract}" -abi=$( cat ${BFANETWORKDIR}/contracts/${basecontract}/abi ) -test -n "${abi}" -hashes= -sum=$( echo -n "$1" | sha256sum | cut -c -64 ) -echo $sum -hashes="web3.toDecimal(\"0x$sum\")" -echo $hashes -js=$( mktemp ) -cleanup "$js" -cat > $js <<EOT -var mycontract = eth.contract(${abi}) -var thecontract = mycontract.at("${basecontract}") -console.log( thecontract.get.call( [${hashes}], {from: eth.accounts[0], gas: 1000000} ) ) -EOT -out=$( mktemp ) -cleanup "$out" -geth_exec_file "${js}" > ${out} -if [ ` wc -l < ${out} ` = 2 -a ` tail -1 < ${out} ` = "true" ] -then - block=` head -1 < $out ` - if [ "${block}" -gt "0" ] - then - echo "Checksum first seen in block ${block}" - else - echo "The checksum has not been stored in the smart contract yet." - exit 1 - fi -else - ( - cat ${js} - echo - echo ' ***' - echo - cat ${out} - ) >&2 -fi diff --git a/bin/txflood.sh b/bin/txflood.sh deleted file mode 100755 index 1d20bbde2ce66a82153c4194a86f6ca80db75979..0000000000000000000000000000000000000000 --- a/bin/txflood.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -if [ -z "${BFAHOME}" ]; then echo "\$BFAHOME not set. Did you source bfa/bin/env ?" >&2; exit 1; fi -source ${BFAHOME}/bin/libbfa.sh || exit 1 - -cd $BFAHOME - -while : -do - while num=` $BFAHOME/bin/numpending.sh `; [ $num -lt 2500 ] - do - contract=$( readlink ${BFANETWORKDIR}/contracts/TimestampDocument ) - abi=$( cat ${BFANETWORKDIR}/contracts/${contract}/abi ) - ( - echo "var mycontract = eth.contract(JSON.parse($abi));" - echo "var thecontract = mycontract.at(\"$contract\");" - n=0 - SECONDS=0 - while [ $n -lt 10000 -a $SECONDS -lt 600 ] - do - n=$(( $n + 1 )) - echo "thecontract.storeDocument.sendTransaction( \"dagenidag.${n}\", {from: eth.accounts[0], gas: 1000000});" - done - ) | - geth_attach - - done - echo `date`: $num pending. - sleep 2 -done - diff --git a/doc/compiling-geth-on-debian.md b/doc/compiling-geth-on-debian.md deleted file mode 100644 index f55b6d07cf076d0c7eee1734f7312b1cc67b740f..0000000000000000000000000000000000000000 --- a/doc/compiling-geth-on-debian.md +++ /dev/null @@ -1,34 +0,0 @@ -# Compiling geth on Debian - -## Prerequisites - -1. `mkdir ~/new ~/bin` -2. `cd ~/new` -3. `sudo apt install build-essential git libjson-perl` -4. `git clone https://github.com/ethereum/go-ethereum` - -## Compiling Go itself (takes less than 5 minutes) - -Go is only needed for compiling geth - afterwards we can delete it - -1. Download __go*.linux-amd64.tar.gz__ from [https://golang.org/dl/] e.g. [https://dl.google.com/go/go1.11.linux-amd64.tar.gz] -2. `tar -xzf go*.tar.gz` -3. `export PATH=${HOME}/new/go/bin:${PATH}:${HOME}/bin` -4. `cd go-ethereum` -5. `make geth` -6. `cp build/bin/geth ~/bin/` -7. `cd ..` -8. `rm -r ~/new/go` - -## Compililng Solc takes a while (like 20-50 times longer than compiling geth) - -If you wish to compile contracts too, compile Solidity as well. - -$ `git clone --recursive https://github.com/ethereum/solidity` -$ `cd solidity` -$ `git submodule update --init --recursive` -$ `./scripts/install_deps.sh` -$ `mkdir build` -$ `cd build` -$ `cmake .. && make` -$ `cp -p solc/solc ~/bin/` diff --git a/doc/installing-geth-on-ubuntu.md b/doc/installing-geth-on-ubuntu.md deleted file mode 100644 index 050ae22d7f7221165fe516e291bcd2e0d6b0b157..0000000000000000000000000000000000000000 --- a/doc/installing-geth-on-ubuntu.md +++ /dev/null @@ -1,5 +0,0 @@ -$ `su` -# `apt install software-properties-common libjson-perl` -# `add-apt-repository -y ppa:ethereum/ethereum` -# `apt update` -# `apt install ethereum` diff --git a/doc/whoiswho.txt b/doc/whoiswho.txt deleted file mode 100644 index 4be4a0d426ef50fc395a05a4e027e87b47ce6650..0000000000000000000000000000000000000000 --- a/doc/whoiswho.txt +++ /dev/null @@ -1,25 +0,0 @@ -NIC1 bfa@bc.duna.com.ar -Sealer 0x2fd693d1204907ae7d97b5d7d2e93ef877ef2c7d -enode://6c81b38551fec2f1142b58ed65137cc1b7dfdc7b35bc556ef26604c41e30fcdeb12212b3c19913584f71dc7bf87d76cd67fa523e96996c0f148390fb76fdc5f7@[200.68.65.135]:5445 -enode://6c81b38551fec2f1142b58ed65137cc1b7dfdc7b35bc556ef26604c41e30fcdeb12212b3c19913584f71dc7bf87d76cd67fa523e96996c0f148390fb76fdc5f7@[2800:40:1:6::135]:5445 - -CABASE1 apugawko@ -Sealer 0xf2d954738d49ff0fca43c7b3915e8499c983c5de -enode://d088f3e97e1b3d41eebe3d9596b61ed05c79a0a3d6496fe63f916a955e30b456dbd96b875ca160adea81c4341bb3049ad4c831f767d8bf948d96a48b51e97c71@[200.9.157.216]:23236 - -NIC2 robert@cloud.duna.com.ar -Sealer 0xbeebad827a9664d6be5be0f9393dd158826833c6 -enode://1a1abca46cf2f7dd1721c48df699c5b1af507c7953b8a52c353c718dbda06df43fc3e5bf43665a07dfb8be0f40f5f94c8b8224b2bd124639c89897d8774479be@[190.210.214.194]:21296 - -NIC3 Mariano Absatz -Sealer 0x95368af92200d72ae698466f44f9f4b34a7abb2f -enode://2076aec363e2429600b1629875841cf00a41c155b6fc8bfe5a525beb85cbff79712a6746b37969de74e4f6afe669e8fe512af50d0c47d40d8902647cb3f22c96@[50.116.48.41]:18844 - -DGSI -Sealer 0xa9cac6c2ef4909a05ef24a12ecadf9e541b5995f -enode://71d9972d30952db3e757954ce4e1c746a9f84b2d217e7378c1b8a1f48fb22b8960eb48e9be10a75df0968535f1916726c28869784d7ca110aa24bacd7a16c4ac@[200.108.145.9]:50310 - -RIU Luciano Minuchin -Sealer 0x737ce178ce5c97248a9a8794a78f30dce1d091ff -enode://015ab9ad905e84f3c943bb2ecded64ded00ac150ae06ff911f3fb9e76674b70fbc26ad6f9938194f7e4c607b4f8067f018d9c917250ad6e0a1e85366fea85fb8@[179.201.44.197]:28045 -enode://015ab9ad905e84f3c943bb2ecded64ded00ac150ae06ff911f3fb9e76674b70fbc26ad6f9938194f7e4c607b4f8067f018d9c917250ad6e0a1e85366fea85fb8@[2800:110:44:6120:b49a:3fff:fe74:5499]:28045 diff --git a/network5445/contracts/0x3935260bb04ee7e820fc03b7b271f1085f4365e3/abi b/network5445/contracts/0x3935260bb04ee7e820fc03b7b271f1085f4365e3/abi deleted file mode 100644 index 05cd2b3cb6985df2d60c8a7df55b4e96f023040e..0000000000000000000000000000000000000000 --- a/network5445/contracts/0x3935260bb04ee7e820fc03b7b271f1085f4365e3/abi +++ /dev/null @@ -1 +0,0 @@ -[{"constant":false,"inputs":[{"name":"hasharray","type":"uint256[]"}],"name":"put","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"hash","type":"uint256"}],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}] diff --git a/network5445/contracts/TimeStampAuthority b/network5445/contracts/TimeStampAuthority deleted file mode 120000 index 5ce30c7def4d672255c9641c94843f012835c521..0000000000000000000000000000000000000000 --- a/network5445/contracts/TimeStampAuthority +++ /dev/null @@ -1 +0,0 @@ -0x3935260bb04ee7e820fc03b7b271f1085f4365e3 \ No newline at end of file diff --git a/src/TimeStampAuthority.sol b/src/TimeStampAuthority.sol deleted file mode 100644 index 2282493d69c52e1bb7ed92a8548e32c2476b3d57..0000000000000000000000000000000000000000 --- a/src/TimeStampAuthority.sol +++ /dev/null @@ -1,26 +0,0 @@ -// 20180718 Robert Martin-Legene <robert@nic.ar> -// Time stamp authority - -pragma solidity ^0.4.24; - -contract TimeStampAuthority { - // This mapping is almost an "associative array" - mapping (uint256 => uint) private hashstore; - - // Stores hashes (256 bit uint) of a document in the mapping - function put( uint256[] hasharray ) public { - uint256 i = hasharray.length; - while (i>0) { - i--; - uint256 h = hasharray[i]; - if (hashstore[h] == 0) { - hashstore[h] = block.number; - } - } - } - - // Returns the block number in which the hash was first seen - function get( uint256 hash ) public view returns (uint) { - return hashstore[hash]; - } -} diff --git a/src/genesis.json b/src/genesis.json index 84812797e136ff53f9abde7ab6d68b2da207c9d9..819f46c6b47d40b302ba3099b0f01b53225fda6a 100644 --- a/src/genesis.json +++ b/src/genesis.json @@ -1,16 +1,25 @@ { "config": { - "chainId": 5445, + "chainId": 200941592, "homesteadBlock": 0, "eip150Block": 0, "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 4, "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "clique": { "period": 15, "epoch": 30000 } + "clique": { "period": 5, "epoch": 30000 } }, "nonce": "0x0000000000000000", - "timestamp": "0x5b293735", - "extraData": "0x426c6f636b636861696e204665646572616c20417267656e74696e61204e49432fd693d1204907ae7d97b5d7d2e93ef877ef2c7d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0x5baa5baa", + "extraData": "0x426c6f636b636861696e204665646572616c20417267656e74696e61204e494319fe7b9b3a1bebde77c5374c8e13c623e3d1b5b2342e1d075d820ed3f9d9a05967ec4055ab23fa1e46991ada2a2544468eb3673524641bf293f23ccc91c055c6478bd0ad6d19bcb58f5e7ca7b04e67f10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "gasLimit": "0xffeeddcc", "difficulty": "0x1", "number": "0x0", "gasUsed": "0x0", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "alloc": { "2fd693d1204907ae7d97b5d7d2e93ef877ef2c7d": { "balance": "0x200000000000000000000000000000000000000000000000000000000000000" } } + "alloc": { + "bfa02a9639318f5ed1291e2cee387aa9f9d68f98": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfa1c42c7381a4ad32e13ce3263b639a0e0488f2": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfa2c97c3f59cc929e8feb1aee2aca0b38235d18": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfa3eb31f6526a5b29ae2302508bb6b1400d1fd1": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfa846ddd1fb18af693f24d316c12d8e88f4b79f": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfa8b1acfb51da0975274c6ebd46704c6c670a07": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfab583022c5c18fec70965d63985b86f96c5657": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, + "bfae9512c1cf4d9ce549333725c02ee8b3e5f049": { "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } + } }