diff --git a/app.py b/app.py index 82d4ab6..9b76661 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,15 @@ -from flask import Flask, render_template, jsonify import os + +from flask import Flask, jsonify + app = Flask(__name__) + @app.route('/') def hello_world(): return 'Hello, World!' + @app.route('/getmarkerlist') def marker_list(): dblist = os.listdir("databases/") @@ -15,4 +19,5 @@ def marker_list(): return jsonify(dbdict) + app.run(debug=True) diff --git a/models.py b/models.py index 6f2eb5c..ca07bb1 100644 --- a/models.py +++ b/models.py @@ -1,11 +1,12 @@ +from sqlalchemy import Column, Integer, Float, String from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy import Column, Integer, Float, String, ForeignKey Base = declarative_base() ContractBase = declarative_base() SystemBase = declarative_base() LatestCacheBase = declarative_base() + class ActiveTable(Base): __tablename__ = "activeTable" @@ -54,6 +55,8 @@ class TransactionHistory(Base): transactionHash = Column('transactionHash', String) blockchainReference = Column('blockchainReference', String) jsonData = Column('jsonData', String) + transactionType = Column('transactionType', String) + parsedFloData = Column('parsedFloData', String) class TokenContractAssociation(Base): @@ -69,7 +72,8 @@ class TokenContractAssociation(Base): transactionHash = Column('transactionHash', String) blockchainReference = Column('blockchainReference', String) jsonData = Column('jsonData', String) - + transactionType = Column('transactionType', String) + parsedFloData = Column('parsedFloData', String) class ContractStructure(ContractBase): @@ -109,6 +113,7 @@ class ContractTransactionHistory(ContractBase): transactionHash = Column('transactionHash', String) blockchainReference = Column('blockchainReference', String) jsonData = Column('jsonData', String) + parsedFloData = Column('parsedFloData', String) class RejectedContractTransactionHistory(SystemBase): @@ -129,6 +134,8 @@ class RejectedContractTransactionHistory(SystemBase): blockchainReference = Column('blockchainReference', String) jsonData = Column('jsonData', String) rejectComment = Column('rejectComment', String) + parsedFloData = Column('parsedFloData', String) + class RejectedTransactionHistory(SystemBase): __tablename__ = "rejectedTransactionHistory" @@ -145,6 +152,8 @@ class RejectedTransactionHistory(SystemBase): blockchainReference = Column('blockchainReference', String) jsonData = Column('jsonData', String) rejectComment = Column('rejectComment', String) + transactionType = Column('transactionType', String) + parsedFloData = Column('parsedFloData', String) class ActiveContracts(SystemBase): @@ -171,6 +180,7 @@ class SystemData(SystemBase): attribute = Column('attribute', String) value = Column('value', String) + class ContractAddressMapping(SystemBase): __tablename__ = "contractAddressMapping" @@ -184,6 +194,7 @@ class ContractAddressMapping(SystemBase): blockNumber = Column('blockNumber', Integer) blockHash = Column('blockHash', String) + class TokenAddressMapping(SystemBase): __tablename__ = "tokenAddressMapping" @@ -194,6 +205,7 @@ class TokenAddressMapping(SystemBase): blockNumber = Column('blockNumber', Integer) blockHash = Column('blockHash', String) + class LatestTransactions(LatestCacheBase): __tablename__ = "latestTransactions" id = Column('id', Integer, primary_key=True) @@ -203,11 +215,10 @@ class LatestTransactions(LatestCacheBase): transactionType = Column('transactionType', String) parsedFloData = Column('parsedFloData', String) + class LatestBlocks(LatestCacheBase): __tablename__ = "latestBlocks" id = Column('id', Integer, primary_key=True) blockNumber = Column('blockNumber', String) blockHash = Column('blockHash', String) jsonData = Column('jsonData', String) - - diff --git a/parsing.py b/parsing.py index de65e03..5f13b63 100644 --- a/parsing.py +++ b/parsing.py @@ -1,6 +1,7 @@ -import re -import arrow import configparser +import re + +import arrow config = configparser.ConfigParser() config.read('config.ini') @@ -10,22 +11,22 @@ operation = None address = None amount = None -months = { 'jan' : 1, -'feb' : 2, -'mar' : 3, -'apr' : 4, -'may' : 5, -'jun' : 6, -'jul' : 7, -'aug' : 8, -'sep' : 9, -'oct' : 10, -'nov' : 11, -'dec' : 12 } +months = {'jan': 1, + 'feb': 2, + 'mar': 3, + 'apr': 4, + 'may': 5, + 'jun': 6, + 'jul': 7, + 'aug': 8, + 'sep': 9, + 'oct': 10, + 'nov': 11, + 'dec': 12} 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: @@ -34,7 +35,7 @@ def isTransfer(text): def isIncorp(text): - wordlist = ['incorporate','create','start'] # keep everything lowercase + wordlist = ['incorporate', 'create', 'start'] # keep everything lowercase textList = text.split(' ') for word in wordlist: if word in textList: @@ -62,7 +63,7 @@ def isSmartContractPay(text): smartContractName = smartContractName[:-1] if smartContractTrigger and smartContractName: - contractconditions = { 'smartContractTrigger':smartContractTrigger, 'smartContractName':smartContractName } + contractconditions = {'smartContractTrigger': smartContractTrigger, 'smartContractName': smartContractName} return contractconditions else: return False @@ -98,11 +99,11 @@ def extractMarker(text): def extractInitTokens(text): - base_units = {'thousand':10**3 , 'million':10**6 ,'billion':10**9, 'trillion':10**12} + base_units = {'thousand': 10 ** 3, 'million': 10 ** 6, 'billion': 10 ** 9, 'trillion': 10 ** 12} textList = text.split(' ') counter = 0 value = None - for idx,word in enumerate(textList): + for idx, word in enumerate(textList): try: result = float(word) if textList[idx + 1] in base_units: @@ -114,9 +115,9 @@ def extractInitTokens(text): except: for unit in base_units: result = word.split(unit) - if len(result) == 2 and result[1]=='' and result[0]!='': + if len(result) == 2 and result[1] == '' and result[0] != '': try: - value = float(result[0])*base_units[unit] + value = float(result[0]) * base_units[unit] counter = counter + 1 except: continue @@ -138,7 +139,7 @@ def extractAddress(text): def extractContractType(text): - operationList = ['one-time-event*'] # keep everything lowercase + operationList = ['one-time-event*'] # keep everything lowercase count = 0 returnval = None for operation in operationList: @@ -152,7 +153,7 @@ def extractContractType(text): def extractUserchoice(text): result = re.split('userchoice:\s*', text) - if len(result) != 1 and result[1]!='': + if len(result) != 1 and result[1] != '': return result[1].strip().strip('"').strip("'") else: return None @@ -164,7 +165,7 @@ def brackets_toNumber(item): def extractContractConditions(text, contracttype, marker, blocktime): rulestext = re.split('contract-conditions:\s*', text)[-1] - #rulelist = re.split('\d\.\s*', rulestext) + # rulelist = re.split('\d\.\s*', rulestext) rulelist = [] numberList = re.findall(r'\(\d\d*\)', rulestext) @@ -180,7 +181,7 @@ def extractContractConditions(text, contracttype, marker, blocktime): break for i in range(len(numberList)): - rule = rulestext.split('({})'.format(i+1))[1].split('({})'.format(i+2))[0] + rule = rulestext.split('({})'.format(i + 1))[1].split('({})'.format(i + 2))[0] rulelist.append(rule.strip()) if contracttype == 'one-time-event*': @@ -194,11 +195,13 @@ def extractContractConditions(text, contracttype, marker, blocktime): try: expirytime_split = expirytime.split(' ') - parse_string = '{}/{}/{} {}'.format(expirytime_split[3], months[expirytime_split[1]], expirytime_split[2], expirytime_split[4]) + parse_string = '{}/{}/{} {}'.format(expirytime_split[3], months[expirytime_split[1]], + expirytime_split[2], expirytime_split[4]) expirytime_object = arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace(tzinfo=expirytime_split[5]) blocktime_object = arrow.get(blocktime) if expirytime_object < blocktime_object: - print('Expirytime of the contract is earlier than the block it is incorporated in. This incorporation will be rejected ') + print( + 'Expirytime of the contract is earlier than the block it is incorporated in. This incorporation will be rejected ') return None extractedRules['expiryTime'] = expirytime except: @@ -206,7 +209,7 @@ def extractContractConditions(text, contracttype, marker, blocktime): return None for rule in rulelist: - if rule=='': + if rule == '': continue elif rule[:14] == 'contractamount': pattern = re.compile('[^contractamount\s*=\s*].*') @@ -245,8 +248,7 @@ def extractContractConditions(text, contracttype, marker, blocktime): payeeAddress = searchResult.split(marker)[0] extractedRules['payeeAddress'] = payeeAddress - - if len(extractedRules)>1 and 'expiryTime' in extractedRules: + if len(extractedRules) > 1 and 'expiryTime' in extractedRules: return extractedRules else: return None @@ -263,7 +265,6 @@ def extractTriggerCondition(text): # Combine test def parse_flodata(string, blockinfo, netvariable): - # todo Rule 20 - remove 'text:' from the start of flodata if it exists if string[0:5] == 'text:': string = string.split('text:')[1] @@ -287,12 +288,12 @@ def parse_flodata(string, blockinfo, netvariable): # todo Rule 25 - If number of # or number of @ is greater than 1, reject # todo Rule 25.a - If a transaction is rejected, it means parsed_data type is noise # 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: + if (len(atList) == 0 and len(hashList) == 0) or len(atList) > 1 or len(hashList) > 1: parsed_data = {'type': 'noise'} # todo Rule 26 - if number of # is 1 and number of @ is 0, then check if its token creation or token transfer transaction - elif len(hashList)==1 and len(atList)==0: + elif len(hashList) == 1 and len(atList) == 0: # Passing the above check means token creation or transfer incorporation = isIncorp(cleanstring) transfer = isTransfer(cleanstring) @@ -307,7 +308,7 @@ def parse_flodata(string, blockinfo, netvariable): initTokens = extractInitTokens(cleanstring) if initTokens is not None: parsed_data = {'type': 'tokenIncorporation', 'flodata': string, 'tokenIdentification': hashList[0][:-1], - 'tokenAmount': initTokens} + 'tokenAmount': initTokens} else: parsed_data = {'type': 'noise'} @@ -317,8 +318,8 @@ def parse_flodata(string, blockinfo, netvariable): amount = extractAmount(cleanstring, hashList[0][:-1]) if None not in [amount]: parsed_data = {'type': 'transfer', 'transferType': 'token', 'flodata': string, - 'tokenIdentification': hashList[0][:-1], - 'tokenAmount': amount} + 'tokenIdentification': hashList[0][:-1], + 'tokenAmount': amount} else: parsed_data = {'type': 'noise'} @@ -336,14 +337,15 @@ def parse_flodata(string, blockinfo, netvariable): elif incorporation and not transfer: contracttype = extractContractType(cleanstring) contractaddress = extractAddress(nospacestring) - contractconditions = extractContractConditions(cleanstring, contracttype, marker=hashList[0][:-1], blocktime=blockinfo['time']) + contractconditions = extractContractConditions(cleanstring, contracttype, marker=hashList[0][:-1], + blocktime=blockinfo['time']) if config['DEFAULT']['NET'] == 'mainnet' and blockinfo['height'] < 3454510: if None not in [contracttype, contractconditions]: parsed_data = {'type': 'smartContractIncorporation', 'contractType': contracttype[:-1], - 'tokenIdentification': hashList[0][:-1], 'contractName': atList[0][:-1], - 'contractAddress': contractaddress[:-1], 'flodata': string, - 'contractConditions': contractconditions} + 'tokenIdentification': hashList[0][:-1], 'contractName': atList[0][:-1], + 'contractAddress': contractaddress[:-1], 'flodata': string, + 'contractConditions': contractconditions} else: parsed_data = {'type': 'noise'} else: @@ -363,9 +365,9 @@ def parse_flodata(string, blockinfo, netvariable): contractaddress = extractAddress(nospacestring) if None not in [amount, userChoice]: parsed_data = {'type': 'transfer', 'transferType': 'smartContract', 'flodata': string, - 'tokenIdentification': hashList[0][:-1], - 'operation': 'transfer', 'tokenAmount': amount, 'contractName': atList[0][:-1], - 'userChoice': userChoice} + 'tokenIdentification': hashList[0][:-1], + 'operation': 'transfer', 'tokenAmount': amount, 'contractName': atList[0][:-1], + 'userChoice': userChoice} if contractaddress: parsed_data['contractAddress'] = contractaddress[:-1] else: @@ -373,12 +375,13 @@ def parse_flodata(string, blockinfo, netvariable): # todo Rule 36 - Check for only a single @ and the substring "smart contract system says" in flodata, else reject - elif (len(hashList)==0 and len(atList)==1): + elif (len(hashList) == 0 and len(atList) == 1): # Passing the above check means Smart Contract pays | exitcondition triggered from the committee # todo Rule 37 - Extract the trigger condition given by the committee. If its missing, reject triggerCondition = extractTriggerCondition(cleanstring) if triggerCondition is not None: - parsed_data = {'type': 'smartContractPays', 'contractName': atList[0][:-1], 'triggerCondition': triggerCondition.group().strip()[1:-1]} + parsed_data = {'type': 'smartContractPays', 'contractName': atList[0][:-1], + 'triggerCondition': triggerCondition.group().strip()[1:-1]} else: parsed_data = {'type': 'noise'} else: diff --git a/tracktokens-smartcontracts.py b/tracktokens-smartcontracts.py index 6b4ec02..2261799 100755 --- a/tracktokens-smartcontracts.py +++ b/tracktokens-smartcontracts.py @@ -1,23 +1,24 @@ -import requests -import json -import sqlite3 import argparse import configparser -import subprocess -import sys -import parsing -import time -import os -import shutil -from sqlalchemy.orm import sessionmaker, relationship -from sqlalchemy import create_engine, func, desc -from models import SystemData, ActiveTable, ConsumedTable, TransferLogs, TransactionHistory, RejectedTransactionHistory, Base, ContractStructure, ContractBase, ContractParticipants, SystemBase, ActiveContracts, ContractAddressMapping, LatestTransactions, LatestCacheBase, LatestBlocks, ContractTransactionHistory, RejectedContractTransactionHistory, TokenContractAssociation -from config import * -import pybtc -import socketio - +import json # Setup logging import logging +import os +import shutil +import sqlite3 +import sys +import pybtc +import requests +import socketio +from sqlalchemy import create_engine, func +from sqlalchemy.orm import sessionmaker + +import parsing +from config import * +from models import SystemData, ActiveTable, ConsumedTable, TransferLogs, TransactionHistory, RejectedTransactionHistory, \ + Base, ContractStructure, ContractBase, ContractParticipants, SystemBase, ActiveContracts, ContractAddressMapping, \ + LatestCacheBase, ContractTransactionHistory, RejectedContractTransactionHistory, TokenContractAssociation + logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -35,7 +36,7 @@ logger.addHandler(stream_handler) def retryRequest(tempserverlist, apicall): - if len(tempserverlist)!=0: + if len(tempserverlist) != 0: try: response = requests.get('{}api/{}'.format(tempserverlist[0], apicall)) except: @@ -53,7 +54,7 @@ def retryRequest(tempserverlist, apicall): def multiRequest(apicall, net): - testserverlist = ['http://0.0.0.0:9000/','https://testnet.flocha.in/', 'https://testnet-flosight.duckdns.org/'] + testserverlist = ['http://0.0.0.0:9000/', 'https://testnet.flocha.in/', 'https://testnet-flosight.duckdns.org/'] mainserverlist = ['http://0.0.0.0:9001/', 'https://livenet.flocha.in/', 'https://testnet-flosight.duckdns.org/'] if net == 'mainnet': return retryRequest(mainserverlist, apicall) @@ -120,7 +121,6 @@ def processBlock(blockindex): def processApiBlock(blockhash): - blockinfo = multiRequest('block/{}'.format(str(blockhash)), config['DEFAULT']['NET']) # todo Rule 8 - read every transaction from every block to find and parse flodata @@ -155,7 +155,10 @@ def processApiBlock(blockhash): def updateLatestTransaction(transactionData, parsed_data): # connect to latest transaction db conn = sqlite3.connect('latestCache.db') - conn.execute("INSERT INTO latestTransactions(transactionHash, blockNumber, jsonData, transactionType, parsedFloData) VALUES (?,?,?,?,?)", (transactionData['txid'], transactionData['blockheight'], json.dumps(transactionData), parsed_data['type'], json.dumps(parsed_data))) + conn.execute( + "INSERT INTO latestTransactions(transactionHash, blockNumber, jsonData, transactionType, parsedFloData) VALUES (?,?,?,?,?)", + (transactionData['txid'], transactionData['blockheight'], json.dumps(transactionData), parsed_data['type'], + json.dumps(parsed_data))) conn.commit() conn.close() @@ -163,12 +166,13 @@ def updateLatestTransaction(transactionData, parsed_data): def updateLatestBlock(blockData): # connect to latest block db conn = sqlite3.connect('latestCache.db') - conn.execute('INSERT INTO latestBlocks(blockNumber, blockHash, jsonData) VALUES (?,?,?)',(blockData['height'], blockData['hash'], json.dumps(blockData))) + conn.execute('INSERT INTO latestBlocks(blockNumber, blockHash, jsonData) VALUES (?,?,?)', + (blockData['height'], blockData['hash'], json.dumps(blockData))) conn.commit() conn.close() -def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress, transaction_data=None): +def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress, transaction_data=None, parsed_data=None): engine = create_engine('sqlite:///tokens/{}.db'.format(tokenIdentification), echo=True) Base.metadata.create_all(bind=engine) session = sessionmaker(bind=engine)() @@ -180,12 +184,13 @@ def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress, return 0 elif availableTokens < commentTransferAmount: - logger.info("The transfer amount passed in the comments is more than the user owns\nThis transaction will be discarded\n") + logger.info( + "The transfer amount passed in the comments is more than the user owns\nThis transaction will be discarded\n") session.close() return 0 elif availableTokens >= commentTransferAmount: - table = session.query(ActiveTable).filter(ActiveTable.address==inputAddress).all() + table = session.query(ActiveTable).filter(ActiveTable.address == inputAddress).all() block_data = multiRequest('block/{}'.format(transaction_data['blockhash']), config['DEFAULT']['NET']) pidlst = [] @@ -205,12 +210,13 @@ def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress, entry = session.query(ActiveTable).filter(ActiveTable.id == piditem[0]).all() consumedpid_string = consumedpid_string + '{},'.format(piditem[0]) session.add(TransferLogs(sourceFloAddress=inputAddress, destFloAddress=outputAddress, - transferAmount=entry[0].transferBalance, sourceId=piditem[0], destinationId=lastid+1, + transferAmount=entry[0].transferBalance, sourceId=piditem[0], + destinationId=lastid + 1, blockNumber=block_data['height'], time=block_data['time'], transactionHash=transaction_data['txid'])) entry[0].transferBalance = 0 - if len(consumedpid_string)>1: + if len(consumedpid_string) > 1: consumedpid_string = consumedpid_string[:-1] # Make new entry @@ -255,18 +261,18 @@ def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress, consumedpid_string = consumedpid_string + '{},'.format(piditem[0]) else: session.add(TransferLogs(sourceFloAddress=inputAddress, destFloAddress=outputAddress, - transferAmount=piditem[1]-(checksum - commentTransferAmount), sourceId=piditem[0], + transferAmount=piditem[1] - (checksum - commentTransferAmount), + sourceId=piditem[0], destinationId=lastid + 1, blockNumber=block_data['height'], time=block_data['time'], transactionHash=transaction_data['txid'])) entry[0].transferBalance = checksum - commentTransferAmount - if len(consumedpid_string) > 1: consumedpid_string = consumedpid_string[:-1] # Make new entry - session.add(ActiveTable(address=outputAddress, parentid= pidlst[-1][0], consumedpid=consumedpid_string, + session.add(ActiveTable(address=outputAddress, parentid=pidlst[-1][0], consumedpid=consumedpid_string, transferBalance=commentTransferAmount)) # Migration @@ -291,13 +297,16 @@ def transferToken(tokenIdentification, tokenAmount, inputAddress, outputAddress, session.commit() session.commit() - block_data = multiRequest('block/{}'.format(transaction_data['blockhash']), config['DEFAULT']['NET']) blockchainReference = neturl + 'tx/' + transaction_data['txid'] session.add(TransactionHistory(sourceFloAddress=inputAddress, destFloAddress=outputAddress, - transferAmount=tokenAmount, blockNumber=block_data['height'], blockHash=block_data['hash'], time=block_data['time'], - transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data))) + transferAmount=tokenAmount, blockNumber=block_data['height'], + blockHash=block_data['hash'], time=block_data['time'], + transactionHash=transaction_data['txid'], + blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), + transactionType=parsed_data['type'], + parsedFloData=json.dumps(parsed_data))) session.commit() session.close() return 1 @@ -307,13 +316,14 @@ def checkLocaltriggerContracts(blockinfo): engine = create_engine('sqlite:///system.db', echo=False) connection = engine.connect() # todo : filter activeContracts which only have local triggers - activeContracts = connection.execute('select contractName, contractAddress from activecontracts where status=="active" ').fetchall() + activeContracts = connection.execute( + 'select contractName, contractAddress from activecontracts where status=="active" ').fetchall() connection.close() for contract in activeContracts: # pull out the contract structure into a dictionary - engine = create_engine('sqlite:///smartContracts/{}-{}.db'.format(contract[0],contract[1]), echo=True) + engine = create_engine('sqlite:///smartContracts/{}-{}.db'.format(contract[0], contract[1]), echo=True) connection = engine.connect() # todo : filter activeContracts which only have local triggers attributevaluepair = connection.execute( @@ -337,24 +347,33 @@ def checkLocaltriggerContracts(blockinfo): # This is a committee trigger contract expiryTime = contractStructure['expiryTime'] expirytime_split = expiryTime.split(' ') - parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]], expirytime_split[2], expirytime_split[4]) - expirytime_object = parsing.arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace(tzinfo=expirytime_split[5][3:]) + parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]], + expirytime_split[2], expirytime_split[4]) + expirytime_object = parsing.arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace( + tzinfo=expirytime_split[5][3:]) blocktime_object = parsing.arrow.get(blockinfo['time']).to('Asia/Kolkata') if blocktime_object > expirytime_object: if 'minimumsubscriptionamount' in contractStructure: minimumsubscriptionamount = contractStructure['minimumsubscriptionamount'] - tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] + tokenAmount_sum = \ + connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] if tokenAmount_sum < minimumsubscriptionamount: # Initialize payback to contract participants - contractParticipants = connection.execute('select participantAddress, tokenAmount, transactionHash from contractparticipants').fetchall()[0][0] + contractParticipants = connection.execute( + 'select participantAddress, tokenAmount, transactionHash from contractparticipants').fetchall()[ + 0][0] for participant in contractParticipants: tokenIdentification = contractStructure['tokenIdentification'] - contractAddress = connection.execute('select * from contractstructure where attribute="contractAddress"').fetchall()[0][0] - returnval = transferToken(tokenIdentification, participant[1], contractAddress, participant[0]) + contractAddress = connection.execute( + 'select * from contractstructure where attribute="contractAddress"').fetchall()[0][ + 0] + returnval = transferToken(tokenIdentification, participant[1], contractAddress, + participant[0]) if returnval is None: - logger.critical("Something went wrong in the token transfer method while doing local Smart Contract Trigger. THIS IS CRITICAL ERROR") + logger.critical( + "Something went wrong in the token transfer method while doing local Smart Contract Trigger. THIS IS CRITICAL ERROR") return connection.execute( 'update contractparticipants set winningAmount="{}" where participantAddress="{}" and transactionHash="{}"'.format( @@ -379,9 +398,11 @@ def checkLocaltriggerContracts(blockinfo): engine = create_engine('sqlite:///system.db', echo=True) connection = engine.connect() connection.execute( - 'update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format(contract[0], contract[1])) + 'update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format( + contract[0], contract[1])) connection.execute( - 'update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format(blockinfo['time'], + 'update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format( + blockinfo['time'], contract[0], contract[1])) connection.close() @@ -391,15 +412,19 @@ def checkLocaltriggerContracts(blockinfo): 'update activecontracts set status="expired" where contractName="{}" and contractAddress="{}"'.format( contract[0], contract[1])) connection.execute( - 'update activecontracts set expirydate="{}" where contractName="{}" and contractAddress="{}"'.format(blockinfo['time'], + 'update activecontracts set expirydate="{}" where contractName="{}" and contractAddress="{}"'.format( + blockinfo['time'], contract[0], contract[1])) connection.close() elif 'payeeAddress' in contractStructure: # This is a local trigger contract if 'maximumsubscriptionamount' in contractStructure: - maximumsubscriptionamount = connection.execute('select value from contractstructure where attribute=="maximumsubscriptionamount"').fetchall()[0][0] - tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] + maximumsubscriptionamount = connection.execute( + 'select value from contractstructure where attribute=="maximumsubscriptionamount"').fetchall()[ + 0][0] + tokenAmount_sum = \ + connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] if tokenAmount_sum >= maximumsubscriptionamount: # Trigger the contract payeeAddress = contractStructure['payeeAddress'] @@ -407,7 +432,8 @@ def checkLocaltriggerContracts(blockinfo): contractAddress = contractStructure['contractAddress'] returnval = transferToken(tokenIdentification, tokenAmount_sum, contractAddress, payeeAddress) if returnval is None: - logger.critical("Something went wrong in the token transfer method while doing local Smart Contract Trigger") + logger.critical( + "Something went wrong in the token transfer method while doing local Smart Contract Trigger") return connection.execute( 'update contractparticipants set winningAmount="{}"'.format( @@ -434,7 +460,8 @@ def checkLocaltriggerContracts(blockinfo): engine = create_engine('sqlite:///system.db', echo=False) connection = engine.connect() connection.execute( - 'update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format(contract[0], contract[1])) + 'update activecontracts set status="closed" where contractName="{}" and contractAddress="{}"'.format( + contract[0], contract[1])) connection.execute( 'update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format( blockinfo['time'], contract[0], contract[1])) @@ -446,7 +473,8 @@ def checkLocaltriggerContracts(blockinfo): expiryTime = contractStructure['expiryTime'] expirytime_split = expiryTime.split(' ') - parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]], expirytime_split[2], expirytime_split[4]) + parse_string = '{}/{}/{} {}'.format(expirytime_split[3], parsing.months[expirytime_split[1]], + expirytime_split[2], expirytime_split[4]) expirytime_object = parsing.arrow.get(parse_string, 'YYYY/M/D HH:mm:ss').replace( tzinfo=expirytime_split[5][3:]) blocktime_object = parsing.arrow.get(blockinfo['time']).to('Asia/Kolkata') @@ -454,25 +482,31 @@ def checkLocaltriggerContracts(blockinfo): if blocktime_object > expirytime_object: if 'minimumsubscriptionamount' in contractStructure: minimumsubscriptionamount = contractStructure['minimumsubscriptionamount'] - tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] + tokenAmount_sum = \ + connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] if tokenAmount_sum < minimumsubscriptionamount: # Initialize payback to contract participants contractParticipants = connection.execute( - 'select participantAddress, tokenAmount, transactionHash from contractparticipants').fetchall()[0][0] + 'select participantAddress, tokenAmount, transactionHash from contractparticipants').fetchall()[ + 0][0] for participant in contractParticipants: tokenIdentification = connection.execute( - 'select * from contractstructure where attribute="tokenIdentification"').fetchall()[0][ + 'select * from contractstructure where attribute="tokenIdentification"').fetchall()[ + 0][ 0] contractAddress = connection.execute( - 'select * from contractstructure where attribute="contractAddress"').fetchall()[0][0] + 'select * from contractstructure where attribute="contractAddress"').fetchall()[0][ + 0] returnval = transferToken(tokenIdentification, participant[1], contractAddress, participant[0]) if returnval is None: logger.critical( "Something went wrong in the token transfer method while doing local Smart Contract Trigger") return - connection.execute('update contractparticipants set winningAmount="{}" where participantAddress="{}" and transactionHash="{}"'.format((participant[1], participant[0], participant[2]))) + connection.execute( + 'update contractparticipants set winningAmount="{}" where participantAddress="{}" and transactionHash="{}"'.format( + (participant[1], participant[0], participant[2]))) # add transaction to ContractTransactionHistory engine = create_engine( @@ -497,7 +531,7 @@ def checkLocaltriggerContracts(blockinfo): contract[0], contract[1])) connection.execute( 'update activecontracts set closeDate="{}" where contractName="{}" and contractAddress="{}"'.format( - blockinfo['time'],contract[0], contract[1])) + blockinfo['time'], contract[0], contract[1])) connection.execute( 'update activecontracts set expiryDate="{}" where contractName="{}" and contractAddress="{}"'.format( blockinfo['time'], contract[0], contract[1])) @@ -511,10 +545,12 @@ def checkLocaltriggerContracts(blockinfo): engine = create_engine('sqlite:///smartContracts/{}-{}.db'.format(contract[0], contract[1]), echo=True) connection = engine.connect() - tokenAmount_sum = connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] + tokenAmount_sum = \ + connection.execute('select sum(tokenAmount) from contractparticipants').fetchall()[0][0] returnval = transferToken(tokenIdentification, tokenAmount_sum, contractAddress, payeeAddress) if returnval is None: - logger.critical("Something went wrong in the token transfer method while doing local Smart Contract Trigger") + logger.critical( + "Something went wrong in the token transfer method while doing local Smart Contract Trigger") return connection.execute('update contractparticipants set winningAmount="{}"'.format(0)) @@ -552,7 +588,6 @@ def checkLocaltriggerContracts(blockinfo): def processTransaction(transaction_data, parsed_data): - # Do the necessary checks for the inputs and outputs # todo Rule 38 - Here we are doing FLO processing. We attach asset amounts to a FLO address, so every FLO address # will have multiple feed ins of the asset. Each of those feedins will be an input to the address. @@ -590,15 +625,16 @@ def processTransaction(transaction_data, parsed_data): temp = item[0] continue if item[0] != temp: - logger.info(f"System has found more than one address as part of vin. Transaction {transaction_data['txid']} is rejected") + logger.info( + f"System has found more than one address as part of vin. Transaction {transaction_data['txid']} is rejected") return 0 inputlist = [vinlist[0][0], totalinputval] - # todo Rule 42 - If the number of vout is more than 2, reject the transaction if len(transaction_data["vout"]) > 2: - logger.info(f"System has found more than 2 address as part of vout. Transaction {transaction_data['txid']} is rejected") + logger.info( + f"System has found more than 2 address as part of vout. Transaction {transaction_data['txid']} is rejected") return 0 # todo Rule 43 - A transaction accepted by the system has two vouts, 1. The FLO address of the receiver @@ -638,19 +674,24 @@ def processTransaction(transaction_data, parsed_data): # Check if the transaction hash already exists in the token db engine = create_engine(f"sqlite:///tokens/{parsed_data['tokenIdentification']}.db", echo=True) connection = engine.connect() - blockno_txhash = connection.execute('select blockNumber, transactionHash from transactionHistory').fetchall() + blockno_txhash = connection.execute( + 'select blockNumber, transactionHash from transactionHistory').fetchall() connection.close() blockno_txhash_T = list(zip(*blockno_txhash)) if transaction_data['txid'] in list(blockno_txhash_T[1]): - logger.warning(f"Transaction {transaction_data['txid']} already exists in the token db. This is unusual, please check your code") - pushData_SSEapi(f"Error | Transaction {transaction_data['txid']} already exists in the token db. This is unusual, please check your code") + logger.warning( + f"Transaction {transaction_data['txid']} already exists in the token db. This is unusual, please check your code") + pushData_SSEapi( + f"Error | Transaction {transaction_data['txid']} already exists in the token db. This is unusual, please check your code") return 0 - returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['tokenAmount'], inputlist[0], outputlist[0], transaction_data) + returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['tokenAmount'], inputlist[0], + outputlist[0], transaction_data, parsed_data) if returnval is None: logger.info("Something went wrong in the token transfer method") - pushData_SSEapi(f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}") + pushData_SSEapi( + f"Error | Something went wrong while doing the internal db transactions for {transaction_data['txid']}") return 0 else: updateLatestTransaction(transaction_data, parsed_data) @@ -658,18 +699,19 @@ def processTransaction(transaction_data, parsed_data): # If this is the first interaction of the outputlist's address with the given token name, add it to token mapping engine = create_engine('sqlite:///system.db', echo=True) connection = engine.connect() - firstInteractionCheck = connection.execute(f"select * from tokenAddressMapping where tokenAddress='{outputlist[0]}' and token='{parsed_data['tokenIdentification']}'").fetchall() + firstInteractionCheck = connection.execute( + f"select * from tokenAddressMapping where tokenAddress='{outputlist[0]}' and token='{parsed_data['tokenIdentification']}'").fetchall() if len(firstInteractionCheck) == 0: - connection.execute(f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{outputlist[0]}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}')") + connection.execute( + f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{outputlist[0]}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}')") connection.close() - # Pass information to SSE channel url = 'https://ranchimallflo.duckdns.org/' headers = {'Accept': 'application/json', 'Content-Type': 'application/json'} - #r = requests.post(url, json={f"message': 'Token Transfer | name:{parsed_data['tokenIdentification']} | transactionHash:{transaction_data['txid']}"}, headers=headers) + # r = requests.post(url, json={f"message': 'Token Transfer | name:{parsed_data['tokenIdentification']} | transactionHash:{transaction_data['txid']}"}, headers=headers) return 1 else: logger.info( @@ -678,7 +720,8 @@ def processTransaction(transaction_data, parsed_data): SystemBase.metadata.create_all(bind=engine) session = sessionmaker(bind=engine)() blockchainReference = neturl + 'tx/' + transaction_data['txid'] - session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'], sourceFloAddress=inputadd, destFloAddress=outputlist[0], + session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'], + sourceFloAddress=inputadd, destFloAddress=outputlist[0], transferAmount=parsed_data['tokenAmount'], blockNumber=transaction_data['blockheight'], blockHash=transaction_data['blockhash'], @@ -686,7 +729,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Token transfer at transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} doesnt not exist")) + rejectComment=f"Token transfer at transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} doesnt not exist", + transactionType=parsed_data['type'], + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -709,7 +755,7 @@ def processTransaction(transaction_data, parsed_data): logger.warning( f"Transaction {transaction_data['txid']} rejected as it already exists in the Smart Contract db. This is unusual, please check your code") pushData_SSEapi( - f"Error | Transaction {transaction_data['txid']} rejected as it already exists in the Smart Contract db. This is unusual, please check your code" ) + f"Error | Transaction {transaction_data['txid']} rejected as it already exists in the Smart Contract db. This is unusual, please check your code") return 0 # if contractAddress was passed, then check if it matches the output address of this contract @@ -737,7 +783,9 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}")) + rejectComment=f"Contract participation at transaction {transaction_data['txid']} rejected as contractAddress specified in flodata, {parsed_data['contractAddress']}, doesnt not match with transaction's output address {outputlist[0]}", + + parsedFloData=json.dumps(parsed_data))) session.commit() session.close() @@ -748,19 +796,23 @@ def processTransaction(transaction_data, parsed_data): headers=headers)''' # Pass information to SSE channel - pushData_SSEapi('Error| Mismatch in contract address specified in flodata and the output address of the transaction {}'.format(transaction_data['txid'])) + pushData_SSEapi( + 'Error| Mismatch in contract address specified in flodata and the output address of the transaction {}'.format( + transaction_data['txid'])) return 0 # check the status of the contract engine = create_engine('sqlite:///system.db', echo=True) connection = engine.connect() contractStatus = connection.execute( - f"select status from activecontracts where contractName=='{parsed_data['contractName']}' and contractAddress='{outputlist[0]}'").fetchall()[0][0] + f"select status from activecontracts where contractName=='{parsed_data['contractName']}' and contractAddress='{outputlist[0]}'").fetchall()[ + 0][0] connection.close() contractList = [] if contractStatus == 'closed': - logger.info(f"Transaction {transaction_data['txid']} closed as Smart contract {parsed_data['contractName']} at the {outputlist[0]} is closed") + logger.info( + f"Transaction {transaction_data['txid']} closed as Smart contract {parsed_data['contractName']} at the {outputlist[0]} is closed") # Store transfer as part of RejectedContractTransactionHistory engine = create_engine( f"sqlite:///system.db", @@ -781,7 +833,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} closed as Smart contract {parsed_data['contractName']} at the {outputlist[0]} is closed")) + rejectComment=f"Transaction {transaction_data['txid']} closed as Smart contract {parsed_data['contractName']} at the {outputlist[0]} is closed", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -832,7 +887,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has expired and will not accept any user participation")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has expired and will not accept any user participation", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -840,9 +898,11 @@ def processTransaction(transaction_data, parsed_data): return 0 # pull out the contract structure into a dictionary - engine = create_engine('sqlite:///smartContracts/{}-{}.db'.format(parsed_data['contractName'], outputlist[0]), echo=True) + engine = create_engine( + 'sqlite:///smartContracts/{}-{}.db'.format(parsed_data['contractName'], outputlist[0]), echo=True) connection = engine.connect() - attributevaluepair = connection.execute("select attribute, value from contractstructure where attribute != 'contractName' and attribute != 'flodata' and attribute != 'contractAddress'").fetchall() + attributevaluepair = connection.execute( + "select attribute, value from contractstructure where attribute != 'contractName' and attribute != 'flodata' and attribute != 'contractAddress'").fetchall() contractStructure = {} conditionDict = {} counter = 0 @@ -880,7 +940,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as userChoice, {parsed_data['userChoice']}, has been passed to Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} which doesn't accept any userChoice")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as userChoice, {parsed_data['userChoice']}, has been passed to Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} which doesn't accept any userChoice", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -911,7 +974,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as the token being transferred, {parsed_data['tokenIdentidication'].upper()}, is not part of the structure of Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as the token being transferred, {parsed_data['tokenIdentidication'].upper()}, is not part of the structure of Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -946,7 +1012,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as contractAmount being transferred is not part of the structure of Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as contractAmount being transferred is not part of the structure of Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -970,7 +1039,8 @@ def processTransaction(transaction_data, parsed_data): amountDeposited = 0 if amountDeposited >= maximumsubscriptionamount: - logger.info(f"Transaction {transaction_data['txid']} rejected as maximum subscription amount has been reached for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}") + logger.info( + f"Transaction {transaction_data['txid']} rejected as maximum subscription amount has been reached for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}") # Store transfer as part of RejectedContractTransactionHistory engine = create_engine( f"sqlite:///system.db", @@ -991,13 +1061,17 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as maximum subscription amount has been reached for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as maximum subscription amount has been reached for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( f"Error | Transaction {transaction_data['txid']} rejected as maximum subscription amount has been reached for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}") return 0 - elif ((float(amountDeposited) + float(parsed_data['tokenAmount'])) > maximumsubscriptionamount) and 'contractAmount' in contractStructure: + elif ((float(amountDeposited) + float(parsed_data[ + 'tokenAmount'])) > maximumsubscriptionamount) and 'contractAmount' in contractStructure: logger.info( f"Transaction {transaction_data['txid']} rejected as the contractAmount surpasses the maximum subscription amount, {contractStructure['maximumsubscriptionamount']} {contractStructure['tokenIdentification'].upper()}, for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}") # Store transfer as part of RejectedContractTransactionHistory @@ -1020,7 +1094,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as the contractAmount surpasses the maximum subscription amount, {contractStructure['maximumsubscriptionamount']} {contractStructure['tokenIdentification'].upper()}, for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as the contractAmount surpasses the maximum subscription amount, {contractStructure['maximumsubscriptionamount']} {contractStructure['tokenIdentification'].upper()}, for the Smart contract named {parsed_data['contractName']} at the address {outputlist[0]}", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -1029,8 +1106,6 @@ def processTransaction(transaction_data, parsed_data): else: partialTransferCounter = 1 - - # Check if exitcondition exists as part of contractstructure and is given in right format if 'exitconditions' in contractStructure: # This means the contract has an external trigger, ie. trigger coming from the contract committee @@ -1043,7 +1118,7 @@ def processTransaction(transaction_data, parsed_data): # Check if the tokenAmount being transferred exists in the address & do the token transfer returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['tokenAmount'], inputlist[0], outputlist[0], - transaction_data) + transaction_data, parsed_data) if returnval is not None: # Store participant details in the smart contract's db session.add(ContractParticipants(participantAddress=inputadd, @@ -1065,7 +1140,10 @@ def processTransaction(transaction_data, parsed_data): time=transaction_data['blocktime'], transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data))) + jsonData=json.dumps(transaction_data), + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1105,7 +1183,7 @@ def processTransaction(transaction_data, parsed_data): # Transfer only part of the tokens users specified, till the time it reaches maximumamount returnval = transferToken(parsed_data['tokenIdentification'], maximumsubscriptionamount - amountDeposited, - inputlist[0], outputlist[0], transaction_data) + inputlist[0], outputlist[0], transaction_data, parsed_data) if returnval is not None: # Store participant details in the smart contract's db session.add(ContractParticipants(participantAddress=inputadd, @@ -1138,7 +1216,8 @@ def processTransaction(transaction_data, parsed_data): return 0 else: - logger.info(f"Transaction {transaction_data['txid']} rejected as wrong userchoice entered for the Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}") + logger.info( + f"Transaction {transaction_data['txid']} rejected as wrong userchoice entered for the Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}") # Store transfer as part of RejectedContractTransactionHistory engine = create_engine( f"sqlite:///system.db", @@ -1159,10 +1238,14 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as wrong userchoice entered for the Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as wrong userchoice entered for the Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() - pushData_SSEapi(f"Error| Transaction {transaction_data['txid']} rejected as wrong userchoice entered for the Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}") + pushData_SSEapi( + f"Error| Transaction {transaction_data['txid']} rejected as wrong userchoice entered for the Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]}") return 0 elif 'payeeAddress' in contractStructure: @@ -1171,7 +1254,7 @@ def processTransaction(transaction_data, parsed_data): # Check if the tokenAmount being transferred exists in the address & do the token transfer returnval = transferToken(parsed_data['tokenIdentification'], parsed_data['tokenAmount'], inputlist[0], outputlist[0], - transaction_data) + transaction_data, parsed_data) if returnval is not None: # Store participant details in the smart contract's db session.add(ContractParticipants(participantAddress=inputadd, @@ -1193,7 +1276,10 @@ def processTransaction(transaction_data, parsed_data): time=transaction_data['blocktime'], transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data))) + jsonData=json.dumps(transaction_data), + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1221,7 +1307,7 @@ def processTransaction(transaction_data, parsed_data): # Transfer only part of the tokens users specified, till the time it reaches maximumamount returnval = transferToken(parsed_data['tokenIdentification'], maximumsubscriptionamount - amountDeposited, - inputlist[0], outputlist[0], transaction_data) + inputlist[0], outputlist[0], transaction_data, parsed_data) if returnval is not None: # Store participant details in the smart contract's db session.add(ContractParticipants(participantAddress=inputadd, @@ -1276,7 +1362,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as the participation doesn't belong to any valid contract type")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as the participation doesn't belong to any valid contract type", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1310,7 +1399,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {outputlist[0]} doesnt exist", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1329,13 +1421,20 @@ def processTransaction(transaction_data, parsed_data): Base.metadata.create_all(bind=engine) session = sessionmaker(bind=engine)() session.add(ActiveTable(address=inputlist[0], parentid=0, transferBalance=parsed_data['tokenAmount'])) - session.add(TransferLogs(sourceFloAddress=inputadd, destFloAddress=outputlist[0], transferAmount=parsed_data['tokenAmount'], sourceId=0, destinationId=1, blockNumber=transaction_data['blockheight'], time=transaction_data['blocktime'], transactionHash=transaction_data['txid'])) + session.add(TransferLogs(sourceFloAddress=inputadd, destFloAddress=outputlist[0], + transferAmount=parsed_data['tokenAmount'], sourceId=0, destinationId=1, + blockNumber=transaction_data['blockheight'], time=transaction_data['blocktime'], + transactionHash=transaction_data['txid'])) blockchainReference = neturl + 'tx/' + transaction_data['txid'] session.add(TransactionHistory(sourceFloAddress=inputadd, destFloAddress=outputlist[0], - transferAmount=parsed_data['tokenAmount'], blockNumber=transaction_data['blockheight'], blockHash=transaction_data['blockhash'], + transferAmount=parsed_data['tokenAmount'], + blockNumber=transaction_data['blockheight'], + blockHash=transaction_data['blockhash'], time=transaction_data['blocktime'], transactionHash=transaction_data['txid'], - blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data))) + blockchainReference=blockchainReference, + jsonData=json.dumps(transaction_data), transactionType=parsed_data['type'], + parsedFloData=json.dumps(parsed_data))) session.commit() session.close() @@ -1343,31 +1442,38 @@ def processTransaction(transaction_data, parsed_data): engine = create_engine('sqlite:///system.db'.format(parsed_data['tokenIdentification']), echo=True) connection = engine.connect() connection.execute( - f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{inputadd}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}');") + f"INSERT INTO tokenAddressMapping (tokenAddress, token, transactionHash, blockNumber, blockHash) VALUES ('{inputadd}', '{parsed_data['tokenIdentification']}', '{transaction_data['txid']}', '{transaction_data['blockheight']}', '{transaction_data['blockhash']}');") connection.close() updateLatestTransaction(transaction_data, parsed_data) - pushData_SSEapi(f"Token | Succesfully incorporated token {parsed_data['tokenIdentification']} at transaction {transaction_data['txid']}") + pushData_SSEapi( + f"Token | Succesfully incorporated token {parsed_data['tokenIdentification']} at transaction {transaction_data['txid']}") return 1 else: - logger.info(f"Transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} has already been incorporated") + logger.info( + f"Transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} has already been incorporated") engine = create_engine(f"sqlite:///system.db", echo=True) SystemBase.metadata.create_all(bind=engine) session = sessionmaker(bind=engine)() blockchainReference = neturl + 'tx/' + transaction_data['txid'] - session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'], sourceFloAddress=inputadd, destFloAddress=outputlist[0], - transferAmount=parsed_data['tokenAmount'], - blockNumber=transaction_data['blockheight'], - blockHash=transaction_data['blockhash'], - time=transaction_data['blocktime'], - transactionHash=transaction_data['txid'], - blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} has already been incorporated")) + session.add(RejectedTransactionHistory(tokenIdentification=parsed_data['tokenIdentification'], + sourceFloAddress=inputadd, destFloAddress=outputlist[0], + transferAmount=parsed_data['tokenAmount'], + blockNumber=transaction_data['blockheight'], + blockHash=transaction_data['blockhash'], + time=transaction_data['blocktime'], + transactionHash=transaction_data['txid'], + blockchainReference=blockchainReference, + jsonData=json.dumps(transaction_data), + rejectComment=f"Transaction {transaction_data['txid']} rejected as a token with the name {parsed_data['tokenIdentification']} has already been incorporated", + transactionType=parsed_data['type'], + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() - pushData_SSEapi(f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists") + pushData_SSEapi( + f"Error | Token incorporation rejected at transaction {transaction_data['txid']} as token {parsed_data['tokenIdentification']} already exists") return 0 # todo Rule 48 - If the parsed data type if smart contract incorporation, then check if the name hasn't been taken already @@ -1379,7 +1485,8 @@ def processTransaction(transaction_data, parsed_data): logger.debug("Smart contract is of the type one-time-event") # either userchoice or payeeAddress condition should be present. Check for it - if 'userchoices' not in parsed_data['contractConditions'] and 'payeeAddress' not in parsed_data['contractConditions']: + if 'userchoices' not in parsed_data['contractConditions'] and 'payeeAddress' not in parsed_data[ + 'contractConditions']: logger.info( f"Either userchoice or payeeAddress should be part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected") # Store transfer as part of RejectedContractTransactionHistory @@ -1402,14 +1509,19 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Either userchoice or payeeAddress should be part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected")) + rejectComment=f"Either userchoice or payeeAddress should be part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() return 0 # userchoice and payeeAddress conditions cannot come together. Check for it - if 'userchoices' in parsed_data['contractConditions'] and 'payeeAddress' in parsed_data['contractConditions']: - logger.info(f"Both userchoice and payeeAddress provided as part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected") + if 'userchoices' in parsed_data['contractConditions'] and 'payeeAddress' in parsed_data[ + 'contractConditions']: + logger.info( + f"Both userchoice and payeeAddress provided as part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected") # Store transfer as part of RejectedContractTransactionHistory engine = create_engine( f"sqlite:///system.db", @@ -1430,7 +1542,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Both userchoice and payeeAddress provided as part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected")) + rejectComment=f"Both userchoice and payeeAddress provided as part of the Contract conditions.\nSmart contract incorporation on transaction {transaction_data['txid']} rejected", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() return 0 @@ -1446,7 +1561,8 @@ def processTransaction(transaction_data, parsed_data): session.add(ContractStructure(attribute='contractType', index=0, value=parsed_data['contractType'])) session.add(ContractStructure(attribute='contractName', index=0, value=parsed_data['contractName'])) session.add( - ContractStructure(attribute='tokenIdentification', index=0, value=parsed_data['tokenIdentification'])) + ContractStructure(attribute='tokenIdentification', index=0, + value=parsed_data['tokenIdentification'])) session.add( ContractStructure(attribute='contractAddress', index=0, value=parsed_data['contractAddress'])) session.add( @@ -1462,12 +1578,12 @@ def processTransaction(transaction_data, parsed_data): if 'minimumsubscriptionamount' in parsed_data['contractConditions']: session.add( - ContractStructure(attribute='minimumsubscriptionamount', index=0, - value=parsed_data['contractConditions']['minimumsubscriptionamount'])) + ContractStructure(attribute='minimumsubscriptionamount', index=0, + value=parsed_data['contractConditions']['minimumsubscriptionamount'])) if 'maximumsubscriptionamount' in parsed_data['contractConditions']: session.add( - ContractStructure(attribute='maximumsubscriptionamount', index=0, - value=parsed_data['contractConditions']['maximumsubscriptionamount'])) + ContractStructure(attribute='maximumsubscriptionamount', index=0, + value=parsed_data['contractConditions']['maximumsubscriptionamount'])) if 'userchoices' in parsed_data['contractConditions']: for key, value in parsed_data['contractConditions']['userchoices'].items(): session.add(ContractStructure(attribute='exitconditions', index=key, value=value)) @@ -1480,22 +1596,23 @@ def processTransaction(transaction_data, parsed_data): session.commit() - # Store transfer as part of ContractTransactionHistory blockchainReference = neturl + 'tx/' + transaction_data['txid'] session.add(ContractTransactionHistory(transactionType='incorporation', sourceFloAddress=inputadd, - destFloAddress=outputlist[0], - transferAmount=None, - blockNumber=transaction_data['blockheight'], - blockHash=transaction_data['blockhash'], - time=transaction_data['blocktime'], - transactionHash=transaction_data['txid'], - blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data))) + destFloAddress=outputlist[0], + transferAmount=None, + blockNumber=transaction_data['blockheight'], + blockHash=transaction_data['blockhash'], + time=transaction_data['blocktime'], + transactionHash=transaction_data['txid'], + blockchainReference=blockchainReference, + jsonData=json.dumps(transaction_data), + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() - # add Smart Contract name in token contract association engine = create_engine(f"sqlite:///tokens/{parsed_data['tokenIdentification']}.db", echo=True) Base.metadata.create_all(bind=engine) @@ -1508,17 +1625,24 @@ def processTransaction(transaction_data, parsed_data): time=transaction_data['blocktime'], transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data))) + jsonData=json.dumps(transaction_data), + transactionType=parsed_data['type'], + parsedFloData=json.dumps(parsed_data))) 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'], status='active', tokenIdentification=parsed_data['tokenIdentification'], contractType=parsed_data['contractType'], transactionHash=transaction_data['txid'], blockNumber=transaction_data['blockheight'], blockHash=transaction_data['blockhash'], incorporationDate=transaction_data['blocktime'])) + contractAddress=parsed_data['contractAddress'], status='active', + tokenIdentification=parsed_data['tokenIdentification'], + contractType=parsed_data['contractType'], + transactionHash=transaction_data['txid'], + blockNumber=transaction_data['blockheight'], + blockHash=transaction_data['blockhash'], + incorporationDate=transaction_data['blocktime'])) session.commit() session.add(ContractAddressMapping(address=inputadd, addressType='incorporation', @@ -1526,7 +1650,8 @@ def processTransaction(transaction_data, parsed_data): contractName=parsed_data['contractName'], contractAddress=inputadd, transactionHash=transaction_data['txid'], - blockNumber=transaction_data['blockheight'], blockHash=transaction_data['blockhash'])) + blockNumber=transaction_data['blockheight'], + blockHash=transaction_data['blockhash'])) session.commit() session.close() @@ -1534,10 +1659,11 @@ def processTransaction(transaction_data, parsed_data): updateLatestTransaction(transaction_data, parsed_data) pushData_SSEapi('Contract | Contract incorporated at transaction {} with name {}-{}'.format( - transaction_data['txid'], parsed_data['contractName'], parsed_data['contractAddress'])) + transaction_data['txid'], parsed_data['contractName'], parsed_data['contractAddress'])) return 1 else: - logger.info(f"Contract Incorporation on transaction {transaction_data['txid']} rejected as contract address in Flodata and input address are different") + logger.info( + f"Contract Incorporation on transaction {transaction_data['txid']} rejected as contract address in Flodata and input address are different") # Store transfer as part of RejectedContractTransactionHistory engine = create_engine( f"sqlite:///system.db", @@ -1558,30 +1684,39 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Contract Incorporation on transaction {transaction_data['txid']} rejected as contract address in flodata and input address are different")) + rejectComment=f"Contract Incorporation on transaction {transaction_data['txid']} rejected as contract address in flodata and input address are different", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() - pushData_SSEapi('Error | Contract Incorporation rejected as address in Flodata and input address are different at transaction {}'.format( + pushData_SSEapi( + 'Error | Contract Incorporation rejected as address in Flodata and input address are different at transaction {}'.format( transaction_data['txid'])) return 0 else: - logger.info(f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {parsed_data['contractAddress']} already exists") + logger.info( + f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {parsed_data['contractAddress']} already exists") # Store transfer as part of RejectedContractTransactionHistory engine = create_engine(f"sqlite:///system.db", echo=True) SystemBase.metadata.create_all(bind=engine) session = sessionmaker(bind=engine)() blockchainReference = neturl + 'tx/' + transaction_data['txid'] - session.add(RejectedContractTransactionHistory(transactionType='incorporation', contractName=parsed_data['contractName'], - contractAddress=outputlist[0], sourceFloAddress=inputadd, - destFloAddress=outputlist[0], - transferAmount=None, - blockNumber=transaction_data['blockheight'], - blockHash=transaction_data['blockhash'], - time=transaction_data['blocktime'], - transactionHash=transaction_data['txid'], - blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {parsed_data['contractAddress']} already exists")) + session.add(RejectedContractTransactionHistory(transactionType='incorporation', + contractName=parsed_data['contractName'], + contractAddress=outputlist[0], sourceFloAddress=inputadd, + destFloAddress=outputlist[0], + transferAmount=None, + blockNumber=transaction_data['blockheight'], + blockHash=transaction_data['blockhash'], + time=transaction_data['blocktime'], + transactionHash=transaction_data['txid'], + blockchainReference=blockchainReference, + jsonData=json.dumps(transaction_data), + rejectComment=f"Transaction {transaction_data['txid']} rejected as a Smart Contract with the name {parsed_data['contractName']} at address {parsed_data['contractAddress']} already exists", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1614,7 +1749,6 @@ def processTransaction(transaction_data, parsed_data): f"Error | Transaction {transaction_data['txid']} rejected as it already exists in the Smart Contract db. This is unusual, please check your code") return 0 - # pull out the contract structure into a dictionary engine = create_engine( 'sqlite:///smartContracts/{}-{}.db'.format(parsed_data['contractName'], outputlist[0]), echo=True) @@ -1634,7 +1768,6 @@ def processTransaction(transaction_data, parsed_data): contractStructure['exitconditions'] = conditionDict del counter, conditionDict - # if contractAddress has been passed, check if output address is contract Incorporation address if 'contractAddress' in contractStructure: if outputlist[0] != contractStructure['contractAddress']: @@ -1660,14 +1793,16 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} hasn't expired yet")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} hasn't expired yet", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( f"Error | Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} hasn't expired yet") return 0 - # check the type of smart contract ie. external trigger or internal trigger if 'payeeAddress' in contractStructure: logger.warning( @@ -1692,7 +1827,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} has an internal trigger")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} has an internal trigger", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -1731,7 +1869,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} closed as Smart contract {parsed_data['contractName']} at the {outputlist[0]} is closed")) + rejectComment=f"Transaction {transaction_data['txid']} closed as Smart contract {parsed_data['contractName']} at the {outputlist[0]} is closed", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1783,14 +1924,16 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has not expired and will not trigger")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has not expired and will not trigger", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( f"Error| Transaction {transaction_data['txid']} rejected as Smart contract {parsed_data['contractName']}-{outputlist[0]} has not expired and will not trigger") return 0 - # check if the user choice passed is part of the contract structure tempchoiceList = [] for item in contractStructure['exitconditions']: @@ -1819,14 +1962,16 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as triggerCondition, {parsed_data['triggerCondition']}, has been passed to Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} which doesn't accept any userChoice of the given name")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as triggerCondition, {parsed_data['triggerCondition']}, has been passed to Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} which doesn't accept any userChoice of the given name", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( f"Error | Transaction {transaction_data['txid']} rejected as triggerCondition, {parsed_data['triggerCondition']}, has been passed to Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} which doesn't accept any userChoice of the given name") return 0 - # check if minimumsubscriptionamount exists as part of the contract structure if 'minimumsubscriptionamount' in contractStructure: # if it has not been reached, close the contract and return money @@ -1862,7 +2007,7 @@ def processTransaction(transaction_data, parsed_data): contractAddress = connection.execute( 'select * from contractstructure where attribute="contractAddress"').fetchall()[0][0] returnval = transferToken(tokenIdentification, participant[1], contractAddress, - participant[0], transaction_data) + participant[0], transaction_data, parsed_data) if returnval is None: logger.info( "CRITICAL ERROR | Something went wrong in the token transfer method while doing local Smart Contract Trigger") @@ -1889,7 +2034,10 @@ def processTransaction(transaction_data, parsed_data): time=transaction_data['blocktime'], transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data))) + jsonData=json.dumps(transaction_data), + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() @@ -1911,7 +2059,6 @@ def processTransaction(transaction_data, parsed_data): parsed_data['contractName'], outputlist[0], transaction_data['txid'])) return 1 - # Trigger the contract engine = create_engine( 'sqlite:///smartContracts/{}-{}.db'.format(parsed_data['contractName'], outputlist[0]), @@ -1924,12 +2071,13 @@ def processTransaction(transaction_data, parsed_data): winnerSum = connection.execute( 'select sum(tokenAmount) from contractparticipants where userChoice="{}"'.format( parsed_data['triggerCondition'])).fetchall()[0][0] - tokenIdentification = connection.execute('select value from contractstructure where attribute="tokenIdentification"').fetchall()[0][0] + tokenIdentification = connection.execute( + 'select value from contractstructure where attribute="tokenIdentification"').fetchall()[0][0] for winner in contractWinners: winnerAmount = "%.8f" % ((winner[2] / winnerSum) * tokenSum) returnval = transferToken(tokenIdentification, winnerAmount, - outputlist[0], winner[1], transaction_data) + outputlist[0], winner[1], transaction_data, parsed_data) if returnval is None: logger.critical( "Something went wrong in the token transfer method while doing local Smart Contract Trigger") @@ -1949,11 +2097,13 @@ def processTransaction(transaction_data, parsed_data): time=transaction_data['blocktime'], transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, - jsonData=json.dumps(transaction_data))) + jsonData=json.dumps(transaction_data), + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() - engine = create_engine('sqlite:///system.db', echo=True) connection = engine.connect() connection.execute( @@ -1994,7 +2144,10 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} doesn't exist")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as Smart Contract named {parsed_data['contractName']} at the address {outputlist[0]} doesn't exist", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() pushData_SSEapi( @@ -2023,14 +2176,17 @@ def processTransaction(transaction_data, parsed_data): transactionHash=transaction_data['txid'], blockchainReference=blockchainReference, jsonData=json.dumps(transaction_data), - rejectComment=f"Transaction {transaction_data['txid']} rejected as input address, {inputlist[0]}, is not part of the committee address list")) + rejectComment=f"Transaction {transaction_data['txid']} rejected as input address, {inputlist[0]}, is not part of the committee address list", + + parsedFloData=json.dumps(parsed_data) + )) session.commit() session.close() - pushData_SSEapi(f"Transaction {transaction_data['txid']} rejected as input address, {inputlist[0]}, is not part of the committee address list") + pushData_SSEapi( + f"Transaction {transaction_data['txid']} rejected as input address, {inputlist[0]}, is not part of the committee address list") return 0 - # todo Rule 1 - Read command line arguments to reset the databases as blank # Rule 2 - Read config to set testnet/mainnet # Rule 3 - Set flo blockexplorer location depending on testnet or mainnet @@ -2039,7 +2195,8 @@ def processTransaction(transaction_data, parsed_data): # Read command line arguments -parser = argparse.ArgumentParser(description='Script tracks RMT using FLO data on the FLO blockchain - https://flo.cash') +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() @@ -2063,7 +2220,8 @@ elif config['DEFAULT']['NET'] == 'testnet': neturl = 'https://testnet.flocha.in/' localapi = '{} --testnet'.format(config['DEFAULT']['FLO_CLI_PATH']) else: - logger.error("NET parameter in config.ini invalid. Options are either 'mainnet' or 'testnet'. Script is exiting now") + logger.error( + "NET parameter in config.ini invalid. Options are either 'mainnet' or 'testnet'. Script is exiting now") # Delete database and smartcontract directory if reset is set to 1 if args.reset == 1: @@ -2087,19 +2245,16 @@ if args.reset == 1: engine = create_engine('sqlite:///system.db', echo=True) SystemBase.metadata.create_all(bind=engine) session = sessionmaker(bind=engine)() - session.add( SystemData(attribute='lastblockscanned', value=startblock-1)) + session.add(SystemData(attribute='lastblockscanned', value=startblock - 1)) session.commit() session.close() - # initialize latest cache DB + # Initialize latest cache DB engine = create_engine('sqlite:///latestCache.db', echo=True) LatestCacheBase.metadata.create_all(bind=engine) session.commit() session.close() - - - # Read start block no engine = create_engine('sqlite:///system.db', echo=True) SystemBase.metadata.create_all(bind=engine) @@ -2108,8 +2263,6 @@ startblock = int(session.query(SystemData).filter_by(attribute='lastblockscanned session.commit() session.close() - - # todo Rule 6 - Find current block height # Rule 7 - Start analysing the block contents from starting block to current height @@ -2118,9 +2271,10 @@ response = multiRequest('blocks?limit=1', config['DEFAULT']['NET']) current_index = response['blocks'][0]['height'] logger.debug("Current block height is %s" % str(current_index)) -for blockindex in range( startblock, current_index ): - if blockindex == 3443677: - print('''sys.exit(0)''') +for blockindex in range(startblock, current_index): + if blockindex == 3454500: + #sys.exit(0) + print(' ') processBlock(blockindex) # At this point the script has updated to the latest block