def genaccounts(numAccounts, network="SHASTA"): # choose tron based on the network if network.upper() == "MAINNET": tr = tron else: tr = shastaTron #connect to database cnx = dbconnect() cur = cnx.cursor() for i in range(0, numAccounts): account = tr.create_account address = account.address.base58 privateKey = account.private_key publicKey = account.public_key addressHex = account.address.hex s = 'INSERT INTO taccounts(address, privkey, pubkey, address_hex, network) VALUES (%s,%s,%s,%s,%s)' s = s % (quotedstr(str(address)), quotedstr(str(privateKey)), quotedstr(str(publicKey)), quotedstr( str(addressHex)), quotedstr(network)) #print(s) try: cur.execute(s) cnx.commit() print(i + " : " + str(address)) except: cnx.rollback() cnx.close()
def readdata(fileHash, network='SHASTA'): # choose tron based on the network if network.upper() == "MAINNET": tr = tron else: tr = shastaTron # connect to database cnx = dbconnect() cur = cnx.cursor() s = 'SELECT name FROM tstoreddata WHERE hash = %s AND network = %s' s = s % (quotedstr(fileHash), quotedstr(network)) cur.execute(s) row = cur.fetchone() if len(row) > 0: fileName = row[0] s = 'SELECT txhash, chunk_idx, chunk_size, chunk_hash FROM ttransactions WHERE data_hash = %s AND network = %s ORDER BY chunk_idx ASC' s = s % (quotedstr(fileHash), quotedstr(network)) cur.execute(s) rows = cur.fetchall() for row in rows: txHash = row[0] chunkIdx = row[1] chunkSize = row[2] chunkHash = row[3] # convert Tron's default toHex when creating transaction data to text using toText chunkDataString = tr.toText(getpayload(txHash, network)) # decode the payload then save as the chunk file originalData = binascii.unhexlify(chunkDataString.encode('utf-8')) #print(originalData) # Create a new file name filename = os.path.join(TEMP_FOLDER_READ, ('part-' + str(chunkIdx))) # Create a destination file dest_file = open(filename, 'wb') # Write to this portion of the destination file dest_file.write(originalData) # Explicitly close dest_file.close() resultPath = os.path.join(RESULT_FOLDER, fileName) join(TEMP_FOLDER_READ, resultPath, MAX_PAYLOAD) #remove all files parts = os.listdir(TEMP_FOLDER_READ) for file in parts: path = os.path.join(TEMP_FOLDER_READ, file) os.remove(path) print('Reading file finished')
def updatebandwidthremaining(network='SHASTA'): # choose tron based on the network if network.upper() == "MAINNET": tr = tron else: tr = shastaTron # connect to database cnx = dbconnect() cur = cnx.cursor() s = 'SELECT address FROM taccounts WHERE initialised = 1 AND network = %s ORDER BY id ASC' s = s % (quotedstr(network)) cur.execute(s) rows = cur.fetchall() totalRemainingBandwidth = 0 totalData = len(rows) progress = 0 for row in rows: address = row[0] remainingBandwidth = getremainingbandwidth(address, network) # store the remaining bandwidth to the respective account s = 'UPDATE taccounts SET bandwidth_remaining = %s WHERE address = %s AND network = %s' s = s % (str(remainingBandwidth), quotedstr(address), quotedstr(network)) try: cur.execute(s) cnx.commit() except: cnx.rollback() totalRemainingBandwidth = totalRemainingBandwidth + remainingBandwidth progress += 1 print('Update in Progress: ' + str(int(progress / totalData * 100)) + '%') # update to database s = 'REPLACE INTO tbandwidth_remaining (bandwidth, network) VALUES (%s, %s)' s = s % (str(totalRemainingBandwidth), quotedstr(network)) try: cur.execute(s) cnx.commit() print('Updated remaining Bandwidth on ' + network + ': ' + str(totalRemainingBandwidth) + ' bytes') except: cnx.rollback() #close the database cnx.close()
def fetchtx(txid): command = "fetch-tx -f json " + quotedstr(txid) raw = getbxoutput(command) if raw != "": res = json.loads(getbxoutput(command)) ret = res['transaction'] else: ret = "" return ret
def fetchbalance(address=""): balance = 0 command = "fetch-balance -f json " + quotedstr(address) raw = getbxoutput(command) if raw != "": res = json.loads(raw) if 'received' in res['balance'] and 'spent' in res['balance']: balance = int(res['balance']['received']) - int(res['balance']['spent']) return balance
def fetchutxo(address="", sat=0): command = "fetch-utxo -f json " + str(sat) + " " + quotedstr(address) #print(command) raw = getbxoutput(command) #print(raw) if raw != "": res = json.loads(getbxoutput(command)) else: res = "" return res['points']
def addresstoscript(address=""): script = "" command = "address-decode -f json " + quotedstr(address) raw = getbxoutput(command) if raw != "": res = json.loads(raw) payload = res['wrapper']['payload'] #pubkeyhash160 = bitcoin160(payload) script = 'dup hash160 [' + payload + '] equalverify checksig' return script
def savedata(fileName, network='SHASTA'): # assuming that the remaining bandwidth is up to date # check the file size and compare it to the remaining bandwidth # connect to database cnx = dbconnect() cur = cnx.cursor() s = 'SELECT bandwidth FROM tbandwidth_remaining WHERE network = %s' s = s % (quotedstr(network)) cur.execute(s) row = cur.fetchone() if len(row) > 0: remainingBandwidth = float(row[0]) else: remainingBandwidth = 0 # get file size fileSize = os.path.getsize(fileName) # get the file hash fileHash = sha1file(fileName) # compute the number of transactions required numTx = int(math.ceil(fileSize / MAX_PAYLOAD)) totalSize = float(fileSize + (numTx * TX_SIZE)) # totalSize of the required bandwidth should be less or equal to 45% of remainingBandwidth, for safety # because the totalSize will double in size when stored as Hex in the transactions usableBandwidth = remainingBandwidth * 0.45 if totalSize <= usableBandwidth: print('Bandwidth is sufficient. Process continues...') # save the file information to the database s = 'REPLACE INTO tstoreddata(hash, name, size, network) VALUES (%s, %s, %s, %s)' s = s % (quotedstr(fileHash), quotedstr(fileName), str(totalSize), quotedstr(network)) fileOK = False try: cur.execute(s) cnx.commit() fileOK = True except: cnx.rollback() fileOK = False if fileOK: # process # 1: splits the file into temporary folders split(fileName, TEMP_FOLDER, MAX_PAYLOAD) # 2: processes each splitted chunks to the database and to the blockchain # Get a list of the file parts parts = os.listdir(TEMP_FOLDER) # Sort them by name (remember that the order num is part of the file name) parts = natural_sort(parts) # Go through each portion one by one chunkIdx = 0 for file in parts: chunkIdx += 1 print('Processing chunk index: ' + str(chunkIdx)) # Assemble the full path to the file path = os.path.join(TEMP_FOLDER, file) # Open the part in bytes input_file = open(path, 'rb') # Open the part in string chunkData = input_file.read(MAX_PAYLOAD) chunkDataString = binascii.hexlify(chunkData).decode('utf-8') isChunkStored = False isChunkStored = sendpayload(fileHash, chunkIdx, chunkDataString, network) # if successfull, remove the chunk if isChunkStored: os.remove(path) else: print('Insufficient bandwidth. Available: ' + str(remainingBandwidth) + ', required: ' + str(totalSize * 2) + ', diff: ' + str(totalSize * 2 - remainingBandwidth)) cnx.close()
def getnewhdpubkeyfrompubkeyidx(pubkey="", idx=0): command = "hd-public --index " + str(idx) + " " + quotedstr(pubkey) return getbxoutput(command)
def initaccount(numAccount, tokenAmount, tokenName, sender, privKeySender, network='SHASTA'): # choose tron based on the network if network.upper() == "MAINNET": tr = tron else: tr = shastaTron # connect to database cnx = dbconnect() cur = cnx.cursor() # select address from TACCOUNTS where initialised = 0 order by id limit 10 s = 'SELECT address, id FROM taccounts WHERE initialised = 0 AND network = %s ORDER BY id LIMIT %s' s = s % (quotedstr(network), str(numAccount)) cur.execute(s) rows = cur.fetchall() for row in rows: receiver = row[0] id = row[1] txt = "SENARAI INITIALISATION. ID: " + str(id) # the result is already in dictionary format result = sendtoken(receiver, tokenAmount, tokenName, sender, privKeySender, fromAddress=None, message=txt, network=network) # print(result) try: isSuccessful = result['result'] txID = result['transaction']['txID'] except: isSuccessful = False print(result) #if transaction is successful, then update status INITIALISED to 1 as well as save the txid if isSuccessful: s = 'UPDATE taccounts SET initialised = 1 WHERE address = %s AND network = %s' s = s % (quotedstr(receiver), quotedstr(network)) try: cur.execute(s) cnx.commit() print('Address ' + str(receiver) + ' is initialised by receiving ' + str(tokenAmount) + ' ' + tokenName) except: cnx.rollback() s = 'INSERT INTO taccountinit(txhash, address, network) VALUES (%s, %s, %s)' s = s % (quotedstr(txID), quotedstr(receiver), quotedstr(network)) try: cur.execute(s) cnx.commit() except: cnx.rollback() cnx.close()
def sendpayload(dataHash=None, chunkIdx=0, message=None, network='SHASTA'): # amount of tokens to be paid is 1 amount = 1 tokenName = DEFAULT_TOKEN_NAME # get the next available account based on remaining bandwidth messageLength = len(message) messageHash = sha1string(message) bandwidthRequired = messageLength + 300 # connect to database cnx = dbconnect() cur = cnx.cursor() #print(bandwidthRequired) # offset is to enable threading so that multiple chunks can be processed at the same time # this ensures different accounts are picked for different chunkIdx # chunkIdx starts from 1, but offset starts from 0, therefore the offset is chunkIdx - 1 s = 'SELECT address, id, privkey FROM taccounts WHERE initialised = 1 AND network = %s AND bandwidth_remaining >= %s ORDER BY bandwidth_remaining ASC, id ASC LIMIT 1 OFFSET %s' s = s % (quotedstr(network), str(bandwidthRequired), str(chunkIdx - 1)) #print(s) cur.execute(s) row = cur.fetchone() isSuccessful = False if row: addressSender = row[0] id = row[1] senderPrivKey = row[2] #get the destination address, which should be the address of id+1 s = 'SELECT address FROM taccounts WHERE id = %s AND network = %s' s = s % (str(id + 1), quotedstr(network)) cur.execute(s) row2 = cur.fetchone() # if there is a next address if len(row2) > 0: addressReceiver = row2[0] # if next address is not available, then go back to the first address else: # get the destination address, which should be the address of id=1 s = 'SELECT address FROM taccounts WHERE id = 1 AND network = %s' s = s % (str(id + 1), quotedstr(network)) cur.execute(s) row3 = cur.fetchone() if len(row3) > 0: addressReceiver = row3[0] else: addressReceiver = DEFAULT_ADDRESS result = sendtoken(addressReceiver, amount, tokenName, addressSender, senderPrivKey, addressSender, message, network) try: isSuccessful = result['result'] except: isSuccessful = False if isSuccessful: txID = result['transaction']['txID'] # store the data to the database s = 'INSERT INTO ttransactions(txhash, address, data_hash, chunk_idx, chunk_size, chunk_hash, network) ' \ 'VALUES (%s, %s, %s, %s, %s, %s, %s)' s = s % (quotedstr(txID), quotedstr(addressSender), quotedstr(dataHash), str(chunkIdx), str(messageLength), quotedstr(messageHash), quotedstr(network)) try: cur.execute(s) cnx.commit() print( 'Chunk index ' + str(chunkIdx) + ' has been successfully stored to the blockchain and the record to the database. TxID: ' + txID) except: cnx.rollback() print( 'Chunk index ' + str(chunkIdx) + ' has been successfully stored to the blockchain but recording to the database failed. TxID: ' + txID) else: print('Chunk index ' + str(chunkIdx) + ' failed to be stored to the blockchain') print(result) else: print('No account with sufficient bandwidth') return isSuccessful
def getecprivkeyfromseed(seed=""): command = "ec-new " + quotedstr(seed) return getbxoutput(command)
def gethdpubkeyfromprivkey(privkey=""): command = "hd-to-public " + quotedstr(privkey) return getbxoutput(command)
def scriptencode(script=""): command = "script-encode " + quotedstr(script) return getbxoutput(command)
def getnewhdprivkeyfromprivkeyidx(privkey="", idx=0): command = "hd-private --index " + str(idx) + " " + quotedstr(privkey) return getbxoutput(command)
def hdtoec(key=""): command = "hd-to-ec " + quotedstr(key) return getbxoutput(command)
def getaddrfromeckey(key=""): command = "ec-to-address " + quotedstr(key) return getbxoutput(command)
def inputset(signature, ecpubkey, trx, idx=0): endorsement = "[" + signature + "] " + "[" + ecpubkey + "]" command = "input-set " + "-i " + str(idx) + " " + quotedstr(endorsement) + " " + trx #print(command) #print() return getbxoutput(command)
def inputsign(privkey, contract, trx, idx=0, signtype="all"): command = "input-sign " + "-i " + str(idx) + " -s " + signtype + " " + privkey + " " + quotedstr(contract) + " " + trx #print(command) return getbxoutput(command)
def base16encode(s=""): command = "base16-encode " + quotedstr(s) # same result as the following # source: https://python-forum.io/Thread-how-to-convert-a-string-to-hex # print(s.encode('utf-8').hex()) return getbxoutput(command)
def getecpubkeyfromecprivkey(ecprivkey=""): command = "ec-to-public " + quotedstr(ecprivkey) return getbxoutput(command)