diff --git a/.gitignore b/.gitignore index 5a0e84e16d4892f4743ee5a47dbd0436634290b5..d9a84d8a68bb72dcd95e39d300b55eddef2c7e98 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,9 @@ cache bin/env network/node network/bootnode -network/contracts/* network/*.pid test2network*/node test2network*/bootnode -test2network*/contracts/* test2network/*.pid node_modules src/*/*.bin diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..9c3ccff9fefb836d18ac2fc3cdf10d1985d46522 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +LGPLv2-only \ No newline at end of file diff --git a/bin/bfageth b/bin/bfageth new file mode 100755 index 0000000000000000000000000000000000000000..17ba3df8dabe334619e97cbdf38e2bfebe07e508 --- /dev/null +++ b/bin/bfageth @@ -0,0 +1,6 @@ +#!/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 + +exec geth --datadir ${BFANODEDIR} --networkid ${BFANETWORKID} "$@" diff --git a/bin/events.js b/bin/events.js new file mode 100755 index 0000000000000000000000000000000000000000..ffaf83c37df2beca7f1a98394935a52f9b1909bd --- /dev/null +++ b/bin/events.js @@ -0,0 +1,96 @@ +#!/usr/bin/node +// 20200828 Robert Martin-Legene +// License: GPLv2-only +// (c) Secretaria Legal y Tecnica, Presidencia De La Nacion, Argentina + +// Looks for the contract you're specifying as argument. +// Tries to show you all the events that contract has ever logged on the blockchain. +// The contract's ABI must be in a text file in ${BFANETWORKDIR}/contracts/${contractaddr}/abi + +const Web3 = require( "web3" ); +const fs = require( "fs" ); +const web3 = new Web3( "http://127.0.0.1:8545" ); + +function writeEvent(ev) +{ + console.log(""); + console.log( "Block number: " + ev.blockNumber ); + console.log( "TX hash: " + ev.transactionHash ); + console.log( "Event name: " + ev.event ); + Object.keys( ev.returnValues ).forEach( + function writeEventValue( value ) + { + // Will skip keys which are made entirely of digits. + if ( ! value.match(/^[0-9]+$/) ) + { + console.log( "* " + value + ": " + ev.returnValues[value] ) + } + } + ); +} + + +function gotPastEvents( e, result ) +{ + // We are called a single time. + // Either success or failure. + if ( e ) + { + console.error( e ); + process.exit( 1 ); + } + result.forEach( writeEvent ); + console.log( "\n" + result.length + " events." ); +} + +var contractname = process.argv[2]; +if ( contractname === undefined ) +{ + console.error( "Usage: " + process.argv[1] + " <contractname|contractaddr>" ); + process.exit( 1 ); +} +if ( process.env.BFANETWORKDIR === undefined ) +{ + console.error( "$BFANETWORKDIR must be defined" ); + process.exit( 1 ); +} +var pathprefix = process.env.BFANETWORKDIR + "/contracts/"; +var filename; +if ( fs.existsSync( contractname )) + filename = contractname; +else +if ( fs.existsSync( contractname.toLowerCase() )) + filename = contractname.toLowerCase(); +else +if ( fs.existsSync( pathprefix + contractname )) + filename = pathprefix + contractname; +else +if ( fs.existsSync( pathprefix + contractname.toLowerCase() )) + filename = pathprefix + contractname.toLowerCase(); +if ( filename === undefined ) +{ + console.error( "Contract not found." ); + process.exit( 1 ); +} +var contractaddr = filename; +var dirname = ""; +var idx = filename.lastIndexOf("/"); +if ( idx > -1 ) +{ + dirname = filename.substr( 0, idx+1 ); + filename = filename.substr( idx+1 ) + contractaddr = filename; +} +var stats = fs.lstatSync( dirname + filename ); +if ( stats.isSymbolicLink() ) +{ + let linkname = fs.readlinkSync( dirname + filename, { encoding: 'utf8' } ); + filename = dirname + linkname; + contractaddr = linkname; +} +filename += "/abi"; +var abi_str = fs.readFileSync( filename, { encoding: 'utf8' } ); +var abi = JSON.parse( abi_str ); +var contract = new web3.eth.Contract( abi, contractaddr ); +console.log( "Address: " + contractaddr ); +contract.getPastEvents( "allEvents", { fromBlock: "earliest", toBlock: "latest" }, gotPastEvents); diff --git a/bin/installbfa.sh b/bin/installbfa.sh index f95aef8b1970b1da9a030cb36e2274cd57961783..39e5dfb1224e53d2c2feb828eb779be51779af0b 100755 --- a/bin/installbfa.sh +++ b/bin/installbfa.sh @@ -28,19 +28,16 @@ function info # Runs as the owner of the given directory, and in the given directory function runasownerof { - path=$1 - precmd= + local where=$1 precmd= shift 1 - pushd $path > /dev/null + pushd $where > /dev/null if [ $( stat --format=%u . ) -ne $UID ] then - precmd="sudo --preserve-env --set-home -u $( stat --format=%U . ) PATH=${PATH}" + precmd="sudo --preserve-env --shell --set-home --user=$( stat --format=%U . ) PATH=${PATH}" fi - unset path ${precmd} "$@" - rv=$? + local rv=$? popd > /dev/null - unset precmd return $rv } @@ -66,56 +63,7 @@ function nodejsinstall aptinstall nodejs info "Installing nodejs modules (will show many warnings)" runasownerof ${BFAHOME} npm install -} - -function golanginstall -{ - if [ ! -d /usr/local/go ] - then - info "Downloading package of go binaries." - mkdir -p ${NEW} - cd ${NEW} - local arch=$( uname -m ) - case "${arch}" in - x86_64) - arch=amd64 - ;; - *) - echo "We have no recipe for how to build on your \"${arch}\" platform." >&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 - if [ $( expand < ~bfa/.bashrc | grep -E "^PATH=.*/usr/local/go/bin" | wc -l ) -eq 0 ] - then - echo "PATH=\${PATH}:/usr/local/go/bin" >> ~bfa/.bashrc - fi - export PATH=${PATH}:/usr/local/go/bin + runasownerof ${BFAHOME} npm audit fix } function gethinstall @@ -142,13 +90,14 @@ function gethinstall function initgenesis { ( + HOME=$( echo ~bfa ) source ${BFAHOME}/bin/env BFANETWORKDIR=${BFANETWORKDIR:-${BFAHOME}/network} BFANODEDIR=${BFANODEDIR:-${BFANETWORKDIR}/node} if [ ! -d "${BFANODEDIR}" -o ! -d "${BFANODEDIR}/geth/chaindata" ] then info "Node is not initialised. Initialising with genesis." - geth --networkid ${BFANETWORKID} --cache 0 --datadir "${BFANODEDIR}" init "${BFANETWORKDIR}/genesis.json" + runasownerof "${BFAHOME}" geth --networkid ${BFANETWORKID} --cache 0 --datadir "${BFANODEDIR}" init "${BFANETWORKDIR}/genesis.json" chown -R bfa:bfa ~bfa fi ) @@ -259,11 +208,10 @@ grep -q Ubuntu /etc/issue && apt-add-repository multiverse # apt update # development tools -aptinstall dirmngr apt-transport-https curl git curl build-essential sudo software-properties-common +aptinstall dirmngr apt-transport-https curl git curl build-essential sudo software-properties-common golang aptinstall jq libjson-perl libwww-perl libclass-accessor-perl userconfig nodejsinstall -golanginstall gethinstall initgenesis cronit diff --git a/bin/libbfa.js b/bin/libbfa.js index 5f562c411337eb04a304d7ae120970607998746f..c968b578fb8aa1dc6b821fb7e63cf2b498b435e6 100644 --- a/bin/libbfa.js +++ b/bin/libbfa.js @@ -167,13 +167,16 @@ module.exports = class Libbfa }); socket.on("error", (e) => { console.error(e); - err = e; + err = e; }); socket.on("close", () => { + if ( result === undefined ) + err = 'Error undefined (close)' + else if ( result.error && result.error.code && result.error.message ) - err = 'Error ' + result.error.code + ": "+ result.error.message; + err = 'Error ' + result.error.code + ": "+ result.error.message; else - result = result.result; + result = result.result; callback( err, result ); }); } diff --git a/bin/monitor.js b/bin/monitor.js index 0596f89767877e73296453229da7e8913feb2765..303af882e0924853926cf35c7d3e29c9315aea5c 100755 --- a/bin/monitor.js +++ b/bin/monitor.js @@ -156,25 +156,24 @@ function gotAdminPeers( err, nodelist ) // Try to connect to a random node if we have very few peers if ( nowpeers.length < 5 ) { - var candidatenew = []; + var candidate = []; // find candidate nodes which we can connect to // (it comes from peers.cache) peerscache.forEach( function(acachedpeer) { - if ( - // Add "a cached peer" to "candidate new" peers - // if the cached peer is not in the list of current node. - currentnodes.find( function(element) { element.info != acachedpeer } ) - ) + // Add "a cached peer" to "candidate" peers + // if the cached peer is not in the list of currently + // connected nodes. + if ( ! currentnodes.includes( acachedpeer ) ) { - candidatenew.push( acachedpeer ); + candidate.push( acachedpeer ); } } ); - if ( candidatenew.length > 0 ) + if ( candidate.length > 0 ) { - var i = Math.floor( Math.random() * candidatenew.length ); - var enode = candidatenew[i]; + var i = Math.floor( Math.random() * candidate.length ); + var enode = candidate[i]; console.log( "We have " + nowpeers.length @@ -311,6 +310,10 @@ function unlock() function timer() { + if ( bfa.sockettype == 'ipc' && ! bfa.fs.existsSync( bfa.socketurl ) ) + { + return; + } if ( netid == 0 ) { web3.eth.net.getId() @@ -318,7 +321,7 @@ function timer() netid = x; } ) .catch( err => { - console.error("monitor.js non-fatal: "+err) + console.log( "monitor.js waiting for geth to open socket." ); }); return; } diff --git a/bin/registro-verificar b/bin/registro-verificar new file mode 100755 index 0000000000000000000000000000000000000000..ed2e286a8e8c629efa26e7bfd5694097cd13af62 --- /dev/null +++ b/bin/registro-verificar @@ -0,0 +1,275 @@ +#!/usr/bin/node + +const Web3 = require( 'web3' ); +// make sure we die early if this is not installed +const dummy = require( 'web3-eth-accounts' ); +const fs = require( 'fs' ); +var web3 = new Web3( 'http://localhost:8545/' ); +var myArgs = process.argv.slice(2); +var myaccount = myArgs[0]; +var proof = myArgs[1]; +var password = myArgs[2] || ''; +var contractaddr; +var networkid; +var chainid; +var rawdata; +var estimate; + +if ( myArgs.length < 2 || myArgs.length > 3 ) +{ + let myname = process.argv[1].replace(/^.*\//, ''); + console.error( "Wrong number of arguments."); + console.error( "Usage: " + myname + " <account> <proof> [<privatekeypassword>]"); + process.exit( 1 ); +} + +function findMatchingFile( needle, accountdir ) +{ + return new Promise( + function(resolve, reject) + { + // strip leading '0x' from the needle, if present + // also lowercase the name + needle = needle.replace(/^0x/, '').toLowerCase(); + let haystack = fs.readdirSync( accountdir, 'utf8' ); + haystack.forEach( + (filename) => { + if ( filename.toLowerCase().endsWith('--'+needle) ) + resolve(accountdir + filename); + } + ); + reject( 'Account not found. Try specifying the absolute path to your key file, or set one of $BFAHOME $BFANETWORKDIR $BFANODEDIR $KEYSTORE' ); + } + ); +} + +function findaccountfile( accountfile ) +{ + return new Promise( + function( resolve, reject ) + { + // find account file + // is it actually just a file? + if ( accountfile.includes('/') ) + { + resolve( accountfile ); + return; + } + let accountdir; + // if not a file, then look (only) at the most specific directory we have been told about. + if ( process.env.KEYSTORE !== undefined ) + accountdir = process.env.KEYSTORE; + else + if ( process.env.BFANODEDIR !== undefined ) + accountdir = process.env.BFANODEDIR + '/keystore/'; + else + if ( process.env.BFANETWORKDIR !== undefined ) + accountdir = process.env.BFANETWORKDIR + '/node/keystore/'; + else + if ( process.env.BFAHOME !== undefined ) + accountdir = process.env.BFAHOME + '/network/node/keystore/'; + else + accountdir = process.env.HOME + '.geth/keystore'; + findMatchingFile( myaccount, accountdir ) + .then( resolve ) + .catch( reject ); + } + ); +} + +function loadaccount( path ) +{ + return new Promise( + function( resolve, reject ) + { + let contents = fs.readFileSync( path, 'utf8' ); + fs.readFile( path, 'utf8', (err,data) => { + if ( err ) + { + reject( err ); + return; + } + let keystore; + try { + keystore = JSON.parse( data ); + } + catch(e) + { + reject( e ); + return; + } + let w; + try { + w = web3.eth.accounts.wallet.decrypt( [keystore], password ); + } + catch(e) + { + reject( e ); + return; + } + // Make sure we have the address properly written (instead of a + // filename) if that was given as parameter when starting the program. + if ( w === undefined ) + { + reject( "Unable to decrypt the key file." ); + return; + } + myaccount = w[0]["address"]; + resolve(); + }); + } + ); +} + +function gasestimate(method) +{ + return new Promise( + function( resolve, reject ) + { + method.estimateGas() + .then( g => { estimate = g } ) + .then( resolve ) + } + ); +} + +function getnetworkid() +{ + return new Promise( + function( resolve, reject ) + { + web3.eth.net.getId() + .then( id => { + networkid = id; + if ( networkid == 0xb10c4d39a ) + { + contractaddr = "0xc3cF96aF51d3c41DfBE428dE75a8E5597d4D7A7B"; + chainid = 0xbfa2018; + } + else + { + reject( "There is insufficient information to function on this chain." ); + return; + } + resolve(); + }); + } + ); +} + +function getnonce( account ) +{ + return new Promise( + function( resolve, reject ) + { + // Cuantas transacciones ya hemos hecho? + web3.eth.getTransactionCount( account ) + .then( txcount => { + nonce = txcount; + resolve(); + }); + } + ); +} + +function prepareCall() +{ + var abi = [ + { + "name" : "hash", + "type" : "function", + "inputs" : [ { "name": "key", "type": "string" } ], + "outputs" : [ { "name": "", "type": "bytes32" } ], + "constant" : true, + "payable" : false, + "stateMutability" : "pure" + }, + { + "name" : "proveControl", + "type" : "function", + "inputs" : [ { "name": "key", "type": "string" } ], + "outputs" : [ { "name": "", "type": "bool" } ], + "constant" : false, + "payable" : false, + "stateMutability" : "nonpayable" + } + ]; + return new Promise( + function(resolve, reject) + { + let p1 = getnetworkid(); + let p2 = getnonce( myaccount ); + Promise.all([ p1, p2 ]) + .then( () => { + if ( contractaddr === undefined ) + { + reject( "The contract address is not defined for this network." ); + return; + } + // Creá una instancia del contrato + var contractInstance = new web3.eth.Contract(abi, contractaddr ); + //Estimá el gas que vas a gastar + let method = contractInstance.methods.proveControl( proof ); +// contractInstance.methods.hash(proof).call().then( console.log ); + rawdata = method.encodeABI(); + gasestimate( method ) + .then( resolve ); + }); + } + ); +} + +function signrawtx() +{ + //Generá una transacción + let promise = web3.eth.accounts.signTransaction( + { + "from" : myaccount, + "to" : contractaddr, + "nonce" : nonce, + "value" : 0, + "data" : rawdata, + "gas" : estimate, + "gasPrice" : 1000000000, + "common" : + { + "customChain" : + { + "name" : "BFA 2018", + "chainId" : chainid, + "networkId" : networkid + } + } + }, + web3.eth.accounts.wallet[0].privateKey + ); + return promise; +} + +function printReceipt( r ) +{ + console.log( "blockNumber: " + r.blockNumber ); + console.log( "transactionHash: " + r.transactionHash ); + console.log( "Status: " + (r.status?'Transaction successful':'Transaction failed') ); +} + +findaccountfile( myaccount ) +.then( (path)=> { return loadaccount(path) } ) +// prepara la instancia del contrato +.then ( prepareCall ) +// Firma "offline" +.then( () => { return signrawtx() }) +// Manda la transaccion a la blockchain +.then( tx => { + console.log( "Sending this transaction: " + tx.rawTransaction ); +console.log( "TX hash: " + tx.transactionHash ); +//process.exit( 0 ); + web3.eth.sendSignedTransaction( tx.rawTransaction ) + //Obtené el recibo. + .once( 'receipt', printReceipt ) + .catch( (e) => { console.error( "It would seem that the transaction has failed:\n" + e)} ); +}) +.catch( e => { + console.error( "Oh no. Something most definitely seems to have gone wrong. What I was told is:" ); + console.error( e ); +}); diff --git a/bin/singlestart.sh b/bin/singlestart.sh index aa7da1c932b63df4d67c36c56e7d40034d5b0782..df3f158329d0dd11f0552c047d4cf7d1d011873e 100755 --- a/bin/singlestart.sh +++ b/bin/singlestart.sh @@ -10,46 +10,73 @@ bootnodekeyfile=${BFANETWORKDIR}/bootnode/key # Bail out if anything fails. trap "exit 1" ERR # Detect children dying -trap "reaper" SIGINT SIGCHLD -unset LOGDIR LOGPIPE PIDIDX -declare -A PIDIDX -trap "killallprocs" SIGTERM +trap "reaper" SIGCHLD +trap "killprocs" SIGTERM +trap "killallprocs" EXIT +unset LOGPIPE PIDIDX ALLPIDIDX TMPDIR SHUTTING_DOWN +declare -A PIDIDX ALLPIDIDX +SHUTTING_DOWN=0 function reaper() { - local wecare=0 + local reaped_a_child_status=0 + # Find out which child died for pid in ${!PIDIDX[*]} do kill -0 $pid 2>/dev/null && continue + reaped_a_child_status=1 local rc=0 wait $pid || rc=$? || true - echo "*** ${PIDIDX[$pid]} (pid $pid) has exited with value $rc" + local name=${PIDIDX[$pid]} + echo "*** $name (pid $pid) has exited with value $rc" + if [ $name = 'geth' ]; then geth_rc_status=$rc; fi unset PIDIDX[$pid] - wecare=1 done - test $wecare = 1 || return - # kill all - an extra kill doesn't hurt. I hope. + # Return if we didn't find out which child died. + if [ $reaped_a_child_status = 0 ]; then return; fi + # Kill all other registered processes for pid in ${!PIDIDX[*]} do - # don't kill log.sh, because it may still be logging for us - if [ "${PIDIDX[$pid]}" != "log.sh" ] - then - echo "*** Killing ${PIDIDX[$pid]} (pid $pid)." - kill $pid || true - fi + kill -0 $pid 2>/dev/null || continue + echo "*** Killing ${PIDIDX[$pid]} (pid $pid)." + kill $pid || true done - max=30 } -function killallprocs() +function killprocs() { + SHUTTING_DOWN=1 if [ ${#PIDIDX[*]} -gt 0 ] then echo "*** Killing all remaining processes: ${PIDIDX[*]} (${!PIDIDX[*]})." - kill -KILL ${!PIDIDX[*]} 2>/dev/null || true + kill ${!PIDIDX[*]} 2>/dev/null || true fi } +function killallprocs() +{ + # merge the 2 pid list, to make killing and echoing easier + for pid in ${!ALLPIDIDX[*]} + do + PIDIDX[$pid]=${ALLPIDIDX[$pid]} + unset ALLPIDIDX[$pid] + done + killprocs + if [ -n "$TMPDIR" -a -e "$TMPDIR" ] + then + rm -rf "$TMPDIR" + fi +} + +function startgeth() +{ + echo "***" Starting geth $* + # "NoPruning=true" means "--gcmode archive" + geth --config ${BFATOML} $* & + gethpid=$! + PIDIDX[${gethpid}]="geth" +} + # You can start as: # BFAHOME=/home/bfa/bfa singlestart.sh # singlestart.sh /home/bfa/bfa @@ -75,8 +102,19 @@ else fi source ${BFAHOME}/bin/libbfa.sh +TMPDIR=$( mktemp -d ) +mknod ${TMPDIR}/sleeppipe p +sleep 987654321 > ${TMPDIR}/sleeppipe & +ALLPIDIDX[$!]='sleep' if [ "$VIRTUALIZATION" = "DOCKER" ] then + echo + echo + echo + echo + date + echo $0 startup + echo echo "See log info with \"docker logs\"" else echo "Logging mostly everything to ${BFANODEDIR}/log" @@ -86,21 +124,40 @@ else # Docker has it's own logging facility, so we will not use our own # logging functionality if we're in docker. echo "*** Setting up logging." - # Clean up logging - LOGDIR=$( mktemp -d ) - trap "rm -rf ${LOGDIR}" EXIT - LOGPIPE=${LOGDIR}/logpipe + LOGPIPE=${TMPDIR}/logpipe mknod ${LOGPIPE} p ${BFAHOME}/bin/log.sh ${BFANODEDIR}/log < ${LOGPIPE} & - PIDIDX[$!]="log.sh" + # Separate pididx for processes we don't want to send signals to + # until in the very end. + ALLPIDIDX[$!]="log.sh" exec > ${LOGPIPE} 2>&1 fi -echo "*** Starting geth." -# "NoPruning=true" means "--gcmode archive" -geth --config ${BFATOML} & -PIDIDX[$!]="geth" +function sleep() +{ + read -t ${1:-1} < ${TMPDIR}/sleeppipe || true +} + +# Start a sync +startgeth --exitwhensynced +echo "*** Starting monitor.js" +monitor.js & +PIDIDX[$!]="monitor.js" + +# geth will exit when it has synced, then we kill it's monitor. +# Then wait here for their exit status to get reaped +while [ "${#PIDIDX[*]}" -gt 0 ]; do sleep 1; done + +# if it went well, start a normal geth (to run "forever") +test $geth_rc_status = 0 || exit $geth_rc_status +test "$SHUTTING_DOWN" != 0 && exit 0 +# regular geth +startgeth +# monitor +echo "*** Starting monitor.js" + monitor.js & +PIDIDX[$!]="monitor.js" # bootnode if [ -r "$bootnodekeyfile" ] then @@ -109,16 +166,4 @@ then PIDIDX[$!]="bootnode" fi -echo "*** Starting monitor.js" -monitor.js & -PIDIDX[$!]="monitor.js" - -max=-1 -# Exit if only 1 process remains - we hope it is log.sh, but either way, -# it is time to end. -while [ "${#PIDIDX[*]}" -gt 1 -a $max -ne 0 ] -do - sleep 1 - max=$(( $max - 1 )) -done -killallprocs +while [ "${#PIDIDX[*]}" -gt 0 ]; do sleep 1; done diff --git a/bin/start.sh b/bin/start.sh index 4fc9770e1f830235080a87b1fb2eebfd0bdefb53..c7934af8855f07edc44f841bfcd15290f4844c38 100755 --- a/bin/start.sh +++ b/bin/start.sh @@ -11,7 +11,7 @@ bootARIUv6="enode://${enodeARIU}@[2800:110:44:6300::aad2:2db3]:30301" enodeUNC="82b66b13d7addcf9ffe1e4e972a105f6ccf50557161c4a0978a5d9ce595ababde609ea8a49897ae89b1d41e90551cb2e9241363238593e950ca68bd5af7c24d6" bootUNCv4="enode://${enodeUNC}@[200.16.28.28]:30301" -enodeDGSI="59ae768ecdee632e0daceccb6f71b215392eba89230d626573f2fb4e9c0786c9a661027ab7343820ca63d96fe48ffd81ed1bf6e4d512f0ba50ec072c9efd9e4e" +enodeDGSI="ddbf37799e8d33b0c42dddbda713037b17d14696b29ecf424ca3d57bb47db78a467505e22c5f2b709a98c3d55ac8ecbf4610765385317dd51049438f498881c6" bootDGSIv4="enode://${enodeDGSI}@[200.108.146.100]:30301" bootnodes="${bootARIUv6},${bootARIUv4},${bootUNCv4},${bootDGSIv4}" diff --git a/bin/unlock.js b/bin/unlock.js index 26809293734731598cb71fa537c13523f2184427..513c325ee9046bf1c66c7a5d63f2e73f8020c368 100755 --- a/bin/unlock.js +++ b/bin/unlock.js @@ -60,8 +60,12 @@ function unlockall() { var wallets = new Array(); web3.bfa.personal.listWallets( - function pushone(x) + function pushone(err,x) { + if ( err ) + bye( 1, err ); + if ( x == undefined ) + bye( 1, "wallets not defined" ); var failures = 0; var promises = new Array(); var i = x.length; diff --git a/network/config.toml b/network/config.toml index 330e90db9debb7dc6f37f8378e351f3d604690e0..a462be1268f6cd56bea8a5eaa31ffae3b7cf7fb4 100644 --- a/network/config.toml +++ b/network/config.toml @@ -59,7 +59,7 @@ HTTPCors = ["*"] omitempty = "" IPCPath = "geth.ipc" HTTPPort = 8545 -HTTPVirtualHosts = ["localhost"] +HTTPVirtualHosts = ["*"] HTTPModules = ["net", "web3", "eth", "clique"] WSHost = "0.0.0.0" WSPort = 8546 diff --git a/network/contracts/0xc3cf96af51d3c41dfbe428de75a8e5597d4d7a7b/abi b/network/contracts/0xc3cf96af51d3c41dfbe428de75a8e5597d4d7a7b/abi new file mode 100644 index 0000000000000000000000000000000000000000..63249fb87ee8648ea0bdf30fa553d27b7b1be4f7 --- /dev/null +++ b/network/contracts/0xc3cf96af51d3c41dfbe428de75a8e5597d4d7a7b/abi @@ -0,0 +1,328 @@ +[ + { + "name": "proofOfControlWeiAmountChanged", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": false, "name": "amount", "type": "uint256" } + ] + }, + { + "name": "limitChanged", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "distr", "type": "address" }, + { "indexed": true, "name": "ben", "type": "address" }, + { "indexed": false, "name": "newLimit", "type": "uint256" } + ] + }, + { + "name": "suitorApproved", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "suitor", "type": "address" } + ] + }, + { + "name": "suitorNotApproved", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "suitor", "type": "address" } + ] + }, + { + "name": "kickedDistributor", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "kicked", "type": "address" } + ] + }, + { + "name": "suitorAdded", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "suitor", "type": "address" }, + { "indexed": true, "name": "distr", "type": "address" } + ] + }, + { + "name": "addedBeneficiary", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "distr", "type": "address" }, + { "indexed": true, "name": "added", "type": "address" }, + { "indexed": false, "name": "limit", "type": "uint256" } + ] + }, + { + "name": "kickedBeneficiary", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "distr", "type": "address" }, + { "indexed": true, "name": "kicked", "type": "address" } + ] + }, + { + "name": "addedDistributor", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "added", "type": "address" }, + { "indexed": false, "name": "top", "type": "uint256" } + ] + }, + { + "name": "replenished", + "type": "event", + "anonymous": false, + "inputs": [ + { "indexed": true, "name": "distr", "type": "address" }, + { "indexed": false, "name": "amount", "type": "uint256" } + ] + }, + { + "name": "addBeneficiary", + "type": "function", + "constant": false, + "inputs": [ + { "name": "acc", "type": "address" }, + { "name": "limit", "type": "uint256" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "name": "addSuitor", + "type": "function", + "constant": false, + "inputs": [ + { "name": "add", "type": "address" }, + { "name": "password", "type": "bytes32" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": true, + "stateMutability": "payable" + }, + { + "name": "changeLimit", + "type": "function", + "constant": false, + "inputs": [ + { "name": "acc", "type": "address" }, + { "name": "limit", "type": "uint256" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "name": "kickBeneficiary", + "type": "function", + "constant": false, + "inputs": [ + { "name": "acc", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "name": "kickDistributor", + "type": "function", + "constant": false, + "inputs": [ + { "name": "acc", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "name": "addDistributor", + "type": "function", + "constant": false, + "inputs": [ + { "name": "acc", "type": "address" }, + { "name": "top", "type": "uint256" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "name": "proveControl", + "type": "function", + "constant": false, + "inputs": [ + { "name": "key", "type": "string" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "name": "replenish", + "type": "function", + "constant": false, + "inputs": [ + { "name": "acc", "type": "address" }, + { "name": "amount", "type": "uint256" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": true, + "stateMutability": "payable" + }, + { + "name": "replenishAll", + "type": "function", + "constant": false, + "inputs": [], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": true, + "stateMutability": "payable" + }, + { + "name": "replenishList", + "type": "function", + "constant": false, + "inputs": [ + { "name": "accs", "type": "address[]" }, + { "name": "amounts", "type": "uint256[]" } + ], + "outputs": [], + "payable": true, + "stateMutability": "payable" + }, + { + "name": "setProofOfControlWeiAmount", + "type": "function", + "constant": false, + "inputs": [ + { "name": "amount", "type": "uint256" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "nonpayable" + }, + { + "type": "constructor", + "inputs": [], + "payable": true, + "stateMutability": "payable" + }, + { + "name": "getBeneficiariesCount", + "type": "function", + "constant": true, + "inputs": [], + "outputs": [ + { "name": "", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view" + }, + { + "name": "getBeneficiaryLimit", + "type": "function", + "constant": true, + "inputs": [ + { "name": "acc", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view" + }, + { + "name": "getDistributorLimit", + "type": "function", + "constant": true, + "inputs": [ + { "name": "acc", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view" + }, + { + "name": "getProofOfControlWeiAmount", + "type": "function", + "constant": true, + "inputs": [], + "outputs": [ + { "name": "", "type": "uint256" } + ], + "payable": false, + "stateMutability": "view" + }, + { + "name": "hash", + "type": "function", + "constant": true, + "inputs": [ + { "name": "key", "type": "string" } + ], + "outputs": [ + { "name": "", "type": "bytes32" } + ], + "payable": false, + "stateMutability": "pure" + }, + { + "name": "isBeneficiary", + "type": "function", + "constant": true, + "inputs": [ + { "name": "add", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "view" + }, + { + "name": "isDistributor", + "type": "function", + "constant": true, + "inputs": [ + { "name": "add", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "bool" } + ], + "payable": false, + "stateMutability": "view" + } +] diff --git a/network/contracts/DGSIdistillery2 b/network/contracts/DGSIdistillery2 new file mode 120000 index 0000000000000000000000000000000000000000..8f90ade527de771b4f550cf819efada0c2706d1a --- /dev/null +++ b/network/contracts/DGSIdistillery2 @@ -0,0 +1 @@ +0xc3cf96af51d3c41dfbe428de75a8e5597d4d7a7b \ No newline at end of file diff --git a/network/docker-config.toml b/network/docker-config.toml new file mode 100644 index 0000000000000000000000000000000000000000..f414c8755727a134f8e906bb7a2ff821c52b1364 --- /dev/null +++ b/network/docker-config.toml @@ -0,0 +1,21 @@ +[Eth] +NetworkId = 47525974938 +SyncMode = "fast" +NoPruning = false +DatabaseCache = 2048 + +[Node] +DataDir = "/home/bfa/bfa/network/node" +HTTPHost = "0.0.0.0" +HTTPCors = ["*"] +IPCPath = "geth.ipc" +HTTPPort = 8545 +HTTPVirtualHosts = ["*"] +HTTPModules = ["net", "web3", "eth", "clique"] +WSHost = "0.0.0.0" +WSPort = 8546 +WSModules = ["net", "web3", "eth", "clique"] + +[Node.P2P] +BootstrapNodes = ["enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@[2800:110:44:6300::aad2:2db3]:30301", "enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@170.210.45.179:30301", "enode://82b66b13d7addcf9ffe1e4e972a105f6ccf50557161c4a0978a5d9ce595ababde609ea8a49897ae89b1d41e90551cb2e9241363238593e950ca68bd5af7c24d6@200.16.28.28:30301", "enode://59ae768ecdee632e0daceccb6f71b215392eba89230d626573f2fb4e9c0786c9a661027ab7343820ca63d96fe48ffd81ed1bf6e4d512f0ba50ec072c9efd9e4e@200.108.146.100:30301"] +BootstrapNodesV5 = ["enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@[2800:110:44:6300::aad2:2db3]:30301", "enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@170.210.45.179:30301", "enode://82b66b13d7addcf9ffe1e4e972a105f6ccf50557161c4a0978a5d9ce595ababde609ea8a49897ae89b1d41e90551cb2e9241363238593e950ca68bd5af7c24d6@200.16.28.28:30301", "enode://59ae768ecdee632e0daceccb6f71b215392eba89230d626573f2fb4e9c0786c9a661027ab7343820ca63d96fe48ffd81ed1bf6e4d512f0ba50ec072c9efd9e4e@200.108.146.100:30301"] diff --git a/package.json b/package.json index 6851a64b7ce534f7cea965c1bca8efd3b6d1b1ed..20d4037b9d4e1a80251b578ef6dd20331e98d262 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "bignumber.js": "^9.0.0", "request": "^2.88.0", "require": "^2.4.20", - "web3": "^1.0.0-beta.55", + "web3": "^1.2.11", + "web3-eth-accounts": "^1.2.11", "xmlhttprequest-ssl": "^1.5.5" }, "repository": { diff --git a/test2network/config.toml b/test2network/config.toml index 1d776baf40a50b3019f58a2efdafe2c0551676a9..d548f4d13fce561074c6d1f39fa96b7661165821 100644 --- a/test2network/config.toml +++ b/test2network/config.toml @@ -59,7 +59,7 @@ HTTPCors = ["*"] omitempty = "" IPCPath = "geth.ipc" HTTPPort = 8545 -HTTPVirtualHosts = ["localhost"] +HTTPVirtualHosts = ["*"] HTTPModules = ["net", "web3", "eth", "clique"] WSHost = "0.0.0.0" WSPort = 8546 diff --git a/test2network/docker-config.toml b/test2network/docker-config.toml new file mode 100644 index 0000000000000000000000000000000000000000..af884e27a0f4cb111ad3e3084d603e0952f385d1 --- /dev/null +++ b/test2network/docker-config.toml @@ -0,0 +1,21 @@ +[Eth] +NetworkId = 55555000000 +SyncMode = "fast" +NoPruning = false +DatabaseCache = 2048 + +[Node] +DataDir = "/home/bfa/bfa/test2network/node" +HTTPHost = "0.0.0.0" +HTTPCors = ["*"] +IPCPath = "geth.ipc" +HTTPPort = 8545 +HTTPVirtualHosts = ["*"] +HTTPModules = ["net", "web3", "eth", "clique"] +WSHost = "0.0.0.0" +WSPort = 8546 +WSModules = ["net", "web3", "eth", "clique"] + +[Node.P2P] +BootstrapNodes = ["enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@[2800:110:44:6300::aad2:2db3]:30301", "enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@170.210.45.179:30301", "enode://82b66b13d7addcf9ffe1e4e972a105f6ccf50557161c4a0978a5d9ce595ababde609ea8a49897ae89b1d41e90551cb2e9241363238593e950ca68bd5af7c24d6@200.16.28.28:30301", "enode://59ae768ecdee632e0daceccb6f71b215392eba89230d626573f2fb4e9c0786c9a661027ab7343820ca63d96fe48ffd81ed1bf6e4d512f0ba50ec072c9efd9e4e@200.108.146.100:30301"] +BootstrapNodesV5 = ["enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@[2800:110:44:6300::aad2:2db3]:30301", "enode://7ec4dd9d5e1a2b29d6b60aa9f95677c0c3a5f9306e73d65dd3bcbfda3737a8c509b02d1eab763ce39f18cfe96423df7ee544d6c36191ec17f59ade75bc99d358@170.210.45.179:30301", "enode://82b66b13d7addcf9ffe1e4e972a105f6ccf50557161c4a0978a5d9ce595ababde609ea8a49897ae89b1d41e90551cb2e9241363238593e950ca68bd5af7c24d6@200.16.28.28:30301", "enode://59ae768ecdee632e0daceccb6f71b215392eba89230d626573f2fb4e9c0786c9a661027ab7343820ca63d96fe48ffd81ed1bf6e4d512f0ba50ec072c9efd9e4e@200.108.146.100:30301"]