Exemplo n.º 1
0
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
Exemplo n.º 2
0
    async def get_account_assets(self, event):
        event_node = event.get("node")
        event_user = event.get("user")

        event_host, event_port = self.get_node_settings(event_node)
        event_user_account, event_user_priv = self.get_user_settings(
            event_user)

        if event_host and event_port and event_user_account and event_user_priv:
            event_account_id = event.get("account_id")

            try:
                logger.debug(
                    f"Calling event {event.get('action')} - host:port {event_host}:{event_port}"
                )
                iroha = Iroha(event_user_account)
                net = IrohaGrpc("{}:{}".format(event_host, event_port))

                query = iroha.query(
                    "GetAccountAssets",
                    account_id=event_account_id,
                )
                IrohaCrypto.sign_query(query, event_user_priv)

                response = net.send_query(query)
                data = response.account_assets_response.account_assets
                for asset in data:
                    logger.debug(
                        "Event {}: asset id = {}, balance = {}".format(
                            event.get("action"), asset.asset_id,
                            asset.balance))

            except Exception as ex:
                logger.debug(
                    f"Could not make event transaction {event.get('action')} - exception {ex}"
                )
        else:
            logger.debug(
                f"Event {event.get('action')} error - missing fields event_host, event_port, event_user_account, event_user_priv"
            )
            logger.debug(
                f"Check if event {event.get('action')} contains correct node {event.get('node')} and user {event.get('user')}"
            )
Exemplo n.º 3
0
def get_a_detail_written_by(name, writer, private_key, detail_key, domain, ip):
    """
    This function can be use when the User object is no available. Consult a details of the node writen by other node

    :Example:
    >>> juan_detail = get_a_detail_written_by('David', 'Juan', 'private key of david', 'detail_key of Juan', 'domain', \
    'ip')
    >>> print(juan_detail)
    {
        "nodeA@domain":{
        "Age":"35"
    }

    :param str name: Name of the node consulting the information
    :param str writer: Name of the node who write the detail
    :param str private_key: Private key of the user
    :param str detail_key: Name of the detail we want to consult
    :param str domain: Name of the domain
    :param str ip: Address for connecting to the BSMD
    :return: returns the detail writen by "the writer"
    :rtype: json

    """

    account_id = name + '@' + domain
    user_id = writer + '@' + domain
    iroha = Iroha(account_id)
    ip_address = ip + ':50051'
    network = IrohaGrpc(ip_address)
    query = iroha.query('GetAccountDetail',
                        account_id=account_id,
                        key=detail_key,
                        writer=user_id)
    IrohaCrypto.sign_query(query, private_key)
    response = network.send_query(query)
    data = response.account_detail_response
    print('Account id = {}, details = {}'.format(account_id, data.detail))
    return data.detail
Exemplo n.º 4
0
def get_account(account: str, port: str):
    """Health check function"""
    # setup of iroha client address
    host = "127.0.0.1"
    net = IrohaGrpc(f"{host}:{port}")
    query = iroha_user.query("GetAccount", account_id=account)
    try:
        with open('/opt/iroha_data/[email protected]', 'r') as file:
            admin_private_key = file.read().strip()
    except Exception as e:
        print("Unable to read admin private key! Reason:", e)
        sys.exit(1)
    IrohaCrypto.sign_query(query, admin_private_key)
    response = net.send_query(query)
    # health check passes when response contains value of account parameter
    if response.account_response.account.account_id == user_account:
        print("Success!")
        sys.exit(0)
    # health check fails when response does not contain "admin@test"
    else:
        print(
            f"Successful connection, but account '{account}' does not exist!")
        sys.exit(1)
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)
Exemplo n.º 7
0
class IrohaConnector(AbstractConnector):
    def __init__(self, socketio, sessionid, iroha_dic, socketIoValidator):
        self.moduleName = "IrohaConnector"
        self.iroha_dic = iroha_dic
        self.socketIoValidator = socketIoValidator

        self.net = IrohaGrpc('localhost:50051')
        self.iroha = Iroha('admin@test')
        self.admin_priv_key = 'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70'  #Private Key of user decided at previous line
        self.latestNumOfBlocks = 0
        self.isMonitoring = False

        print(f"##{self.moduleName}.__init__")

    def getValidatorInformation(self, validatorURL):
        """Get the validator information including version, name, ID, and other information"""
        print(f"##{self.moduleName}.getValidatorInformation()")

    def sendAsyncRequest(self, requestData):
        """Request a verifier to execute a ledger operation"""
        print(f"##{self.moduleName}.sendAsyncRequest()")
        command = requestData['method']['command']
        if command == 'sendTx':
            return send_tx(requestData['args']['tx'])

    def send_tx(self, tx):
        #hex_hash = binascii.hexlify(IrohaCrypto.hash(tx))
        net.send_tx(tx)

    def getBalance(self, address):
        """Get balance of an account for native token on a leder"""
        print(f"##{self.moduleName}.getBalance()")

    def execSyncFunction(self, address, funcName, args):
        """Execute a synchronous function held by a smart contract"""
        print(f"##{self.moduleName}.execSyncFunction()")

        command = args['method']['command']
        print(
            f"##execSyncFunction : args['args']['args'] : {args['args']['args']}"
        )

    def startMonitor(self):
        """Request a validator to start monitoring ledger"""

        # initial execution for getting current number of blocks
        self.monitoring_routine(True)
        self.isMonitoring = True
        print(f"##{self.moduleName}.startMonitor()")
        schedule.every(1).minutes.do(self.monitoring_routine)
        while self.isMonitoring:
            schedule.run_pending()

    def stopMonitor(self):
        """Request a validator to stop monitoring ledger"""
        self.isMonitoring = False
        print(f"##{self.moduleName}.stopMonitor()")

    def cb(self, callbackData):
        """Callback function to call when receiving data from Ledger"""
        print(f"##{self.moduleName}.cb()")

    def nop(self):
        """Nop function for testing"""
        print(f"##{self.moduleName}.nop()")

    def run_coroutine(self, coroutine, command, args, loop=None):
        if loop is None:
            loop = asyncio.get_event_loop()
        result = loop.run_until_complete(coroutine(command, args))
        return result

    def get_block(self, blockNum):
        print(f'##get_block block num is : {blockNum}')

        # create Query
        get_block_query = self.iroha.query('GetBlock', height=blockNum)
        # sign Query
        IrohaCrypto.sign_query(get_block_query, self.admin_priv_key)
        # send Query
        response = self.net.send_query(get_block_query)
        return response

    def monitoring_routine(self, isInit=False):
        print(f'##called monitoring_routine()')
        while (True):
            blockData = self.get_block(self.latestNumOfBlocks + 1)
            if (blockData.error_response.error_code == 0):
                self.latestNumOfBlocks += 1
                if (not isInit):
                    event = self.extract_event(blockData)
                    self.socketIoValidator.publish_event(event)
            elif (blockData.error_response.error_code == 3):
                break

    def extract_event(self, blockData):
        # TODO return event which is extracted from blockData
        # improve temporary returning blockData
        return blockData
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
Arquivo: user.py Projeto: LiTrans/BSMD
class User:
    """
    Create an User object. This object can be use to create a passive node in the BSMD
    
    :Example:
    >>> import json
    >>> from utils.administrator import Domain
    >>> x = { "age": 30, "city": "New York" }
    >>> public = Domain('public', 'default_role')
    >>> account_information = json.dumps(x)
    >>> me = User('private_key', 'My Name', public, '123.456.789', account_information)
    >>> print(me.name)
    My name

    :param str private_key: private key of the user. This is not save in the class is just used to generate
                    a public_key. In other functions the private_key must be used to sign transactions. You can
                    generate private keys with IrohaCrypto.private_key()

    :param str name: name of the user (lower case)
    :param Domain domain: domain where the user will live
    :param str ip: ip of one node hosting the blockchain
    :param json public_info: public information of the user. If domain is public this field can't be null
    
    """

    def __init__(self, private_key, name, domain, ip, public_info):
        self.public_key = IrohaCrypto.derive_public_key(private_key)
        self.name = name
        self.domain = domain
        self.domain.name = domain.name
        ip_address = ip + ':50051'
        self.network = IrohaGrpc(ip_address)
        if domain.name == 'public':
            self.public_info = public_info

    # ###############
    # create my own account
    # ###############
    def create_account(self, private_key):
        """
        Create a personal account in the BSMD. In the public domain all your public information is automatically
        populated

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> public = Domain('public', 'default_role')
        >>> user = User('private_key','David', public, '123.456.789', account_information)
        >>> user.create_account('private_key')

        :param str private_key: The private key of the user

        """
        account_id = self.name + '@' + self.domain.name
        iroha = Iroha(account_id)
        tx = iroha.transaction(
            [iroha.command('CreateAccount',
                           account_name=self.name,
                           domain_id=self.domain,
                           public_key=self.public_key)])
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

        if self.domain == 'public':
            self.set_detail('public', self.public_info, private_key)

    # ###############
    # Domain related functions
    # ###############
    def create_domain(self, domain, private_key):
        """
        Creates a domain for personal use. You can create a domain for a particular process, e.g., Federated Learning

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key', 'My Name', 'My domain', '123.456.789', account_information)
        >>> user.create_domain(domain, 'private_key')

        :param Domain domain: domain to be created
        :param str private_key: key to sign the transaction

        """
        account_id = self.name + '@' + self.domain.name
        iroha = Iroha(account_id)
        tx = iroha.transaction(
            [iroha.command('CreateDomain',
                           domain_id=domain.name,
                           default_role=domain.default_role)])

        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

    # ###############
    # asset functions
    # ###############
    def get_balance(self, private_key):
        """
        Get the balance of my account. Use the private key of the user to get his current balance. The function will
        return a dictionary with the id of the asset, the account id  and the balance.

        :Example:
        >>> import json
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> user = User('private_key', 'My Name', 'My domain', '123.456.789', account_information)
        >>> balance = user.get_balance('private_key')
        >>> print(balance)
        {asset_id: "fedcoin#federated",
        account_id: "generator@federated",
        balance: "1000"}

        :param str private_key: key to sign the transaction
        :return: A a dictionary with the id of the asset, the account id  and the balance
        :rtype: dict

        """
        account_id = self.name + '@' + self.domain.name
        iroha = Iroha(account_id)
        query = iroha.query('GetAccountAssets',
                            account_id=account_id)
        IrohaCrypto.sign_query(query, private_key)

        response = self.network.send_query(query)
        data = response.account_assets_response.account_assets
        for asset in data:
            print('Asset id = {}, balance = {}'.format(asset.asset_id, asset.balance))
        return data

    def transfer_assets_to(self, user, asset_name, quantity, description, private_key):
        """
        Transfer assets from one account to another. Both users must be in the same domain.

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> x = { "age": 34, "city": "Mexico" }
        >>> account_information_dante = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> dante = User('dante_private_key','Dante',domain, account_information_dante)
        >>> user.transfer_assets_to(dante, 'coin', '2', 'Shut up and take my money')

        :param User user: User you want to transfer the assets
        :param str asset_name: Name of the asset to be transferred
        :param float quantity: Number of assets we want to transfer
        :param str description: Small message to the receiver of assets
        :param str private_key: Key to sign the transaction

        """

        account_id = self.name + '@' + self.domain.name
        iroha = Iroha(account_id)
        destination_account = user.name + '@' + self.domain.name
        asset_id = asset_name + '#' + self.domain.name
        tx = iroha.transaction([
            iroha.command('TransferAsset',
                          src_account_id=account_id,
                          dest_account_id=destination_account,
                          asset_id=asset_id,
                          description=description,
                          amount=quantity)
        ])
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

    # ###############
    # get own account information
    # ###############
    def get_all_details(self, private_key):
        """
        Consult all details of the user in all the domains

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> details = user.get_all_details('private_key')
        >>> print(details)

        :param str private_key: Key to sign the transaction
        :return: solicited details of the user
        :rtype: json

        {
            "user@domainA":{
                "Age":"35",
                "Name":"Quetzalcoatl"
            },
            "user@domainB":{
                "Location":"35.3333535,-45.2141556464",
                "Status":"valid"
            },
            "user@domainC":{
                "FederatingParam":"35.242553",
                "Loop":"3"
            }
        }

        """
        account_id = self.name + '@' + self.domain.name.name
        iroha = Iroha(account_id)
        query = iroha.query('GetAccountDetail',
                            account_id=account_id)
        IrohaCrypto.sign_query(query, private_key)
        response = self.network.send_query(query)
        data = response.account_detail_response
        print('Account id = {}, details = {}'.format(account_id, data.detail))
        return data.detail

    def get_a_detail(self, detail_key, private_key):
        """
        Consult a detail of the user

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> details = user.get_a_detail('private_key', 'age')
        >>> print(details)
        {
            "user@domainA":{
                "Age":"35"
            }
        }

        :param str private_key: key to sign the transaction
        :param str detail_key: name of the detail to be consulted
        :return: solicited details of the user
        :rtype: json

        """

        account_id = self.name + '@' + self.domain.name
        iroha = Iroha(account_id)
        query = iroha.query('GetAccountDetail',
                            account_id=account_id,
                            key=detail_key)
        IrohaCrypto.sign_query(query, private_key)
        response = self.network.send_query(query)
        data = response.account_detail_response
        print('Account id = {}, details = {}'.format(account_id, data.detail))
        return data.detail

    def get_all_details_written_by(self, user, private_key):
        """
        Consult all details writen by some other node

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> x = { "age": 34, "city": "Mexico" }
        >>> account_information_juan = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> juan = User('private_key_juan','Juan',domain, account_information_juan)
        >>> details = user.get_all_details_written_by(juan, 'private_key')
        >>> print(details)
        {
            "user@domain":{
                "FederatingParam":"35.242553",
                "Loop":"3"
            },
            "user@domain":{
                "sa_param":"44",
                "Loop":"3"
            }
        }

        :param str private_key: key to sign the transaction
        :param User user: user who write information on your identification
        :return: solicited details of the user
        :rtype: json

        """
        account_id = self.name + '@' + self.domain.name
        user_id = user.name + '@' + user.domain
        iroha = Iroha(account_id)
        query = iroha.query('GetAccountDetail',
                            account_id=account_id,
                            writer=user_id)
        IrohaCrypto.sign_query(query, private_key)
        response = self.network.send_query(query)
        data = response.account_detail_response
        print('Account id = {}, details = {}'.format(account_id, data.detail))
        return data.detail

    def get_a_detail_written_by(self, user, detail_key, private_key):
        """
        Consult a detail of the node writen by other node

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> x = { "age": 34, "city": "Mexico" }
        >>> account_information_juan = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> juan = User('private_key_juan','Juan',domain, account_information_juan)
        >>> details = user.get_a_detail_written_by(juan, 'FederatingParam',  'private_key')
        >>> print(details)
        {
            "user@domainC":{
                "FederatingParam":"35.242553"
            }
        }

        :param str private_key: key to sign the transaction
        :param User user: user who write information on your identification
        :param str detail_key: name of the detail to be consulted
        :return: solicited details of the user
        :rtype: json

        """
        account_id = self.name + '@' + self.domain.name
        user_id = user.name + '@' + user.domain
        iroha = Iroha(account_id)
        query = iroha.query('GetAccountDetail',
                            account_id=account_id,
                            key=detail_key,
                            writer=user_id)
        IrohaCrypto.sign_query(query, private_key)
        response = self.network.send_query(query)
        data = response.account_detail_response
        print('Account id = {}, details = {}'.format(account_id, data.detail))
        return data.detail

    # ###############
    # set own account information
    # ###############
    def set_detail(self, detail_key, detail_value, private_key):
        """
        Set a detail in my account. The details can be stored in JSON format with limit of 4096 characters per detail

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "gender": 30, "address": "123 Tennis" }
        >>> account_information = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David', domain, account_information)
        >>> user.set_detail('personal information', account_information, 'private_key')

        :param str detail_key: Name of the detail we want to set
        :param json detail_value: Value of the detail
        :param str private_key: Key to sign the transaction

        """

        account_id = self.name + '@' + self.domain.name
        iroha = Iroha(account_id)
        tx = iroha.transaction([
            iroha.command('SetAccountDetail',
                          account_id=account_id,
                          key=detail_key,
                          value=detail_value)
        ])
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

    # ###############
    # set information to other account
    # ###############
    def set_detail_to(self, user, detail_key, detail_value, private_key):
        """
        Set a detail to a node. The details can be stored in JSON format with limit of 4096 characters per detail.
        You must have the permission from the node to set information on his identification

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> x = { "age": 34, "city": "Mexico" }
        >>> account_information_juan = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> juan = User('private_key_juan','Juan',domain, account_information_juan)
        >>> user.set_detail_to(juan, 'Job', 'Bartender', 'private_key')

        :param User user: user you want to set the details
        :param str detail_key: Name of the detail we want to set
        :param str detail_value: Value of the detail
        :param str private_key: key to sign the transaction

        """
        account = self.name + '@' + self.domain.name
        iroha = Iroha(account)
        account_id = user.name + '@' + user.domain
        tx = iroha.transaction([
            iroha.command('SetAccountDetail',
                          account_id=account_id,
                          key=detail_key,
                          value=detail_value)
        ])
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

    # ###############
    # grant permissions
    # ###############
    def grants_access_set_details_to(self, user, private_key):
        """
        Grant permission to a node to set details on your identification

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> x = { "age": 34, "city": "Mexico" }
        >>> account_information_juan = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> juan = User('private_key_juan','Juan',domain, account_information_juan)
        >>> user.grants_access_set_details_to(juan, 'private_key')

        :param User user: User you want to grant permissions to set detail on your behalf
        :param str private_key: Key to sign the transaction

        """
        my_id_account = self.name + '@' + self.domain.name
        grant_account_id = user.name + '@' + user.domain
        iroha = Iroha(my_id_account)
        tx = iroha.transaction([
            iroha.command('GrantPermission',
                          account_id=grant_account_id,
                          permission=can_set_my_account_detail)
        ],
            creator_account=my_id_account)
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

    def revoke_access_set_details_to(self, user, private_key):
        """
        Revoke permission to a node to set details on your identification

        :Example:
        >>> import json
        >>> from utils.administrator import Domain
        >>> x = { "age": 30, "city": "New York" }
        >>> account_information = json.dumps(x)
        >>> x = { "age": 34, "city": "Mexico" }
        >>> account_information_juan = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David',domain, account_information)
        >>> juan = User('private_key_juan','Juan',domain, account_information_juan)
        >>> user.revoke_access_set_details_to(juan, 'private_key')

        :param User user: User you want to revoke permissions to set details on your behalf
        :param str private_key: Key to sign the transaction

        """
        my_id_account = self.name + '@' + self.domain.name
        grant_account_id = user.name + '@' + user.domain
        iroha = Iroha(my_id_account)
        tx = iroha.transaction([
            iroha.command('RevokePermission',
                          account_id=grant_account_id,
                          permission=can_set_my_account_detail)
        ],
            creator_account=my_id_account)
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)
def auth(account_name, private_key):
    """
    This method is used to authenticate an existing user on the blockchain. Since Iroha expect an account_name when
    retrieving and account we first try to retrieve it be name. If the name doesn't exist we throw a 404 response.
    If the name exists we go ahead and check the private key. Since the account name is easily guessable or obtainable,
    we must use the private key to make sure that only the account owner can authenticate.

    :param str account_name: Unique name of the account
    :param str private_key:
    :return: JSON response, status code
    """

    # Gethering tools
    iroha_net = IrohaGrpc(constants.iroha_network)
    response = {}
    encoder = json.encoder.JSONEncoder()

    # Defining the query
    new_query = constants.iroha_client.query(
        'GetSignatories',
        account_id=account_name
    )

    # Signing the query and sending it to network
    IrohaCrypto.sign_query(new_query, constants.private_key)
    iroha_response = iroha_net.send_query(new_query)
    keys = iroha_response.signatories_response.keys

    if not keys:
        response['status'] = 'error'
        response['msg'] = 'Account not found.'
        return encoder.encode(response), 404

    public_key = keys[0]

    # Verify if private key generates the same public key as the one from network
    try:
        if IrohaCrypto.derive_public_key(private_key).decode('utf-8') != public_key:
            response['status'] = 'error'
            response['msg'] = "Authentication failed. Private key did not match."
            return encoder.encode(response), 403
        else:
            response['status'] = 'success'
            response['msg'] = "Authentication successful."

            # Generate a token and save in redis alongside public key
            # The token will expire in 3 days
            r = redis.Redis(constants.redis_network, '6379', db=0)

            t = r.get(account_name)
            if not t:
                token = token_hex(32)
                r.setex(account_name, timedelta(days=1), token)
                response['token'] = token
            else:
                response['token'] = t.decode('utf-8')

            return encoder.encode(response), 200
    except Error as err:
        response['status'] = 'error'
        response['msg'] = str(err)
        return encoder.encode(response), 403
Exemplo n.º 11
0
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
Exemplo n.º 12
0
class Broker:
    """
    Brokers look for users (passive nodes) in the BSMD and arrange transactions. Brokers are created in the public
    domain and can get the public details of all passive nodes

    :param str private_key: Private key of the broker. This is not save in the class is just used to generate
                        a public_key. In other functions the private_key must be used to sign transactions. You can
                        generate private keys with IrohaCrypto.private_key()
    :param str name: name of the user (lower case)
    :param str ip: ip of one node hosting the blockchain
    :param json public_info: public information of the broker, e.g., type of node: broker

    """
    def __init__(self, private_key, name, ip, public_info):
        self.public_key = IrohaCrypto.derive_public_key(private_key)
        self.name = name
        ip_address = ip + ':50051'
        self.network = IrohaGrpc(ip_address)
        self.public_info = public_info

    def create_account(self, private_key):
        """
        Create a broker account in the BSMD. Brokers are automatically created in the public domain. This function works
        in two steps

        #. The broker account in created in the public domain
        #. Set the public details of the broker

        :Example:
        >>> import json
        >>> from admin.administrator import Domain
        >>> x = { "address": "123 Street, City", "type": "broker" }
        >>> public_info = json.dumps(x)
        >>> broker = Broker('private_key','broker', '123.456.789', public_info)
        >>> broker.create_account('private_key')

        :param str private_key: The private key of the user

        """
        account_id = self.name + '@public'
        iroha = Iroha(account_id)
        tx = iroha.transaction([
            iroha.command('CreateAccount',
                          account_name=self.name,
                          domain_id='public',
                          public_key=self.public_key)
        ])
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

        tx = iroha.transaction([
            iroha.command('SetAccountDetail',
                          account_id=account_id,
                          key='public information',
                          value=self.public_info)
        ])
        IrohaCrypto.sign_transaction(tx, private_key)
        send_transaction_and_print_status(tx, self.network)

    def get_details_from(self, user, private_key):
        """
        Consult all details of the node. Broker can only consult details in the 'public' domain

        :Example:
        >>> import json
        >>> from admin.administrator import Domain
        >>> from layers.identification.identification import User
        >>> x = { "gender": 30, "address": "123 Tennis" }
        >>> user_info = json.dumps(x)
        >>> x = { "address": "123 Street, City", "type": "broker" }
        >>> broker_info = json.dumps(x)
        >>> domain = Domain('name', 'default_role')
        >>> user = User('private_key','David', domain, user_info)
        >>> broker = Broker('private_key','broker', '123.456.789', broker_info)
        >>> user_public_details = broker.get_details_from(user, 'private_key')
        >>> print(user_public_details)
        {
            "node@domain":{
                "Type":"user"
            }
        }

        :param str private_key: Key to sign the transaction
        :param User user: The user the broker want to consult
        :return: solicited details of the user
        :rtype: json

        """
        account_id = self.name + '@' + 'public'
        user_id = user.name + '@' + 'public'
        iroha = Iroha(account_id)
        query = iroha.query('GetAccountDetail',
                            account_id=account_id,
                            writer=user_id)
        IrohaCrypto.sign_query(query, private_key)
        response = self.network.send_query(query)
        data = response.account_detail_response
        print('Account id = {}, details = {}'.format(account_id, data.detail))
        return data.detail
Exemplo n.º 13
0
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
Exemplo n.º 14
0
from iroha import Iroha, IrohaCrypto, IrohaGrpc, IrohaTlsOptions

iroha = Iroha("admin@test")
net = IrohaGrpc("localhost:50052",
                enable_tls=True,
                tls_options=IrohaTlsOptions.from_files(
                    "/opt/iroha/example/torii_tls/server.crt"))

# this is a sample private key from hyperledger/iroha repo
admin_private_key = "f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70"
admin_qry = iroha.query("GetAccount", account_id="admin@test")
IrohaCrypto.sign_query(admin_qry, admin_private_key)

response = net.send_query(admin_qry)

print(response)
import os
import sys

from iroha import Iroha, IrohaCrypto, IrohaGrpc

# Iroha torii url
url = sys.argv[1]
# Iroha admin account that will perform the query
admin_account = sys.argv[2]
# Iroha admin account private key path
admin_priv_path = sys.argv[3]
# Iroha account to be queried
query_account = sys.argv[4]

iroha = Iroha(admin_account)
net = IrohaGrpc(url)

admin_key = open(admin_priv_path, "r").read()

query = iroha.query(
    "GetAccountAssets",
    account_id=query_account
)

IrohaCrypto.sign_query(query, admin_key)
response = net.send_query(query)

for asset in response.account_assets_response.account_assets:
    print("asset_id = {}, balance = {}".format(asset.asset_id, asset.balance))