class ModuleTransactionFactory(DjangoModelFactory): class Meta: model = ModuleTransaction internal_tx = factory.SubFactory(InternalTxFactory) safe = factory.LazyFunction(lambda: Account.create().address) module = factory.LazyFunction(lambda: Account.create().address) to = factory.LazyFunction(lambda: Account.create().address) value = FuzzyInteger(low=0, high=10) data = factory.Sequence(lambda n: Web3.keccak(text=f'module-tx-{n}')) operation = FuzzyInteger(low=0, high=1) failed = False
def generate_address_via_create2( address: str, salt: str, init_code: str, ) -> ChecksumEthAddress: """Python implementation of CREATE2 opcode. Given an address (deployer), a salt and an init code (contract creation bytecode), returns the expected contract address once it is deployed. Pseudocode: keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:] EIP-1014: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md """ contract_address = Web3.keccak( hexstring_to_bytes('0xff') + hexstring_to_bytes(address) + hexstring_to_bytes(salt) + Web3.keccak(hexstring_to_bytes(init_code)), )[12:].hex() return to_checksum_address(contract_address)
def test_send_notification_owner_task(self): from ..tasks import logger as task_logger safe_contract = SafeContractFactory() safe_address = safe_contract.address threshold = 2 owners = [Account.create().address for _ in range(2)] safe_tx_hash = Web3.keccak(text='hola').hex() with self.assertLogs(logger=task_logger) as cm: self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (0, 0)) self.assertIn('Cannot find threshold information', cm.output[0]) safe_status = SafeStatusFactory(address=safe_address, threshold=1, owners=owners) with self.assertLogs(logger=task_logger) as cm: self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (0, 0)) self.assertIn('No need to send confirmation notification for ', cm.output[0]) safe_status.threshold = threshold safe_status.save(update_fields=['threshold']) with self.assertLogs(logger=task_logger) as cm: self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (0, 0)) self.assertIn('No cloud messaging tokens found', cm.output[0]) firebase_device_owner_factories = [FirebaseDeviceOwnerFactory(owner=owner) for owner in owners] # Notification is not sent to both owners as they are not related to the safe address self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (0, 0)) for firebase_device_owner in firebase_device_owner_factories: firebase_device_owner.firebase_device.safes.add(safe_contract) self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (2, 0)) # Duplicated notifications are not sent with self.assertLogs(logger=task_logger) as cm: self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (0, 0)) self.assertIn('Duplicated notification', cm.output[0]) # Disable duplicated detection with mock.patch.object(DuplicateNotification, 'is_duplicated', autospec=True, return_value=False): self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (2, 0)) # Add one confirmation for that transaction and other random confirmation for other transaction # to check that they don't influence each other multisig_confirmation = MultisigConfirmationFactory(owner=owners[0], multisig_transaction__safe_tx_hash=safe_tx_hash) MultisigConfirmationFactory(owner=owners[1]) # Not related multisig transaction # Just one transaction sent, as owners[0] already confirmed self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (1, 0)) # Reach the threshold with an unrelated owner MultisigConfirmationFactory(multisig_transaction=multisig_confirmation.multisig_transaction) with self.assertLogs(logger=task_logger) as cm: self.assertEqual(send_notification_owner_task(safe_address, safe_tx_hash), (0, 0)) self.assertIn('does not require more confirmations', cm.output[0])
def _get_bond_id( identity_address: ChecksumAddress, amount: int, pool_id: HexStr, nonce: int, ) -> HexStr: """Given a LogBond event data, return its `bondId`. """ arg_types = ['address', 'address', 'uint', 'bytes32', 'uint'] args = [STAKING_ADDR, identity_address, amount, pool_id, nonce] return HexStr( Web3.keccak(Web3().codec.encode_abi(arg_types, args)).hex())
def test_approved_hash_signature_build(self): owner = Account.create().address safe_tx_hash = Web3.keccak(text='random') safe_signature = SafeSignatureApprovedHash.build_for_owner(owner, safe_tx_hash) self.assertEqual(len(safe_signature.signature), 65) self.assertEqual(safe_signature.signature_type, SafeSignatureType.APPROVED_HASH) self.assertEqual(safe_signature.owner, owner) # Check parse signature get the same result safe_signature = SafeSignature.parse_signature(safe_signature.signature, safe_tx_hash)[0] self.assertEqual(safe_signature.signature_type, SafeSignatureType.APPROVED_HASH) self.assertEqual(safe_signature.owner, owner)
class MultisigConfirmationFactory(DjangoModelFactory): class Meta: model = MultisigConfirmation ethereum_tx = factory.SubFactory(EthereumTxFactory) multisig_transaction = factory.SubFactory(MultisigTransactionFactory) multisig_transaction_hash = factory.Sequence( lambda n: Web3.keccak(text=f"multisig-confirmation-tx-{n}").hex() ) owner = factory.LazyFunction(lambda: Account.create().address) signature = None signature_type = SafeSignatureType.APPROVED_HASH.value
def test_sign_full_metadata(ethereum_accounts): data = { 'name': 'polyswarmtransaction.bounty:AssertionTransaction', 'from': '0x3f17f1962B36e491b30A40b2405849e597Ba5FB5', 'data': { 'guid': 'test', 'verdict': True, 'bid': '1000000000000000000', 'metadata': { 'malware_family': '', 'domains': ['test-domain'], 'ip_addresses': ['127.0.0.1'], 'stix': [{ 'schema': '', 'signature': 'test-stix' }], 'scanner': { 'version': '1.0.0', 'polyswarmclient_version': '2.8.0', 'vendor_version': '1', 'signatures_version': '0.1.0', 'environment': { 'operating_system': 'test-os', 'architecture': 'test-arch', } }, 'extra': 'extra' } } } scanner = json.loads( Scanner(environment={ 'operating_system': 'test-os', 'architecture': 'test-arch' }, version='1.0.0', polyswarmclient_version='2.8.0', signatures_version='0.1.0', vendor_version='1').json()) metadata = json.loads(VerdictMetadata().set_malware_family('').set_scanner( **scanner).add_domain('test-domain').add_ip_address( '127.0.0.1').add_stix_signature('', 'test-stix').add_extra( 'extra', 'extra').json()) transaction = AssertionTransaction('test', True, '1000000000000000000', metadata) signed = transaction.sign(ethereum_accounts[0].key) assert signed.raw_transaction == json.dumps(data) assert signed.signature == PrivateKey( ethereum_accounts[0].key).sign_msg_hash( Web3.keccak(text=json.dumps(data)))
def test_keccak256_field(self): value_hexbytes = Web3.keccak(text=faker.name()) value_hex_with_0x: str = value_hexbytes.hex() value_hex_without_0x: str = value_hex_with_0x[2:] value: bytes = bytes(value_hexbytes) values = [ value, value_hex_without_0x, value_hex_with_0x, value_hexbytes ] for v in values: with self.subTest(v=v): keccak256_hash = Keccak256Hash(value=v) self.assertIsNone(keccak256_hash.full_clean()) keccak256_hash.save() keccak256_hash.refresh_from_db() self.assertEqual(keccak256_hash.value, value_hex_with_0x) for v in values: with self.subTest(v=v): self.assertEqual( Keccak256Hash.objects.filter(value=v).count(), len(values)) # Hash null keccak256_hash = Keccak256Hash.objects.create(value=None) keccak256_hash.refresh_from_db() self.assertIsNone(keccak256_hash.value) # Hash too big value_hex_invalid: str = "0x" + value_hex_without_0x + "a" with self.assertRaisesMessage( ValidationError, f'"{value_hex_invalid}" hash must have exactly 32 bytes.'): with transaction.atomic(): Keccak256Hash.objects.create(value=value_hex_invalid) # Hash too small value_hex_invalid: str = "0x" + "a1" with self.assertRaisesMessage( ValidationError, f'"{value_hex_invalid}" hash must have exactly 32 bytes.'): with transaction.atomic(): Keccak256Hash.objects.create(value=value_hex_invalid) # Invalid hash value_hex_invalid: str = "UX/IO" with self.assertRaisesMessage( ValidationError, f'"{value_hex_invalid}" hash must be a 32 bytes hexadecimal.', ): with transaction.atomic(): Keccak256Hash.objects.create(value=value_hex_invalid)
def generate_signature(data): # convert sorted dictionary to string with no white spaces to_sign_str = json.dumps(data, sort_keys=True, ensure_ascii=False, separators=(',', ':'), cls=DateTimeEncoder) # generate hash for if data contains unicode chars to_sign_hash = Web3.keccak(text=to_sign_str).hex() # generate SignableMessage for sign_message() encoded_to_sign = encode_defunct(hexstr=to_sign_hash) # sign to get signature signed_message = w3.eth.account.sign_message(encoded_to_sign, private_key=shared_config['delegate']['private_key']) return signed_message.signature.hex()
def calculate_pair_address(self, token_address: str, token_address_2: str): """ Calculate pair address without querying blockchain. https://uniswap.org/docs/v2/smart-contract-integration/getting-pair-addresses/#docs-header :param token_address: :param token_address_2: :return: Checksummed address for token pair. It could be not created yet """ if token_address.lower() > token_address_2.lower(): token_address, token_address_2 = token_address_2, token_address salt = Web3.keccak( encode_abi_packed(["address", "address"], [token_address, token_address_2]) ) address = Web3.keccak( encode_abi_packed( ["bytes", "address", "bytes", "bytes"], [HexBytes("ff"), self.factory_address, salt, self.pair_init_code], ) )[-20:] return Web3.toChecksumAddress(address)
def get_signatures(self, contract_abi, typ): """ Returns sha3 signature of methods or events. e.g. >>> {'LogResult': '0x6883...5c88', 'LogBet': '0x1cb5...75c4'} """ signatures = {} definitions = self.definitions(contract_abi, typ) for name in definitions: definition = definitions[name] signature = Web3.keccak(text=definition) signatures = dict(signatures, **{name: signature}) return signatures
def generate_tx_nonce(seller: Address, client: Address) -> str: """ Generate a unique hash to distinguish txs with the same terms. :param seller: the address of the seller. :param client: the address of the client. :return: return the hash in hex. """ time_stamp = int(time.time()) aggregate_hash = Web3.keccak( b"".join([seller.encode(), client.encode(), time_stamp.to_bytes(32, "big")]) ) return aggregate_hash.hex()
def __init__(self, ethClient: EthClientInterface): self.w3 = Web3() self.ethClient = ethClient with open('./contracts/CryptoKitties.json') as contractJsonFile: contractJson = json.load(contractJsonFile) self.cryptoKittiesContract = self.w3.eth.contract(address='0x06012c8cf97BEaD5deAe237070F9587f8E7A266d', abi=contractJson['abi']) self.cryptoKittiesTransferEvent = self.cryptoKittiesContract.events.Transfer() with open('./contracts/CryptoPunksMarket.json') as contractJsonFile: contractJson = json.load(contractJsonFile) self.cryptoPunksContract = self.w3.eth.contract(address='0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB', abi=contractJson['abi']) self.cryptoPunksTransferEvent = self.cryptoPunksContract.events.PunkTransfer() self.cryptoPunksBoughtEvent = self.cryptoPunksContract.events.PunkBought() with open('./contracts/IERC721.json') as contractJsonFile: contractJson = json.load(contractJsonFile) self.ierc721Contract = self.w3.eth.contract(abi=contractJson['abi']) self.ierc721TransferEvent = self.ierc721Contract.events.Transfer() # TODO(krishan711): use the contract to get the signature hash instead of doing manually # self.contractFilter = self.ierc721Contract.events.Transfer.createFilter(fromBlock=6517190, toBlock=6517190, topics=[None, None, None, None]) self.erc721TansferEventSignatureHash = Web3.keccak(text='Transfer(address,address,uint256)').hex() with open('./contracts/IERC1155.json') as contractJsonFile: contractJson = json.load(contractJsonFile) self.ierc1155Contract = self.w3.eth.contract(abi=contractJson['abi']) self.ierc1155TransferEvent = self.ierc1155Contract.events.TransferSingle() # TODO(krishan711): use the contract to get the signature hash instead of doing manually # self.contractFilter = self.ierc1155Contract.events.Transfer.createFilter(fromBlock=6517190, toBlock=6517190, topics=[None, None, None, None]) self.erc1155TansferEventSignatureHash = Web3.keccak(text='TransferSingle(address,address,address,uint256,uint256)').hex() with open('./contracts/IERC1155.json') as contractJsonFile: contractJson = json.load(contractJsonFile) self.ierc1155Contract = self.w3.eth.contract(abi=contractJson['abi']) self.ierc1155TransferEvent = self.ierc1155Contract.events.TransferBatch() # TODO(krishan711): use the contract to get the signature hash instead of doing manually # self.contractFilter = self.ierc1155Contract.events.Transfer.createFilter(fromBlock=6517190, toBlock=6517190, topics=[None, None, None, None]) self.erc1155TansferBatchEventSignatureHash = Web3.keccak(text='TransferBatch(address,address,address,uint256[],uint256[])').hex()
def test_recover_vote_when_computed(ethereum_accounts): data = { 'name': 'polyswarmtransaction.bounty:VoteTransaction', 'from': '0x3f17f1962B36e491b30A40b2405849e597Ba5FB5', 'data': { 'guid': 'test', 'vote': True, } } transaction = VoteTransaction('test', True) signed = transaction.sign(ethereum_accounts[0].key) assert signed.signature == PrivateKey( ethereum_accounts[0].key).sign_msg_hash( Web3.keccak(text=json.dumps(data)))
def compute_init_hash(): """Computes the init hash when compiled with the truffle suit""" file_ = "build/contracts/UniswapV2Pair.json" with open(file_, "r") as f: raw_data = f.read() json_data = json.loads(raw_data) h = Web3.keccak(hexstr=json_data["bytecode"]) h = h.hex() print("Computed hex code '{}' from '{}' bytecode".format(h, file_)) return h
class EthereumTxFactory(factory.DjangoModelFactory): class Meta: model = EthereumTx block = factory.SubFactory(EthereumBlockFactory) tx_hash = factory.Sequence(lambda n: Web3.keccak(text=f'ethereum_tx_hash-{n}').hex()) _from = factory.LazyFunction(lambda: Account.create().address) gas = factory.fuzzy.FuzzyInteger(1000, 5000) gas_price = factory.fuzzy.FuzzyInteger(1, 100) data = factory.Sequence(lambda n: HexBytes('%x' % (n + 1000))) nonce = factory.Sequence(lambda n: n) to = factory.LazyFunction(lambda: Account.create().address) value = factory.fuzzy.FuzzyInteger(0, 1000) logs = factory.LazyFunction(lambda: [])
def generate_address_2(from_: Union[str, bytes], salt: Union[str, bytes], init_code: Union[str, bytes]) -> str: """ Generates an address for a contract created using CREATE2. :param from_: The address which is creating this new address (need to be 20 bytes) :param salt: A salt (32 bytes) :param init_code: A init code of the contract being created :return: Address of the new contract """ from_ = HexBytes(from_) salt = HexBytes(salt) init_code = HexBytes(init_code) assert len( from_) == 20, f'Address {from_.hex()} is not valid. Must be 20 bytes' assert len(salt) == 32, f'Salt {salt.hex()} is not valid. Must be 32 bytes' assert len(init_code) > 0, f'Init code {init_code.hex()} is not valid' init_code_hash = Web3.keccak(init_code) contract_address = Web3.keccak( HexBytes('ff') + from_ + salt + init_code_hash) return Web3.toChecksumAddress(contract_address[12:])
def calculate_pair_adress(self, tokenA, tokenB): tokenA = Web3.toChecksumAddress(tokenA) tokenB = Web3.toChecksumAddress(tokenB) tokenA_hex = bytes.fromhex(tokenA[2:]) tokenB_hex = bytes.fromhex(tokenB[2:]) if tokenA_hex < tokenB_hex: token0 = tokenA token1 = tokenB else: token1 = tokenA token0 = tokenB b_salt = Web3.keccak(encode_abi_packed(['address', 'address'], [token0, token1])) pre = '0xff' b_pre = bytes.fromhex(pre[2:]) b_address = bytes.fromhex(self.factory_address[2:]) b_init_code = bytes.fromhex(self.init_code_hash[2:]) b_result = Web3.keccak( encode_abi_packed(['bytes', 'bytes', 'bytes', 'bytes'], [b_pre, b_address, b_salt, b_init_code])) result_address = Web3.toChecksumAddress(b_result[12:].hex()) return result_address, token0, token1
def place_order(self, order: Order, private_key: HexStr) -> Union[HexStr, ErrorResponse]: """ Place order. If `feeAmount=0` in Order it will be calculated calling `get_fee(order)` :return: UUID for the order as an hex hash """ assert (order["buyAmount"] and order["sellAmount"] ), "Order buyAmount and sellAmount cannot be empty" url = self.base_url + "orders/" order["feeAmount"] = order["feeAmount"] or self.get_fee(order) signable_bytes = order.signable_bytes(domain=self.domain_separator) signable_hash = Web3.keccak(signable_bytes) message = encode_defunct(primitive=signable_hash) signed_message = Account.from_key(private_key).sign_message(message) data_json = { "sellToken": order["sellToken"].lower(), "buyToken": order["buyToken"].lower(), "sellAmount": str(order["sellAmount"]), "buyAmount": str(order["buyAmount"]), "validTo": order["validTo"], "appData": HexBytes(order["appData"]).hex() if isinstance( order["appData"], bytes) else order["appData"], "feeAmount": str(order["feeAmount"]), "kind": order["kind"], "partiallyFillable": order["partiallyFillable"], "signature": signed_message.signature.hex(), "signingScheme": "ethsign", "from": Account.from_key(private_key).address, } r = requests.post(url, json=data_json) if r.ok: return HexStr(r.json()) else: return ErrorResponse(r.json())
def test_contract_multiple_signatures(self): """ Test decode of multiple `CONTRACT_SIGNATURE` together """ owner_1 = self.ethereum_test_account deployed_safe = self.deploy_test_safe(owners=[owner_1.address], initial_funding_wei=Web3.toWei(0.01, 'ether')) safe = Safe(deployed_safe.safe_address, self.ethereum_client) safe_contract = safe.get_contract() safe_tx_hash = Web3.keccak(text='test') tx = safe_contract.functions.signMessage( safe_tx_hash ).buildTransaction({'from': safe.address}) safe_tx = safe.build_multisig_tx(safe.address, 0, tx['data']) safe_tx.sign(owner_1.key) safe_tx.execute(owner_1.key) # Check multiple signatures. In this case we reuse signatures for the same owner, it won't make sense # in real life signature_r_1 = HexBytes(safe.address.replace('0x', '').rjust(64, '0')) signature_s_1 = HexBytes('0' * 62 + '82') # Position of end of signature `0x82 == (65 * 2)` signature_v_1 = HexBytes('00') contract_signature_1 = b'' encoded_contract_signature_1 = encode_single('bytes', contract_signature_1) signature_r_2 = HexBytes(safe.address.replace('0x', '').rjust(64, '0')) signature_s_2 = HexBytes('0' * 62 + 'c2') # Position of end of signature `0xc2 == (65 * 2) + 64` signature_v_2 = HexBytes('00') safe_tx_hash_message_hash = safe_contract.functions.getMessageHash(safe_tx_hash).call() contract_signature_2 = owner_1.signHash(safe_tx_hash_message_hash)['signature'] encoded_contract_signature_2 = encode_single('bytes', contract_signature_2) # It will add size of bytes signature = (signature_r_1 + signature_s_1 + signature_v_1 + signature_r_2 + signature_s_2 + signature_v_2 + encoded_contract_signature_1 + encoded_contract_signature_2) count = 0 for safe_signature, contract_signature in zip(SafeSignature.parse_signature(signature, safe_tx_hash), [contract_signature_1, contract_signature_2]): self.assertEqual(safe_signature.contract_signature, contract_signature) self.assertTrue(safe_signature.is_valid(self.ethereum_client, None)) self.assertEqual(safe_signature.signature_type, SafeSignatureType.CONTRACT_SIGNATURE) # Test exported signature exported_signature = SafeSignature.parse_signature(safe_signature.export_signature(), safe_tx_hash)[0] self.assertEqual(exported_signature.contract_signature, safe_signature.contract_signature) self.assertTrue(exported_signature.is_valid(self.ethereum_client, None)) count += 1 self.assertEqual(count, 2)
def register_user_in_election(cls, user, election): voter_uuid = str(uuid.uuid4()) user_id_hash = Web3.keccak(text=user.user_id).hex() voter = Voter(uuid= voter_uuid, user_id_hash = user_id_hash, user = user, election = election) # do we need to generate an alias? if election.use_voter_aliases: heliosutils.lock_row(Election, election.id) alias_num = election.last_alias_num + 1 voter.alias = "V%s" % alias_num voter.save() return voter
def hash_order(makerAddress, takerAddress, feeRecipientAddress, senderAddress, makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimeSeconds, salt, makerAssetData, takerAssetData): order_hash_types = [ 'bytes32', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'bytes', 'bytes' ] order_hash_data = [ Web3.toBytes(hexstr=EIP712_ORDER_SCHEMA_HASH), Web3.toInt(hexstr=makerAddress), Web3.toInt(hexstr=takerAddress), Web3.toInt(hexstr=feeRecipientAddress), Web3.toInt(hexstr=senderAddress), makerAssetAmount, takerAssetAmount, makerFee, takerFee, expirationTimeSeconds, salt, Web3.keccak(hexstr=makerAssetData), Web3.keccak(hexstr=takerAssetData) ] return Web3.toHex( Web3.solidityKeccak(['string', 'bytes32', 'bytes32'], [ EIP191_HEADER, Web3.toBytes(hexstr=EIP712_DOMAIN_HASH), Web3.solidityKeccak(order_hash_types, order_hash_data) ]))
def get_bloom_bits(value): """ Bloom filter helper function. Get the Bloom bits of a given value. Args: value (bytes): Value to be encoded into the Bloom filter. """ # Could decode the ipfs_hash and use it as is, but instead hash the # multihash representation to side-step different hash formats going # forward. Should rexamine this decision value_hash = Web3.keccak(value) for chunk in BloomFilter.get_chunks_for_bloom(value_hash): bloom_bits = BloomFilter.chunk_to_bloom_bits(chunk) yield bloom_bits
def test_send_notification_owner_task_called(self): safe_address = Account.create().address safe_tx_hash = Web3.keccak(text='hola').hex() payload = { 'address': safe_address, 'type': WebHookType.PENDING_MULTISIG_TRANSACTION.name, 'safeTxHash': safe_tx_hash, } with mock.patch( 'safe_transaction_service.notifications.tasks.send_notification_owner_task.delay' ) as send_notification_owner_task_mock: send_notification_owner_task_mock.assert_not_called() send_notification_task.delay(safe_address, payload) send_notification_owner_task_mock.assert_called_with(safe_address, safe_tx_hash)
def test_keccak256_field_form(self): form = Keccak256Form(data={"value": "not a hash"}) self.assertFalse(form.is_valid()) self.assertEqual( form.errors["value"], ['"not a hash" is not a valid keccak256 hash.'] ) form = Keccak256Form(data={"value": "0x1234"}) self.assertFalse(form.is_valid()) self.assertEqual( form.errors["value"], ['"0x1234" keccak256 hash should be 32 bytes.'] ) form = Keccak256Form(data={"value": Web3.keccak(text="testing").hex()}) self.assertTrue(form.is_valid())
def public_key_from_signature(message: str, signature: str) -> PublicKey: if signature.startswith("0x"): signature = signature[2:] bytes_sig = bytes.fromhex(signature) if not len(bytes_sig) == 65: raise ValidationError(param='signature', type_name='65 bytes') vrs = ( big_endian_to_int(bytes_sig[64:65]) - 27, big_endian_to_int(bytes_sig[0:32]), big_endian_to_int(bytes_sig[32:64]), ) sig = eth_keys.keys.Signature(vrs=vrs) pub_key = eth_keys.keys.ecdsa_recover(Web3.keccak(text=message), sig) return pub_key
def recover_wallet(data, signature): json_dump = json.dumps(data, sort_keys=True, ensure_ascii=False, separators=(',', ':'), cls=DateTimeEncoder) # generate hash for if data contains unicode chars to_recover_hash = Web3.keccak(text=json_dump).hex() encoded_to_recover = encode_defunct(hexstr=to_recover_hash) recovered_wallet = w3.eth.account.recover_message(encoded_to_recover, signature=signature) return recovered_wallet
def validate_vote_signature(web3_client: Web3, encoded_data: bytes, account: ChecksumAddress, signature: HexStr) -> bool: """Checks whether vote was signed by specific Ethereum account.""" try: candidate_id: bytes = Web3.keccak(primitive=encoded_data) message_hash = encode_defunct(primitive=candidate_id) signer = web3_client.eth.account.recover_message(message_hash, signature=signature) except Exception: return False if account != signer: return False return True
def test_get_fee(self): order = Order( sellToken=self.gno_token_address, buyToken=self.gno_token_address, receiver=NULL_ADDRESS, sellAmount=1, buyAmount=1, validTo=int(time()) + 3600, appData=Web3.keccak(text="hola"), feeAmount=0, kind="sell", partiallyFillable=False, sellTokenBalance="erc20", buyTokenBalance="erc20", ) self.assertGreaterEqual(self.gnosis_protocol_api.get_fee(order), 0)
def test_eth_account_sign(acct, message_text, key, expected_bytes, expected_hash, v, r, s, signature): message = encode_defunct(text=message_text) signed_message = Web3.keccak( b"\x19Ethereum Signed Message:\n" + bytes(f"{len(message.body)}", encoding='utf-8') + message.body) assert signed_message == expected_hash signed = acct.sign_message(message, private_key=key) assert signed.messageHash == expected_hash assert signed.v == v assert signed.r == r assert signed.s == s assert signed.signature == signature account = acct.from_key(key) assert account.sign_message(message) == signed