From 5cdfb88fecb2f5d265b92b2903818713ea16cd96 Mon Sep 17 00:00:00 2001 From: Robert Martin-Legene <robert@nic.ar> Date: Fri, 19 Mar 2021 12:25:43 -0300 Subject: [PATCH] MasterDestiller ahora esta escrito en python3 --- bin/MasterDistiller.js | 264 ----------------------------------------- bin/MasterDistiller.py | 145 ++++++++++++++++++++++ 2 files changed, 145 insertions(+), 264 deletions(-) delete mode 100755 bin/MasterDistiller.js create mode 100755 bin/MasterDistiller.py diff --git a/bin/MasterDistiller.js b/bin/MasterDistiller.js deleted file mode 100755 index 47a73c7..0000000 --- a/bin/MasterDistiller.js +++ /dev/null @@ -1,264 +0,0 @@ -#!/usr/bin/node - -"use strict" - -const BigNumber = require('bignumber.js'); -const Libbfa = require( process.env.BFAHOME + '/bin/libbfa.js'); -const rl = require('readline').createInterface( - { input: process.stdin, output: process.stdout } - ); -var web3; -var Distillery; -var bfa; -var notation = { "potency": 15 }; - -function init() -{ - var table = [ - 6, 'Mwei', - 9, 'Gwei', - 12, 'micro', - 15, 'finney', - 18, 'ether', - 21, 'kether', - 24, 'grand', - 27, 'mether', - 30, 'gether', - 33, 'tether' - ]; - for (var i = 0; table[i]; i+=2) - if ( table[i] == notation.potency ) - notation.name = table[i+1] - if ( undefined == notation.name ) - notation = { 'potency': 15, 'name': 'finney' }; - notation.num = BigNumber( 10 ).pow( notation.potency ); - bfa = new Libbfa(); - web3 = bfa.newweb3(); - Distillery = bfa.contract( web3, 'Distillery' ); - requestDistBalance() - .then( requestBalances ) -} - -function palletSort(a,b) -{ - if ( b == undefined ) - { - if ( a == undefined ) - return 0; - else - return -1; - } - if ( a == undefined ) - return 1; - var strA = a.addr.toLowerCase(); - var strB = b.addr.toLowerCase(); - if ( strA < strB ) - return -1; - if ( strA > strB ) - return 1; - return 0; -} - -async function requestDistBalance() -{ - return web3.eth.getBalance(Distillery.contractaddress) - .then( (bal) => { return Distillery.contractbalance = new BigNumber( bal ) } ) -} - -async function requestBalances() -{ - var count = await Distillery.methods.numberOfBeneficiaries().call(); - var pallet = new Array; - var i; - // Fetch addresses from the list in the contract. - for ( i=0; i<count; i++ ) - { - var addressandsetting = await Distillery.methods.atPosition(i).call(); - var addr = addressandsetting[0]; - var setting = addressandsetting[1]; - var bal = await web3.eth.getBalance( addr ); - pallet.push( { "addr": addr, "setting": new BigNumber(setting), "balance": new BigNumber(bal) } ); - } - displayBalances(pallet); -} - -function editAccount( entry, pallet ) -{ - if ( entry == undefined ) - return; - var acct; - var value; - // it is an existing account address? - if ( bfa.isAddr(entry) ) - { - var i = 0; - var n = pallet.length; - while ( i < n ) - { - if (String(pallet[i].addr).toLowerCase() == String(entry).toLowerCase() ) - entry = i; - i++; - } - } - // it is a new account address? - if ( bfa.isAddr(entry) ) - { - acct = entry; - value = 0; - } - else - if ( bfa.isNumeric(entry) && entry < pallet.length ) - { - acct = pallet[entry].addr; - value = pallet[entry].setting; - } - else - if ( entry == "x" ) - { - var rcpt; - // trigger distribution - Distillery.methods.distribute().send( {"from": bfa.account, "gas": 4000000, gasPrice: 1000000000 } ) - .on( 'error', (x) => { bfa.fatal( "Distribute returned errors: " + x ) } ) - .on( 'confirmation', (n,x) => - { - if ( undefined == rcpt ) - { - rcpt = x; - console.log( - "Distribute returned succesfully in block# " - + rcpt.blockNumber - + " using " - + rcpt.gasUsed - + " gas." - ); - var beforeBal = Distillery.contractbalance; - requestDistBalance() - .then( - function() - { - console.log( - "Distributed " - + beforeBal.minus( Distillery.contractbalance ).div( notation.num ).toFixed() - + " " - + notation.name - + "." - ); - requestBalances(); - } - ) - } - } - ); - return; - } - else - if ( entry == "" ) - { - // Do nothing, basically just update the display - return; - } - else - { - bfa.fatal("I don't know what to do with \""+entry+"\"." ); - } - rl.question( - "Adjust the " - + notation.name - + " fill value of " - + acct - + " (setting to 0 is the same as deleting)\n" - + "Amount?: ", - (answer) => { - if ( bfa.isNumeric(answer) ) - { - var bi = BigNumber( answer ).multipliedBy( notation.num ); - console.log("Sending update to the SC..."); - var rcpt; - Distillery.methods.setEtherAllowance(acct,web3.utils.toHex(bi)) - .send( {"from": bfa.account, gasPrice: 1000000000, gas: 100000 } ) - .on( 'error', (err) => { - bfa.fatal( - "\nMaybe you are not authorized:\n" - +err - +"\n\n\nI think you should leave now.\n" - ); - } - ) - .on( 'confirmation', (n,x) => { - if ( undefined == rcpt ) - { - rcpt = x; - console.log("Update accepted.") - requestBalances(); - } - } - ); - } - else - bfa.fatal( "I have no idea what to do with \""+answer+"\"." ); - rl.close; - } - ); -} - -function displayBalances( pallet ) -{ - var n = pallet.length; - var i; - pallet.sort(palletSort); - console.log( - "The contract's account (" - + Distillery.contractaddress - + ") has " - + Distillery.contractbalance.div( notation.num ).toFixed() - + " " - + notation.name - + ".\n" - ); - var longest = 1; - for ( i=0; i<n; i++ ) - { - var len = pallet[i].setting.div(notation.num).toFixed(notation.potency).length; - if ( len > longest ) - longest = len; - } - for ( i=0; i<n; i++ ) - { - var entry = pallet[i]; - if ( entry == undefined ) - console.log( i+": <undef>" ); - else - { - var numstr = pallet[i].setting.div(notation.num).toFixed(notation.potency); - while ( numstr.length < longest ) - numstr = " "+numstr; - console.log( - i - + ": " - + pallet[i].addr - + " fills to " - + numstr - + " " - + notation.name - + " (has " - + pallet[i].balance.div(notation.num).toFixed(notation.potency) - + ")." - ); - } - } - console.log("\n[ Q=quit x=distribute ]"); - rl.question("Which account to edit (enter index number of full account number)?: ", - (answer) => { - if ( answer != undefined ) - { - if ( String(answer).toUpperCase() == 'Q' ) - process.exit( 0 ); - else - editAccount(answer, pallet); - } - rl.close; - } - ) -} - -init(); diff --git a/bin/MasterDistiller.py b/bin/MasterDistiller.py new file mode 100755 index 0000000..310153e --- /dev/null +++ b/bin/MasterDistiller.py @@ -0,0 +1,145 @@ +#!/usr/bin/python3 + +import sys +import os +import json +import re +import decimal +os.environ['BFAHOME']='/home/bfa/bfa' +sys.path.append( os.path.join(os.environ['BFAHOME'],'bin' )) +import libbfa +bfa = libbfa.Bfa('prod') +notation = dict() +janitor = None +distillery = None + +def distbalance() -> int: + return bfa.w3.eth.getBalance(distillery.address) + +def editAccount(entry:str, pallet:list): + acct = None + # is it an account address? + if entry == '': + # Do nothing, basically just update the display + pass + elif re.search('^0x[0-9a-fA-F]{40}$', entry): + acct = entry.lower() + # is it a known account address? + elif re.search('^[0-9]+$', entry) and int(entry) < len(pallet): + acct = pallet[int(entry)].addr + elif entry == 'x': + # trigger distribution + beforeBal = distbalance() + rcpt = janitor.transact( web3=bfa.w3, function=distillery.functions.distribute, extragas=4000000) + print('Distribute returned succesfully in block# {} using {} gas.'.format(rcpt.blockNumber, rcpt.gasUsed)) + afterBal = distbalance() + print('Distributed {} {}.'.format( int(decimal.Decimal(beforeBal - afterBal) / notation['num']), notation['name'])) + else: + print('I do not know what to do with "{}".'.format(entry), file=sys.stderr) + exit(1) + if acct is None: + return + answer = input('Adjust the {} fill value of {} (setting to 0 is the same as deleting)\nAmount?: '.format(notation['name'], acct)) + if re.search('^[0-9\.]+$', answer) is None: + print('I have no idea what to do with "{}".'.format(answer), file=sys.stderr) + exit(1) + print('Sending update to the SC...') + weilimit = float(answer) * int(notation['num']) + rcpt = janitor.transact( bfa.w3.toChecksumAddress(acct), int(weilimit), web3=bfa.w3, function=distillery.functions.setEtherAllowance) + if rcpt.status: + print('Update accepted.') + else: + print('Update failed.') + +def getPallet() -> list: + count = distillery.functions.numberOfBeneficiaries().call() + pallet = list() + # Fetch addresses from the list in the contract. + for i in range(count): + print("Indexing accounts ({}/{})...\x1B[J\r".format(i,count), end='') + (addr,topuplimit) = distillery.functions.atPosition(i).call() + bal = bfa.w3.eth.getBalance( addr ) + pallet.append( { "addr": addr, "topuplimit": topuplimit, "balance": bal } ) + print("\r\x1B[J".format(i,count), end='') + s = lambda x:x['addr'].lower() + pallet.sort(key=s) + return pallet + +def printPallet(pallet:list): + # find the length of the longest number-string + longestlimit = 1 + longestbalance = 1 + numformat = notation['strformat'].format + for i in range(len(pallet)): + entry = pallet[i] + numstr = numformat(decimal.Decimal(entry['topuplimit']) / notation['num']) + thislen = len(numstr) + if thislen > longestlimit: + longestlimit = thislen + numstr = numformat(decimal.Decimal(entry['balance']) / notation['num']) + thislen = len(numstr) + if thislen > longestbalance: + longestbalance = thislen + # print them all + theformat = '{:' + str(len(str(len(pallet)-1))) + '}: {} fills to {:' + str(longestlimit) + '.' + str(notation['potency']) + 'f} {} (has {:' + str(longestbalance) + '.' + str(notation['potency']) + 'f}).' + for i in range(len(pallet)): + entry = pallet[i] + numstr = numformat(decimal.Decimal(entry['topuplimit']) / notation['num']) + while len(numstr) < longestlimit: + numstr = ' ' + numstr + print(theformat.format( + i, + bfa.w3.toChecksumAddress(entry['addr']), + decimal.Decimal(entry['topuplimit'])/notation['num'], + notation['name'], + decimal.Decimal(entry['balance']) / notation['num'] + )) + +def overview(): + print( "The contract's account ({}) has {} {}.".format( + distillery.address, + int(decimal.Decimal(distbalance()) / notation['num']), + notation['name'] + )) + pallet = getPallet() + printPallet(pallet) + answer = input("\n[ Q=quit x=distribute ]\nWhich account to edit (enter index number or full account number)?: ") + if answer is None or answer.upper() == 'Q': + exit( 0 ) + editAccount(answer, pallet) + +def init(): + global janitor, notation, distillery; + janitor = libbfa.Account('0xd15dd6dbbe722b451156a013c01b29d91e23c3d6') + table = dict([ + (6, 'Mwei'), + (9, 'Gwei'), + (12, 'micro'), + (15, 'finney'), + (18, 'ether'), + (21, 'kether'), + (24, 'grand'), + (27, 'mether'), + (30, 'gether'), + (33, 'tether'), + ]) + potency = 18 + notation['potency'] = potency + notation['name'] = table[potency] + notation['num'] = pow(10, potency) + notation['strformat'] = '{' + ':.{}f'.format(potency) + '}' + abifile = '' + if os.getenv('BFAHOME'): + abifile = os.path.join(os.path.join(os.environ['BFAHOME'], 'network')) + if os.getenv('BFANETWORKDIR'): + abifile = os.path.join(os.environ['BFANETWORKDIR']) + abifile = os.path.join(abifile, 'contracts', 'Distillery', 'abi') + with open(abifile, 'rt', encoding='utf-8') as infile: + abitxt = infile.read() + abi = json.loads(abitxt) + addr = '0xECB6aFF6e38dC58C4d9AaE2F7927A282bcB77AC2' + distillery = bfa.w3.eth.contract(address=addr, abi=abi) + +init() +while True: + overview() -- GitLab