import time import logging import sys sys.path.append( "/home/pi/.local/lib/python2.7/site-packages" ) #path muss hinzugefügt werden damit PyOta librarys gefunden werden können from iota import Iota, ProposedTransaction, ProposedBundle, Address, Tag, TryteString #importe Iota-Bibliothek um die API anzusprechen from iota.crypto.addresses import AddressGenerator # Reciever Seed: GCUKFZRLCTBGBDKQCQY9SMJPDPLFBDJJFTXZANHDJUTCZKIQQEUHSAVOYWKPTDDNEWRGBFWDMWYYRLRUR # returned Address at index 0 for Security Level 2 reciever_address = "LOZMZOKJWWVASYYWT999JPLDBMUSFZKMLZW9IXHTOAUOQKZMRLRAZCWECAFONWKT9HSHKHLMKAWSQFFXX" seed = "DSPOAXMVSC99IUIVJXTIBZFATVFKTCLLJYOLAGSMFJGFXAWEB9GNTQWEDVRYHKIOQF9T9IZY9IVPKTSZK" url = "https://potato.iotasalad.org:14265" #fullnode url api = Iota(url, seed) #erstelle Iota API logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG) logger = logging.getLogger(__name__) api.adapter.set_logger(logger) proposedTrx = ProposedTransaction( address=Address(reciever_address), value=0, tag=Tag("BACHELORTEST"), message=TryteString.from_string("This is a test transaction")) proposedBundle = ProposedBundle([proposedTrx]) preparedBundle = api.prepare_transfer(proposedBundle) publishedBundle = api.send_transfer(depth=3, transfers=proposedBundle)
# Send PoW requests to local node. # All other requests go to light wallet node. router = RoutingWrapper('http://service.iotasupport.com:14265') router.add_route('attachToTangle', 'http://localhost:14265') api = Iota(router, seed=b'SEED9GOES9HERE') # Example of sending a transfer using the adapter. bundle = api.send_transfer( depth=3, transfers=[ ProposedTransaction( # Recipient of the transfer. address=Address( # b'TESTVALUE9DONTUSEINPRODUCTION99999FBFFTG' # b'QFWEHEL9KCAFXBJBXGE9HID9XCOHFIDABHDG9AHDR' ), # Amount of IOTA to transfer. # This value may be zero. value=1, # Optional tag to attach to the transfer. tag=Tag(b'ADAPT'), # Optional message to include with the transfer. message=TryteString.from_string('Hello!'), ), ], )
class Escrow: def __init__(self, node='https://nodes.thetangle.org:443', seed=None): #Get Seed if seed is None: self.seed = self.getSeed() else: self.seed = seed #Setup API self.api = Iota(node, self.seed) #Generates a seed for escrow account def getSeed(self): #If no seed, create one if not os.path.isfile('seed.txt'): path = pathlib.Path(__file__).parent.absolute() seed = ''.join([random.choice(LETTERS) for i in range(81)]) open('seed.txt', 'w+').write(seed) logging.info("Placed new seed in seed.txt") return open('seed.txt').read().strip().encode('utf-8') #Creates an escrow holding address def createEscrow(self): try: self.holdingAddress = self.api.get_new_addresses( count=None, checksum=True)['addresses'][0] except iota.adapter.BadApiResponse as e: logging.warning("Bad response from server retrying.") return self.createEscrow() return self.holdingAddress #Waits for a transactions with a refund address def getRefundAddress(self): #This is the escrow address address = self.holdingAddress try: #Get Hashes from ledger txHashes = self.api.find_transactions(addresses=[ address, ])['hashes'] #If no hashes, user has not submitted an address yet. if len(txHashes) == 0: return None else: #Check messages for a valid address txs = self.api.get_transaction_objects( txHashes)['transactions'] for tx in txs: msg = tx.signature_message_fragment.decode() try: self.deposit = Address(msg.strip()) return self.deposit except: pass logging.warning("Invalid address recieved") except requests.exceptions.ConnectionError as e: #Sometimes the public nodes will reject a request print("Error contacting server; retrying") return self.getRefundAddress() #Cli version of escrow def startCli(self, collateral, fee=0, delay=120, deposit=None): #Create holding address self.createEscrow() self.fee = fee self.collateral = collateral #Wait for a deposit address to be entered if self.requestDeposit(collateral, deposit, delay): while not self.checkCondition(): sleep(3) self.finalizeEscrow() #Wait for escrow address to recieve collateral def requestDeposit(self, collateral, deposit=None, duration=120): #For CLI prompt a deposit address if deposit is None: self.deposit = input("What is the deposit address: ") print( f"You have {duration/60:.1f} min to deposit {collateral} IOTA to {self.holdingAddress}" ) #Wait for escrow to recive collateral funds. count = 0 while count < duration: time.sleep(1) balance = self.getBalance(self.holdingAddress) if balance >= collateral: print("Successfully deposited into escrow", balance) return True return False #Condition to release escrow def checkCondition(self): #Setup a check condition #For example RFID or some ledger condition return True #Refund user their collateral, remoing the fee def finalizeEscrow(self, fee=None, deposit=None): if fee is None: fee = self.fee if deposit is None: deposit = self.deposit #Return money to deposit address returnAmount = self.getBalance(self.holdingAddress) #Calcualte return amount if returnAmount > 0: returnAmount -= fee #Setup transaction message = "Repayment of collateral" feeLocation = self.api.get_new_addresses(count=1, checksum=True)['addresses'][0] txs = [ ProposedTransaction(address=Address(deposit), value=returnAmount, message=TryteString.from_unicode(message)), ] #Send transaction try: bundle = self.api.send_transfer(transfers=txs)['bundle'] except iota.adapter.BadApiResponse as e: print("Node did not respond. Retrying.") return self.finalizeEscrow(fee, deposit) logging.info(bundle.transactions[0].hash) logging.info("Sent money back to recipient") self.addRevenue(fee) def getBalance(self, address): try: response = self.api.get_balances(addresses=[address])['balances'] return response[0] except requests.exceptions.ConnectionError as e: logging.info("Error contacting server; retrying") return self.getBalance(self, address) #Record the amount of revenue recieved def addRevenue(self, money, filename='revenue.txt'): if not os.path.isfile(filename): open(filename, 'w+').write('0') current = int(open(filename).read().strip()) current += money open(filename, 'w+').write(str(current)) #Get the current amount of revenue def getRevenue(self, filename="revenue.txt"): if not os.path.isfile(filename): return 0 return int(open(filename).read().strip()) #Send revenue to an address def sendRevenue(self, outputAddress): revenue = self.getRevenue() logger.info(f"Currently have {revenue} revenue.") message = "Output fees from escrow." txs = [ ProposedTransaction(address=Address(outputAddress), value=revenue, message=TryteString.from_unicode(message)), ] try: logger.info("Sending transfer to node.") bundle = self.api.send_transfer(transfers=txs)['bundle'] except iota.adapter.BadApiResponse as e: print("Bad api resonse retrying") return self.sendRevenue(outputAddress) print(bundle.transactions[0].hash)
'YCXCVQDFGWUKPUABPYNMVPAQUGUHYYLMWZQWRUIDIXGTDAOJKOUGRWDJUUOWGOHMVYLTZHGEZCZHBTMT9RM9XGRJUW' ] }] for account in accounts: # fetch seed seed = account['seed'] fund = account['fund'] addrs = account['addresses'] # log print '[%s] Start' % (seed) # setup iota client api = Iota('http://localhost:14265', seed) # attach each address for address in addrs: # prepare trx trx = ProposedTransaction(address=Address(address), message=TryteString.from_string( "MSG%s%s" % (seed[:5], address[:5])), tag=Tag("TAG%s%s" % (seed[:5], address[:5])), value=0) # attach api.send_transfer(1, [trx]) # ensure we can get the expected amount of funding for that account now api_fund = api.get_account_data(0)['balance'] if api_fund == fund: print '[%s] Success' % (seed) else: print '[%s] Fail: expected %d IOTA, got %d IOTA' % (seed, fund, api_fund)
from iota import Iota, TryteString, Address, Tag, ProposedTransaction from pprint import pprint # Declare an API object api = Iota('https://nodes.devnet.iota.org:443', devnet=True) # Prepare custom data my_data = TryteString.from_unicode('Hello from the Tangle!') # Generate a random address that doesn't have to belong to anyone my_address = Address.random() # Tag is optional here my_tag = Tag(b'MY9FIRST9TAG') # Prepare a transaction object tx = ProposedTransaction( address=my_address, value=0, tag=my_tag, message=my_data ) # Send the transaction to the network response = api.send_transfer([tx]) pprint('Check your transaction on the Tangle!') pprint('https://utils.iota.org/transaction/%s/devnet' % response['bundle'][0].hash)
class MyIOTA: def __init__(self, node, seed): self.node = node self.seed = seed self.api = False self._update = False self.transfers = [] self._debug = False self.wallet = self.get_filename() self.addr_dict = {} self.min_weight_magnitude = 14 self.api = Iota(self.node, self.seed) self.USED = True self.NOT_USED = False def get_addr_dict(self): return self.addr_dict def set_addr_dict(self, addr, value, used): self.addr_dict[addr] = (value, used) def s_addr(self, addr, n=3): s_addr = str(addr) l = len(s_addr) return s_addr[:n] + '...' + s_addr[l - n:] def get_filename(self): h = hashlib.sha256() h.update(self.seed) filename = h.hexdigest()[:20] + '.txt' return filename def init_wallet(self): filename = self.wallet # file exists if os.path.isfile(filename): filefd = open(filename, 'r+') self.debug( 'Wallet file {0} exists. Opening it...'.format(filename)) for line in filefd: line = line.rstrip('\n') addr, index, value, used = line.split(',') self.debug('reading from file: {0},{1},{2}'.format( self.s_addr(addr, 3), value, used)) used = used == 'True' addr = Address(addr, key_index=int(index), security_level=2) self.addr_dict[addr] = (int(index), int(value), used) filefd.close() else: filefd = open(filename, 'w') self.debug('Wallet file {0} doesnt exist. Creating it...'.format( filename)) filefd.close() def is_empty_wallet(self): return len(self.addr_dict) == 0 def get_fund_inputs(self, inputs): total_fund = 0 for addr in inputs: index, value, used = self.addr_dict[addr] # TODO: abs. is this right? total_fund += abs(value) return total_fund def write_updates(self): filefd = open(self.wallet, 'w') self.debug('Writing (updating) wallet...') for addr in self.addr_dict: v = self.addr_dict[addr] line = 'Writing: {0},{1},{2},{3}\n'.format(self.s_addr(addr), v[0], v[1], v[2]) self.debug(line) filefd.write('{0},{1},{2},{3}\n'.format(addr, v[0], v[1], v[2])) filefd.close() def update_wallet(self, input_fund, inputs, change_addr): copy_dict = self.addr_dict.copy() for addr in inputs: v = self.addr_dict[addr] #self.debug('Spending {0} from input {1}'.format(self.s_addr(addr), v)) # Negative fund and used address new_value = (v[0], -v[1], not v[2]) self.debug('Updating input address {0} to: {1}'.format( self.s_addr(addr), new_value)) self.addr_dict[addr] = new_value change_fund = self.get_fund_inputs(inputs) - input_fund v = self.addr_dict[change_addr] change_value = (v[0], change_fund, self.NOT_USED) self.debug('Updating change address {0} to: {1}'.format( self.s_addr(change_addr), change_value)) self.addr_dict[change_addr] = change_value self.write_updates() def enable_debug(self): self._debug = True def debug(self, msg): if self._debug: print '[+] Debug: ', msg def get_node_info(self): self.api.get_node_info() def make_addr_list(self, start_index, n): self.iota_assert(start_index >= 0 and n > 0, 'must be positive numbers. N should be at least 1.') result = self.api.get_new_addresses(index=start_index, count=n) addresses = result['addresses'] for i in range(n): addr = addresses[i] value = self.get_addr_balance(addr) # TODO: Why always False self.addr_dict[addr] = (i, value, False) def get_addr_balance(self, addr): # TODO: addr is a list with just one element result = self.api.get_balances([addr]) balance = result['balances'] return (balance[0]) def prepare_transfer(self, transfer_value, dest_addr, tag='DEFAULT', msg='DEFAULT'): # TODO: verify address (checksum) # TODO: use mi, gi, etc msg = TryteString.from_string(msg) txn = ProposedTransaction( address=Address(dest_addr), message=msg, tag=Tag(tag), value=transfer_value, ) return txn def find_transactions(self): addr_list = [] for e in self.addr_dict.items(): addr = e[0] addr_list.append(addr) return self.api.findTransactions(addresses=addr_list)['hashes'] def get_bundle(self, trans): return self.api.getBundles(transaction=trans) def get_latest_inclusion(self, addrl): return self.api.get_latest_inclusion(hashes=addrl) def get_total_fund(self): total_fund = 0 for addr in self.addr_dict.items(): # key and value from dict k, v = addr print k, v index, value, used = v #if not used: total_fund += value return total_fund def send_transfer(self, input_fund, inputs, outputs, change_addr): iota.debug('Sending {0} transactions, please wait...'.format( len(outputs))) #self.update_wallet(input_fund, inputs, change_addr) #return self.api.send_transfer(inputs=inputs, depth=7, transfers=outputs, change_address=change_addr, min_weight_magnitude=self.min_weight_magnitude) self.update_wallet(input_fund, inputs, change_addr) def get_trytes(self, hashl): return self.api.get_trytes(hashl)['trytes'][0] def get_transaction_from_trytes(self, trytes): txn = Transaction.from_tryte_string(trytes) return txn def get_transaction_fields(self, txn): #print dir(txn) confirmed = str(txn.is_confirmed) timestamp = str(txn.timestamp) address = str(txn.address) value = str(txn.value) message = str(txn.signature_message_fragment) #message = str(txn.message) tag = str(txn.tag) return (confirmed, timestamp, address, value, tag, message) def get_info_transactions(self, transactions_hashes): txn_tuples = [] for h in transactions_hashes: trytes = iota.get_trytes([h]) txn = iota.get_transaction_from_trytes(trytes) (_, _, addr_t, value_t, tag_t, msg_t) = iota.get_transaction_fields(txn) txn_tuples.append((addr_t, value_t, tag_t, msg_t)) #txn_tuples.append((tag_t, msg_t)) return txn_tuples def get_inputs(self, fund, get_change_addr=False): # TODO: Zero fund fund_sum = 0 addr_list = [] change_addr = None for e in self.addr_dict.items(): addr, v = e index, value, used = v if fund_sum < fund: #if value > 0 and not used: if value > 0 and used == self.NOT_USED: fund_sum += value iota.debug( 'Found request: {0}. Found address {1} with fund {2}.'. format(fund, iota.s_addr(addr), value)) addr_list.append(addr) if get_change_addr: for e in self.addr_dict.items(): addr, v = e index, value, used = v if used == self.NOT_USED and addr not in addr_list: change_addr = addr iota.debug('Using {0} as change addr.'.format( iota.s_addr(addr))) return (addr_list, change_addr) # TODO self.iota_assert(True, 'No change addr available.') return addr_list def iota_assert(self, condition, msg): if not condition: print 'Error: ', msg sys.exit(-1)
from config import SEED, DEPTH, MIN_WEIGHT_MAGNITUDE, NODE_URL receiver_address = "ILXW9VMJQVFQVKVE9GUZSODEMIMGOJIJNFAX9PPJHYQPUHZLTWCJZKZKCZYKKJJRAKFCCNJN9EWOW9N9YDGZDDQDDC" txn_tag = "TXNTAGS" message = {"key": "values"} value = 0 # Iota instance api = Iota(NODE_URL, SEED) # Txn description txn = ProposedTransaction( address=Address(receiver_address), message=TryteString.from_string(json.dumps(message)), tag=Tag(txn_tag), value=value, ) # Send transaction prepared_transferes = [] bundle = "" prepared_transferes.append(txn) try: bundle = api.send_transfer(depth=DEPTH, transfers=prepared_transferes, min_weight_magnitude=MIN_WEIGHT_MAGNITUDE) except Exception as e: print(e) print(bundle['bundle'].hash)
class IotaCache(object): def __init__(self, uri=None, seed=None): if not uri: self.uri = "http://localhost:14700" else: self.uri = uri if not seed: self.seed = 'EBZYNR9YVFIOAZUPQOLRZXPPPIKRCJ9EJKVCXMYVLMNOCCOPYPJKCWUZNLJZZZZWTMVQUXZFYLVLZXJ9Q' else: self.seed = seed self.api = Iota(self.uri, self.seed, testnet=True) self.mwm = 1 self.depth = 15 def cache_txn_in_tangle_sdk(self, ipfs_addr, tag): api_response = self.api.get_new_addresses() addy = api_response['addresses'][0] address = binary_type(addy).decode('ascii') result = self.api.send_transfer( depth=self.depth, transfers=[ ProposedTransaction( address=Address(address), value=0, tag=Tag(tag), message=TryteString.from_string(ipfs_addr), ), ], min_weight_magnitude=self.mwm, ) return result def cache_txn_in_tangle_simple(self, data, tag): address = "JVSVAFSXWHUIZPFDLORNDMASGNXWFGZFMXGLCJQGFWFEZWWOA9KYSPHCLZHFBCOHMNCCBAGNACPIGHVYX" txns = self.api.get_transactions_to_approve(self.depth) tr = self.api.get_trytes([txns[u'branchTransaction']]) txn = Transaction.from_tryte_string(tr[u'trytes'][0], txns[u'branchTransaction']) txn.trunk_transaction_hash = txns[u'trunkTransaction'] txn.branch_transaction_hash = txns[u'branchTransaction'] txn.tag = Tag(TryteString.from_string(tag)) txn.signature_message_fragment = Fragment(TryteString.from_bytes(data)) attach_trytes = attachToTangle(self.uri, txns[u'trunkTransaction'].__str__(), txns[u'branchTransaction'].__str__(), 1, txn.as_tryte_string().__str__()) res = self.api.broadcast_and_store(attach_trytes[u'trytes']) return res def cache_txn_in_tangle_message(self, data, tag): #address = "JVSVAFSXWHUIZPFDLORNDMASGNXWFGZFMXGLCJQGFWFEZWWOA9KYSPHCLZHFBCOHMNCCBAGNACPIGHVYX" address = "14dD6ygPi5WXdwwBTt1FBZK3aD8uDem1FY" res = storeMessage(self.uri, address, data, tag) return res def get_balance(self, coin_type, account): address = "JVSVAFSXWHUIZPFDLORNDMASGNXWFGZFMXGLCJQGFWFEZWWOA9KYSPHCLZHFBCOHMNCCBAGNACPIGHVYX" res = getBalance(self.uri, address, coin_type, account) return res def get_approved_txns(self, tag): ret = [] transactions = self.api.find_transactions(None, None, [tag], None) if len(transactions['hashes']) == 0: return ret tips = self.api.get_tips() states = self.api.get_inclusion_states(transactions['hashes'], tips['hashes']) i = 0 for txn in transactions['hashes']: if states['states'][i] is True: ret.append(txn) return ret def get_non_consumed_txns(self, tag): ret = [] txn_hashes_all = self.get_approved_txns(tag) if len(txn_hashes_all) == 0: return ret txn_trytes_all = self.api.get_trytes(txn_hashes_all) consumedSet = [] txn_hashes_consumed = self.api.find_transactions(None, None, [tag+b"CONSUMED"], None) if len(txn_hashes_consumed['hashes']) != 0: txn_trytes_consumed = self.api.get_trytes(txn_hashes_consumed['hashes']) i=0 for txnTrytes in txn_trytes_consumed['trytes']: txn = Transaction.from_tryte_string(txnTrytes, txn_hashes_consumed['hashes'][i]) i+=1 consumedSet.append(txn.signature_message_fragment) i=0 for txnTrytes in txn_trytes_all['trytes']: txn = Transaction.from_tryte_string(txnTrytes, txn_hashes_all[i]) i+=1 if txn.signature_message_fragment not in consumedSet: msgTryte = txn.signature_message_fragment.decode() ret.append(msgTryte) return ret def set_txn_as_synced(self, ipfs_addr, tag): result = self.cache_txn_in_tangle_sdk(ipfs_addr, tag+b"CONSUMED") return result def add_neighbors(self, uris): res = addNeighbors(self.uri, uris) return res def get_block_content(self, hashes): res = getBlockContent(self.uri, hashes) return res def get_dag(self, dag_type): res = getDAG(self.uri, dag_type) return res def get_utxo(self, dag_type): res = getUTXO(self.uri, dag_type) return res def get_total_order(self): res = getTotalOrder(self.uri) return res
my_seed = Seed(b'YOURSEEDFROMTHEPREVIOUSTUTORIAL') # Declare an API object api = Iota( adapter='https://nodes.devnet.iota.org:443', seed=my_seed, devnet=True, ) # Addres to receive 1i # Feel free to replace it. For example, run the code from Tutorial 4.a # and use that newly generated address with a 'fresh' seed. receiver = Address( b'WWUTQBO99YDCBVBPAPVCANW9ATSNUPPLCPGDQXGQEVLUBSFHCEWOA9DIYYOXJONDIRHYPXQXOYXDPHREZ' ) print('Constructing transfer of 1i...') # Create the transfer object tx = ProposedTransaction( address=receiver, value=1, message=TryteString.from_unicode('I just sent you 1i, use it wisely!'), tag=Tag('VALUETX'), ) print('Preparing bundle and sending it to the network...') # Prepare the transfer and send it to the network response = api.send_transfer(transfers=[tx]) print('Check your transaction on the Tangle!') print('https://utils.iota.org/bundle/%s/devnet' % response['bundle'].hash)
class TangleConnector: def __init__(self, url='https://perma.iota.partners:443', seed="TESTSEED9"): self.iri_url = url self.iota_api = Iota(url, seed) def get_node(self) -> Dict: """ Get IRI node info """ try: res = self.iota_api.get_node_info() except BadApiResponse as e: logger.warning("Failed to IRI node info for " + self.iri_url, e) res = None return res def get_tips(self) -> Dict: """ Get all unreferenced transactions """ try: res = self.iota_api.get_tips() except BadApiResponse as e: logger.warning("Failed to get tips", e) res = None return res def get_hashes_from_addr(self, address: Address) -> List[TransactionHash]: """ Get all tx from address """ try: response = self.iota_api.find_transactions(addresses=[address]) hashes = response['hashes'] except (BadApiResponse, KeyError) as e: logger.warning( "Failed to get all tx from address " + address.__str__(), e) hashes = None return hashes def get_trytes_from_hashes( self, hashes: List[TransactionHash]) -> List[TryteString]: """ Get tryte signature fragments from hashes """ try: response = self.iota_api.get_trytes(hashes) trytes = [tryte[0:2187] for tryte in response['trytes']] except (BadApiResponse, KeyError) as e: logger.warning("Failed to get all signature fragments", e) trytes = None return trytes def get_all_trytes_from_address( self, address: Address) -> Dict[TransactionHash, TryteString]: """ Get all trytes from address """ hashes = self.get_hashes_from_addr(address) trytes = self.get_trytes_from_hashes(hashes) if hashes and trytes: result = dict(zip(hashes, trytes)) else: result = None return result @staticmethod def get_json_from_tryte(tryte: TryteString) -> Dict: try: str_from_tryte = tryte.as_string() dict_from_tryte = json.loads(str_from_tryte) except ValueError as e: logger.error("Failed to convet trytes to JSON", e) dict_from_tryte = None return dict_from_tryte def send_msg_to_addr(self, address: Address, msg: str, tag: str) -> Dict: """ Sends msg on Tangle to address with a tag """ try: response = self.iota_api.send_transfer( depth=2, transfers=[ ProposedTransaction(address=address, value=0, tag=Tag(tag), message=TryteString.from_string(msg)) ]) except BadApiResponse as e: logger.warning( "Message '" + msg + "' has failed to be stored in " + address.__str__(), e) response = None return response def get_bundles_from_addr(self, address: Address) -> List[Dict]: ''' Retrive all bundles sent to this address from IRI # requres IRI 1.6+ (or it seems so) ''' hashes = self.get_hashes_from_addr(address) bundles = [] if hashes: for tx in hashes: try: # have to loop through all txs, if tx is not 'tail' of a bundle then get_bundles() throws error bundle = self.iota_api.get_bundles(tx) except BadApiResponse: bundle = None if bundle: bundles.append(bundle) return bundles def get_messages_from_bundles(self, bundles: List) -> Dict: """ Loop through list of bundles and get string per bundle # requres IRI 1.6+ (or it seems so) """ output_msgs = {} for bundle in bundles: tx_list = bundle['bundles'][0].as_json_compatible() msg = '' for tx in tx_list: # if its a bundle with iotas, just get text from first tx in bundle, the rest are signatures if tx['current_index'] == 0 and tx['value'] > 0: msg = tx['signature_message_fragment'].as_string() break # if its a bundle without iota value, then consequently get all message fields and join strings if tx['value'] == 0: msg = msg + tx['signature_message_fragment'].as_string() bundle_hash = tx_list[0]['bundle_hash'].__str__() addr = tx_list[0]['address'].__str__() timestamp = tx_list[0]['timestamp'] value = tx_list[0]['value'] output_msgs[bundle_hash] = { 'msg': msg, 'address': addr, 'timestamp': timestamp, 'value': value } return output_msgs def get_all_msg_from_addr_by_bundle(self, address: Address) -> Dict: ''' Get dict of all msg with timestamps from address by bundle hash as key # requres IRI 1.6+ (or it seems so) ''' bundles = self.get_bundles_from_addr(address) hashes_and_msgs = self.get_messages_from_bundles(bundles) return hashes_and_msgs
if __name__ == '__main__': parse_cli_arg() api = Iota(f'{URL}', testnet=TESTNET) txn_array = [] tag = gen_rand_trytes(27) address = [] message = [] for i in range(sent_transaction_number): address.append(gen_rand_trytes(81)) message.append(TryteString.from_unicode(f'{payload}, number: {i}')) tx_elt = ProposedTransaction(address=Address(address[i]), tag=tag, message=message[i], value=0) txn_array.append(api.send_transfer(transfers=[tx_elt])) curr_hash = txn_array[i]['bundle'].tail_transaction.hash logging.info( f'hash: {curr_hash}, address: {address[i]}, tag: {tag}, message: {message[i]}' ) # Get raw transaction trytes txn_trytes = [] txn_hashes = [] txn_tags = [] for i in range(sent_transaction_number): txn_trytes.append( txn_array[i]['bundle'].tail_transaction.as_tryte_string()) txn_hashes.append(txn_array[i]['bundle'].tail_transaction.hash) txn_tags.append(txn_array[i]['bundle'].tail_transaction.tag)
class IotaCache(object): def __init__(self, uri=None, seed=None): if not uri: self.uri = "http://localhost:14700" else: self.uri = uri if not seed: self.seed = 'EBZYNR9YVFIOAZUPQOLRZXPPPIKRCJ9EJKVCXMYVLMNOCCOPYPJKCWUZNLJZZZZWTMVQUXZFYLVLZXJ9Q' else: self.seed = seed self.api = Iota(self.uri, self.seed) def cache_txn_in_tangle(self, ipfs_addr, tag): api_response = self.api.get_new_addresses() addy = api_response['addresses'][0] address = binary_type(addy).decode('ascii') result = self.api.send_transfer( depth=3, transfers=[ ProposedTransaction( address=Address(address), value=0, tag=Tag(tag), message=TryteString.from_string(ipfs_addr), ), ], ) return result def get_approved_txns(self, tag): ret = [] transactions = self.api.find_transactions(None, None, [tag], None) if len(transactions['hashes']) == 0: return ret tips = self.api.get_tips() states = self.api.get_inclusion_states(transactions['hashes'], tips['hashes']) i = 0 for txn in transactions['hashes']: if states['states'][i] is True: ret.append(txn) return ret def get_non_consumed_txns(self, tag): txn_hashes_all = self.get_approved_txns(tag) txn_trytes_all = self.api.get_trytes(txn_hashes_all) txn_hashes_consumed = self.api.find_transactions( None, None, [tag + b"CONSUMED"], None) txn_trytes_consumed = self.api.get_trytes( txn_hashes_consumed['hashes']) consumedSet = [] ret = [] for txnTrytes in txn_trytes_consumed['trytes']: txn = Transaction.from_tryte_string(txnTrytes) consumedSet.append(txn.signature_message_fragment) for txnTrytes in txn_trytes_all['trytes']: txn = Transaction.from_tryte_string(txnTrytes) if txn.signature_message_fragment not in consumedSet: msgTryte = txn.signature_message_fragment.decode() ret.append(msgTryte) return ret def set_txn_as_synced(self, ipfs_addr, tag): result = self.cache_txn_in_tangle(ipfs_addr, tag + b"CONSUMED") return result
from iota import Iota, TryteString, Address, Tag, ProposedTransaction from pprint import pprint api = Iota('https://nodes.devnet.iota.org:443', testnet=True) message = TryteString.from_unicode('Hello world') adress = "ZLGVEQ9JUZZWCZXLWVNTHBDX9G9KZTJP9PREEIIFHY9SIQKYBVAHIMLHXPQVE9IXFDDXNHQINXJDRPFDX" tag = Tag(b'MY9FIRST9TAG') tx = ProposedTransaction(address=Address(adress), message=message, value=0) result = api.send_transfer([tx]) pprint('Check your transaction on the Tangle!') pprint('https://utils.iota.org/transaction/%s/devnet' % result['bundle'][0].hash) #ZLGVEQ9JUZZWCZXLWVNTHBDX9G9KZTJP9PREEIIFHY9SIQKYBVAHIMLHXPQVE9IXFDDXNHQINXJDRPFDX
from iota import ProposedTransaction from iota import Address from iota import Tag from iota import TryteString from iota.crypto.types import Seed node1 = 'https://nodes.comnet.thetangle.org:443' node2 = 'http://localhost:14265' seed1 = 'QVZCNIFLUY9GXPGKLY9VTFPFS9PLTFAUQDOHNLVRYJONGAX9TPDXDEJ9OXFR9RRKGFUJNXOJUAATRKNTX' seed2 = 'TSGVUYISRDCWWOWTIQKPTEUELXKFPCSITBJDCYVLN9LSUYGLWGRGDRJX9SEWIOPXKFUEOXYAXUPPCQFYX' print('Seed 1 is:', seed1) print('Seed 2 is:', seed2, '\n') address1 = 'QVZCNIFLUY9GXPGKLY9VTFPFS9PLTFAUQDOHNLVRYJONGAX9TPDXDEJ9OXFR9RRKGFUJNXOJUAATRKNTX' address2 = 'TSGVUYISRDCWWOWTIQKPTEUELXKFPCSITBJDCYVLN9LSUYGLWGRGDRJX9SEWIOPXKFUEOXYAXUPPCQFYX' print('Address 1 is:', address1) print('Address 2 is:', address2, '\n') api = Iota(node2, seed1) security_level = 2 balance = api.get_account_data() print('The balance of seed1 is: ', balance['balance']) tx = ProposedTransaction(address=Address(address2), value=500) result = api.send_transfer(transfers=[tx], min_weight_magnitude=10) print('Bundle: ') print(result['bundle'].hash)
h = blake2b(digest_size=16) h_pw = h.update(bytes(secret_key.encode('utf-8'))) hh = h.hexdigest() pw_string = str(hh).encode('utf-8') b64_pw = base64.b64encode(pw_string) ## Encrypt the Message data = {'message': Message} msg = json.dumps(data) key = b64_pw f = Fernet(key) token = f.encrypt(bytes(msg.encode('utf-8'))) msg_data = token.decode('ascii') ## Create a Bundle pt = ProposedTransaction(address=root_address, message=TryteString.from_unicode(msg_data), tag=TAG, value=0) ## Send the Transaction FinalBundle = api.send_transfer(depth=3, transfers=[pt], min_weight_magnitude=14)['bundle'] print(new_address) root_address = new_address except KeyboardInterrupt: print("Cleanup")
def doTransaction(self, message): api = Iota(self.api, testnet = True) msg = TryteString.from_unicode(message) tx = ProposedTransaction(address = Address(self.address),message = msg,value = 0) result = api.send_transfer(transfers = [tx]) return(result['bundle'].tail_transaction.hash)
class TangleConnector: def __init__(self, url='https://nutzdoch.einfachiota.de', seed="TESTSEED9"): self.iri_url = url self.iota_api = Iota(url, seed) def get_node(self) -> dict: """ Get IRI node info """ try: res = self.iota_api.get_node_info() except Exception as e: logging.warning("Failed to IRI node info for " + self.iri_url, e) res = None return res def get_tips(self) -> dict: """ Get all unreferenced transactions """ try: res = self.iota_api.get_tips() except Exception as e: logging.warning("Failed to get tips", e) res = None return res def get_hashes_from_addr(self, address: Address) -> List[TransactionHash]: """ Get all tx from address """ try: response = self.iota_api.find_transactions(addresses=[address]) hashes = response['hashes'] except Exception as e: logging.warning( "Failed to get all tx from address " + address.__str__(), e) hashes = None return hashes def get_trytes_from_hashes( self, hashes: List[TransactionHash]) -> List[TryteString]: """ Get tryte signature fragments from hashes """ try: response = self.iota_api.get_trytes(hashes) if response['trytes']: trytes = [tryte[0:2187] for tryte in response['trytes']] except Exception: #logging.warning("Failed to get all signature fragments") trytes = None return trytes def get_all_trytes_from_address( self, address: Address) -> Dict[TransactionHash, TryteString]: """ Get all trytes from address """ hashes = self.get_hashes_from_addr(address) trytes = self.get_trytes_from_hashes(hashes) if hashes and trytes: result = dict(zip(hashes, trytes)) else: result = None return result @staticmethod def get_json_from_tryte(tryte: TryteString) -> dict: try: str_from_tryte = tryte.as_string() dict_from_tryte = json.loads(str_from_tryte) except Exception as e: logging.error("Failed to convet trytes to JSON", e) dict_from_tryte = None return dict_from_tryte def send_msg_to_addr(self, address: Address, msg: str, tag: str) -> dict: """ Sends msg on Tangle to address with a tag """ try: response = self.iota_api.send_transfer( depth=5, transfers=[ ProposedTransaction(address=address, value=0, tag=Tag(tag), message=TryteString.from_string(msg)) ]) except Exception as e: logging.warning( "Message '" + msg + "' has failed to be stored in " + address.__str__(), e) response = None return response
# check balance of account balance = api.get_account_data() print(balance) #addresses = [] #addresses.append('SVCSKJPIIAOOSAAYMS9HKQVSIRVCKGOFNVQRTEXJNBFMCYFDIEWWYXBWZQDSKNJCVXCQGS9GUJLBHEAVBNS9UNPGFB') #balances = api.get_balances(addresses, None) #print(balances) # address for output transaction address = 'OCARSUKVZEZJUKSQU9RIKLANCKHDGCZGELJUUISZTAWQAUXSHHD9RJTKKM9ZMDNDZYFKEBKHEXHBPFAED' tx = ProposedTransaction(address=Address(address), value=10, message=TryteString.from_unicode(testdata)) result = api.send_transfer(transfers=[tx]) print('Bundle: ') print(result['bundle']) ''' #//////////////////////////////////////////////// #// Generate an unspent address #//////////////////////////////////////////////// from iota import Iota # The seed that will be used to generate an address seed = 'CVBCQHX9MUZZBZAZGOO9GYHWYBEZRMTWNXKBQHNSFETKUPHKHRGUYWLTSGXYAQEVLNI9XTQPTZAGOIUZH' # Connect to a node api = Iota('https://nodes.devnet.iota.org:443', seed, testnet = True)
def detct(): # for i in range(101): if GPIO.input(M_pin): motion = 'Someone is closing' #print ("Someone is closing!") # buzzer(M_pin) else: GPIO.output(B_pin, GPIO.HIGH) motion = 'Nobody Here' #print ("Nobody!") # time.sleep(2) t, h = dt11() s = smoke() f = flame() #data = 'Temp: ' + str(t) + '\xb0 | Humi: ' + str(h)+'% | Gas: ' + s+' | Flame: '+ f +' | Motion: ' + motion data = 'Temp: ' + str(t) + ' | Humi: ' + str(h) + ' | Gas: ' + \ s + ' | Flame: ' + f + ' | Motion: ' + motion #data = 'abcd' api = Iota('https://nodes.devnet.iota.org:443', testnet=True) #address = Address.random(81) address = Address( 'YEQFOMPOTSQXIDGVULITXSXHQOSRLJIUZB9LKTXRHUM9IHYLWYXZTBMLBZRATRFPUVRVRMSYZPDRMWNMQCTGMTRGSZ' ) ###### ###### my_data = TryteString.from_unicode(data) # Define a zero-value transaction object # that sends the message to the address tx = ProposedTransaction(address=address, message=my_data, value=0) print('Attaching to IOTA') result = api.send_transfer(transfers=[tx]) txn_hash = result['bundle'].tail_transaction.hash print('Attached') print('Transaction Hash:', txn_hash) # time.sleep(.5) print('Retriving from IOTA') bundle = api.get_bundles(txn_hash) message = bundle['bundles'][0].tail_transaction.signature_message_fragment output = message.decode() print('Message:', output) print('https://explorer.iota.org/devnet/address/' + str(address)) exp = output.split(' ') if s == 'Gas Leakage' or f == 'Fire! Fire!!' or motion == 'Someone is closing': buzzer(True)
# read file and send each line to the tangle import json from iota import Address, Iota, ProposedTransaction, TryteString with open("tangle/config/address_dump.conf") as in_file: ADDRESS = in_file.read().rstrip("\n").encode() api = Iota("https://durian.iotasalad.org:14265") receiver = Address(ADDRESS) with open("pitangle/current_measurements.csv") as f: lis = [line.rstrip("\n\r").split(",") for line in f] # create a list of lists for i, x in enumerate(lis): (idx, humidity, ts, temp) = x # print the list items print(idx) measurment = { "humidity": humidity, "temperature": temp, "measuredAt": ts } message = TryteString.from_string(json.dumps(measurment)) tx = ProposedTransaction(address=receiver, value=0, message=message) api.send_transfer(depth=1, transfers=[tx])
class Wallet: """docstring for Wallet""" def __init__(self, uri: str, seed: Optional[str] = None) -> None: self._iota_api = Iota(uri, seed) self._account: _Account @property def account(self) -> _Account: try: return self._account except AttributeError: # We get an attibute error if we check this property before ever # calling refresh_account. self.refresh_account() return self._account @property def addresses(self) -> List[Address]: return self.account.addresses @property def balance(self) -> int: return self.account.balance @property def bundles(self) -> Dict[str, Iterable[Bundle]]: return { 'confirmed': self.account.confirmed_bundles, 'unconfirmed': self.account.unconfirmed_bundles, 'duplicate': self.account.duplicate_bundles, } def _is_above_max_depth(self, transaction: Transaction) -> bool: current_millis = time.time() * 1000 max_age = 11 * 60 * 1000 # 11 minutes diff = current_millis - cast(float, transaction.attachment_timestamp) return (0 < diff < max_age) def _is_promotable(self, bundle: Bundle) -> bool: return (self._is_above_max_depth(bundle.tail_transaction) and self._iota_api.helpers.is_promotable( bundle.tail_transaction.hash)) def _promote(self, bundle: Bundle) -> Bundle: tail_hash = bundle.tail_transaction.hash response = self._iota_api.get_latest_inclusion([tail_hash]) if response['states'][tail_hash]: raise BundleAlreadyPromoted() response = self._iota_api.promote_transaction(transaction=tail_hash, depth=DEPTH) return response['bundle'] def _reattach(self, bundle: Bundle) -> Bundle: response = self._iota_api.replay_bundle( bundle.tail_transaction.hash, DEPTH, ) return Bundle.from_tryte_strings(response['trytes']) def create_new_address(self) -> Address: response = self._iota_api.get_new_addresses(count=None) address = response['addresses'][0] # Attach the address self._iota_api.send_transfer( depth=DEPTH, transfers=[ProposedTransaction(address, value=0)], ) return address def refresh_account(self) -> None: response = self._iota_api.get_account_data(inclusion_states=True) addresses = response['addresses'] balance = response['balance'] bundles = response['bundles'] self._account = _Account(addresses, balance, bundles) def retry_unconfirmed_bundles(self, *bundles: Bundle) -> None: if len(bundles) == 0: bundles = tuple(self.bundles['unconfirmed']) for bundle in bundles: print(f'Retrying bundle: {bundle.hash}') if not self._is_promotable(bundle): bundle = self._reattach(bundle) while True: time.sleep(2) if self._is_promotable(bundle): break for attempt in range(5): try: promote_bundle = self._promote(bundle) except BundleAlreadyPromoted: break else: print( f'Promotion attempt ({attempt}): Bundle {promote_bundle.hash}' ) def send(self, address: str, value: int) -> None: print(f'Sending {value} iota to {address}...') response = self._iota_api.send_transfer( depth=DEPTH, transfers=[ProposedTransaction(Address(address), value=value)]) bundle = response['bundle'] print(f'Iota sent! Bundle hash: {bundle.hash}')
class IotaClient(object): """Python IOTA client wrapper""" def __init__(self, seed, provider, depth=5, min_weight_magnitude=14): self._api = Iota(provider, seed) self._depth = depth self._min_weight_magnitude = min_weight_magnitude self.address = self._get_address() @staticmethod def _compose_transaction(address, msg, tag, val): txn = \ ProposedTransaction( address=Address(address), message=TryteString.from_unicode(msg), tag=Tag(tag), value=val ) return txn def _get_address(self): address = self._api.get_new_addresses(0, 1)['addresses'][0] return str(address) def get_transactions_from_address(self, address): """ Gets transaction object from address sorted on timestamp (from latest to earliest). :param address: Address to fetch transaction from """ transactions = self._api.find_transactions(addresses=[address]) transaction_hashes = transactions['hashes'] if not transaction_hashes: raise ValueError("No transactions on address") trytes = self._api.get_trytes(transaction_hashes)['trytes'] trytes_and_hashes = list(zip(trytes, transaction_hashes)) transactions = list( map(lambda pair: Transaction.from_tryte_string(pair[0], pair[1]), trytes_and_hashes)) sorted_transactions = sorted(transactions, key=lambda t: t.timestamp, reverse=True) return sorted_transactions def get_messages_from_address(self, address): """ Gets messages (sorted by timestamp). Returns a dict with 'json_message' and 'timestamp keys' :param address: Address to fetch messages from """ sorted_transactions = self.get_transactions_from_address(address) messages = list( map( lambda t: { 'json_message': json.loads(Fragment.as_string(t.signature_message_fragment) ), 'timestamp': t.timestamp }, sorted_transactions)) return messages @staticmethod def get_message(transaction): message = transaction['signature_message_fragment'].decode() json_message = json.loads(message) return json_message def send_transaction(self, address, msg, tag, val): txn = self._compose_transaction(Address(address), msg, tag, val) mwm = self._min_weight_magnitude depth = self._depth self._api.send_transfer(depth, [txn], None, None, mwm)
address=Address( b'ADDRESS9GOES9HERE99999999999999999999999999999999999TESTVALUE9DONTUSEINPRODUCTION' ), # Amount of Iota you want to send value=1, # Optional Tag (27-trytes) tag=Tag(b'ROUTING9WRAPPER9WORKS'), # Message (2187-trytes) message=TryteString.from_string( 'I used iota.adapter.wrappers.RoutingWrapper.')) bundle.add_transaction(output) """ A ProposedBundle is a Bundle that is not yet attached to the Tangle. A ProposedTransaction is a Transaction that is not yet attached to the Tangle. """ print("Sending transfer...") response = API.send_transfer(3, bundle) print('Bundle Hash: ' + response['bundle'].hash.as_json_compatible()) """ The API.send_transfer function will take care of signing and inserting the input transaction and remainder transaction. I'm printing the bundle hash which can be used for reattaching if necessary. """