예제 #1
0
    def used(self,
             provenance_id,
             did,
             agent_id,
             activity_id,
             signature,
             account,
             attributes=None):
        """
        Implements the W3C PROV Usage action

        :param provenance_id: provenance ID
        :param did: Identifier of the entity created
        :param agent_id: Agent Identifier
        :param activity_id: Identifier of the activity creating the new entity
        :param signature: Signature (optional) provided by the agent involved
        :param attributes: Attributes associated with the action
        :param account: Account making the call

        :return: true if the provenance event was registered correctly

        """
        try:
            receipt = self._keeper.did_registry.used(
                convert_to_bytes(provenance_id), convert_to_bytes(did),
                convert_to_bytes(agent_id), convert_to_bytes(activity_id),
                signature, account, attributes)
            return bool(receipt and receipt.status == 1)
        except Exception as e:
            logging.critical(f'On-chain call error: {e}')
            return False
예제 #2
0
    def was_derived_from(self,
                         provenance_id,
                         new_entity_did,
                         used_entity_did,
                         agent_id,
                         activity_id,
                         account,
                         attributes=None):
        """
        Implements the W3C PROV Derivation action

        :param provenance_id: provenance ID
        :param new_entity_did: Identifier of the new entity derived
        :param used_entity_did: Identifier of the entity used to derive the new entity
        :param agent_id: Agent Identifier
        :param activity_id: Identifier of the activity creating the new entity
        :param attributes: Attributes associated with the action
        :param account: Account making the call

        :return: true if the provenance event was registered correctly
        """
        try:
            receipt = self._keeper.did_registry.was_derived_from(
                convert_to_bytes(provenance_id),
                convert_to_bytes(new_entity_did),
                convert_to_bytes(used_entity_did), convert_to_bytes(agent_id),
                convert_to_bytes(activity_id), account, attributes)
            return bool(receipt and receipt.status == 1)
        except Exception as e:
            logging.critical(f'On-chain call error: {e}')
        return False
예제 #3
0
def used_by(provenance_id, did, consumer_address, activity_id, signature,
            attributes, account, keeper):
    try:
        receipt = keeper.did_registry.used(
            convert_to_bytes(provenance_id), convert_to_bytes(did),
            convert_to_bytes(consumer_address),
            convert_to_bytes(Web3Provider.get_web3().keccak(text=activity_id)),
            signature, account, attributes)
        return bool(receipt and receipt.status == 1)
    except Exception as e:
        logging.debug(f'On-chain call error: {e}')
        return False
예제 #4
0
    def balance(self, address, did):
        """
        Return nft balance.

        :param address: ethereum account address, hex str
        :param did: the id of an asset on-chain, hex str
        """
        return self._keeper.did_registry.balance(address,
                                                 convert_to_bytes(did))
예제 #5
0
 def burn(self, did, amount, account):
     """
     Burn an amount of nfts.
     :param did: the id of an asset on-chain, hex str
     :param amount: amount of nft to be burnt, int
     :param account: Account executing the action
     """
     return self._keeper.did_registry.burn(convert_to_bytes(did), amount,
                                           account)
예제 #6
0
    def get_did_provenance_events(self, did):
        """
        Search for ProvenanceAttributeRegistered events related with a specific DID
        :param did: Identifier of the asset

        :return: list of provenance events.
        """
        return self._keeper.did_registry.get_did_provenance_events(
            convert_to_bytes(did))
예제 #7
0
    def get_provenance_owner(self, provenance_id):
        """
        Get the provenance owner.
        :param provenance_id: provenance ID

        :return: String with the address owning the provenance entry
        """
        return self._keeper.did_registry.get_provenance_owner(
            convert_to_bytes(provenance_id))
예제 #8
0
 def is_provenance_delegate(self, did, delegate):
     """
     Indicates if an address is a provenance delegate for a given DID
     :param did: Identifier of the asset
     :param delegate: delegate address of the delegate
     :return: true if the address is a provenance delegate
     """
     return self._keeper.did_registry.is_provenance_delegate(
         convert_to_bytes(did), delegate)
예제 #9
0
 def remove_did_provenance_delegate(self, did, delegated_address, account):
     """
     Remove an address as delegate for a given DID
     :param did: Identifier of the asset
     :param delegated_address: delegate address of the delegate
     :param account: Account making the call
     :return: true if the address is a provenance delegate
     """
     return self._keeper.did_registry.remove_did_provenance_delegate(
         convert_to_bytes(did), delegated_address, account)
예제 #10
0
    def get_did_provenance_methods_events(self, method, did):
        """
        Search for provenance methods (used, wasGeneratedBy, etc.) given a DID

        :param method: Provenance methods to fetch
        :param did: Identifier of the asset

        :return: list of provenance events.

        """
        return self._keeper.did_registry.get_provenance_method_events(
            method, convert_to_bytes(did))
예제 #11
0
    def get_provenance_entry(self, provenance_id):
        """
        Fetch from the on-chain Provenance registry the information about one provenance event, given a provenance id

        :param provenance_id: provenance ID
        :return: information on-chain related with the provenance
        """
        provenance_entry = self._keeper.did_registry.get_provenance_entry(
            convert_to_bytes(provenance_id))
        provenance_entry['did'] = id_to_did(provenance_entry['did'])
        provenance_entry['related_did'] = id_to_did(
            provenance_entry['related_did'])
        return provenance_entry
예제 #12
0
def run(args):
    logging.debug(f"script called with args: {args}")

    # setup config
    options = {
        "keeper-contracts": {
            "keeper.url": args.node,
            "secret_store.url": args.secretstore_url,
        },
        "resources": {
            "downloads.path": args.path.as_posix(),
            "metadata.url": args.metadata_url,
            "gateway.url": args.gateway_url,
        },
    }
    config = Config(options_dict=options)
    logging.debug(f"nevermined config: {config}")

    # setup paths
    outputs_path = args.path / "outputs"

    # setup nevermined
    nevermined = Nevermined(config)

    # setup consumer
    # here we need to create a temporary key file from the credentials
    key_file = NamedTemporaryFile("w", delete=False)
    json.dump(args.credentials, key_file)
    key_file.flush()
    key_file.close()
    account = Account(
        Web3.toChecksumAddress(args.credentials["address"]),
        password=args.password,
        key_file=key_file.name,
    )

    # resolve workflow
    workflow = nevermined.assets.resolve(args.workflow)
    logging.info(f"resolved workflow {args.workflow}")
    logging.debug(f"workflow ddo {workflow.as_dictionary()}")

    workflow_owner = nevermined.assets.owner(workflow.did)
    provenance_id = uuid.uuid4()

    # get files to upload
    files = []
    index = 0
    for f in outputs_path.rglob("*"):
        if f.is_file():
            files.append({
                "index": index,
                "name": f.name,
                "path": f.as_posix(),
                "contentType": mimetypes.guess_type(f)[0],
                "contentLength": f.stat().st_size,
            })
            index += 1

    # create bucket
    minio_client = Minio(
        "172.17.0.1:8060",
        access_key="AKIAIOSFODNN7EXAMPLE",
        secret_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
        secure=False,
    )
    bucket_name = f"pod-publishing-{str(uuid.uuid4())}"
    minio_client.make_bucket(bucket_name, location="eu-central-1")
    logging.info(f"Created bucket {bucket_name}")
    minio_client.set_bucket_policy(bucket_name,
                                   s3_readonly_policy(bucket_name))
    logging.info(f"Set bucket {bucket_name} policy to READ_ONLY")
    nevermined.provenance.used(
        provenance_id=Web3.toBytes(provenance_id.bytes),
        did=convert_to_bytes(workflow.did),
        agent_id=convert_to_bytes(workflow_owner),
        activity_id=convert_to_bytes(nevermined._web3.keccak(text='compute')),
        signature=nevermined.keeper.sign_hash(add_ethereum_prefix_and_hash_msg(
            str(provenance_id)),
                                              account=account),
        account=account,
        attributes='compute')

    # upload files
    for f in files:
        minio_client.fput_object(bucket_name, f["name"], f["path"])
        logging.info(f"Uploaded file {f['path']}")

        del f["path"]
        f["url"] = minio_client.presigned_get_object(bucket_name, f["name"])
        logging.info(f"File url {f['url']}")

    # Create ddo
    publishing_date = datetime.utcnow().isoformat(timespec="seconds") + "Z"
    metadata = {
        "main": {
            "dateCreated": publishing_date,
            "datePublished": publishing_date,
            "author": "pod-publishing",
            "license": "No License Specified",
            "price": "1",
            "metadata": {
                "workflow": workflow.metadata,
                "executionId": os.getenv("EXECUTION_ID"),
            },
            "files": files,
            "type": "dataset",
        }
    }

    # publish the ddo
    ddo = None
    retry = 0
    while ddo is None:
        try:
            ddo = nevermined.assets.create(
                metadata,
                account,
                providers=[account.address],
            )
            nevermined.provenance.was_derived_from(
                provenance_id=Web3.toBytes(provenance_id.bytes),
                new_entity_did=convert_to_bytes(ddo.did),
                used_entity_did=convert_to_bytes(workflow.did),
                agent_id=convert_to_bytes(workflow_owner),
                activity_id=convert_to_bytes(
                    nevermined._web3.keccak(text='published')),
                account=account,
                attributes='published')
        except ValueError:
            if retry == 3:
                raise
            logging.warning("retrying creation of asset")
            retry += 1
            time.sleep(30)
    logging.info(f"Publishing {ddo.did}")
    logging.debug(f"Publishing ddo: {ddo}")

    # transfer ownership to the owner of the workflow
    retry = 0
    while True:
        try:
            nevermined.assets.transfer_ownership(ddo.did, workflow_owner,
                                                 account)
            nevermined.provenance.was_associated_with(
                provenance_id=Web3.toBytes(provenance_id.bytes),
                did=workflow.did,
                agent_id=workflow_owner,
                activity_id=convert_to_bytes(
                    nevermined._web3.keccak(text='transferOwnership')),
                account=account,
                attributes='transferOwnership')
        except ValueError:
            if retry == 3:
                raise
            logging.warning("retrying transfer of ownership")
            retry += 1
            time.sleep(30)
        else:
            break
    logging.info(
        f"Transfered ownership of {workflow.did} from {account.address} to {workflow_owner}"
    )