Esempio n. 1
0
 def ec_recover(message, signed_message):
     w3 = Web3Provider.get_web3()
     v, r, s = split_signature(w3, w3.toBytes(hexstr=signed_message))
     signature_object = SignatureFix(vrs=(v, big_endian_to_int(r), big_endian_to_int(s)))
     return Web3Provider.get_web3().personal.ecRecover(
         message,
         signature_object.to_hex_v_hacked())
Esempio n. 2
0
def create_agreement(did,
                     service_definition_id,
                     agreement_id,
                     consumer_address,
                     ocean=None):
    assert consumer_address and Web3Provider.get_web3().isChecksumAddress(
        consumer_address), f'Invalid consumer address {consumer_address}'

    asset = ocean.assets.resolve(did)
    asset_id = asset.asset_id
    service_agreement = ServiceAgreement.from_ddo(service_definition_id, asset)
    agreement_template = ocean.keeper.escrow_access_secretstore_template.get_instance(
    )

    publisher_address = Web3Provider.get_web3().toChecksumAddress(
        asset.publisher)
    condition_ids = service_agreement\
        .generate_agreement_condition_ids(
            agreement_id,
            asset_id,
            consumer_address,
            publisher_address,
            ocean.keeper
        )
    time_locks = service_agreement.conditions_timelocks
    time_outs = service_agreement.conditions_timeouts
    return agreement_template.create_agreement(agreement_id, asset_id,
                                               condition_ids, time_locks,
                                               time_outs, consumer_address,
                                               ocean.account)
Esempio n. 3
0
def test_create_data_asset(publisher_ocean_instance, consumer_ocean_instance):
    """
    Setup accounts and asset, register this asset on Aquarius (MetaData store)
    """
    pub_ocn = publisher_ocean_instance
    cons_ocn = consumer_ocean_instance

    logging.debug("".format())
    sample_ddo_path = get_resource_path('ddo', 'ddo_sa_sample.json')
    assert sample_ddo_path.exists(), "{} does not exist!".format(
        sample_ddo_path)

    ##########################################################
    # Setup 2 accounts
    ##########################################################
    aquarius_acct = pub_ocn.main_account
    consumer_acct = cons_ocn.main_account

    # ensure Ocean token balance
    if pub_ocn.accounts.balance(aquarius_acct).ocn == 0:
        rcpt = pub_ocn.accounts.request_tokens(aquarius_acct, 200)
        Web3Provider.get_web3().eth.waitForTransactionReceipt(rcpt)
    if cons_ocn.accounts.balance(consumer_acct).ocn == 0:
        rcpt = cons_ocn.accounts.request_tokens(consumer_acct, 200)
        Web3Provider.get_web3().eth.waitForTransactionReceipt(rcpt)

    # You will need some token to make this transfer!
    assert pub_ocn.accounts.balance(aquarius_acct).ocn > 0
    assert cons_ocn.accounts.balance(consumer_acct).ocn > 0

    ##########################################################
    # Create an Asset with valid metadata
    ##########################################################
    asset = DDO(json_filename=sample_ddo_path)

    ##########################################################
    # List currently published assets
    ##########################################################
    meta_data_assets = pub_ocn.assets.search('')
    if meta_data_assets:
        print("Currently registered assets:")
        print(meta_data_assets)

    if asset.did in meta_data_assets:
        pub_ocn.assets.resolve(asset.did)
        pub_ocn.assets.retire(asset.did)
    # Publish the metadata
    new_asset = pub_ocn.assets.create(asset.metadata, aquarius_acct)

    # TODO: Ensure returned metadata equals sent!
    # get_asset_metadata only returns 'base' key, is this correct?
    published_metadata = cons_ocn.assets.resolve(new_asset.did)

    assert published_metadata
    # only compare top level keys
    assert sorted(list(
        asset.metadata['base'].keys())).remove('files') == sorted(
            list(published_metadata.metadata['base'].keys())).remove(
                'encryptedFiles')
Esempio n. 4
0
    def get_registered_attribute(self, did_bytes):
        """

        Example of event logs from event_filter.get_all_entries():
        [AttributeDict(
            {'args': AttributeDict(
                {'did': b'\x02n\xfc\xfb\xfdNM\xe9\xb8\xe0\xba\xc2\xb2\xc7\xbeg\xc9/\x95\xc3\x16\
                           x98G^\xb9\xe1\xf0T\xce\x83\xcf\xab',
                 'owner': '0xAd12CFbff2Cb3E558303334e7e6f0d25D5791fc2',
                 'value': 'http://localhost:5000',
                 'checksum': '0x...',
                 'updatedAt': 1947}),
             'event': 'DIDAttributeRegistered',
             'logIndex': 0,
             'transactionIndex': 1,
             'transactionHash': HexBytes(
             '0xea9ca5748d54766fb43fe9660dd04b2e3bb29a0fbe18414457cca3dd488d359d'),
             'address': '0x86DF95937ec3761588e6DEbAB6E3508e271cC4dc',
             'blockHash': HexBytes(
             '0xbbbe1046b737f33b2076cb0bb5ba85a840c836cf1ffe88891afd71193d677ba2'),
             'blockNumber': 1947})]

        """
        result = None
        did = Web3Provider.get_web3().toHex(did_bytes)
        block_number = self.get_block_number_updated(did_bytes)
        logger.debug(f'got blockNumber {block_number} for did {did}')
        if block_number == 0:
            raise OceanDIDNotFound(
                f'DID "{did}" is not found on-chain in the current did registry. '
                f'Please ensure assets are registered in the correct keeper contracts. '
                f'The keeper-contracts DIDRegistry address is {self.address}')

        block_filter = self._get_event_filter(did=did, from_block=block_number, to_block=block_number)
        log_items = block_filter.get_all_entries(max_tries=5)
        if log_items:
            log_item = log_items[-1].args
            value = log_item['_value']
            block_number = log_item['_blockNumberUpdated']
            result = {
                'checksum': log_item['_checksum'],
                'value': value,
                'block_number': block_number,
                'did_bytes': log_item['_did'],
                'owner': Web3Provider.get_web3().toChecksumAddress(log_item['_owner']),
            }
        else:
            logger.warning(f'Could not find {DIDRegistry.DID_REGISTRY_EVENT_NAME} event logs for '
                           f'did {did} at blockNumber {block_number}')
        return result
Esempio n. 5
0
    def get_tx_receipt(tx_hash):
        """
        Get the receipt of a tx.

        :param tx_hash: hash of the transaction
        :return: Tx receipt
        """
        try:
            Web3Provider.get_web3().eth.waitForTransactionReceipt(tx_hash,
                                                                  timeout=20)
        except Timeout:
            logger.info('Waiting for transaction receipt timed out.')
            return
        return Web3Provider.get_web3().eth.getTransactionReceipt(tx_hash)
Esempio n. 6
0
def test_agreement():
    template_id = Web3Provider.get_web3().toChecksumAddress('0x' + ('f' * 40))
    agreement_id = '0x' + ('e' * 64)
    access_id = '0x' + ('a' * 64)
    lock_id = '0x' + ('b' * 64)
    escrow_id = '0x' + ('c' * 64)

    signature = ServiceAgreement.generate_service_agreement_hash(
        template_id, [access_id, lock_id, escrow_id], [0, 0, 0], [0, 0, 0],
        agreement_id)

    print({signature})
    assert signature == Web3Provider.get_web3().toBytes(
        hexstr="0x67901517c18a3d23e05806fff7f04235cc8ae3b1f82345b8bfb3e4b02b5800c7"), \
        "The signatuere is not correct."
Esempio n. 7
0
    def _get_event_filter(self, did=None, owner=None, from_block=0, to_block='latest'):
        _filters = {}
        if did is not None:
            _filters['_did'] = Web3Provider.get_web3().toBytes(hexstr=did)
        if owner is not None:
            _filters['_owner'] = Web3Provider.get_web3().toBytes(hexstr=owner)

        block_filter = EventFilter(
            DIDRegistry.DID_REGISTRY_EVENT_NAME,
            getattr(self.events, DIDRegistry.DID_REGISTRY_EVENT_NAME),
            from_block=from_block,
            to_block=to_block,
            argument_filters=_filters
        )
        return block_filter
Esempio n. 8
0
    def register(self, did, checksum, url, account, providers=None):
        """
        Register or update a DID on the block chain using the DIDRegistry smart contract.

        :param did: DID to register/update, can be a 32 byte or hexstring
        :param checksum: hex str hash of TODO
        :param url: URL of the resolved DID
        :param account: instance of Account to use to register/update the DID
        :param providers: list of addresses of providers to be allowed to serve the asset and play
            a part in creating and fulfilling service agreements
        :return: Receipt
        """

        did_source_id = did_to_id_bytes(did)
        if not did_source_id:
            raise ValueError(f'{did} must be a valid DID to register')

        if not urlparse(url):
            raise ValueError(f'Invalid URL {url} to register for DID {did}')

        if checksum is None:
            checksum = Web3Provider.get_web3().toBytes(0)

        if not isinstance(checksum, bytes):
            raise ValueError(f'Invalid checksum value {checksum}, must be bytes or string')

        if account is None:
            raise ValueError('You must provide an account to use to register a DID')

        transaction = self._register_attribute(
            did_source_id, checksum, url, account, providers or []
        )
        receipt = self.get_tx_receipt(transaction)
        return receipt
Esempio n. 9
0
    def subscribe_condition_fulfilled(self,
                                      agreement_id,
                                      timeout,
                                      callback,
                                      args,
                                      timeout_callback=None,
                                      wait=False):
        """
        Subscribe to the condition fullfilled event.

        :param agreement_id: id of the agreement, hex str
        :param timeout:
        :param callback:
        :param args:
        :param timeout_callback:
        :param wait: if true block the listener until get the event, bool
        :return:
        """
        logger.info(
            f'Subscribing {self.FULFILLED_EVENT} event with agreement id {agreement_id}.'
        )
        return self.subscribe_to_event(
            self.FULFILLED_EVENT,
            timeout, {
                '_agreementId':
                Web3Provider.get_web3().toBytes(hexstr=agreement_id)
            },
            callback=callback,
            timeout_callback=timeout_callback,
            args=args,
            wait=wait)
    def subscribe_agreement_created(self,
                                    agreement_id,
                                    timeout,
                                    callback,
                                    args,
                                    wait=False):
        """
        Subscribe to an agreement created.

        :param agreement_id: id of the agreement, hex str
        :param timeout:
        :param callback:
        :param args:
        :param wait: if true block the listener until get the event, bool
        :return:
        """
        logger.info(
            f'Subscribing {self.AGREEMENT_CREATED_EVENT} event with agreement id {agreement_id}.'
        )
        return self.subscribe_to_event(
            self.AGREEMENT_CREATED_EVENT,
            timeout, {
                '_agreementId':
                Web3Provider.get_web3().toBytes(hexstr=agreement_id)
            },
            callback=callback,
            args=args,
            wait=wait)
Esempio n. 11
0
def get_default_account(config):
    account_address = config.get('keeper-contracts', 'account.address')
    account_password = config.get('keeper-contracts', 'account.password')
    account = Account(
        Web3Provider.get_web3().toChecksumAddress(account_address),
        account_password)
    return account
Esempio n. 12
0
def test_agreement_hash(publisher_ocean_instance):
    """
    This test verifies generating agreement hash using fixed inputs and ddo example.
    This will make it easier to compare the hash generated from different languages.
    """
    w3 = Web3Provider.get_web3()
    did = "did:op:cb36cf78d87f4ce4a784f17c2a4a694f19f3fbf05b814ac6b0b7197163888865"
    template_id = w3.toChecksumAddress(
        "0x00bd138abd70e2f00903268f3db08f2d25677c9e")
    agreement_id = '0xf136d6fadecb48fdb2fc1fb420f5a5d1c32d22d9424e47ab9461556e058fefaa'
    ddo = get_ddo_sample()

    sa = ServiceAgreement.from_service_dict(
        ddo.get_service(service_type='Access').as_dictionary())
    sa.service_agreement_template.set_template_id(template_id)
    assert template_id == sa.template_id, ''
    assert did == ddo.did
    # Don't generate condition ids, use fixed ids so we get consistent hash
    # (access_id, lock_id, escrow_id) = sa.generate_agreement_condition_ids(
    #     agreement_id, ddo.asset_id, consumer, publisher, keeper)
    access_id = '0x2d7c1d60dc0c3f52aa9bd71ffdbe434a0e58435571e64c893bc9646fea7f6ec1'
    lock_id = '0x1e265c434c14e668695dda1555088f0ea4356f596bdecb8058812e7dcba9ee73'
    escrow_id = '0xe487fa6d435c2f09ef14b65b34521302f1532ac82ba8f6c86116acd8566e2da3'
    print(f'condition ids: \n'
          f'{access_id} \n'
          f'{lock_id} \n'
          f'{escrow_id}')
    agreement_hash = ServiceAgreement.generate_service_agreement_hash(
        sa.template_id, (access_id, lock_id, escrow_id),
        sa.conditions_timelocks, sa.conditions_timeouts, agreement_id)
    print('agreement hash: ', agreement_hash.hex())
    expected = '0x96732b390dacec0f19ad304ac176b3407968a0184d01b3262687fd23a3f0995e'
    print('expected hash: ', expected)
    assert agreement_hash.hex() == expected, 'hash does not match.'
Esempio n. 13
0
    def get_network_id():
        """
        Return the ethereum network id calling the `web3.version.network` method.

        :return: Network id, int
        """
        return int(Web3Provider.get_web3().version.network)
Esempio n. 14
0
    def unlock_account(account):
        """
        Unlock the account.

        :param account: Account
        :return:
        """
        return Web3Provider.get_web3().personal.unlockAccount(account.address, account.password)
Esempio n. 15
0
    def to_checksum_address(address):
        """
        Validate the address provided.

        :param address: Address, hex str
        :return: address, hex str
        """
        return Web3Provider.get_web3().toChecksumAddress(address)
Esempio n. 16
0
    def _load(contract_name):
        """Retrieve the contract instance for `contract_name` that represent the smart
        contract in the keeper network.

        :param contract_name: str name of the solidity keeper contract without the network name.
        :return: web3.eth.Contract instance
        """
        contract_definition = ContractHandler.get_contract_dict_by_name(
            contract_name)
        address = Web3Provider.get_web3().toChecksumAddress(
            contract_definition['address'])
        abi = contract_definition['abi']
        contract = Web3Provider.get_web3().eth.contract(address=address,
                                                        abi=abi)
        ContractHandler._contracts[contract_name] = (contract,
                                                     ConciseContract(contract))
        return ContractHandler._contracts[contract_name]
Esempio n. 17
0
    def get_ether_balance(address):
        """
        Get balance of an ethereum address.

        :param address: address, bytes32
        :return: balance, int
        """
        return Web3Provider.get_web3().eth.getBalance(address, block_identifier='latest')
Esempio n. 18
0
def get(did):
    register_values = Keeper.get_instance().did_registry.contract_concise\
        .getDIDRegister(did_to_id(did))
    response = []
    if register_values and len(register_values) == 5:
        response = DIDRegisterValues(*register_values)._asdict()
        response['last_checksum'] = Web3Provider.get_web3()\
            .toHex(response['last_checksum'])
    return response
Esempio n. 19
0
    def token_approve(self, spender_address, price, from_account):
        """
        Approve the passed address to spend the specified amount of tokens.

        :param spender_address: Account address, str
        :param price: Asset price, int
        :param from_account: Account address, str
        :return: bool
        """
        if not Web3Provider.get_web3().isChecksumAddress(spender_address):
            spender_address = Web3Provider.get_web3().toChecksumAddress(
                spender_address)

        tx_hash = self.send_transaction('approve', (spender_address, price),
                                        transact={
                                            'from': from_account.address,
                                            'passphrase': from_account.password
                                        })
        return self.get_tx_receipt(tx_hash).status == 1
Esempio n. 20
0
    def sign_hash(msg_hash, account):
        """

        :param msg_hash:
        :param account: Account
        :return:
        """
        return Web3Provider.get_web3().personal.sign(
            msg_hash, account.address, account.password
        )
Esempio n. 21
0
def test_get_publickey_from_address(publisher_ocean_instance):
    from eth_keys.exceptions import BadSignature
    for account in publisher_ocean_instance.accounts.list():
        try:
            pub_key = utilities.get_public_key_from_address(Web3Provider.get_web3(),
                                                            account)
            assert pub_key.to_checksum_address() == account.address, \
                'recovered public key address does not match original address.'
        except BadSignature:
            pytest.fail("BadSignature")
        except ValueError:
            pass
Esempio n. 22
0
def generate_multi_value_hash(types, values):
    """
    Return the hash of the given list of values.
    This is equivalent to packing and hashing values in a solidity smart contract
    hence the use of `soliditySha3`.

    :param types: list of solidity types expressed as strings
    :param values: list of values matching the `types` list
    :return: bytes
    """
    assert len(types) == len(values)
    return Web3Provider.get_web3().soliditySha3(types, values)
Esempio n. 23
0
def access(ctx):
    ocean, account = ctx.obj['ocean'], ctx.obj['account']
    template = ocean.keeper.escrow_access_secretstore_template.get_instance()
    filter = template.events.AgreementCreated.createFilter(fromBlock='latest')
    while True:
        for event in filter.get_new_entries():
            access_provider = event['args']['_accessProvider']
            if access_provider == account.address:
                agreement_id = Web3Provider.get_web3().toHex(
                    event['args']['_agreementId'])
                access_consumer = event['args']['_accessConsumer']
                from .api.conditions import access_release
                access_release(ocean, account, agreement_id, access_consumer)
        time.sleep(0.5)
def ocean_agreements():
    keeper = Keeper.get_instance()
    w3 = Web3Provider.get_web3()
    did_resolver = Mock()
    ddo = get_ddo_sample()
    service = ddo.get_service(ServiceTypes.ASSET_ACCESS)
    service.update_value(
        ServiceAgreementTemplate.TEMPLATE_ID_KEY,
        w3.toChecksumAddress("0x00bd138abd70e2f00903268f3db08f2d25677c9e"))
    did_resolver.resolve = MagicMock(return_value=ddo)
    consumer_class = Mock
    consumer_class.download = MagicMock(return_value='')
    return OceanAgreements(keeper, did_resolver, AssetConsumer,
                           ConfigProvider.get_config())
Esempio n. 25
0
def listen_lock_reward(callback_agreement_created=handle_agreement_created,
                       callback_lock_reward=handle_lock_reward,
                       ocean=None):
    template = ocean.keeper.escrow_access_secretstore_template.get_instance()
    lock_reward = ocean.keeper.lock_reward_condition.get_instance()
    filters = [
        template.events.AgreementCreated.createFilter(fromBlock='latest'),
        lock_reward.events.Fulfilled.createFilter(fromBlock='latest'),
    ]

    while True:
        for _filter in filters:
            try:
                for event in _filter.get_new_entries():
                    print(
                        f"\n\n{'*'*30}\nEVENT: {event['event']}\n{'*'*30}\n\n",
                        event)
                    agreement_id = Web3Provider.get_web3().toHex(
                        event['args'].get('_agreementId', None))

                    print(ocean.agreements.status(agreement_id))

                    if event['event'] == 'AgreementCreated':
                        agreements[agreement_id] = \
                            callback_agreement_created(event=event,
                                                       agreement_id=agreement_id,
                                                       ocean=ocean)
                    elif event['event'] == 'Fulfilled':
                        if agreement_id in agreements:
                            agreement = agreements[agreement_id]
                            callback_lock_reward(event=event,
                                                 agreement_id=agreement_id,
                                                 agreement=agreement,
                                                 ocean=ocean)
                            del agreements[agreement_id]
                        else:
                            # todo clean error handling
                            print(f'error: agreement {agreement_id} '
                                  f'not in {agreements}')
                    print(ocean.agreements.status(agreement_id))
            except ValueError as e:
                print('error', e)
                # avoid hangup, refresh filters
                filters = [
                    template.events.AgreementCreated.createFilter(
                        fromBlock='latest'),
                    lock_reward.events.Fulfilled.createFilter(
                        fromBlock='latest'),
                ]
        time.sleep(0.1)
Esempio n. 26
0
def verify_signature(_address, _agreement_hash, _signature, expected_match):
    w3 = Web3Provider.get_web3()
    prefixed_hash = prepare_prefixed_hash(_agreement_hash)
    recovered_address0 = w3.eth.account.recoverHash(prefixed_hash,
                                                    signature=_signature)
    recovered_address1 = w3.eth.account.recoverHash(_agreement_hash,
                                                    signature=_signature)
    print('original address: ', _address)
    print(
        'w3.eth.account.recoverHash(prefixed_hash, signature=signature)  => ',
        recovered_address0)
    print(
        'w3.eth.account.recoverHash(agreement_hash, signature=signature) => ',
        recovered_address1)
    assert _address == (recovered_address0, recovered_address1)[expected_match], \
        'Could not verify signature using address {}'.format(_address)
Esempio n. 27
0
def get_account_from_config(config, config_account_key, config_account_password_key):
    address = None
    if config.has_option('keeper-contracts', config_account_key):
        address = config.get('keeper-contracts', config_account_key)

    if not address:
        return None

    password = None
    address = Web3Provider.get_web3().toChecksumAddress(address) if address else None
    if (address
            and address in Keeper.get_instance().accounts
            and config.has_option('keeper-contracts', config_account_password_key)):
        password = config.get('keeper-contracts', config_account_password_key)

    return Account(address, password)
Esempio n. 28
0
    def __init__(self):
        self.network_name = Keeper.get_network_name(Keeper.get_network_id())
        self.artifacts_path = ConfigProvider.get_config().keeper_path
        self.accounts = Web3Provider.get_web3().eth.accounts

        self.dispenser = Dispenser.get_instance()
        self.token = Token.get_instance()
        self.did_registry = DIDRegistry.get_instance()
        self.template_manager = TemplateStoreManager.get_instance()
        self.escrow_access_secretstore_template = EscrowAccessSecretStoreTemplate.get_instance()
        self.agreement_manager = AgreementStoreManager.get_instance()
        self.condition_manager = ConditionStoreManager.get_instance()
        self.sign_condition = SignCondition.get_instance()
        self.lock_reward_condition = LockRewardCondition.get_instance()
        self.escrow_reward_condition = EscrowRewardCondition.get_instance()
        self.access_secret_store_condition = AccessSecretStoreCondition.get_instance()
        self.hash_lock_condition = HashLockCondition.get_instance()
Esempio n. 29
0
def list_agreements(did_or_address, ocean=None):
    try:
        assert (is_did_valid(did_or_address), True)
        agreement_store = AgreementStoreManager.get_instance()
        agreement_ids = [
            Web3Provider.get_web3().toHex(_id)
            for _id in agreement_store.contract_concise \
                .getAgreementIdsForDID(did_to_id_bytes(did_or_address))
        ]
    except Exception as e:
        if did_or_address == 'me':
            did_or_address = ocean.account.address
        agreement_ids = []
        for did in ocean.assets.list(did_or_address):
            try:
                agreement_ids += list_agreements(did, ocean)
            except ValueError as e:
                pass
    return agreement_ids
Esempio n. 30
0
def list_agreements(ocn, account, did_or_address):
    try:
        assert (is_did_valid(did_or_address), True)
        agreement_store = AgreementStoreManager.get_instance()
        agreement_ids = [
            Web3Provider.get_web3().toHex(_id)
            for _id in agreement_store.contract_concise \
                .getAgreementIdsForDID(did_to_id_bytes(did_or_address))
        ]
    except Exception as e:
        if did_or_address == 'me':
            did_or_address = account.address
        agreement_ids = []
        from ocean_cli.api.assets import list_assets
        for did in list_assets(ocn, account, did_or_address):
            try:
                agreement_ids += list_agreements(ocn, account, did)
            except ValueError as e:
                pass
    return agreement_ids