def get_flt_account(self, public_key, index):
        address = addresser.float_account_address(account_id=public_key,
                                                  index=index)
        ##entries will be a weird list of the form
        ##[address: "318c9fa5d39e9ccd2769115795e384b8e83b3267172ae518136ac49ddc5adf71d87814"
        ##data: "\nB02dbf0f4a3defef38df754122ef7c10fee6a4bb363312367524f86d230e205d459\022$b6de5d5b-7870-49df-971e-0885986bfa96\032
        ##\006seller\"\021978-0-9956537-6-4*\0161-191-790-04532\r1-932866-82-5:\001\000"]

        entries = self._context.get_state(addresses=[address],
                                          timeout=self._timeout)

        try:
            entry = entries[0]
            logging.info("float_account data corresponding to \
                            {} is {}".format(address, entry))
        except Exception as e:
            logging.info("float_account data corresponding to \
                            {} is {}".format(address, None))
            return False

        float_account = create_empty_float_account()
        float_account.ParseFromString(entry.data)
        logging.info("This is the float_account stored on blockchain \
                    {}".format(float_account))
        return float_account
    def set_float_account(self, **input_data):
        """
        parent_pub=header.signer_public_key,
        pancard=float_account.pancard,
        phone_number=float_account.phone_number,
        email=float_account.email,
        claimed=float_account.claimed,
        claimed_by=float_account.claimed_by,
        create_asset_index=create_asset_index.float_account,
        parent_idx=float_account.parent_idx,
        time=float_account.time, //when this float account transaction was created
        indian_time=float_account.indian_time,
        claimed_on=float_account.claimed_on,
        parent_role=float_account.parent_role,
        user_role=float_account.user_role
        """

        logging.info("Paylaod from set_float_account {}".format(input_data))
        if input_data["parent_role"] != "ADMIN":
            ##change idx in the account present at public key input_data["parent_zero_pub"]
            self.set_float_account_idxs(input_data["parent_zero_pub"],
                                        input_data["parent_idx"])

        ##here the parent pub is the nth index key of the parent on thich
        ##this float account address is generated
        address = addresser.float_account_address(
            account_id=input_data["parent_pub"],
            index=input_data["parent_idx"])
        float_account = create_empty_float_account()

        logging.info("This is the value of create_asset_idxs \
                        {}".format(input_data['create_asset_idxs']))
        float_account.pancard = input_data["pancard"]
        float_account.phone_number = input_data["phone_number"]
        float_account.email = input_data["email"]
        float_account.claimed = input_data["claimed"]
        float_account.claimed_by = input_data["claimed_by"]

        ##this is not required because create_asset_idxs will wlays be empty
        ##when intilizing float_account
        #float_account.create_asset_idxs=input_data["create_asset_idxs"]
        float_account.parent_idx = input_data["parent_idx"]
        float_account.time = input_data["time"]
        float_account.indian_time = input_data["indian_time"]
        float_account.claimed_on = input_data["claimed_on"]
        float_account.parent_pub = input_data["parent_pub"]
        float_account.parent_role = input_data["parent_role"]
        float_account.user_role = input_data["user_role"]
        logging.info(float_account)
        logging.info("Account after serialization %s",
                     float_account.SerializeToString())
        return self._context.set_state(
            {address: float_account.SerializeToString()}, self._timeout)
    async def float_account_addresses(self):
        float_account_idxs, nth_keys = await self.indexes_n_pub_priv_pairs(
            "float_account_idxs")
        address_list = []
        address_list = []
        nth_keys = await remote_calls.key_index_keys(self.app,
                                                     self.decrypted_mnemonic,
                                                     float_account_idxs)

        for key_index in float_account_idxs:
            public_key = nth_keys[str(key_index)]["public_key"]
            child_address = addresser.float_account_address(
                account_id=public_key, index=key_index)
            address_list.append(child_address)
        return address_list
    def claim_float_account(self, public_key, parent_idx, claimed_by,
                            claimed_on):
        """
        Make claimed_on as the time sent by the transaction and claimed_by as
        the zeroth index key of the user.
        THen update the float_account address
        """
        float_account = self.get_flt_account(public_key, parent_idx)
        float_account.claimed = True
        float_account.claimed_by = claimed_by
        float_account.claimed_on = claimed_on
        address = addresser.float_account_address(public_key, parent_idx)

        self._context.set_state({address: float_account.SerializeToString()},
                                self._timeout)
        return
    def set_asset(self, payload, public, account, account_type):
        """
        payload will have the CreateAsset in the payload
        public: hex public key with whose private key transaction was signed
        account: could be a float account or account
        account_type: could be FLOAT_ACCOUNT or CREATE_ACCOUNT
        """
        logging.info("Account  in set_asset <<{}>>".format(account))
        if account_type == "FLOAT_ACCOUNT":
            account_address = addresser.float_account_address(
                account_id=payload.flt_account_parent_pub,
                index=payload.flt_account_parent_idx)
        else:
            account_address = addresser.create_account_address(
                account_id=payload.zero_pub, index=0)

        self.update_asset_index(account_address, account, payload.idx)

        address = addresser.create_asset_address(asset_id=public,
                                                 index=payload.idx)

        asset = create_empty_asset()

        asset.key = payload.key
        asset.url = payload.url
        asset.time = payload.time
        asset.indiantime = payload.indiantime
        asset.file_name = payload.file_name
        asset.file_hash = payload.file_hash
        asset.idx = payload.idx
        asset.master_key = payload.master_key
        asset.master_url = payload.master_url
        asset.role = payload.role
        asset.public = public

        if payload.scope:
            asset.scope.cert_type = payload.scope.cert_type
            asset.scope.product_type = payload.scope.product_type
            asset.scope.product_name = payload.scope.product_name

        logging.info(asset)
        logging.info("Account after serialization %s",
                     asset.SerializeToString())
        return self._context.set_state({address: asset.SerializeToString()},
                                       self._timeout)
def upload(issuer, receiver):
    headers = get_headers_on_email(issuer["email"], issuer["password"])

    receiver = db_find_on_key_pending(receiver["email"])
    address = addresser.float_account_address(receiver["parent_pub"],
                                              receiver["parent_idx"])

    file_hash, base64_file_bytes, file_name = generate_file_like()
    data = {
        "file_name": file_name,
        "base64_file_bytes": base64_file_bytes,
        "file_hash": file_hash,
        "scope": create_scope(),
        "expired_on": revoke_time_stamp(days=100, hours=1, minutes=10),
        "address": address
    }

    r = requests.post("http://localhost:8000/assets/upload",
                      data=json.dumps(data),
                      headers=headers)
    logging.info(json.dumps(r.json(), indent=4))

    if r.json()["error"]:
        logging.info("Since this account has already been claimed")
        logging.info("Trying upload with organization account")
        receiver = db_find_on_key(receiver["email"])

        address = addresser.create_organization_account_address(
            receiver["acc_zero_pub"], 0)
        data.update({"address": address})
        r = requests.post("http://localhost:8000/assets/upload",
                          data=json.dumps(data),
                          headers=headers)
        logging.info(json.dumps(r.json(), indent=4))

    return r.json()["data"]["issuer_address"], r.json(
    )["data"]["receiver_address"]
Exemple #7
0
async def send_create_asset(**in_data):
    """
    Args
        key(str), hex_encoded: encrypted AES key with user publickey present
                at random index
        url(str): s3 url encrypted with user public key
        time(str): when this asset was created
        indiantime(str): time in indian format
        file_name(str): file_name
        file_hash(str): sha3_512 hash of file content
        child_idx(int): random index
        parent_zero_pub(str): Parent zero public key of the parent
        master_key(str): encrypted s3 url, encrypted with aes key generated
                        with qci_public and user private key
        master_url(str): encrypted s3 url, encrypted with aes key
                        generated with private key of user and  public of QCI
        scope(Scope(defined in asset.proto)):
        string expired_on=13; //the date on which this certificate is intended
    """
    ##TODO: Processor side : Float this asset and make change to create_asset_idxs
    ## to either float_Account_Address or create_Account_Address depending upon
    ##whther the user has been claimed or not
    inputs = [
        addresser.create_asset_address(
            asset_id=in_data["txn_key"].get_public_key().as_hex(),
            index=in_data["idx"]),
    ]

    outputs = [
        addresser.create_asset_address(
            asset_id=in_data["txn_key"].get_public_key().as_hex(),
            index=in_data["idx"])
    ]

    ##ideally if account is claimed, we should have nothing to do with float account
    ## but we are sending both addresses to the processor and let processor handle
    ## the logic i.e float_account should exists and is_claimed shall be true
    ##to append create_asset_idxs to the account_transaction
    if not in_data["is_acc_claimed"]:
        ##implies user havent claimed his float_account_address, so the
        ## create_asset_idx aill be chnaged on flt_account_addresslogging.info("Float account parent pub %s"%in_data["flt_account_parent_pub"])
        logging.info("Float account parent idx %s" %
                     str(in_data["flt_account_parent_idx"]))
        float_account_address = addresser.float_account_address(
            account_id=in_data["flt_account_parent_pub"],
            index=in_data["flt_account_parent_idx"])
        inputs.append(float_account_address)
        outputs.append(float_account_address)
    else:

        account_address = addresser.create_organization_account_address(
            account_id=in_data["zero_pub"], index=0)

        inputs.append(account_address)
        outputs.append(account_address)

    if in_data["child_zero_pub"]:
        child_address = addresser.child_account_address(
            account_id=in_data["child_zero_pub"], index=0)
        inputs.append(child_address)
        outputs.append(child_address)

    if in_data["scope"]:
        scope = payload_pb2.PayloadScope(
            group=in_data["scope"]["group"],
            sub_group=in_data["scope"]["sub_group"],
            field=in_data["scope"]["field"],
            nature=in_data["scope"]["nature"],
            operations=in_data["scope"]["operations"],
            description=in_data["scope"]["description"],
        )
    else:
        scope = None

    logging.info(f"Input Address<<{inputs}>>")
    logging.info(f"Output Address<<{outputs}>>")

    asset = payload_pb2.CreateAsset(
        key=in_data["key"],
        url=in_data["url"],
        time=in_data["time"],
        indiantime=in_data["indiantime"],
        file_name=in_data["file_name"],
        file_hash=in_data["file_hash"],
        idx=in_data["idx"],
        master_key=in_data["master_key"],
        master_url=in_data["master_url"],
        role=in_data["role"],
        scope=scope,
        zero_pub=in_data["zero_pub"],
        flt_account_parent_pub=in_data["flt_account_parent_pub"],
        flt_account_parent_idx=in_data["flt_account_parent_idx"],
        child_zero_pub=in_data["child_zero_pub"])

    logging.info(f"Create asset transaction {asset}")
    payload = payload_pb2.TransactionPayload(
        payload_type=payload_pb2.TransactionPayload.CREATE_ASSET,
        create_asset=asset)

    transaction_ids, batches, batch_id, batch_list_bytes = make_header_and_batch(
        payload=payload,
        inputs=inputs,
        outputs=outputs,
        txn_key=in_data["txn_key"],
        batch_key=in_data["batch_key"])

    logging.info(f"This is the batch_id {batch_id}")

    rest_api_response = await messaging.send(batch_list_bytes,
                                             in_data["config"])

    try:
        result = await messaging.wait_for_status(batch_id, in_data["config"])
    except (ApiBadRequest, ApiInternalError) as err:
        #await auth_query.remove_auth_entry(request.app.config.DB_CONN, request.json.get('email'))
        logging.error(f"Transaction failed with {err}")
        raise ApiInternalError(err)
        #raise err
    return transaction_ids, batch_id
async def submit_organization_account(app, user):
    """
    """

    ##no9w the create account address and signer will be the user himself

    master_pub, master_priv, zero_pub, zero_priv = await \
                remote_calls.from_mnemonic(app.config.GOAPI_URL, user["mnemonic"])

    if user["acc_zero_pub"] != zero_pub:
        raise Exception("wrong mnemonic for user, Key mismatch error")
    acc_signer=encryption_utils.create_signer(zero_priv)
    ##hashing gst number and tan number if present

    ##fecth float account details from the blokchchain, because it might be a possibility
    ##that there are several create_asset transaction in pipeline, and the user
    ## now start the procedute to claim the acccount, Now if we fetch pending user
    ## rom db rather then blokchcain then flt_acc_idxs will differ

    flt_acc_address = addresser.float_account_address(
                user["parent_pub"], user["parent_idx"])

    flt_account = await deserialize_state.deserialize_float_account(
                app.config.REST_API_URL, flt_acc_address)



    ##import from ledger.account import float_account, other then create_asset_idxs
    ## wil be emprty for the float_account, if we push empty list on blockchain
    ##it wil hsow an error, its better to not to send them at the first place
    transaction_data= {"config": app.config,
                        "txn_key": acc_signer,
                        "batch_key": app.config.SIGNER,
                        "org_name": user["org_name"],
                        "parent_pub": user["parent_pub"], #required to find
                                                        #float_account address
                        "user_id": user["user_id"],
                        "pancard": hashlib.\
                                    sha512(user["pancard"].encode())\
                                    .hexdigest(),
                        "gst_number": hashlib.\
                                    sha512(user["gst_number"].encode())\
                                    .hexdigest(),
                        "tan_number": hashlib.\
                                    sha512(user["tan_number"].encode())\
                                    .hexdigest(),
                        "phone_number": hashlib.\
                                    sha512(user["phone_number"].encode())\
                                    .hexdigest(),

                        "email": user["email"],
                        "time": int(time.time()),
                        "indian_time": upload_utils.indian_time_stamp(),
                        "parent_zero_pub": user["parent_zero_pub"],
                        "parent_role": user["parent_role"],
                        "role": user["role"],
                        "create_asset_idxs": flt_account.get("create_asset_idxs"),
                        "deactivate": False,
                        "deactivate_on": None,
                        "parent_idx": user["parent_idx"],
                        "float_account_address": flt_acc_address,
                        }



    transaction_ids, batch_id = await __send_organization_account(**transaction_data)

    logging.info(batch_id)
    if batch_id:
        logging.debug(user)
        ##if successful, insert this user in pending_users table
        user.update({
                    "time": transaction_data["time"],
                    "indian_time": transaction_data["indian_time"],
                    "transaction_id": transaction_ids[0],
                    "batch_id": batch_id,
                    "create_asset_idxs": flt_account.get("create_asset_idxs"),
                    "type": "ORGANIZATION"})

        user.pop("mnemonic")
        logging.debug(user)
        await accounts_query.insert_account(app, user)

        ##update user pending_user with claim, claim_by , claimed_on keys
        await accounts_query.claim_account(app, user["user_id"],
                user["email"], user["phone_number"], user["indian_time"])
    ##return new user data whose float_account has just been created
    return user
def create_asset(**in_data):
    """
    Inputs will have asset_address,
        account_address (The key index will be appended to the account address)
        float_accout (if the user only has a float_account till now, key_index will be
            appended to the float_account address)
        child_account_address (In case the asset being created by the child)
    """

    ##TODO: Processor side : Float this asset and make change to create_asset_idxs
    ## to either float_Account_Address or create_Account_Address depending upon
    ##whther the user has been claimed or not
    inputs = [
        addresser.create_asset_address(
            asset_id=in_data["txn_key"].get_public_key().as_hex(),
            index=in_data["idx"]),
    ]

    outputs = [
        addresser.create_asset_address(
            asset_id=in_data["txn_key"].get_public_key().as_hex(),
            index=in_data["idx"])
    ]

    ##ideally if account is claimed, we should have nothing to do with float account
    ## but we are sending both addresses to the processor and let processor handle
    ## the logic i.e float_account should exists and is_claimed shall be true
    ##to append create_asset_idxs to the account_transaction
    if not in_data["is_acc_claimed"]:
        ##implies user havent claimed his float_account_address, so the
        ## create_asset_idx aill be chnaged on flt_account_addresslogging.info("Float account parent pub %s"%in_data["flt_account_parent_pub"])
        logging.info("Float account parent idx %s" %
                     str(in_data["flt_account_parent_idx"]))
        float_account_address = addresser.float_account_address(
            account_id=in_data["flt_account_parent_pub"],
            index=in_data["flt_account_parent_idx"])
        inputs.append(float_account_address)
        outputs.append(float_account_address)
    else:

        account_address = addresser.create_organization_account_address(
            account_id=in_data["zero_pub"], index=0)

        inputs.append(account_address)
        outputs.append(account_address)

    if in_data["child_zero_pub"]:
        child_address = addresser.child_account_address(
            account_id=in_data["child_zero_pub"], index=0)
        inputs.append(child_address)
        outputs.append(child_address)

    if in_data["scope"]:
        scope = payload_pb2.PayloadScope(
            group=in_data["scope"]["group"],
            sub_group=in_data["scope"]["sub_group"],
            field=in_data["scope"]["field"],
            nature=in_data["scope"]["nature"],
            operations=in_data["scope"]["operations"],
            description=in_data["scope"]["description"],
        )
    else:
        scope = None

    logging.info(f"Input Address<<{inputs}>>")
    logging.info(f"Output Address<<{outputs}>>")

    asset = payload_pb2.CreateAsset(
        key=in_data["key"],
        url=in_data["url"],
        time=in_data["time"],
        indiantime=in_data["indiantime"],
        file_name=in_data["file_name"],
        file_hash=in_data["file_hash"],
        idx=in_data["idx"],
        master_key=in_data["master_key"],
        master_url=in_data["master_url"],
        role=in_data["role"],
        scope=scope,
        zero_pub=in_data["zero_pub"],
        flt_account_parent_pub=in_data["flt_account_parent_pub"],
        flt_account_parent_idx=in_data["flt_account_parent_idx"],
        child_zero_pub=in_data["child_zero_pub"])

    logging.info(f"Create asset transaction {asset}")
    payload = payload_pb2.TransactionPayload(
        payload_type=payload_pb2.TransactionPayload.CREATE_ASSET,
        create_asset=asset)

    return make_header_and_batch(payload=payload,
                                 inputs=inputs,
                                 outputs=outputs,
                                 txn_key=in_data["txn_key"],
                                 batch_key=in_data["batch_key"])
def create_organization_account(**in_data):
    """Create a CreateAccount txn and wrap it in a batch and list.
    need to change two addresses

    create a account from user zeroth key
    edit float_accout address from parent nindex key and marked it claimed
    Args:
        txn_key (sawtooth_signing.Signer): The Txn signer key pair.
        batch_key (sawtooth_signing.Signer): The Batch signer key pair.
        label (str): The account's label.
        description (str): The description of the account.

    Returns:
        tuple: List of Batch, signature tuple
    """

    inputs = [
        addresser.create_organization_account_address(
            account_id=in_data["txn_key"].get_public_key().as_hex(), index=0),
    ]

    outputs = [
        addresser.create_organization_account_address(
            account_id=in_data["txn_key"].get_public_key().as_hex(), index=0),
    ]

    if in_data["role"] != "ADMIN":
        inputs.append(
            addresser.float_account_address(account_id=in_data["parent_pub"],
                                            index=in_data["parent_idx"]))
        outputs.append(
            addresser.float_account_address(account_id=in_data["parent_pub"],
                                            index=in_data["parent_idx"]))

    if in_data.get("parent_pub"):
        logging.info(f"This is the parent pub {in_data['parent_pub']}")

    account = payload_pb2.CreateOrganizationAccount(
        role=in_data["role"],
        parent_role=in_data["parent_role"],
        phone_number=in_data["phone_number"],
        pancard=in_data["pancard"],
        user_id=in_data["user_id"],
        email=in_data["email"],
        org_name=in_data["org_name"],
        gst_number=in_data["gst_number"],
        tan_number=in_data["tan_number"],
        time=in_data["time"],
        indian_time=in_data["indian_time"],
        parent_zero_pub=in_data["parent_zero_pub"],
        deactivate=in_data["deactivate"],
        deactivate_on=in_data["deactivate_on"],
        create_asset_idxs=in_data["create_asset_idxs"],
        parent_pub=in_data["parent_pub"],
        parent_idx=in_data["parent_idx"],
        float_account_address=in_data["float_account_address"],
    )

    logging.info(account)
    logging.info(f"THe address for the user on blockchain {inputs[0]}")

    payload = payload_pb2.TransactionPayload(
        payload_type=payload_pb2.TransactionPayload.
        CREATE_ORGANIZATION_ACCOUNT,
        create_organization_account=account)

    logging.info(payload)
    return make_header_and_batch(payload=payload,
                                 inputs=inputs,
                                 outputs=outputs,
                                 txn_key=in_data["txn_key"],
                                 batch_key=in_data["batch_key"])
def create_float_account(**in_data):
    """Create a CreateAccount txn and wrap it in a batch and list.

    Args:
        txn_key(sawtooth_signing.Signer): signer created from user zeroth public key
        parent_zero_pub(string): zeroth account key of the pub who floated this trnasaction
        batch_key(sawtooth_signing.Signer):  signer created from QCI mnemonic zero private key,
        pancard(str): pancard of the user ,
        phone_number(str): phone_number of the user,
        email(str): email of the user,
        claimed(bool): If this float account is claimed or not,
        claimed_by(str): Public key of the user for whom this float_acc transaction,
        create_asset_index(int): random key index at which the first asset was created,
        parent_pub(str): public key of the parent ,
        parent_idx(str): Required to be appened to parent accoutn flt_key_inds, key_index,
        time=time.time();
        indian_time=indian_time_stamp(),
        claimed_on(str): Date on which this flt account was claimed and converted to create account)
        parent_zero_pub: parent zero pub required for calcualting parent address
        parent_role=parent["role"],
        user_role=user_data["role"]

    Returns:
        tuple: List of Batch, signature tuple
    """
    logging.info(f"THis is the data received in trsaction ceratrion {in_data}")

    inputs = [
        addresser.create_organization_account_address(
            account_id=in_data["parent_zero_pub"], index=0),
        addresser.float_account_address(
            account_id=in_data["txn_key"].get_public_key().as_hex(),
            index=in_data["parent_idx"])
    ]

    logging.info(
        f"THe account address for the parent on blockchain {inputs[0]}")
    logging.info(f"THe float account address for the user {inputs[1]}")
    outputs = [
        addresser.create_organization_account_address(
            account_id=in_data["parent_zero_pub"], index=0),
        addresser.float_account_address(
            account_id=in_data["txn_key"].get_public_key().as_hex(),
            index=in_data["parent_idx"])
    ]

    if in_data["child_zero_pub"]:

        child_address = addresser.child_account_address(
            account_id=in_data["child_zero_pub"], index=0)
        logging.info(f"CHILD address is {child_address}")
        inputs.append(child_address)
        outputs.append(child_address)

    logging.info(f"INPUTS ADDRESSES --<{inputs}>--")
    logging.info(f"OUTPUTS ADDRESSES --<{outputs}>--")

    float_account = payload_pb2.CreateFloatAccount(
        claimed_on=in_data["claimed_on"],
        org_name=in_data["org_name"],
        pancard=in_data["pancard"],
        gst_number=in_data["gst_number"],
        tan_number=in_data["tan_number"],
        phone_number=in_data["phone_number"],
        email=in_data["email"],
        claimed=in_data["claimed"],
        claimed_by=in_data["claimed_by"],
        create_asset_idxs=in_data["create_asset_idxs"],
        parent_idx=in_data["parent_idx"],
        time=in_data["time"],
        indian_time=in_data["indian_time"],
        parent_role=in_data["parent_role"],
        role=in_data["role"],
        parent_zero_pub=in_data["parent_zero_pub"],
        nonce=in_data["nonce"],
        nonce_hash=in_data["nonce_hash"],
        signed_nonce=in_data["signed_nonce"],
        child_zero_pub=in_data["child_zero_pub"])

    logging.info(float_account)
    logging.info(
        f"THe serialized protobuf for float_account is {float_account}")

    payload = payload_pb2.TransactionPayload(
        payload_type=payload_pb2.TransactionPayload.CREATE_FLOAT_ACCOUNT,
        create_float_account=float_account)

    return make_header_and_batch(payload=payload,
                                 inputs=inputs,
                                 outputs=outputs,
                                 txn_key=in_data["txn_key"],
                                 batch_key=in_data["batch_key"])
    def set_asset(self, public, payload):
        """
        payload will have the CreateAsset in the payload
        public: hex public key with whose private key transaction was signed
        account: could be a float account or account
        account_type: could be FLOAT_ACCOUNT or CREATE_ACCOUNT
        """
        logging.info("Payload  in set_asset <<{}>>".format(payload))
        if payload.flt_account_parent_pub:
            account_address = addresser.float_account_address(
                account_id=payload.flt_account_parent_pub,
                index=payload.flt_account_parent_idx)
            logging.info("Updating create_asset_idxs in float_account\
                at {}".format(account_address))
            float_account = self.get_flt_account(
                public_key=payload.flt_account_parent_pub,
                index=payload.flt_account_parent_idx)
            self.update_asset_index(account_address, float_account,
                                    payload.idx)

        else:
            account_address = addresser.create_organization_account_address(
                account_id=payload.zero_pub, index=0)
            logging.info("Updating create_asset_idxs in \
                    organization_account at {}".format(account_address))
            organization_account = self.get_organization(
                public_key=payload.zero_pub)

            self.update_asset_index(account_address, organization_account,
                                    payload.idx)

        ##if this is present that means that this asset is being created by child
        ##of the organization, so the payload.idx needs to be appended to the
        ##create_asset_idxs array of the child too
        if payload.child_zero_pub:
            account_address = addresser.child_account_address(
                account_id=payload.child_zero_pub, index=0)

            child_account = self.get_child(payload.child_zero_pub, 0)
            self.update_asset_index(account_address, child_account,
                                    payload.idx)

        address = addresser.create_asset_address(asset_id=public,
                                                 index=payload.idx)

        asset = create_empty_asset()

        asset.key = payload.key
        asset.url = payload.url
        asset.time = payload.time
        asset.indiantime = payload.indiantime
        asset.file_name = payload.file_name
        asset.file_hash = payload.file_hash
        asset.idx = payload.idx
        asset.master_key = payload.master_key
        asset.master_url = payload.master_url
        asset.expired_on = payload.expired_on
        asset.role = payload.role
        asset.public = public
        asset.child_zero_pub = payload.child_zero_pub
        if payload.scope:
            asset.scope.group = payload.scope.group
            asset.scope.sub_group = payload.scope.sub_group
            asset.scope.field = payload.scope.field
            asset.scope.nature = payload.scope.nature
            asset.scope.operations = payload.scope.operations
            asset.scope.description = payload.scope.description

        logging.info(asset)
        logging.info("Account after serialization %s",
                     asset.SerializeToString())
        return self._context.set_state({address: asset.SerializeToString()},
                                       self._timeout)
    def set_float_account(self, public_key, payload):

        logging.info("Paylaod from set_float_account {}".format(payload))

        ##change idx in the account present at public key input_data["parent_zero_pub"]
        self.set_org_float_account_idxs(payload.parent_zero_pub,
                                        payload.parent_idx)

        ##this implies that this float account being created by the child of
        ##payload.parent_role
        if payload.child_zero_pub:
            self.set_child_float_account_idxs(payload.child_zero_pub,
                                              payload.parent_idx)

        ##here the parent pub is the nth index key of the parent on thich
        ##this float account address is generated
        address = addresser.float_account_address(account_id=public_key,
                                                  index=payload.parent_idx)

        float_account = create_empty_float_account()

        logging.info("This is the value of create_asset_idxs \
                        {}".format(payload.create_asset_idxs))
        float_account.pancard = payload.pancard
        float_account.phone_number = payload.phone_number
        float_account.email = payload.email
        float_account.gst_number = payload.gst_number
        float_account.tan_number = payload.tan_number
        float_account.org_name = payload.org_name

        ##will be changed when the person or orgnization claims this account
        float_account.claimed = payload.claimed
        float_account.claimed_by = payload.claimed_by
        float_account.claimed_on = payload.claimed_on

        ##this is not required because create_asset_idxs will wlays be empty
        ##when intilizing float_account
        #float_account.create_asset_idxs=input_data["create_asset_idxs"]
        float_account.time = payload.time
        float_account.indian_time = payload.indian_time

        ##parent_pub at random_idxs in float_account_idxs array with which this
        ##float account address was generated
        float_account.parent_idx = payload.parent_idx

        ##this was required to check the signed_nonce signed by the zeroth private
        ##key of the creator
        float_account.parent_zero_pub = payload.parent_zero_pub
        float_account.parent_role = payload.parent_role
        float_account.role = payload.role
        float_account.public = public_key

        ##so that we can track if its been made by a child of the organiation or not
        ##it will be an empty field if the organization themselves made the account
        float_account.child_zero_pub = payload.child_zero_pub
        float_account.parent_zero_pub = payload.parent_zero_pub

        ##so that we can later check who actually made this float_account and
        ## and was a vald account
        float_account.nonce = payload.nonce
        float_account.nonce_hash = payload.nonce_hash
        float_account.signed_nonce = payload.signed_nonce

        logging.info(float_account)

        logging.info("Account after serialization %s",
                     float_account.SerializeToString())
        return self._context.set_state(
            {address: float_account.SerializeToString()}, self._timeout)
Exemple #14
0
async def send_float_account(**in_data):
    """
        txn_key(sawtooth_signing.Signer): signer created from user zeroth public key
        batch_key(sawtooth_signing.Signer):  signer created from QCI mnemonic zero private key,
        pancard(str): pancard of the user ,
        phone_number(str): phone_number of the user,
        email(str): email of the user,
        claimed(bool): If this float account is claimed or not,
        claimed_by(str): Public key of the user for whom this float_acc transaction,
        create_asset_index(int): random key index at which the first asset was created,
        parent_pub(str): public key of the parent ,
        parent_idx(str): Required to be appened to parent accoutn flt_key_inds, key_index,
        time=time.time();
        indian_time=indian_time_stamp(),
        claimed_on(str): Date on which this flt account was claimed and converted to create account)
    """
    inputs = [addresser.create_organization_account_address(
                        account_id=in_data["parent_zero_pub"],
                        index=0),
            addresser.float_account_address(
                        account_id=in_data["txn_key"].get_public_key().as_hex(),
                        index=in_data["parent_idx"]
         )
        ]

    logging.info(f"THe account address for the parent on blockchain {inputs[0]}")
    logging.info(f"THe float account address for the user {inputs[1]}")
    outputs = [addresser.create_organization_account_address(
                            account_id=in_data["parent_zero_pub"],
                            index=0),
                addresser.float_account_address(
                            account_id=in_data["txn_key"].get_public_key().as_hex(),
                            index=in_data["parent_idx"]
             )
            ]


    if in_data["child_zero_pub"]:

        child_address = addresser.child_account_address(
                    account_id=in_data["child_zero_pub"],
                    index=0
        )
        logging.info(f"CHILD address is {child_address}")
        inputs.append(child_address)
        outputs.append(child_address)


    logging.info(f"INPUTS ADDRESSES --<{inputs}>--")
    logging.info(f"OUTPUTS ADDRESSES --<{outputs}>--")


    float_account = payload_pb2.CreateFloatAccount(
              claimed_on=in_data["claimed_on"],
              org_name=in_data["org_name"],
              pancard=in_data["pancard"],
              gst_number=in_data["gst_number"],
              tan_number=in_data["tan_number"],
              phone_number=in_data["phone_number"],
              email=in_data["email"],
              claimed=in_data["claimed"],
              claimed_by=in_data["claimed_by"],
              create_asset_idxs=in_data["create_asset_idxs"],
              parent_idx=in_data["parent_idx"],
              time=in_data["time"],
              indian_time=in_data["indian_time"],
              parent_role=in_data["parent_role"],
              role=in_data["role"],
              parent_zero_pub=in_data["parent_zero_pub"],
              nonce=in_data["nonce"],
              nonce_hash=in_data["nonce_hash"],
              signed_nonce=in_data["signed_nonce"],
              child_zero_pub=in_data["child_zero_pub"]
    )

    logging.info(float_account)
    logging.info(f"THe serialized protobuf for float_account is {float_account}")

    payload = payload_pb2.TransactionPayload(
        payload_type=payload_pb2.TransactionPayload.CREATE_FLOAT_ACCOUNT,
        create_float_account=float_account)

    transaction_ids, batches, batch_id, batch_list_bytes= make_header_and_batch(
        payload=payload,
        inputs=inputs,
        outputs=outputs,
        txn_key=in_data["txn_key"],
        batch_key=in_data["batch_key"])


    logging.info(f"This is the batch_id {batch_id}")

    rest_api_response = await messaging.send(
        batch_list_bytes,
        in_data["config"])


    try:
        result = await  messaging.wait_for_status(batch_id, in_data["config"])
    except (ApiBadRequest, ApiInternalError) as err:
        #await auth_query.remove_auth_entry(request.app.config.DB_CONN, request.json.get('email'))
        raise err
        return False, False

    return transaction_ids, batch_id
Exemple #15
0
async def submit_float_account(app, requester, user):

    ##retrive float_account from parent

    ## handle if the parent is actually a child account, then the flt_acc_idxs
    ## of the parent must be used

    ##elseif organization is directly creating another org account then its
    ## own flt_account_idxs must be used

    ##a junk entry needs to be sent which is A once signed by the parent orgnisation of the
    ## child or the organization itself zeroth_private_key, which that the float_account is
    ## actually being sent by the concerned authority, otherwise anyone can generate any
    ## random keys and then make a float_transaction because we are not checking any other details
    ## for cros checking


    if requester["role"] == "CHILD":
        ##now find the parent pub of this child to track the parent
        ##organization account
        ##child will get the flt_acc_idxs of the parent organization
        org_address = addresser.create_organization_account_address(
                    requester["parent_zero_pub"], 0)

        org_account = await deserialize_state.deserialize_org_account(
                    app.config.REST_API_URL, org_address)

        logging.info(org_account)
        ##lets chaeck if the parent user_id hash matched with the child parent_id
        if requester["parent_idx"] not in org_account["child_account_idxs"]:
            raise Exception("Child parent_idx not in parent org child_account_idxs")


        if requester["org_name"] != org_account["org_name"]:
            raise Exception("Child org_name is different from  parent")


        ##since child was created from the PUblic key present at parent_idx at the
        ##parent org mnemonic, We need to get that so that we can generated child
        ##adddress, Remember, child_account_addresses generates from parent_org
        ##not with the zeroth key of the child mnemonic

        ##TODO: you can also check whether the child address generated from
        #parent org public key pair at requester parent_idx is same as requester
        ## address
        ##float_account_idxs array of the child's parent organisation

        flt_acc_idxs = org_account.get("float_account_idxs")

        ##now we need to decrypt the parent mnemonic so that we can get the Public/private key
        ##pair corresponding to the the random index
        parent_id = org_account["user_id"]
        logging.info(f"Parent id for the child is {parent_id} and\
            float_account_idxs are {flt_acc_idxs}")

        org_db = await accounts_query.find_on_key(app, "user_id", parent_id)

        logging.info(org_db)
        if org_db["role"] != "ADMIN":
            decrypted_mnemonic = await ledger_utils.decrypted_user_mnemonic(
                                app,
                                org_db["encrypted_admin_mnemonic"],
                                org_db["role"])
        else:
            decrypted_mnemonic = app.config.ADMIN_MNEMONIC
        logging.info(decrypted_mnemonic)


        nth_keys = await remote_calls.key_index_keys(app,
                                decrypted_mnemonic, [requester["parent_idx"]])


        nth_priv, nth_pub = nth_keys[str(requester["parent_idx"])]["private_key"], \
                            nth_keys[str(requester["parent_idx"])]["public_key"]


        zero_pub = org_db["acc_zero_pub"]
        parent_role = org_db["role"]
        child_zero_pub = nth_pub

    else: #orgnisation itself is creating this float_account
        logging.info(requester)

        ##float_account_idxs array of the orgnization itself
        flt_acc_idxs = await accounts_query.get_field(app, requester["user_id"],
                "float_account_idxs")
        flt_acc_idxs = flt_acc_idxs.get("float_account_idxs")

        logging.info(f"Float account indxs for the orgnization {flt_acc_idxs}")
        decrypted_mnemonic = await ledger_utils.decrypted_user_mnemonic(app,
                                requester["encrypted_admin_mnemonic"],
                                requester["role"])

        logging.info(decrypted_mnemonic)

        zero_pub = requester["acc_zero_pub"]
        parent_role = requester["role"]
        child_zero_pub = None


    logging.info(f"This is the decrypted mnemonic for parent {decrypted_mnemonic}")

    ##This will generate a new key which doesnt exists in the flt_acc_idxs array
    key_index = await ledger_utils.generate_key_index(flt_acc_idxs)
    logging.info(f"THis is the key index for parent {key_index}")

    nth_keys = await remote_calls.key_index_keys(app,
                                        decrypted_mnemonic, [key_index, 0])


    nth_priv, nth_pub = nth_keys[str(key_index)]["private_key"], \
                            nth_keys[str(key_index)]["public_key"]


    ##getting zeroth private key to be used later

    zeroth_priv, zeroth_pub = nth_keys[str(0)]["private_key"], \
                            nth_keys[str(0)]["public_key"]

    flt_acc_address = addresser.float_account_address(nth_pub,
                key_index)

    logging.info(f"This is the flt acc addressfor user {flt_acc_address}")
    logging.info(f"Checking if valid account address has been generated\
                                    {addresser.address_is(flt_acc_address)}")


    ##signer created from the parent key
    flt_acc_signer=upload_utils.create_signer(nth_priv)

    ##sending signatures, A nonce signed by zeroth_private_key
    nonce = random.randint(2**20, 2**31)
    nonce_hash = hashlib.sha224(str(nonce).encode()).hexdigest()
    hex_signatures = signatures.ecdsa_signature(zeroth_priv, nonce)


    ##hashing gst number and tan number if present
    if user.get("gst_number"):
        gst_number = hashlib.sha224(user["gst_number"].encode()).hexdigest()
    else:
        gst_number = None

    if user.get("tan_number"):
        tan_number = hashlib.sha224(user["tan_number"]\
                            .encode()).hexdigest()
    else:
        tan_number = None

    ##import from ledger.account import float_account
    transaction_data= {"config": app.config,
                        "txn_key": flt_acc_signer,
                        "batch_key": app.config.SIGNER,
                        "org_name": user["org_name"],
                        "pancard": hashlib.sha224(user["pancard"]\
                                            .encode()).hexdigest(),
                        "gst_number": gst_number,
                        "tan_number": tan_number,
                        "phone_number": user["phone_number"],
                        "email": user["email"],
                        "claimed": False,
                        "claimed_by": None,
                        "create_asset_idxs": [],
                        "parent_pub": nth_pub,
                        "parent_idx": key_index,
                        "time": int(time.time()),
                        "indian_time": upload_utils.indian_time_stamp(),
                        "parent_zero_pub": zero_pub,
                        "parent_role": parent_role,
                        "role": user["role"],
                        "claimed_on": None,
                        "nonce": nonce,
                        "nonce_hash": nonce_hash,
                        "signed_nonce": hex_signatures,
                        "child_zero_pub": child_zero_pub
                        }

    transaction_ids, batch_id = await send_float_account(**transaction_data)

    if batch_id:
        logging.debug(user)
        ##if successful, insert this user in pending_users table
        user.update({"parent_pub": nth_pub,
                    "parent_idx": key_index,
                    "time": transaction_data["time"],
                    "indian_time": transaction_data["indian_time"],
                    "parent_zero_pub": transaction_data["parent_zero_pub"],
                    "parent_role": transaction_data["parent_role"],
                    "transaction_id": transaction_ids[0],
                    "batch_id": batch_id,
                    "child_zero_pub": child_zero_pub,
                    })
        logging.debug(f"User after submitting float_Account trasaction {user}")
        await accounts_query.insert_pending_account(app, user)

    if requester["role"] == "CHILD":
        ##update parent create_flt_idcs array
        await accounts_query.update_flt_acc_idxs(app, org_db["user_id"], key_index)
        ##update float_account_idxs of the child also, so that we would
        ##know which child created which float_account_idxs
        await accounts_query.update_flt_acc_idxs(app, requester["user_id"], key_index)

    else:
        await accounts_query.update_flt_acc_idxs(app, requester["user_id"], key_index)

    ##return new user data whose float_account has just been created
    return user