class TransactionBuilder(object): def __init__(self, admin_account, admin_private_key, port): self.admin_account = admin_account self.admin_private_key = admin_private_key self.port = port self.iroha = Iroha(self.admin_account) self.net = IrohaGrpc(self.port) def __send_transaction_and_print_status(self, transaction): hex_hash = binascii.hexlify(IrohaCrypto.hash(transaction)) print('Transaction hash = {}, creator = {}'.format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) for status in self.net.tx_status_stream(transaction): print(status) for status in self.net.tx_status_stream(transaction): if status == ('COMMITTED', 5, 0): return "COMMITTED" def create_client(self, client_name): user_private_key = IrohaCrypto.private_key() user_public_key = IrohaCrypto.derive_public_key(user_private_key) commands = [ self.iroha.command('CreateAccount', account_name=client_name, domain_id="test", public_key=user_public_key), ] transaction = self.iroha.transaction(commands) IrohaCrypto.sign_transaction(transaction, self.admin_private_key) self.__send_transaction_and_print_status(transaction) tx = self.iroha.transaction([ self.iroha.command('GrantPermission', account_id='admin@test', permission=primitive_pb2.can_set_my_account_detail) ]) IrohaCrypto.sign_transaction(tx, user_private_key) if self.__send_transaction_and_print_status(transaction) == "COMMITTED": return "Your key: " + user_private_key, 201 else: return 'Internal Error', 500 def add_coin_to_client(self, number, private_key): tx = self.iroha.transaction([ self.iroha.command('AddAssetQuantity', asset_id='coin#test', amount=str(number) + '.00') ]) IrohaCrypto.sign_transaction(tx, private_key) if self.__send_transaction_and_print_status(tx) == "COMMITTED": return "Added " + str(number), 201 else: return 'Internal Error', 500
def send_transaction_print_status_and_return_result(iroha_host_addr, iroha_port, transaction): net = IrohaGrpc(f"{iroha_host_addr}:{iroha_port}", timeout=60) hex_hash = binascii.hexlify(ic.hash(transaction)) print("Transaction hash = {}, \n creator = {}".format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) net.send_tx(transaction) tx_result = [] for status in net.tx_status_stream(transaction): tx_result.append(status) print(status) tx_result.append(hex_hash) return tx_result
class TestIroha: def __init__(self, user, port="50051", host="localhost"): self.IROHA_HOST_ADDR = os.getenv('IROHA_HOST_ADDR', '192.168.88.202') #andrey # self.IROHA_HOST_ADDR = os.getenv('IROHA_HOST_ADDR', '192.168.88.62') #sergey # self.IROHA_HOST_ADDR = os.getenv('IROHA_HOST_ADDR', host) self.IROHA_PORT = os.getenv('IROHA_PORT', port) self.admin_private_key = 'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70' self.iroha = Iroha(user.Name) self.net = IrohaGrpc( '{}:{}'.format(self.IROHA_HOST_ADDR, self.IROHA_PORT), 1000) def SendTx(self, transaction): hex_hash = binascii.hexlify(IrohaCrypto.hash(transaction)) print('Transaction hash = {}, creator = {}'.format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) exit_status = list() # for status in self.net.tx_status_stream(transaction): # print(status) return exit_status def SignTx(self, from_user, to_user): tx = self.iroha.transaction([ self.iroha.command('TransferAsset', src_account_id=from_user.Name, dest_account_id=to_user.Name, asset_id='coin#domain', description='sending', amount='0.01') ]) IrohaCrypto.sign_transaction(tx, from_user.PrivKey) transactions.append(tx) def GetTxsStatus(self): txsChecked = 0 print("Starting checking") for transaction in transactions: txsChecked += 1 for status in self.net.tx_status_stream(transaction): txsStatus.append(status) if txsChecked % 10 == 0: print(txsChecked, " transaction checked")
def send_transaction_return_result(iroha_host_addr, iroha_port, transaction): net = IrohaGrpc(f"{iroha_host_addr}:{iroha_port}", timeout=60) hex_hash = binascii.hexlify(ic.hash(transaction)) tx_result = {} try: net.send_tx(transaction) tx_status = [] for status in net.tx_status_stream(transaction): tx_status.append(status) tx_result = { "tx_hash": hex_hash, "tx_statuses": tx_status, "tx_result": tx_status[-1][0], } except Exception as error: print(error) tx_result = { "tx_hash": hex_hash, "tx_statuses": [], "tx_result": "REJECTED", } return tx_result
class IrohaClient(): def __init__(self, creator_account, iroha_host_addr, iroha_port): self.creator_account = creator_account self.iroha = Iroha(creator_account) self.permissions = iroha_primitive #change to local encrypted storage self.private_key_file = creator_account + '.priv' self.user_private_key = open(self.private_key_file, 'rb+').read() self.net = IrohaGrpc(f'{iroha_host_addr}:{iroha_port}', timeout=30) def send_transaction_and_print_status(self, transaction): hex_hash = binascii.hexlify(ic.hash(transaction)) print('Transaction hash = {}, creator = {}'.format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) for status in self.net.tx_status_stream(transaction): print(status) return hex_hash def send_batch_and_print_status(self, transactions): self.net.send_txs(transactions) for tx in transactions: hex_hash = binascii.hexlify(ic.hash(tx)) print('\t' + '-' * 20) print('Transaction hash = {}, creator = {}'.format( hex_hash, tx.payload.reduced_payload.creator_account_id)) for status in self.net.tx_status_stream(tx): print(status) def send_batch_and_return_status(self, *transactions): self.net.send_txs(transactions) for tx in transactions: hex_hash = binascii.hexlify(ic.hash(tx)) print('\t' + '-' * 20) print('Transaction hash = {}, creator = {}'.format( hex_hash, tx.payload.reduced_payload.creator_account_id)) tx_result = [] for status in self.net.tx_status_stream(transactions): tx_result.append(status) return tx_result def send_transaction_print_status_and_return_result(self, transaction): hex_hash = binascii.hexlify(ic.hash(transaction)) print('Transaction hash = {}, \n creator = {}'.format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) tx_result = [] for status in self.net.tx_status_stream(transaction): tx_result.append(status) print(status) tx_result.append(hex_hash) return tx_result def sign_and_submit_admin_tx(self, transction): new_tx = self.iroha.transaction([]) tx = ParseDict(transction, new_tx) print(tx) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def check_pending_txs(self): query = self.iroha.query('GetPendingTransactions') ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToJson(response) return data def get_tx_history(self, account_id, total): """ List total number of tx details for specified user@domain """ query = self.iroha.query('GetTransactions', account_id=account_id, page_size=total) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data #Accounts def get_account_assets(self, account_id): query = self.iroha.query('GetAccountAssets', account_id=account_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToJson(response) return data def get_asset_info(self, account_id, asset_id): query = self.iroha.query('GetAssetInfo', asset_id=asset_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToJson(response) return data def get_acc_tx_history(self, account_id, total): """ List total number of tx details for specified user@domain """ query = self.iroha.query('GetAccountTransactions', account_id=account_id, page_size=total) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_asset_tx_history(self, account_id, total): """ List Asset tx details for specified user@domain """ query = self.iroha.query('GetAccountAssetTransactions', account_id=account_id, page_size=total) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_roles(self): """ List Roles """ query = self.iroha.query('GetRoles') ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_role_permissions(self, role_id): """ List Role Permissions for specified Role """ query = self.iroha.query('GetRolePermissions', role_id=role_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def stream_blocks(self): """ Start incomming stream for new blocks """ #add height query = self.iroha.blocks_query() ic.sign_query(query, self.user_private_key) for block in self.net.send_blocks_stream_query(query): pprint('The next block arrived: {}'.format(MessageToDict(block)), indent=1) def get_signatories(self, account_id): """ List signatories by public key for specified user@domain """ query = self.iroha.query('GetSignatories', account_id=account_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_account(self, account_id): """ List Account user@domain """ query = self.iroha.query('GetAccount', account_id=account_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_account_details(self, account_id, writer=None, key=None): """ List Account details for user@domain """ query = self.iroha.query('GetAccountDetail', account_id=account_id, writer=writer, key=key) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = json.loads(response.account_detail_response.detail) return data def create_new_account(self, account_name, domain, public_key): """ register new user """ tx = self.iroha.transaction([ self.iroha.command('CreateAccount', account_name=account_name, domain_id=domain, public_key=public_key) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def set_account_detail(self, account_id, key, value): tx = self.iroha.transaction([ self.iroha.command('SetAccountDetail', account_id=account_id, key=key, value=value) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def create_domain(self, domain_id, default_role): """ register non existing/new domain on network """ tx = self.iroha.transaction([ self.iroha.command('CreateDomain', domain_id=domain_id, default_role='user') ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_account_write_permission(self, account_id): """ grand permission write permission for AccountDetails """ tx = self.iroha.transaction([ self.iroha.command( 'GrantPermission', account_id=account_id, permission=self.permissions.can_set_my_account_detail) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_account_read_permission(self, account_id): tx = self.iroha.transaction([ self.iroha.command( 'GrantPermission', account_id=account_id, permission=self.permissions.can_get_my_acc_detail) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) #add signatory #remove signatory #find peer and remove peer has been added in v1.1 def add_peer(self, ip_address, peer_key): peer = self.permissions.Peer() peer.address = ip_address peer.peer_key = peer_key tx = self.iroha.transaction([self.iroha.command('AddPeer', peer=peer)]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_asset_tx_history_permission(self, account_id): tx = self.iroha.transaction([ self.iroha.command('GrantPermission', account_id=account_id, permission=can_get_my_acc_ast_txs) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_account_tx_history_permission(self, account_id): tx = self.iroha.transaction([ self.iroha.command('GrantPermission', account_id=account_id, permission=can_get_my_acc_txs) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def create_new_asset(self, asset, domain, precision): tx = self.iroha.transaction([ self.iroha.command('CreateAsset', asset_name=asset, domain_id=domain, precision=precision) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def transfer_asset(self, account_id, recipient, asset_id, description, qty): tx = self.iroha.transaction([ self.iroha.command('TransferAsset', src_account_id=account_id, dest_account_id=recipient, asset_id=asset_id, description=description, amount=qty) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def add_asset_qty(self, asset_id, qty): """ Add asset supply """ tx = self.iroha.transaction([ self.iroha.command('AddAssetQuantity', asset_id=asset_id, amount=qty) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def subtract_asset_qty(self, asset_id, qty): """ Subtract asset supply """ tx = self.iroha.transaction([ self.iroha.command('SubtractAssetQuantity', asset_id=asset_id, amount=qty) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx)
class IrohaBlockchain: IROHA_HOST_ADDR = env("IROHA_HOST_ADDR", "127.0.0.1") IROHA_PORT = env("IROHA_PORT", "50051") def __init__(self, creator_account_details): self.creator_account_details = creator_account_details self.iroha = Iroha( f"{self.creator_account_details.gov_id}@afyamkononi") self.net = IrohaGrpc(f"{self.IROHA_HOST_ADDR}:{self.IROHA_PORT}") def send_transaction_and_return_status(self, transaction): """ Sends a transaction to the blockchain """ self.net.send_tx(transaction) stati = [] for status in self.net.tx_status_stream(transaction): stati.append(status) return stati def create_account(self, user): """ Creates a user account """ tx = self.iroha.transaction([ self.iroha.command( "CreateAccount", account_name=user.gov_id, domain_id="afyamkononi", public_key=user.public_key, ) ]) IrohaCrypto.sign_transaction(tx, self.creator_account_details.private_key) return self.send_transaction_and_return_status(tx) def append_role(self, user): """ Appends a role to a user """ tx = self.iroha.transaction( [ self.iroha.command( "AppendRole", account_id=f"{user.gov_id}@afyamkononi", role_name=user.type, ) ], creator_account= f"{self.creator_account_details.gov_id}@afyamkononi", ) IrohaCrypto.sign_transaction(tx, self.creator_account_details.private_key) return self.send_transaction_and_return_status(tx) def set_account_details(self, user): """ Set account details """ tx = self.iroha.transaction([ self.iroha.command( "SetAccountDetail", account_id=f"{user.gov_id}@afyamkononi", key="gov_id", value=f"{user.gov_id}", ), self.iroha.command( "SetAccountDetail", account_id=f"{user.gov_id}@afyamkononi", key="name", value=f"{user.name}", ), self.iroha.command( "SetAccountDetail", account_id=f"{user.gov_id}@afyamkononi", key="email", value=f"{user.email}", ), self.iroha.command( "SetAccountDetail", account_id=f"{user.gov_id}@afyamkononi", key="phone_number", value=f"{user.phone_number}", ), ]) IrohaCrypto.sign_transaction(tx, self.creator_account_details.private_key) return self.send_transaction_and_return_status(tx) def get_account_details(self, gov_id, data_key=None): """ Get all the kv-storage entries for a user """ if data_key == None: query = self.iroha.query("GetAccountDetail", account_id=f"{gov_id}@afyamkononi") else: query = self.iroha.query("GetAccountDetail", account_id=f"{gov_id}@afyamkononi", key=data_key) IrohaCrypto.sign_query(query, self.creator_account_details.private_key) response = self.net.send_query(query) return response.account_detail_response def grant_set_account_detail_perms(self, user): """ Make creator account able to set detail to account """ tx = self.iroha.transaction( [ self.iroha.command( "GrantPermission", account_id= f"{self.creator_account_details.gov_id}@afyamkononi", permission=can_set_my_account_detail, ) ], creator_account=f"{user.gov_id}@afyamkononi", ) IrohaCrypto.sign_transaction(tx, user.private_key) return self.send_transaction_and_return_status(tx) def revoke_set_account_detail_perms(self, user): """ Revoke creator account able to set detail to account """ tx = self.iroha.transaction( [ self.iroha.command( "RevokePermission", account_id= f"{self.creator_account_details.gov_id}@afyamkononi", permission=can_set_my_account_detail, ) ], creator_account=f"{user.gov_id}@afyamkononi", ) IrohaCrypto.sign_transaction(tx, user.private_key) return self.send_transaction_and_return_status(tx) def set_patient_record(self, patient, history_update): """ Set patient records """ history_update = (json.dumps(history_update)).replace('"', '\\"') tx = self.iroha.transaction([ self.iroha.command( "SetAccountDetail", account_id=f"{patient.gov_id}@afyamkononi", key="gov_id", value=f"{patient.gov_id}", ), self.iroha.command( "SetAccountDetail", account_id=f"{patient.gov_id}@afyamkononi", key="name", value=f"{patient.name}", ), self.iroha.command( "SetAccountDetail", account_id=f"{patient.gov_id}@afyamkononi", key="email", value=f"{patient.email}", ), self.iroha.command( "SetAccountDetail", account_id=f"{patient.gov_id}@afyamkononi", key="phone_number", value=f"{patient.phone_number}", ), self.iroha.command( "SetAccountDetail", account_id=f"{patient.gov_id}@afyamkononi", key="medical_data", value=history_update, ) ]) IrohaCrypto.sign_transaction(tx, self.creator_account_details.private_key) return self.send_transaction_and_return_status(tx) def get_all_account_transactions(self, gov_id): query = self.iroha.query("GetAccountTransactions", account_id=f"{gov_id}@afyamkononi", page_size=30) IrohaCrypto.sign_query(query, self.creator_account_details.private_key) return self.net.send_query(query) def get_all_roles(self): query = self.iroha.query( "GetRoles", creator_account= f"{self.creator_account_details.gov_id}@afyamkononi", ) query = IrohaCrypto.sign_query( query, self.creator_account_details.private_key) return self.net.send_query(query) def get_role_permissions(self, role): query = self.iroha.query("GetRolePermissions", role_id=role) query = IrohaCrypto.sign_query( query, self.creator_account_details.private_key) return self.net.send_query(query) def grant_edit_permissions(self, subject): tx = self.iroha.transaction( [ self.iroha.command( "GrantPermission", account_id=f"{subject.gov_id}@afyamkononi", permission=can_set_my_account_detail, ) ], creator_account= f"{self.creator_account_details.gov_id}@afyamkononi", ) IrohaCrypto.sign_transaction(tx, self.creator_account_details.private_key) return self.send_transaction_and_return_status(tx) def revoke_edit_permissions(self, subject): tx = self.iroha.transaction( [ self.iroha.command( "RevokePermission", account_id=f"{subject.gov_id}@afyamkononi", permission=can_set_my_account_detail, ) ], creator_account= f"{self.creator_account_details.gov_id}@afyamkononi", ) IrohaCrypto.sign_transaction(tx, self.creator_account_details.private_key) return self.send_transaction_and_return_status(tx)
class IrohaClient: def __init__(self, creator_account, iroha_host): self.creator_account = creator_account self.iroha = Iroha(creator_account) self.permissions = iroha_primitive self.user_private_key = os.getenv("UBAIN_API_SECRET") self.net = IrohaGrpc(f"{iroha_host}", timeout=60) def send_transaction_and_print_status(self, transaction): hex_hash = binascii.hexlify(ic.hash(transaction)) print("Transaction hash = {}, creator = {}".format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) for status in self.net.tx_status_stream(transaction): print(status) return hex_hash def send_batch_and_print_status(self, transactions): self.net.send_txs(transactions) for tx in transactions: hex_hash = binascii.hexlify(ic.hash(tx)) print("\t" + "-" * 20) print("Transaction hash = {}, creator = {}".format( hex_hash, tx.payload.reduced_payload.creator_account_id)) for status in self.net.tx_status_stream(tx): print(status) def send_batch_and_return_status(self, *transactions): self.net.send_txs(transactions) for tx in transactions: hex_hash = binascii.hexlify(ic.hash(tx)) print("\t" + "-" * 20) print("Transaction hash = {}, creator = {}".format( hex_hash, tx.payload.reduced_payload.creator_account_id)) tx_result = [] for status in self.net.tx_status_stream(transactions): tx_result.append(status) return tx_result def send_transaction_print_status_and_return_result(self, transaction): hex_hash = binascii.hexlify(ic.hash(transaction)) print("Transaction hash = {}, \n creator = {}".format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) tx_result = [] for status in self.net.tx_status_stream(transaction): tx_result.append(status) print(status) tx_result.append(hex_hash) return tx_result ## Important Function def sign_and_submit_tx(self, transaction): new_tx = self.iroha.transaction([]) tx = ParseDict(transaction, new_tx) print(tx) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def check_pending_txs(self): query = self.iroha.query("GetPendingTransactions") ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToJson(response) return data def stream_blocks(self): """ Start incomming stream for new blocks """ # add height query = self.iroha.blocks_query() ic.sign_query(query, self.user_private_key) for block in self.net.send_blocks_stream_query(query): pprint("The next block arrived: {}".format(MessageToDict(block)), indent=1) def get_signatories(self, account_id): """ List signatories by public key for specified user@domain """ query = self.iroha.query("GetSignatories", account_id=account_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_account(self, account_id): """ List Account user@domain """ query = self.iroha.query("GetAccount", account_id=account_id) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = MessageToDict(response) return data def get_account_details(self, account_id, writer=None, key=None): """ List Account details for user@domain """ query = self.iroha.query("GetAccountDetail", account_id=account_id, writer=writer, key=key) ic.sign_query(query, self.user_private_key) response = self.net.send_query(query) data = json.loads(response.account_detail_response.detail) return data def create_new_account(self, account_name, domain, public_key): """ register new user """ tx = self.iroha.transaction([ self.iroha.command( "CreateAccount", account_name=account_name, domain_id=domain, public_key=public_key, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def set_account_detail(self, account_id, key, value): tx = self.iroha.transaction([ self.iroha.command("SetAccountDetail", account_id=account_id, key=key, value=value) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def create_domain(self, domain_id, default_role): """ register non existing/new domain on network """ tx = self.iroha.transaction([ self.iroha.command("CreateDomain", domain_id=domain_id, default_role="user") ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) ### Dev Batch Functions def init_test_balance_batch(self, account_id): # Add Dummy Asset Supply For Demo qty = "10.00000000" description = "Welcome To Ubuntu Exchange" currencies = ["BTC", "LTC", "ETH", "XLM", "XMR"] tx = self.iroha.transaction([ self.iroha.command("AddAssetQuantity", asset_id="btc#iroha", amount=qty), self.iroha.command("AddAssetQuantity", asset_id="ltc#iroha", amount=qty), self.iroha.command("AddAssetQuantity", asset_id="eth#iroha", amount=qty), self.iroha.command("AddAssetQuantity", asset_id="xlm#iroha", amount=qty), self.iroha.command("AddAssetQuantity", asset_id="xmr#iroha", amount=qty), self.iroha.command( "TransferAsset", description=description, src_account_id="admin@iroha", dest_account_id=account_id, asset_id="btc#iroha", amount=qty, ), self.iroha.command( "TransferAsset", description=description, src_account_id="admin@iroha", dest_account_id=account_id, asset_id="ltc#iroha", amount=qty, ), self.iroha.command( "TransferAsset", description=description, src_account_id="admin@iroha", dest_account_id=account_id, asset_id="eth#iroha", amount=qty, ), self.iroha.command( "TransferAsset", description=description, src_account_id="admin@iroha", dest_account_id=account_id, asset_id="xlm#iroha", amount=qty, ), self.iroha.command( "TransferAsset", description=description, src_account_id="admin@iroha", dest_account_id=account_id, asset_id="xmr#iroha", amount=qty, ), ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_account_write_permission(self, account_id): """ grand permission write permission for AccountDetails """ tx = self.iroha.transaction([ self.iroha.command( "GrantPermission", account_id=account_id, permission=self.permissions.can_set_my_account_detail, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_account_read_permission(self, account_id): tx = self.iroha.transaction([ self.iroha.command( "GrantPermission", account_id=account_id, permission=self.permissions.can_get_my_acc_detail, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def add_peer(self, ip_address, peer_key): peer = self.permissions.Peer() peer.address = ip_address peer.peer_key = peer_key tx = self.iroha.transaction([self.iroha.command("AddPeer", peer=peer)]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_asset_tx_history_permission(self, account_id): tx = self.iroha.transaction([ self.iroha.command( "GrantPermission", account_id=account_id, permission=self.permissions.can_get_my_acc_ast_txs, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def grant_account_tx_history_permission(self, account_id): tx = self.iroha.transaction([ self.iroha.command( "GrantPermission", account_id=account_id, permission=self.permissions.can_get_my_acc_txs, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def create_new_asset(self, asset, domain, precision): tx = self.iroha.transaction([ self.iroha.command( "CreateAsset", asset_name=asset, domain_id=domain, precision=precision, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def transfer_asset(self, account_id, recipient, asset_id, description, qty): tx = self.iroha.transaction([ self.iroha.command( "TransferAsset", src_account_id=account_id, dest_account_id=recipient, asset_id=asset_id, description=description, amount=qty, ) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def add_asset_qty(self, asset_id, qty): """ Add asset supply """ tx = self.iroha.transaction([ self.iroha.command("AddAssetQuantity", asset_id=asset_id, amount=qty) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx) def subtract_asset_qty(self, asset_id, qty): """ Subtract asset supply """ tx = self.iroha.transaction([ self.iroha.command("SubtractAssetQuantity", asset_id=asset_id, amount=qty) ]) ic.sign_transaction(tx, self.user_private_key) self.send_transaction_print_status_and_return_result(tx)
class IrohaClientAPI: """ Iroha Client API utilities Supports gRPC & HTTP JSON Transactions & Queries """ def __init__(self, ic, creator_account, private_key, iroha_host): self.ic = ic self.creator_account = creator_account self.iroha = Iroha(creator_account) self.permissions = iroha_primitive self.user_private_key = private_key self.net = IrohaGrpc(iroha_host, timeout=60) def send_transaction_return_result(self, transaction): hex_hash = binascii.hexlify(self.ic.hash(transaction)) tx_result = {} try: self.net.send_tx(transaction) tx_status = [] for status in self.net.tx_status_stream(transaction): tx_status.append(status) tx_result = { "tx_hash": hex_hash, "tx_statuses": tx_status, "tx_result": tx_status[-1][0], } except Exception as error: print(error) tx_result = { "tx_hash": hex_hash, "tx_statuses": [], "tx_result": "REJECTED", } return tx_result def send_query_print_status_and_return_result(iroha_host_addr, iroha_port, transaction): hex_hash = binascii.hexlify(ic.hash(transaction)) print(f"Transaction hash = {hex_hash}") net = IrohaGrpc(f"{iroha_host_addr}:{iroha_port}", timeout=60) response = net.send_query(transaction) data = MessageToJson(response) return data def submit_json_tx(self, account_id: str, transaction): iroha = Iroha(account_id) new_tx = iroha.transaction([]) iroha_host_addr = "127.0.0.1" iroha_port = "50051" try: transaction = ParseDict(transaction, new_tx) print(transaction) result = self.send_transaction_return_result( iroha_host_addr, iroha_port, transaction) return result except Exception as e: print(e) def submit_json_query(self, account_id, transaction): print("start iroha query") # iroha = Iroha(account_id) new_tx = queries_pb2.Query() print(f"new query {new_tx}") try: transaction = ParseDict(transaction, new_tx) print(transaction) return self.send_query_print_status_and_return_result( account_id, transaction) except Exception as e: print(e)
import os import sys from iroha import Iroha, IrohaCrypto, IrohaGrpc # Iroha torii url url = sys.argv[1] # Iroha admin account that will send the transaction admin_account = sys.argv[2] # Iroha admin account private key path admin_priv_path = sys.argv[3] # Iroha asset asset = sys.argv[4] # Amount to be added to the account amount = sys.argv[5] iroha = Iroha(admin_account) net = IrohaGrpc(url) admin_key = open(admin_priv_path, "r").read() tx = iroha.transaction( [iroha.command("AddAssetQuantity", asset_id=asset, amount=amount)]) IrohaCrypto.sign_transaction(tx, admin_key) net.send_tx(tx) for status in net.tx_status_stream(tx): print(status)
def create(acc_name, domain_name): """ This route creates a new private key, derives the public key and then sends it back to the requester in a json form. Parameters ---------- acc_name : str The name of the account to be created. Must be unique. domain_name : str The name of the domain where the account should be register. Returns ------- response : json A response containing the created keys. """ private_key = IrohaCrypto.private_key().decode('utf-8') public_key = IrohaCrypto.derive_public_key(private_key).decode('utf-8') iroha_network = IrohaGrpc(constants.iroha_network) iroha_client = constants.iroha_client # Defining the account creation transaction new_account_tx = iroha_client.transaction([ iroha_client.command( 'CreateAccount', account_name=acc_name, domain_id=domain_name, public_key=public_key ) ]) # Signing the transaction with the instrumentality private key IrohaCrypto.sign_transaction(new_account_tx, constants.private_key) # Sending the transaction to be validated by the peers iroha_network.send_tx(new_account_tx) encoder = json.encoder.JSONEncoder() response = {} for status in iroha_network.tx_status_stream(new_account_tx): if status[0] == "STATEFUL_VALIDATION_FAILED": response['status'] = 'error' # Checking which error we got # First error: Couldn't create account. Internal error. if status[2] == 1: response['msg'] = "Couldn't create account. Internal error." response['code'] = "500" return encoder.encode(response), 500 # Second error: No such permissions elif status[2] == 2: response['msg'] = "The node doesn't have permission to create accounts." response['code'] = "403" return encoder.encode(response), 403 # Third error: No such domain elif status[2] == 3: response['msg'] = "There is no such domain." response['code'] = "404" return encoder.encode(response), 404 # Fourth error: Account already exists elif status[2] == 4: response['msg'] = "Account with this name already exists." response['code'] = "403" return encoder.encode(response), 403 elif status[0] == "COMMITTED": response['status'] = "success" response['private_key'] = private_key response['public_key'] = public_key response['msg'] = "Transaction written in ledger." response['code'] = 200 return encoder.encode(response), 200
class TransactionBuilder(object): def __init__(self, admin_account, admin_private_key, port): self.admin_account = admin_account self.admin_private_key = admin_private_key self.port = port self.iroha = Iroha(self.admin_account) self.net = IrohaGrpc(self.port) def __send_transaction_and_print_status(self, transaction): hex_hash = binascii.hexlify(IrohaCrypto.hash(transaction)) print('Transaction hash = {}, creator = {}'.format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) for status in self.net.tx_status_stream(transaction): print(status) for status in self.net.tx_status_stream(transaction): if status == ('COMMITTED', 5, 0): return "COMMITTED" def create_company_domain(self, company_name): commands = [ self.iroha.command('CreateDomain', domain_id=company_name, default_role=agent_role), ] transaction = self.iroha.transaction(commands) IrohaCrypto.sign_transaction(transaction, self.admin_private_key) if self.__send_transaction_and_print_status( transaction) == "COMMITTED": return company_name, 201 else: return 'Internal Error', 500 def create_agent(self, company_name, agent_name): user_private_key = IrohaCrypto.private_key() user_public_key = IrohaCrypto.derive_public_key(user_private_key) commands = [ self.iroha.command('CreateAccount', account_name=agent_name, domain_id=company_name, public_key=user_public_key), self.iroha.command( 'GrantPermission', account_id=get_full_acc(agent_name, company_name), permission=primitive_pb2.can_set_my_account_detail), self.iroha.command('AddSignatory', account_id=self.admin_account, public_key=user_public_key) ] transaction = self.iroha.transaction(commands) IrohaCrypto.sign_transaction(transaction, self.admin_private_key) self.__send_transaction_and_print_status(transaction) if self.__send_transaction_and_print_status( transaction) == "COMMITTED": return "Your private key: " + str( user_private_key) + " Your public key: " + str( user_public_key), 201 else: return 'Internal Error', 500 def is_insurable_item(self, item, private_key): query = self.iroha.query('GetAccountDetail', account_id=self.admin_account, key=item["item_id"]) IrohaCrypto.sign_query(query, private_key) response = self.net.send_query(query) if "reason: NO_ACCOUNT_DETAIL" not in str(response.error_response): response_json = json.loads(response.account_detail_response.detail) data = json.loads( base64.urlsafe_b64decode(response_json["reg@common"][ item["item_id"]].encode()).decode()) date_string = data['insurance_expiration_date'] if is_expired(date_string): return True else: return False else: return True def is_claimable_item(self, item, private_key): query = self.iroha.query('GetAccountDetail', account_id=self.admin_account, key=item["item_id"]) IrohaCrypto.sign_query(query, private_key) response = self.net.send_query(query) if "reason: NO_ACCOUNT_DETAIL" not in str(response.error_response): response_json = json.loads(response.account_detail_response.detail) data = json.loads( base64.urlsafe_b64decode(response_json["reg@common"][ item["item_id"]].encode()).decode()) date_string = data['insurance_expiration_date'] if is_expired(date_string): return False else: return True else: return False # item is dictionary. item_id; insurance_expiration_date; def put_item(self, item, account, company, private_key): if not self.is_insurable_item(item=item, private_key=private_key): return 'Item is already insured', 409 item["account"] = account item["company"] = company commands = [ self.iroha.command('SetAccountDetail', account_id=self.admin_account, key=item['item_id'], value=base64.urlsafe_b64encode( json.dumps(item).encode()).decode()), ] transaction = self.iroha.transaction( commands=commands, creator_account=self.admin_account) IrohaCrypto.sign_transaction(transaction, private_key) if self.__send_transaction_and_print_status( transaction) == "COMMITTED": return str(item), 201 else: return 'Internal Error', 500 def claim_item(self, item, account, company, private_key): if not self.is_claimable_item(item=item, private_key=private_key): return 'Claim cannot be done', 409 item["account"] = account item["company"] = company today = datetime.now() item["insurance_expiration_date"] = today.strftime('%d-%m-%Y') commands = [ self.iroha.command('SetAccountDetail', account_id=self.admin_account, key=item['item_id'], value=base64.urlsafe_b64encode( json.dumps(item).encode()).decode()), ] transaction = self.iroha.transaction(commands) IrohaCrypto.sign_transaction(transaction, private_key) if self.__send_transaction_and_print_status( transaction) == "COMMITTED": return str(item) + "\nCLAIMED AND EXPIRED", 200 else: return 'Internal Error', 500
class Ledger: def __init__(self, sawmills, l): self.domain_name = "trade" self.admin_private_key = ADMIN_PRIVATE_KEY self.iroha = Iroha(ADMIN_ACCOUNT_ID) self.net = IrohaGrpc('{}:{}'.format(IROHA_HOST_ADDR, IROHA_PORT)) self.sawmills = sawmills self.woods = list(map(config.to_lower_case_only_letters, config.woods)) # uses as assets self.commands = [ self.iroha.command('CreateDomain', domain_id=self.domain_name, default_role='user'), *[ self.iroha.command('CreateAsset', asset_name=wood, domain_id=self.domain_name, precision=0) for wood in self.woods ] ] tx = IrohaCrypto.sign_transaction( self.iroha.transaction(self.commands), self.admin_private_key) print(self.send_transaction_and_log_status(tx)) self.get_admin_details() tx = self.iroha.transaction([ self.iroha.command('AddAssetQuantity', asset_id=f'{wood}#{self.domain_name}', amount=str(10000 // l)) for wood in self.woods ]) IrohaCrypto.sign_transaction(tx, self.admin_private_key) print(self.send_transaction_and_log_status(tx)) self.get_admin_details() def send_transaction_and_log_status(self, transaction): hex_hash = binascii.hexlify(IrohaCrypto.hash(transaction)) print('Transaction hash = {}, creator = {}'.format( hex_hash, transaction.payload.reduced_payload.creator_account_id)) self.net.send_tx(transaction) return list(self.net.tx_status_stream(transaction)) def get_admin_details(self): print('admin details...') result_dict = {} query = self.iroha.query('GetAccountAssets', account_id=f'admin@test') IrohaCrypto.sign_query(query, self.admin_private_key) response = self.net.send_query(query) data = response.account_assets_response.account_assets for asset in data: print('Asset id = {}, balance = {}'.format(asset.asset_id, asset.balance)) result_dict[asset.asset_id] = asset.balance return result_dict def init_ledger(self): print('init ledger...') tx = self.iroha.transaction([ self.iroha.command('CreateAccount', account_name=sawmill.account_name, domain_id=sawmill.domain, public_key=sawmill.public_key) for sawmill in self.sawmills ]) IrohaCrypto.sign_transaction(tx, self.admin_private_key) print(self.send_transaction_and_log_status(tx)) print("=" * 20) tx_commands = [] for i in self.sawmills: for j in self.woods: tx_commands.append( self.iroha.command( 'TransferAsset', src_account_id='admin@test', dest_account_id=f'{i.account_name}@{self.domain_name}', asset_id=f'{j}#{self.domain_name}', amount=str(randint(1, 100)))) tx = self.iroha.transaction(tx_commands) IrohaCrypto.sign_transaction(tx, self.admin_private_key) print(self.send_transaction_and_log_status(tx)) self.get_admin_details() print(self.get_accounts_info()) print("=" * 20) def get_accounts_info(self): result_dict = {} for i in self.sawmills: result_dict[i.account_name] = i.get_woods_balance() return result_dict