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
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
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
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))
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)
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))
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))
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)
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)
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))
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
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}" )