def get_signature_vrs(raw): try: hashed_raw = sha256(raw) wallet = get_aquarius_wallet() keys_pk = keys.PrivateKey(wallet.key) prefix = "\x19Ethereum Signed Message:\n32" signable_hash = Web3.solidityKeccak( ["bytes", "bytes"], [Web3.toBytes(text=prefix), Web3.toBytes(hashed_raw.digest())], ) signed = keys.ecdsa_sign(message_hash=signable_hash, private_key=keys_pk) values = { "hash": "0x" + hashed_raw.hexdigest(), "publicKey": wallet.address } values["v"] = (signed.v + 27) if signed.v <= 1 else signed.v values["r"] = (Web3.toHex(Web3.toBytes(signed.r).rjust(32, b"\0")), ) values["s"] = (Web3.toHex(Web3.toBytes(signed.s).rjust(32, b"\0")), ) except AquariusPrivateKeyException: values = {"hash": "", "publicKey": "", "r": "", "s": "", "v": ""} return values
def to_32byte_hex(val: int) -> str: """ :param val: :return: """ return Web3.toBytes(val).rjust(32, b"\0")
def convert_to_bytes(data: str) -> bytes: """ :param data: :return: """ return Web3.toBytes(text=data)
def ec_recover(message: str, signed_message: str) -> str: """ This method does not prepend the message with the prefix `\x19Ethereum Signed Message:\n32`. The caller should add the prefix to the msg/hash before calling this if the signature was produced for an ethereum-prefixed message. :param message: :param signed_message: :return: """ v, r, s = split_signature(Web3.toBytes(hexstr=signed_message)) signature_object = SignatureFix(vrs=(v, big_endian_to_int(r), big_endian_to_int(s))) return Account.recoverHash(message, signature=signature_object.to_hex_v_hacked())
def get_signature_bytes(raw): try: wallet = get_aquarius_wallet() keys_pk = keys.PrivateKey(wallet.key) message_hash = Web3.solidityKeccak( ["bytes"], [Web3.toBytes(text=raw)], ) prefix = "\x19Ethereum Signed Message:\n32" signable_hash = Web3.solidityKeccak( ["bytes", "bytes"], [Web3.toBytes(text=prefix), Web3.toBytes(message_hash)]) signed = keys.ecdsa_sign(message_hash=signable_hash, private_key=keys_pk) v = str(Web3.toHex(Web3.toBytes(signed.v))) r = str(Web3.toHex(Web3.toBytes(signed.r).rjust(32, b"\0"))) s = str(Web3.toHex(Web3.toBytes(signed.s).rjust(32, b"\0"))) signature = "0x" + r[2:] + s[2:] + v[2:] except AquariusPrivateKeyException: signature = None return signature
def _build_asset_contents(self, asset: V3Asset, encrypt: bool = False): if not encrypt: return bytes([1]), lzma.compress(Web3.toBytes(text=asset.as_text())) return bytes([2]), self._get_aquarius().encrypt(asset.as_text())
def to_32byte_hex(val): return Web3.toHex(Web3.toBytes(val).rjust(32, b'\0'))
def test_order_started(events_object, client, base_ddo_url): web3 = events_object._web3 # get_web3() block = web3.eth.block_number _ddo = new_ddo(test_account1, web3, f"dt.{block}") did = _ddo.id _, dt_contract, erc20_address = send_create_update_tx( "create", _ddo, bytes([2]), test_account1) events_object.process_current_blocks() token_contract = web3.eth.contract( abi=ERC20Template.abi, address=web3.toChecksumAddress(erc20_address)) token_contract.functions.mint( web3.toChecksumAddress(test_account3.address), web3.toWei(10, "ether")).transact({"from": test_account1.address}) # mock provider fees provider_wallet = get_aquarius_wallet() provider_fee_amount = 0 provider_data = json.dumps({"timeout": 0}, separators=(",", ":")) provider_fee_address = provider_wallet.address provider_fee_token = "0x0000000000000000000000000000000000000000" message_hash = Web3.solidityKeccak( ["bytes", "address", "address", "uint256", "uint256"], [ Web3.toHex(Web3.toBytes(text=provider_data)), provider_fee_address, provider_fee_token, provider_fee_amount, 0, ], ) pk = keys.PrivateKey(provider_wallet.key) prefix = "\x19Ethereum Signed Message:\n32" signable_hash = Web3.solidityKeccak( ["bytes", "bytes"], [Web3.toBytes(text=prefix), Web3.toBytes(message_hash)]) signed = keys.ecdsa_sign(message_hash=signable_hash, private_key=pk) provider_fee = { "providerFeeAddress": web3.toChecksumAddress(provider_fee_address), "providerFeeToken": web3.toChecksumAddress(provider_fee_token), "providerFeeAmount": provider_fee_amount, "providerData": Web3.toHex(Web3.toBytes(text=provider_data)), # make it compatible with last openzepellin https://github.com/OpenZeppelin/openzeppelin-contracts/pull/1622 "v": (signed.v + 27) if signed.v <= 1 else signed.v, "r": Web3.toHex(Web3.toBytes(signed.r).rjust(32, b"\0")), "s": Web3.toHex(Web3.toBytes(signed.s).rjust(32, b"\0")), "validUntil": 0, } txn = token_contract.functions.startOrder( web3.toChecksumAddress(test_account3.address), 1, ( web3.toChecksumAddress(provider_fee["providerFeeAddress"]), web3.toChecksumAddress(provider_fee["providerFeeToken"]), provider_fee["providerFeeAmount"], provider_fee["v"], provider_fee["r"], provider_fee["s"], provider_fee["validUntil"], provider_fee["providerData"], ), ( "0x0000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000", 0, ), ).transact({"from": test_account3.address}) web3.eth.wait_for_transaction_receipt(txn) events_object.process_current_blocks() published_ddo = get_ddo(client, base_ddo_url, did) assert published_ddo["stats"]["orders"] == 1
def test_ddo_on_chain(config, web3): """Tests chain operations on a DDO.""" ddo_address = get_contracts_addresses(config.address_file, "ganache")[ MetadataContract.CONTRACT_NAME ] dtfactory_address = get_contracts_addresses(config.address_file, "ganache")[ DTFactory.CONTRACT_NAME ] ddo_registry = MetadataContract(web3, ddo_address) wallet = get_publisher_wallet() dtfactory = DTFactory(web3, dtfactory_address) tx_id = dtfactory.createToken("", "dt1", "dt1", 1000, wallet) dt = DataToken(web3, dtfactory.get_token_address(tx_id)) # test create ddo asset = get_ddo_sample(dt.address) old_name = asset.metadata["main"]["name"] txid = ddo_registry.create( asset.asset_id, b"", lzma.compress(Web3.toBytes(text=asset.as_text())), wallet ) assert ddo_registry.verify_tx(txid), f"create ddo failed: txid={txid}" logs = ddo_registry.event_MetadataCreated.processReceipt( ddo_registry.get_tx_receipt(web3, txid), errors=DISCARD ) assert logs, f"no logs found for create ddo tx {txid}" log = logs[0] assert add_0x_prefix(log.args.dataToken) == asset.asset_id # read back the asset ddo from the event log ddo_text = Web3.toText(lzma.decompress(log.args.data)) assert ddo_text == asset.as_text(), "ddo text does not match original." _asset = V3Asset(json_text=ddo_text) assert _asset.did == asset.did, "did does not match." name = _asset.metadata["main"]["name"] assert name == old_name, f"name does not match: {name} != {old_name}" # test_update ddo asset.metadata["main"]["name"] = "updated name for test" txid = ddo_registry.update( asset.asset_id, b"", lzma.compress(Web3.toBytes(text=asset.as_text())), wallet ) assert ddo_registry.verify_tx(txid), f"update ddo failed: txid={txid}" logs = ddo_registry.event_MetadataUpdated.processReceipt( ddo_registry.get_tx_receipt(web3, txid), errors=DISCARD ) assert logs, f"no logs found for update ddo tx {txid}" log = logs[0] assert add_0x_prefix(log.args.dataToken) == asset.asset_id # read back the asset ddo from the event log ddo_text = Web3.toText(lzma.decompress(log.args.data)) assert ddo_text == asset.as_text(), "ddo text does not match original." _asset = V3Asset(json_text=ddo_text) assert ( _asset.metadata["main"]["name"] == "updated name for test" ), "name does not seem to be updated." assert DataToken(web3, asset.asset_id).contract.caller.isMinter(wallet.address) # test update fails from wallet other than the original publisher bob = get_consumer_wallet() try: txid = ddo_registry.update( asset.asset_id, b"", lzma.compress(Web3.toBytes(text=asset.as_text())), bob ) assert ddo_registry.verify_tx(txid) is False, f"update ddo failed: txid={txid}" logs = ddo_registry.event_MetadataUpdated.processReceipt( ddo_registry.get_tx_receipt(web3, txid), errors=DISCARD ) assert ( not logs ), f"should be no logs for MetadataUpdated, but seems there are some logs: tx {txid}, logs {logs}" except ValueError: print("as expected, only owner can update a published ddo.") # test ddoOwner assert DataToken(web3, asset.asset_id).contract.caller.isMinter(wallet.address), ( f"ddo owner does not match the expected publisher address {wallet.address}, " f"owner is {DataToken(web3, asset.asset_id).contract.caller.minter(wallet.address)}" )