From f49693d71bd67d76bc851e1bfd01160988bb60b5 Mon Sep 17 00:00:00 2001 From: Vivek Teega Date: Sat, 23 Mar 2019 20:49:53 +0000 Subject: [PATCH] Spine of betting smart contract This commit introduces the betting smart contract on FLO blockchain --- config.ini | 2 +- models.py | 15 ++ parsing.py | 163 +++++++++----- smartContracts/electionbetting.db | Bin 8192 -> 0 bytes tokens/rmt.db | Bin 24576 -> 0 bytes track-tokens-mod.py | 302 ------------------------- track-tokens.py | 351 ------------------------------ tracktokens-smartcontract.py | 207 ++++++++++++++++-- 8 files changed, 309 insertions(+), 731 deletions(-) delete mode 100644 smartContracts/electionbetting.db delete mode 100644 tokens/rmt.db delete mode 100644 track-tokens-mod.py delete mode 100644 track-tokens.py diff --git a/config.ini b/config.ini index dcddbc0..aff3442 100644 --- a/config.ini +++ b/config.ini @@ -1,6 +1,6 @@ [DEFAULT] NET = testnet FLO_CLI_PATH = /usr/local/bin/flo-cli -START_BLOCK = 489130 +START_BLOCK = 498770 diff --git a/models.py b/models.py index 9cd4822..bbe505a 100644 --- a/models.py +++ b/models.py @@ -3,6 +3,7 @@ from sqlalchemy import Column, Integer, Float, String, ForeignKey Base = declarative_base() ContractBase = declarative_base() +SystemBase = declarative_base() class Extra(Base): __tablename__ = "extra" @@ -52,4 +53,18 @@ class ContractStructure(ContractBase): index = Column('index', Integer) value = Column('value', String) +class ContractParticipants(ContractBase): + __tablename__ = "contractparticipants" + + id = Column('id', Integer, primary_key=True) + participantAddress = Column('participantAddress', String) + tokenAmount = Column('tokenAmount', Float) + contractCondition = Column('contractCondition', String) + +class ActiveContracts(SystemBase): + __tablename__ = "activecontracts" + + id = Column('id', Integer, primary_key=True) + contractName = Column('contractName', String) + contractAddress = Column('contractAddress', String) diff --git a/parsing.py b/parsing.py index 629c664..222ed12 100644 --- a/parsing.py +++ b/parsing.py @@ -7,7 +7,7 @@ amount = None def isTransfer(text): - wordlist = ['transfer','send','give'] #keep everything lowercase + wordlist = ['transfer','send','give'] # keep everything lowercase textList = text.split(' ') for word in wordlist: if word in textList: @@ -27,7 +27,9 @@ def isIncorp(text): def isSmartContract(text): textList = text.split(' ') for word in textList: - if word[-1] == '@': + if word == '': + continue + if word.endswith('@'): return word return False @@ -48,27 +50,13 @@ def isSmartContractPay(text): return False -def extractOperation(text): - operationList = ['send', 'transfer', 'give'] # keep everything lowercase - count = 0 - returnval = None - for operation in operationList: - count = count + text.count(operation) - if count > 1: - return 'Too many' - if count == 1 and (returnval is None): - returnval = operation - return returnval - - -# todo pass marker to the function and support all types -def extractAmount(text): +def extractAmount(text, marker): count = 0 returnval = None splitText = re.split("\W+", text) for word in splitText: - word = word.replace('rmt', '') + word = word.replace(marker, '') try: float(word) count = count + 1 @@ -84,7 +72,9 @@ def extractAmount(text): def extractMarker(text): textList = text.split(' ') for word in textList: - if word[-1] == '#': + if word == '': + continue + if word.endswith('#'): return word return False @@ -97,17 +87,20 @@ def extractInitTokens(text): result = float(word) if textList[idx+1] in base_units: return result*base_units[textList[idx+1]] - return res + return result except: continue + return None def extractAddress(text): textList = text.split(' ') for word in textList: + if word == '': + continue if word[-1] == '$': return word - return False + return None def extractContractType(text): @@ -124,7 +117,11 @@ def extractContractType(text): def extractContractCondition(text): - return text.split("contractcondition:")[1][1:-1] + result = text.split("contractcondition:") + if len(result) != 1: + return result[1].strip()[1:-1] + else: + return None def extractContractConditions(text, contracttype, marker): @@ -149,9 +146,19 @@ def extractContractConditions(text, contracttype, marker): else: print("something is wrong with smartcontractpays conditions") + if 'userassetcommitment' in extractedRules and 'smartcontractpays' in extractedRules: + return extractedRules + else: + return None + return None - return extractedRules - return False + +def extractTriggerCondition(text): + searchResult = re.search('\".*\"', text) + if searchResult is None: + searchResult = re.search('\'.*\'', text) + return searchResult + return searchResult # Combine test @@ -163,45 +170,83 @@ def parse_flodata(string): nospacestring = re.sub(' +', ' ', string) cleanstring = nospacestring.lower() + atList = [] + hashList = [] - if isTransfer(cleanstring): - if isSmartContract(cleanstring): - contractname = isSmartContract(cleanstring) - marker = extractMarker(cleanstring) - operation = extractOperation(cleanstring) - amount = extractAmount(cleanstring) - contractcondition = extractContractCondition(cleanstring) - parsed_data = { 'type': 'transfer', 'transferType': 'smartContract', 'flodata': string, 'tokenIdentification': marker[:-1], - 'operation': operation, 'tokenAmount': amount, 'contractName': contractname, 'contractCondition': contractcondition} - else: - marker = extractMarker(cleanstring) - operation = extractOperation(cleanstring) - amount = extractAmount(cleanstring) - address = extractAddress(nospacestring) - parsed_data = {'type': 'transfer', 'transferType': 'token', 'flodata': string, 'tokenIdentification': marker[:-1], 'operation': operation, - 'amount': amount, 'address': address} + for word in cleanstring.split(' '): + if word.endswith('@'): + atList.append(word) + if word.endswith('#'): + hashList.append(word) - elif isSmartContractPay(nospacestring): - contractConditions = isSmartContractPay(nospacestring) - parsed_data = {'type': 'smartContractPays', 'flodata': string, 'smartContractTrigger':contractConditions['smartContractTrigger'], 'smartContractName':contractConditions['smartContractName']} - - elif isSmartContract(cleanstring): - contractname = isSmartContract(cleanstring) - marker = extractMarker(cleanstring) - contracttype = extractContractType(cleanstring) - contractaddress = extractAddress(nospacestring) - contractconditions = extractContractConditions(cleanstring, 'betting*', marker) - parsed_data = {'type': 'smartContractIncorporation', 'contractType': contracttype[:-1], 'tokenIdentification': marker[:-1], 'contractName': contractname[:-1], 'contractAddress':contractaddress[:-1], 'flodata': string, 'contractConditions': contractconditions} - - elif isIncorp(cleanstring): - incMarker = extractMarker(cleanstring) - initTokens = extractInitTokens(cleanstring) - parsed_data = {'type': 'tokenIncorporation', 'flodata': string, 'tokenIdentification': incMarker[:-1], 'tokenAmount': initTokens} - - else: + # Filter noise first - check if the words end with either @ or # + if (len(atList)==0 and len(hashList)==0) or len(atList)>1 or len(hashList)>1: parsed_data = {'type': 'noise'} + elif len(hashList)==1 and len(atList)==0: + # Passing the above check means token creation or transfer + incorporation = isIncorp(cleanstring) + transfer = isTransfer(cleanstring) + + if incorporation and not transfer: + initTokens = extractInitTokens(cleanstring) + if initTokens is not None: + parsed_data = {'type': 'tokenIncorporation', 'flodata': string, 'tokenIdentification': hashList[0][:-1], + 'tokenAmount': initTokens} + else: + parsed_data = {'type': 'noise'} + elif not incorporation and transfer: + amount = extractAmount(cleanstring, hashList[0][:-1]) + address = extractAddress(nospacestring) + if None not in [amount, address]: + parsed_data = {'type': 'transfer', 'transferType': 'token', 'flodata': string, + 'tokenIdentification': hashList[0][:-1], + 'tokenAmount': amount, 'address': address[:-1]} + else: + parsed_data = {'type': 'noise'} + else: + parsed_data = {'type': 'noise'} + + elif len(hashList)==1 and len(atList)==1: + # Passing the above check means Smart Contract creation or transfer + incorporation = isIncorp(cleanstring) + transfer = isTransfer(cleanstring) + + if incorporation and not transfer: + contracttype = extractContractType(cleanstring) + contractaddress = extractAddress(nospacestring) + contractconditions = extractContractConditions(cleanstring, 'betting*', marker) + + if None not in [contracttype, contractaddress, contractconditions]: + parsed_data = {'type': 'smartContractIncorporation', 'contractType': contracttype[:-1], + 'tokenIdentification': hashList[0][:-1], 'contractName': atList[0][:-1], + 'contractAddress': contractaddress[:-1], 'flodata': string, + 'contractConditions': contractconditions} + else: + parsed_data = {'type': 'noise'} + elif not incorporation and transfer: + amount = extractAmount(cleanstring, hashList[0][:-1]) + contractcondition = extractContractCondition(cleanstring) + if None not in [amount, contractcondition]: + parsed_data = {'type': 'transfer', 'transferType': 'smartContract', 'flodata': string, + 'tokenIdentification': hashList[0][:-1], + 'operation': 'transfer', 'tokenAmount': amount, 'contractName': atList[0][:-1], + 'contractCondition': contractcondition} + else: + parsed_data = {'type': 'noise'} + else: + parsed_data = {'type': 'noise'} + + + elif len(hashList)==0 and len(atList)==1: + # Passing the above check means Smart Contract pays | exitcondition triggered from the committee + triggerCondition = extractTriggerCondition(cleanstring) + if triggerCondition is not None: + parsed_data = {'type': 'smartContractPays', 'contractName': atList[0][:-1], 'triggerCondition': triggerCondition.group().strip()[1:-1]} + else: + parsed_data = {'type':'noise'} + return parsed_data -result = parse_flodata('create electionbetting@ at address oM4pCYsbT5xg7bqLNCTXmoADUs6zBwLfXi$ of type betting* using the token rmt# with contractconditions: 1. userAssetCommitment="1rmt" 2. smartContractPays="NAMO=WIN | NAMO=LOOSE 3. expirydate=1553040000"') +result = parse_flodata("for contractname@ Smart Contract System says 'NAMO=WIN'") print(result) \ No newline at end of file diff --git a/smartContracts/electionbetting.db b/smartContracts/electionbetting.db deleted file mode 100644 index dfe0768d499e0149f30928b32615970434f70c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8192 zcmeI%!EVzq7yw|WtXo=%1_>cRWztUoX=Bi-D;$PYX`w`;EKN&VHg@3PHZHShlFD}I zI&m4i0B^yShu~Rw4xFwXf+6jU^jk^n*uNe7yZuV{wZ|2MVIm@`phm6{!yr2Vgpl0) z*43;S`nfc3XI1uoS;>*go$pt5lwrLh`oe+&D1ZVefC4Ch0w{n2D1ZVefCB%yz-i4` zxw*M%e7>P*f5Zk!tOOk>sYE(ZskqpYYXq*-bD`%v_guIT4{OB&525Mz++8;Szug1> zjpsdrVu30pct6#7`@R!2UOGY6Y4bQ_$M#}E*7cE&(m!H4L9^uqhp^`!!Ws|Pi|bi# zZkD!*_0#%ceY3`;ucfr~R(D`Q0Te(16hHwKKmim$0Te(16hMJYVAaf%^}=0t%#}`E zL#}ud%a}$iD6f>E94GM!LoU+6QXc>I0`^v`MgYTX|9z@wP_5_*OgPzQ8|Ry? z+f_ZyhOG+7hzdP&mhyM#RMu_ZX|?MIO&>nNtm(DeUDtlPlqVZzdy(xsXJ@$d2<0o8 r*!9_7o1uo{Lq4FHh~5F@^5lWJu~^fm5&O&QmXSr27ZE*8F_-uSg?rxh diff --git a/tokens/rmt.db b/tokens/rmt.db deleted file mode 100644 index 5c9835238d78708f06fb0432d4d582cf03fc11aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24576 zcmeI%&u-c<90%~Y<)Z&a_vs)>UATb}8S>b0tH z<%Pqo;#6kQyyexby0b&BN_TmgIgy@OH8EbXEl2vzi$#wqETF-3h3vU#1-P9LdS-r3RXnanB@L6(2!n@}QN4rUu zc&>`Rn01*s;==XmZKUG=Kc61Ss;WxH)i5%@3?hbyl|-=c(wr;z{}fB*y_009U<00Izz z00bg|$^M^g{7`}y8U!E!0SG_<0uX=z1Rwwb2tWV=%Omidq?OZ0Dbd}p9e&XIAA4V_ zCvCeeFa5G5N9B$u-^+fvx!)%hQNjQJ%d@bk6ao-{00bZa0SG_<0uX=z1R$`e0QUcj c%HewufB*y_009U<00Izz00bZaf#nhS4K)8eIRF3v diff --git a/track-tokens-mod.py b/track-tokens-mod.py deleted file mode 100644 index b25a33f..0000000 --- a/track-tokens-mod.py +++ /dev/null @@ -1,302 +0,0 @@ -import requests -import json -import sqlite3 -import argparse -import configparser -import subprocess -import sys -import parsing -from sqlalchemy.orm import sessionmaker, relationship -from sqlalchemy import create_engine, func, desc -from models import Extra, TransactionHistory, TransactionTable, TransferLogs, Webtable, Base, ContractStructure - - -def startWorking(transaction_data, parsed_data): - engine = create_engine('sqlite:///databases/{}.db'.format(parsed_data['marker'][:-1]), echo=True) - Base.metadata.create_all(bind=engine) - Session = sessionmaker(bind=engine) - session = Session() - - # Play area - if parsed_data['type'] == 'transfer': - if parsed_data['amount'] is None: - print("Value for token transfer has not been specified") - return - elif parsed_data['type'] == 'incorporation': - if parsed_data['initTokens'] is None: - print("Value for token transfer has not been specified") - return - - inputlist = [] - querylist = [] - - for obj in transaction_data["vin"]: - querylist.append([obj["txid"], obj["vout"]]) - - inputval = 0 - inputadd = '' - - for query in querylist: - string = "{} getrawtransaction {} 1".format(localapi, str(query[0])) - response = subprocess.check_output(string, shell=True) - content = json.loads(response.decode("utf-8")) - - for objec in content["vout"]: - if objec["n"] == query[1]: - inputadd = objec["scriptPubKey"]["addresses"][0] - inputval = inputval + objec["value"] - - inputlist = [[inputadd, inputval]] - - if len(inputlist) > 1: - print("Program has detected more than one input address ") - print("This transaction will be discarded") - break - - outputlist = [] - for obj in transaction_data["vout"]: - if obj["scriptPubKey"]["type"] == "pubkeyhash": - if inputlist[0][0] == obj["scriptPubKey"]["addresses"][0]: - continue - temp = [] - temp.append(obj["scriptPubKey"]["addresses"][0]) - temp.append(obj["value"]) - - outputlist.append(temp) - - print("\n\nInput List") - print(inputlist) - print("\nOutput List") - print(outputlist) - - if len(inputlist) > 1: - print("Program has detected more than one input address ") - print("This transaction will be discarded") - continue - - # Check if the transaction is of the type 'incorporation' or 'smartcontract' - if parsed_data['type'] == 'smartcontract': - print("I JUST FOUND THE INCORPORATION OF SMART CONTRACT \n" + str(parsed_data)) - if parsed_data['contracttype'] == 'betting*': - print("Smart contract is of the type betting") - if parsed_data['contractname'] is not None and parsed_data['contractaddress'][:-1] == outputlist[0][0]: - print("Hey I have passed the first test for smart contract") - #check if a db with contractname exists - scengine = create_engine('sqlite:///smartContracts/{}.db'.format(parsed_data['contractname'][:-1]), echo=True) - Base.metadata.create_all(bind=scengine) - scsession = sessionmaker(bind=scengine)() - scsession.add(ContractStructure(attribute='contracttype', index=0, value=parsed_data['contracttype'][:-1])) - scsession.add(ContractStructure(attribute='contractname', index=0, value=parsed_data['contractname'][:-1])) - scsession.add( - ContractStructure(attribute='marker', index=0, value=parsed_data['marker'][:-1])) - - scsession.commit() - scsession.close() - - sys.exit(0) - elif parsed_data['type'] == 'incorporation': - session.add(TransactionTable(address=outputlist[0][0], parentid=0, transferBalance=parsed_data['initTokens'])) - session.commit() - #transferDescription = "Root address = " + str(root_address) + " has been initialized with " + str(root_init_value) + " tokens" - #blockchainReference = '{}tx/'.format(neturl) - #session.add(TransferLogs(primaryIDReference=1, transferDescription=transferDescription, transferIDConsumed=0, blockchainReference=blockchainReference)) - #session.add(TransactionHistory(blockno=root_block_index, fromAddress='', toAddress=root_address, amount=root_init_value, blockchainReference=blockchainReference)) - #session.commit() - return - - availableTokens = session.query(func.sum(TransactionTable.transferBalance)).filter_by(address=inputlist[0][0]).all()[0][0] - commentTransferAmount = parsed_data['amount'] - - if availableTokens is None: - print("The input address dosen't exist in our database ") - - elif availableTokens < commentTransferAmount: - print("\nThe transfer amount passed in the comments is more than the user owns\nThis transaction will be discarded\n") - continue - - elif availableTokens >= commentTransferAmount: - '''if len(commentTransferAmount) != len(outputlist): - print("The parameters in the comments aren't enough") - print("This transaction will be discarded") - continue''' - - # if output[0] == inputlist[0][0]: - # continue - - #c.execute("SELECT * FROM transactiontable WHERE address=?", (inputlist[0][0],)) - #table = c.fetchall() - table = session.query(TransactionTable).filter_by(address=inputlist[0][0]).all() - - pidlst = [] - checksum = 0 - for row in table: - if checksum >= commentTransferAmount: - break - pidlst.append(row.id) - checksum = checksum + row.transferBalance - - balance = commentTransferAmount - #c.execute("SELECT sum(transferBalance) FROM transactiontable WHERE address=?", (outputlist[i][0],)) - #opbalance = c.fetchall()[0][0] - opbalance = session.query(func.sum(TransactionTable.transferBalance)).filter_by(address=outputlist[0][0]).all()[0][0] - - if opbalance is None: - opbalance = 0 - - #c.execute("SELECT sum(transferBalance) FROM transactiontable WHERE address=?", (inputlist[0][0],)) - #ipbalance = c.fetchall()[0][0] - ipbalance = session.query(func.sum(TransactionTable.transferBalance)).filter_by(address=inputlist[0][0]).all()[0][0] - - for pid in pidlst: - #c.execute("SELECT transferBalance FROM transactiontable WHERE id=?", (pid,)) - #temp = c.fetchall() - #temp = temp[0][0] - temp = session.query(TransactionTable.transferBalance).filter_by(id=pid).all()[0][0] - - if balance <= temp: - #c.execute("INSERT INTO transactiontable (address, parentid, transferBalance) VALUES (?,?,?)", - # (outputlist[i][0], pid, balance)) - #c.execute("UPDATE transactiontable SET transferBalance=? WHERE id=?", (temp - balance, pid)) - - session.add(TransactionTable(address=outputlist[0][0], parentid=pid, transferBalance=balance)) - entry = session.query(TransactionTable).filter(TransactionTable.id == pid).all() - entry[0].transferBalance = temp - balance - session.commit() - - ## transaction logs section ## - result = session.query(TransactionTable.id).order_by(desc(TransactionTable.id)).all() - lastid = result[-1].id - transferDescription = str(balance) + " tokens transferred to " + str( - outputlist[0][0]) + " from " + str(inputlist[0][0]) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - session.add(TransferLogs(primaryIDReference=lastid, transferDescription=transferDescription, - transferIDConsumed=pid, blockchainReference=blockchainReference)) - transferDescription = str(inputlist[0][0]) + " balance UPDATED from " + str( - temp) + " to " + str(temp - balance) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - session.add(TransferLogs(primaryIDReference=pid, transferDescription=transferDescription, - blockchainReference=blockchainReference)) - - ## transaction history table ## - session.add(TransactionHistory(blockno=blockindex, fromAddress=inputlist[0][0], - toAddress=outputlist[0][0], amount=str(balance), - blockchainReference=blockchainReference)) - - ##webpage table section ## - transferDescription = str(commentTransferAmount) + " tokens transferred from " + str( - inputlist[0][0]) + " to " + str(outputlist[0][0]) - session.add( - Webtable(transferDescription=transferDescription, blockchainReference=blockchainReference)) - - transferDescription = "UPDATE " + str(outputlist[0][0]) + " balance from " + str( - opbalance) + " to " + str(opbalance + commentTransferAmount) - session.add( - Webtable(transferDescription=transferDescription, blockchainReference=blockchainReference)) - - transferDescription = "UPDATE " + str(inputlist[0][0]) + " balance from " + str( - ipbalance) + " to " + str(ipbalance - commentTransferAmount) - session.add( - Webtable(transferDescription=transferDescription, blockchainReference=blockchainReference)) - - balance = 0 - session.commit() - - elif balance > temp: - session.add(TransactionTable(address=outputlist[0][0], parentid=pid, transferBalance=temp)) - entry = session.query(TransactionTable).filter(TransactionTable.id == pid).all() - entry[0].transferBalance = 0 - session.commit() - - ##transaction logs section ## - session.query(TransactionTable.id).order_by(desc(TransactionTable.id)) - result = session.query(TransactionTable.id).order_by(desc(TransactionTable.id)).all() - lastid = result[-1].id - transferDescription = str(temp) + " tokens transferred to " + str( - outputlist[0][0]) + " from " + str(inputlist[0][0]) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - session.add(TransactionTable(primaryIDReference=lastid, transferDescription=transferDescription, - transferIDConsumed=pid, blockchainReference=blockchainReference)) - - transferDescription = str() + " balance UPDATED from " + str(temp) + " to " + str(0) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - session.add(TransactionTable(primaryIDReference=pid, transferDescription=transferDescription, - blockchainReference=blockchainReference)) - - ## transaction history table ## - session.add(TransactionHistory(blockno=blockindex, fromAddress=inputlist[0][0], - toAddress=outputlist[0][0], amount=str(balance), - blockchainReference=blockchainReference)) - balance = balance - temp - session.commit() - - # Finishing statements - session.commit() - session.close() - - - -# Read configuration -config = configparser.ConfigParser() -config.read('config.ini') - -# Read command line arguments -parser = argparse.ArgumentParser(description='Script tracks RMT using FLO data on the FLO blockchain - https://flo.cash') -parser.add_argument('-r', '--reset', nargs='?', const=1, type=int, help='Purge existing db and rebuild it') -args = parser.parse_args() - -# Assignment the flo-cli command -if config['DEFAULT']['NET'] == 'mainnet': - neturl = 'https://florincoin.info/' - localapi = config['DEFAULT']['FLO_CLI_PATH'] -elif config['DEFAULT']['NET'] == 'testnet': - neturl = 'https://testnet.florincoin.info/' - localapi = '{} --testnet'.format(config['DEFAULT']['FLO_CLI_PATH']) -else: - print("NET parameter is wrong\nThe script will exit now ") - - -# Delete database directory if reset is set to 1 -if args.reset == 1: - import os - import shutil - apppath = os.path.dirname(os.path.realpath(__file__)) - dirpath = os.path.join(apppath, 'databases') - shutil.rmtree(dirpath) - os.mkdir(dirpath) - - -# Read start block no -startblock = int(config['DEFAULT']['START_BLOCK']) - -# Find current block height -string = "{} getblockcount".format(localapi) -response = subprocess.check_output(string, shell=True) -current_index = json.loads(response.decode("utf-8")) -print("current_block_height : " + str(current_index)) - - -for blockindex in range( startblock, current_index ): - print(blockindex) - - # Scan every block - string = "{} getblockhash {}".format(localapi, str(blockindex)) - response = subprocess.check_output(string, shell=True) - blockhash = response.decode("utf-8") - - string = "{} getblock {}".format(localapi, str(blockhash)) - response = subprocess.check_output(string, shell=True) - blockinfo = json.loads(response.decode("utf-8")) - - # Scan every transaction - for transaction in blockinfo["tx"]: - string = "{} getrawtransaction {} 1".format(localapi, str(transaction)) - response = subprocess.check_output(string, shell=True) - transaction_data = json.loads(response.decode("utf-8")) - text = transaction_data["floData"] - text = text[5:] - - parsed_data = parsing.parse_flodata(text) - if parsed_data['type'] != 'noise': - print(blockindex) - print(parsed_data['type']) - startWorking(transaction_data, parsed_data) \ No newline at end of file diff --git a/track-tokens.py b/track-tokens.py deleted file mode 100644 index 1dc2a6e..0000000 --- a/track-tokens.py +++ /dev/null @@ -1,351 +0,0 @@ -import requests -import json -import sqlite3 -import argparse -import configparser -import subprocess - - -# Read configuration -config = configparser.ConfigParser() -config.read('config.ini') - -# Read command line arguments -parser = argparse.ArgumentParser(description='Script tracks RMT using FLO data on the FLO blockchain - https://flo.cash') -parser.add_argument('-r', '--reset', nargs='?', const=1, type=int, help='Purge existing db and rebuild it') -args = parser.parse_args() - -if config['DEFAULT']['NET'] == 'mainnet': - neturl = 'https://florincoin.info/' - localapi = config['DEFAULT']['FLO_CLI_PATH'] -elif config['DEFAULT']['NET'] == 'testnet': - neturl = 'https://testnet.florincoin.info/' - localapi = '{} --testnet'.format(config['DEFAULT']['FLO_CLI_PATH']) -else: - print('NET parameter is wrong') - - -def listcheck(lst): - for element in lst: - try: - float(element) - except ValueError: - print("values to be transferred aren't in the right format") - return 1 - return 0 - -def startTracking(blockindex, config, conn, c): - string = "{} getblockhash {}".format(localapi, str(blockindex)) - response = subprocess.check_output(string, shell=True) - blockhash = response.decode("utf-8") - - string = "{} getblock {}".format(localapi, str(blockhash)) - response = subprocess.check_output(string, shell=True) - blockinfo = json.loads(response.decode("utf-8")) - - for transaction in blockinfo["tx"]: - string = "{} getrawtransaction {} 1".format(localapi, str(transaction)) - response = subprocess.check_output(string, shell=True) - data = json.loads(response.decode("utf-8")) - text = data["floData"] - text = text[5:] - comment_list = text.split("#") - - if comment_list[0] == config['DEFAULT']['PREFIX']: - print("I just saw "+str(config['DEFAULT']['PREFIX'])) - commentTransferAmount = comment_list[1:] - - #if not all(isinstance(x, (int, float)) for x in commentTransferAmount): - # print("Values to be transffered aren't in the right format") - # continue - - if len(commentTransferAmount) == 0: - print("Value for token transfer has not been specified") - continue - - returnval = listcheck(commentTransferAmount) - if returnval == 1: - continue - - commentTransferAmount = list(map(float, commentTransferAmount)) - - inputlist = [] - querylist = [] - - for obj in data["vin"]: - querylist.append([obj["txid"], obj["vout"]]) - - inputval = 0 - inputadd = '' - - for query in querylist: - string = "{} getrawtransaction {} 1".format(localapi, str(query[0])) - response = subprocess.check_output(string, shell=True) - content = json.loads(response.decode("utf-8")) - - for objec in content["vout"]: - if objec["n"] == query[1]: - inputadd = objec["scriptPubKey"]["addresses"][0] - inputval = inputval + objec["value"] - - inputlist = [[inputadd, inputval]] - - if len(inputlist) > 1: - print("Program has detected more than one input address ") - print("This transaction will be discarded") - continue - - outputlist = [] - for obj in data["vout"]: - if obj["scriptPubKey"]["type"] == "pubkeyhash": - if inputlist[0][0] == obj["scriptPubKey"]["addresses"][0]: - continue - temp = [] - temp.append(obj["scriptPubKey"]["addresses"][0]) - temp.append(obj["value"]) - - outputlist.append(temp) - - - print("\n\nInput List") - print(inputlist) - print("\nOutput List") - print(outputlist) - - if len(inputlist) > 1: - print("Program has detected more than one input address ") - print("This transaction will be discarded") - continue - - c.execute("SELECT sum(transferBalance) FROM transactiontable WHERE address=?" , (inputlist[0][0],)) - availableTokens = c.fetchall() - availableTokens = availableTokens[0][0] - - if availableTokens is None: - print("The input address dosen't exist in our database ") - - elif availableTokens < sum(commentTransferAmount): - print("\nThe transfer amount passed in the comments is more than the user owns\nThis transaction will be discarded\n") - continue - - elif availableTokens >= sum(commentTransferAmount): - if len(commentTransferAmount) != len(outputlist): - print("The parameters in the comments aren't enough") - print("This transaction will be discarded") - continue - - for i in range(len(commentTransferAmount)): - # if output[0] == inputlist[0][0]: - # continue - - c.execute("SELECT * FROM transactiontable WHERE address=?",(inputlist[0][0],)) - table = c.fetchall() - - pidlst = [] - checksum = 0 - for row in table: - if checksum >= commentTransferAmount[i]: - break - pidlst.append(row[0]) - checksum = checksum + row[3] - - balance = commentTransferAmount[i] - c.execute("SELECT sum(transferBalance) FROM transactiontable WHERE address=?", ( outputlist[i][0],)) - opbalance = c.fetchall()[0][0] - if opbalance is None: - opbalance = 0 - - c.execute("SELECT sum(transferBalance) FROM transactiontable WHERE address=?", ( inputlist[0][0],)) - ipbalance = c.fetchall()[0][0] - - for pid in pidlst: - c.execute("SELECT transferBalance FROM transactiontable WHERE id=?", (pid,)) - temp = c.fetchall() - temp = temp[0][0] - - if balance <= temp: - c.execute("INSERT INTO transactiontable (address, parentid, transferBalance) VALUES (?,?,?)", (outputlist[i][0],pid,balance)) - c.execute("UPDATE transactiontable SET transferBalance=? WHERE id=?", (temp-balance, pid)) - - ## transaction logs section ## - c.execute("SELECT id FROM transactiontable ORDER BY id DESC LIMIT 1") - lastid = c.fetchall()[0][0] - transferDescription = str(balance) + " tokens transferred to " + str(outputlist[i][0]) + " from " + str(inputlist[0][0]) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - c.execute("""INSERT INTO transferlogs (primaryIDReference, transferDescription, transferIDConsumed, blockchainReference) - VALUES (?,?,?,?)""", ( lastid, transferDescription, pid, blockchainReference)) - - transferDescription = str(inputlist[0][0]) + " balance UPDATED from " + str(temp) + " to " + str(temp-balance) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - c.execute("""INSERT INTO transferlogs (primaryIDReference, transferDescription, blockchainReference) - VALUES (?,?,?)""", ( pid, transferDescription, blockchainReference)) - - ## transaction history table ## - c.execute( - '''INSERT INTO transactionHistory (blockno, fromAddress, toAddress, amount, blockchainReference) VALUES (?,?,?,?,?)''', - (blockindex, inputlist[0][0], outputlist[0][0], str(balance), blockchainReference)) - - ##webpage table section ## - transferDescription = str(commentTransferAmount[i]) + " tokens transferred from " + str(inputlist[0][0]) + " to " + str(outputlist[i][0]) - c.execute("""INSERT INTO webtable (transferDescription, blockchainReference) - VALUES (?,?)""", ( transferDescription, blockchainReference)) - - transferDescription = "UPDATE " + str(outputlist[i][0]) + " balance from " + str(opbalance) + " to " + str(opbalance + commentTransferAmount[i]) - c.execute("""INSERT INTO webtable (transferDescription, blockchainReference) - VALUES (?,?)""", ( transferDescription, blockchainReference)) - - transferDescription = "UPDATE " + str(inputlist[0][0]) + " balance from " + str(ipbalance) + " to " + str(ipbalance - commentTransferAmount[i]) - c.execute("""INSERT INTO webtable (transferDescription, blockchainReference) - VALUES (?,?)""", ( transferDescription, blockchainReference)) - - balance = 0 - conn.commit() - elif balance > temp: - c.execute("INSERT INTO transactiontable (address, parentid, transferBalance) VALUES (?,?,?)", (outputlist[i][0], pid, temp )) - c.execute("UPDATE transactiontable SET transferBalance=? WHERE id=?", (0, pid)) - - ##transaction logs section ## - c.execute("SELECT id FROM transactiontable ORDER BY id DESC LIMIT 1") - lastid = c.fetchall()[0][0] - transferDescription = str(temp) + " tokens transferred to " + str(outputlist[i][0]) + " from " + str(inputlist[0][0]) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - c.execute("""INSERT INTO transferlogs (primaryIDReference, transferDescription, transferIDConsumed, blockchainReference) - VALUES (?,?,?,?)""", ( lastid, transferDescription, pid, blockchainReference)) - - transferDescription = str() + " balance UPDATED from " + str(temp) + " to " + str(0) - blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) - c.execute("""INSERT INTO transferlogs (primaryIDReference, transferDescription, blockchainReference) - VALUES (?,?,?)""", ( pid, transferDescription, blockchainReference)) - - ## transaction history table ## - c.execute( - '''INSERT INTO transactionHistory (blockno, fromAddress, toAddress, amount, blockchainReference) VALUES (?,?,?,?,?)''', - (blockindex, inputlist[0][0], outputlist[0][0], str(balance), blockchainReference)) - - balance = balance - temp - conn.commit() - -def resetDatabase(c, conn): - c.execute("DROP TABLE IF EXISTS transactiontable") - c.execute("""CREATE TABLE transactiontable ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - address TEXT, - parentid INT, - transferBalance REAL - )""") - - c.execute("DROP TABLE IF EXISTS transferlogs") - c.execute("""CREATE TABLE transferlogs ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - primaryIDReference INTEGER, - transferDescription TEXT, - transferIDConsumed INT, - blockchainReference TEXT - )""") - - c.execute("DROP TABLE IF EXISTS webtable") - c.execute("""CREATE TABLE webtable ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - transferDescription TEXT, - blockchainReference TEXT - )""") - - c.execute("DROP TABLE IF EXISTS transactionHistory") - c.execute("""CREATE TABLE transactionHistory ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - blockno INT, - fromAddress TEXT, - toAddress TEXT, - amount REAL, - blockchainReference TEXT - )""") - - c.execute("DROP TABLE IF EXISTS extra") - c.execute("CREATE TABLE extra ( id INTEGER PRIMARY KEY , lastblockscanned INT)") - conn.commit() - - -def main(): - - # Connect to db - conn = sqlite3.connect(config['DEFAULT']['DB_NAME']) - c = conn.cursor() - - # get current block height - string = "{} getblockcount".format(localapi) - response = subprocess.check_output(string, shell=True) - current_index = json.loads(response.decode("utf-8")) - print("current_block_height : " + str(current_index)) - - if args.reset == 1: - resetDatabase(c, conn) - # Read root address - root_address = config['DEFAULT']['ROOT_ADDRESS'] - root_init_value = int(config['DEFAULT']['INIT_TOKEN_NO']) - - # Find root address's block no - string = "{}ext/getaddress/{}/".format(neturl, str(root_address)) - response = requests.get(string) - content = json.loads(response.content.decode("utf-8")) - root_trans_hash = '' - for cur in content["last_txs"]: - if cur["type"] == "vout": - root_trans_hash = cur["addresses"] - break - - string = "{} getrawtransaction {} 1".format(localapi, str(root_trans_hash)) - response = subprocess.check_output(string, shell=True) - content = json.loads(response.decode("utf-8")) - root_block_hash = content["blockhash"] - - string = "{} getblock {}".format(localapi, str(root_block_hash)) - response = subprocess.check_output(string, shell=True) - content = json.loads(response.decode("utf-8")) - root_block_index = content["height"] - # root_block_index = 26066 - - print("root_block_index = " + str(root_block_index)) - - c.execute("INSERT INTO transactiontable ( address, parentid, transferBalance) VALUES (?,?,?)", - (root_address, 0, root_init_value)) - conn.commit() - - transferDescription = "Root address = " + str(root_address) + " has been initialized with " + str( - root_init_value) + " tokens" - blockchainReference = '{}tx/'.format(neturl) - c.execute("""INSERT INTO transferlogs (primaryIDReference, transferDescription, transferIDConsumed, blockchainReference) - VALUES (?,?,?,?)""", - (1, transferDescription, 0, blockchainReference)) - - c.execute( - '''INSERT INTO transactionHistory (blockno, fromAddress, toAddress, amount, blockchainReference) VALUES (?,?,?,?,?)''', - (root_block_index, '', root_address, root_init_value, blockchainReference)) - - c.execute("INSERT INTO extra (id, lastblockscanned) VALUES (?,?)", (1, root_block_index)) - conn.commit() - lastblockscanned = root_block_index - - else: - response = requests.get("{}api/getblockcount".format(neturl)) - string = "{} getblockcount".format(localapi) - response = subprocess.check_output(string, shell=True) - current_index = json.loads(response.decode("utf-8")) - - c.execute("SELECT lastblockscanned FROM extra WHERE id=1") - lastblockscanned = c.fetchall()[0][0] - - - # run loop and pass blockno - for blockindex in range(lastblockscanned + 1, current_index+1): - if blockindex == 3127800: - print('hi') - print(blockindex) - startTracking(blockindex, config, conn, c) - c.execute("UPDATE extra SET lastblockscanned=? WHERE id=?", (blockindex,1)) - conn.commit() - - conn.commit() - conn.close() - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/tracktokens-smartcontract.py b/tracktokens-smartcontract.py index eb144f4..86e769a 100644 --- a/tracktokens-smartcontract.py +++ b/tracktokens-smartcontract.py @@ -10,7 +10,121 @@ import os import shutil from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy import create_engine, func, desc -from models import Extra, TransactionHistory, TransactionTable, TransferLogs, Webtable, Base, ContractStructure, ContractBase +from models import Extra, TransactionHistory, TransactionTable, TransferLogs, Webtable, Base, ContractStructure, ContractBase, ContractParticipants, SystemBase, ActiveContracts + + +committeeAddressList = ['oUc4dVvxwK7w5MHUHtev8UawN3eDjiZnNx'] + +def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress): + engine = create_engine('sqlite:///tokens/{}.db'.format(tokenIdentification), echo=True) + Base.metadata.create_all(bind=engine) + session = sessionmaker(bind=engine)() + availableTokens = session.query(func.sum(TransactionTable.transferBalance)).filter_by(address=inputAddress).all()[0][0] + commentTransferAmount = tokenAmount + if availableTokens is None: + print("The input address dosen't exist in our database ") + session.close() + return None + + elif availableTokens < commentTransferAmount: + print( + "\nThe transfer amount passed in the comments is more than the user owns\nThis transaction will be discarded\n") + session.close() + return None + + elif availableTokens >= commentTransferAmount: + table = session.query(TransactionTable).filter(TransactionTable.address==inputAddress, TransactionTable.transferBalance>0).all() + pidlst = [] + checksum = 0 + for row in table: + if checksum >= commentTransferAmount: + break + pidlst.append(row.id) + checksum = checksum + row.transferBalance + + balance = commentTransferAmount + opbalance = session.query(func.sum(TransactionTable.transferBalance)).filter_by(address=outputAddress).all()[0][0] + + if opbalance is None: + opbalance = 0 + + ipbalance = availableTokens + + for pid in pidlst: + temp = session.query(TransactionTable.transferBalance).filter_by(id=pid).all()[0][0] + + if balance <= temp: + + session.add(TransactionTable(address=outputAddress, parentid=pid, transferBalance=balance)) + entry = session.query(TransactionTable).filter(TransactionTable.id == pid).all() + entry[0].transferBalance = temp - balance + session.commit() + + ## transaction logs section ## + result = session.query(TransactionTable.id).order_by(desc(TransactionTable.id)).all() + lastid = result[-1].id + transferDescription = str(balance) + " tokens transferred to " + str( + outputAddress) + " from " + str(inputAddress) + blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) + session.add(TransferLogs(primaryIDReference=lastid, transferDescription=transferDescription, + transferIDConsumed=pid, blockchainReference=blockchainReference)) + transferDescription = str(inputAddress) + " balance UPDATED from " + str( + temp) + " to " + str(temp - balance) + blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) + session.add(TransferLogs(primaryIDReference=pid, transferDescription=transferDescription, + blockchainReference=blockchainReference)) + + ## transaction history table ## + session.add(TransactionHistory(blockno=blockindex, fromAddress=inputAddress, + toAddress=outputAddress, amount=str(balance), + blockchainReference=blockchainReference)) + + ##webpage table section ## + transferDescription = str(commentTransferAmount) + " tokens transferred from " + str( + inputAddress) + " to " + str(outputAddress) + session.add( + Webtable(transferDescription=transferDescription, blockchainReference=blockchainReference)) + + transferDescription = "UPDATE " + str(outputAddress) + " balance from " + str( + opbalance) + " to " + str(opbalance + commentTransferAmount) + session.add( + Webtable(transferDescription=transferDescription, blockchainReference=blockchainReference)) + + transferDescription = "UPDATE " + str(inputAddress) + " balance from " + str( + ipbalance) + " to " + str(ipbalance - commentTransferAmount) + session.add( + Webtable(transferDescription=transferDescription, blockchainReference=blockchainReference)) + + balance = 0 + session.commit() + + elif balance > temp: + session.add(TransactionTable(address=outputAddress, parentid=pid, transferBalance=temp)) + entry = session.query(TransactionTable).filter(TransactionTable.id == pid).all() + entry[0].transferBalance = 0 + session.commit() + + ##transaction logs section ## + result = session.query(TransactionTable.id).order_by(desc(TransactionTable.id)).all() + lastid = result[-1].id + transferDescription = str(temp) + " tokens transferred to " + str(outputAddress) + " from " + str(inputAddress) + blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) + session.add(TransferLogs(primaryIDReference=lastid, transferDescription=transferDescription, + transferIDConsumed=pid, blockchainReference=blockchainReference)) + + transferDescription = str() + " balance UPDATED from " + str(temp) + " to " + str(0) + blockchainReference = '{}tx/{}'.format(neturl, str(transaction)) + session.add(TransferLogs(primaryIDReference=pid, transferDescription=transferDescription, + blockchainReference=blockchainReference)) + + ## transaction history table ## + session.add(TransactionHistory(blockno=blockindex, fromAddress=inputAddress, + toAddress=outputAddress, amount=str(balance), + blockchainReference=blockchainReference)) + balance = balance - temp + session.commit() + session.close() + return 1 def startWorking(transaction_data, parsed_data): @@ -67,25 +181,30 @@ def startWorking(transaction_data, parsed_data): if parsed_data['type'] == 'transfer': print('Found a transaction of the type transfer') - if parsed_data['transferType'] == 'smartContract': - print('do something') + if parsed_data['transferType'] == 'token': - elif parsed_data['transferType'] == 'token': - engine = create_engine('sqlite:///tokens/{}.db'.format(parsed_data['tokenIdentification']), echo=True) - Base.metadata.create_all(bind=engine) - session = sessionmaker(bind=engine)() - availableTokens = session.query(func.sum(TransactionTable.transferBalance)).filter_by(address=inputlist[0][0]).all()[0][0] - commentTransferAmount = parsed_data['amount'] - if availableTokens is None: - print("The input address dosen't exist in our database ") + returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['tokenAmount'], inputlist[0][0], outputlist[0][0]) + if returnval is None: + print("Something went wrong in the token transfer method") - elif availableTokens < commentTransferAmount: - print( - "\nThe transfer amount passed in the comments is more than the user owns\nThis transaction will be discarded\n") - return + elif parsed_data['transferType'] == 'smartContract': + + # Check if the tokenAmount being transferred exists in the address & do the token transfer + returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['tokenAmount'], inputlist[0][0], outputlist[0][0]) + if returnval is not None: + # Store participant details in the smart contract's db + engine = create_engine('sqlite:///smartContracts/{}.db'.format(parsed_data['contractName']), echo=True) + Base.metadata.create_all(bind=engine) + session = sessionmaker(bind=engine)() + session.add(ContractParticipants(participantAddress=inputadd, tokenAmount=parsed_data['tokenAmount'], + contractCondition=parsed_data['contractCondition'])) + session.commit() + session.close() + + + else: + print("Something went wrong in the smartcontract token transfer method") - elif availableTokens >= commentTransferAmount: - print("well i've reached here") elif parsed_data['type'] == 'tokenIncorporation': if not os.path.isfile('./tokens/{}.db'.format(parsed_data['tokenIdentification'])): @@ -112,7 +231,7 @@ def startWorking(transaction_data, parsed_data): session.add( ContractStructure(attribute='tokenIdentification', index=0, value=parsed_data['tokenIdentification'])) session.add( - ContractStructure(attribute='contractAddress', index=0, value=parsed_data['contractAddress'][:-1])) + ContractStructure(attribute='contractAddress', index=0, value=parsed_data['contractAddress'])) session.add( ContractStructure(attribute='flodata', index=0, value=parsed_data['flodata'])) @@ -123,11 +242,50 @@ def startWorking(transaction_data, parsed_data): session.add(ContractStructure(attribute='exitconditions', index=key, value=value)) session.commit() session.close() + + # Store smart contract address in system's db, to be ignored during future transfers + engine = create_engine('sqlite:///system.db', + echo=True) + SystemBase.metadata.create_all(bind=engine) + session = sessionmaker(bind=engine)() + session.add( + ActiveContracts(contractName=parsed_data['contractName'], contractAddress=parsed_data['contractAddress'])) + session.commit() + session.close() else: print('Transaction rejected as a smartcontract with same name has already been incorporated') elif parsed_data['type'] == 'smartContractPays': print('Found a transaction of the type smartContractPays') + # Check if input address is a committee address + if inputlist[0][0] in committeeAddressList: + + # Check if the output address is an active Smart contract address + engine = create_engine('sqlite:///system.db', echo=True) + connection = engine.connect() + activeContracts = connection.execute('select * from activecontracts').fetchall() + connection.close() + + # Change columns into rows - https://stackoverflow.com/questions/44360162/how-to-access-a-column-in-a-list-of-lists-in-python + activeContracts = list(zip(*activeContracts)) + if outputlist[0][0] in activeContracts[2] and parsed_data['contractName'] in activeContracts[1]: + + engine = create_engine('sqlite:///smartContracts/{}.db'.format(parsed_data['contractName']), echo=True) + connection = engine.connect() + contractWinners = connection.execute('select * from contractparticipants where contractCondition="{}"'.format(parsed_data['triggerCondition'])).fetchall() + tokenSum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] + tokenIdentification = connection.execute('select value from contractstructure where attribute="tokenIdentification"').fetchall()[0][0] + connection.close() + + contractWinners = list(zip(*contractWinners)) + for address in contractWinners[1]: + transferToken(tokenIdentification, tokenSum/len(contractWinners[1]), outputlist[0][0], address) + + else: + print('This trigger doesn\'t apply to an active contract. It will be discarded') + + else: + print('Input address is not part of the committee address list. This trigger is rejected') @@ -150,6 +308,13 @@ elif config['DEFAULT']['NET'] == 'testnet': else: print("NET parameter is wrong\nThe script will exit now ") +apppath = os.path.dirname(os.path.realpath(__file__)) +dirpath = os.path.join(apppath, 'tokens') +if not os.path.isdir(dirpath): + os.mkdir(dirpath) +dirpath = os.path.join(apppath, 'smartContracts') +if not os.path.isdir(dirpath): + os.mkdir(dirpath) # Delete database and smartcontract directory if reset is set to 1 if args.reset == 1: @@ -160,6 +325,9 @@ if args.reset == 1: dirpath = os.path.join(apppath, 'smartContracts') shutil.rmtree(dirpath) os.mkdir(dirpath) + dirpath = os.path.join(apppath, 'system.db') + if os.path.exists(dirpath): + os.remove(dirpath) # Read start block no @@ -191,6 +359,9 @@ for blockindex in range( startblock, current_index ): transaction_data = json.loads(response.decode("utf-8")) text = transaction_data["floData"] + if blockindex == 498385: + print('debug point') + parsed_data = parsing.parse_flodata(text) if parsed_data['type'] != 'noise': print(blockindex)