def acct(request): if request.param == 'instance': return Account() elif request.param == 'class': return Account else: raise Exception(f"account invocation {request.param} is not supported")
def test_internal_tx_view(self): safe_address = Account().create().address SafeContractFactory(address=safe_address) response = self.client.get( reverse('v1:internal-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) internal_tx = InternalTxFactory(to=safe_address) response = self.client.get( reverse('v1:internal-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) response_internal_tx = response.json()['results'][0] self.assertEqual(internal_tx._from, response_internal_tx['from']) self.assertEqual(internal_tx.to, response_internal_tx['to']) self.assertEqual(internal_tx.data.hex(), response_internal_tx['data']) self.assertEqual(internal_tx.value, int(response_internal_tx['value'])) self.assertEqual(internal_tx.ethereum_tx.to, response_internal_tx['ethereumTx']['to']) InternalTxFactory(_from=safe_address) InternalTxFactory() response = self.client.get( reverse('v1:internal-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.json()['count'], 2)
def create_account(keystore_dir: PS, passphrase: Optional[str] = None) -> str: """ Create a new Ethereum account and save it to the keystore """ if not isinstance(keystore_dir, Path): keystore_dir = Path(keystore_dir) if not passphrase: if not passphrase: passphrase = getpass("Enter password to encrypt account:") eth_account = Account() new_account = eth_account.create() PRIVATE_KEY = new_account.privateKey new_account_json = eth_account.encrypt(PRIVATE_KEY, passphrase) filename = keystore_dir.joinpath('UTC--{}--{}'.format( datetime.now().isoformat(), Web3.toChecksumAddress(new_account_json.get('address')))) with filename.open('w') as json_file: try: json_string = json.dumps(new_account_json) json_file.write(json_string) except Exception as e: log.error("Error writing JSON file {}: {}".format( filename, str(e))) return new_account.address
def test_erc721_view(self): safe_address = Account().create().address SafeContractFactory(address=safe_address) response = self.client.get( reverse('v1:erc721-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) ethereum_erc721_event = EthereumEventFactory(to=safe_address, erc721=True) response = self.client.get( reverse('v1:erc721-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) response_ethereum_erc721_event = response.json()['results'][0] self.assertEqual(ethereum_erc721_event.token_address, response_ethereum_erc721_event['tokenAddress']) self.assertEqual(ethereum_erc721_event.arguments['to'], response_ethereum_erc721_event['to']) self.assertEqual(ethereum_erc721_event.arguments['from'], response_ethereum_erc721_event['from']) self.assertEqual(ethereum_erc721_event.arguments['tokenId'], int(response_ethereum_erc721_event['tokenId'])) self.assertEqual(ethereum_erc721_event.ethereum_tx.to, response_ethereum_erc721_event['ethereumTx']['to']) EthereumEventFactory(from_=safe_address, erc721=True) EthereumEventFactory(erc721=True) response = self.client.get( reverse('v1:erc721-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.json()['count'], 2)
def test_decode_execute_transaction(self): owners = [Account.create() for _ in range(2)] owner_addresses = [owner.address for owner in owners] threshold = 1 safe_creation = self.deploy_test_safe(owners=owner_addresses, threshold=threshold, initial_funding_wei=self.w3.toWei(0.1, 'ether')) safe_address = safe_creation.safe_address to = Account().create().address value = self.w3.toWei(0.01, 'ether') safe_tx_gas = 200000 data_gas = 100000 safe_tx = SafeTx(self.ethereum_client, safe_address, to, value, b'', 0, safe_tx_gas, data_gas, self.gas_price, None, None, safe_nonce=0) safe_tx.sign(owners[0].privateKey) self.assertEqual(safe_tx.call(tx_sender_address=self.ethereum_test_account.address), 1) tx_hash, _ = safe_tx.execute(tx_sender_private_key=self.ethereum_test_account.privateKey) self.ethereum_client.get_transaction_receipt(tx_hash, timeout=60) self.assertEqual(self.ethereum_client.get_balance(to), value) tx_decoder = TxDecoder() function_name, arguments = tx_decoder.decode_transaction(safe_tx.tx['data']) self.assertEqual(function_name, 'execTransaction') self.assertIn('baseGas', arguments)
def _private_key_to_account(private_key): """Get the account associated with the private key.""" if isinstance(private_key, PrivateKey): private_key = private_key.to_hex() else: private_key = HexBytes(private_key).hex() return Account().privateKeyToAccount(private_key)
def test_estimate_tx(self): safe_address = Account.create().address to = Account.create().address value = 0 data = b'' operation = SafeOperation.CALL.value gas_token = Account().create().address with self.assertRaises(InvalidGasToken): self.transaction_service.estimate_tx(safe_address, to, value, data, operation, gas_token) TokenFactory(address=gas_token, gas=True) with self.assertRaises(SafeDoesNotExist): self.transaction_service.estimate_tx(safe_address, to, value, data, operation, gas_token) # We need a real safe deployed for this method to work gas_token = NULL_ADDRESS safe_address = self.deploy_test_safe().safe_address transaction_estimation = self.transaction_service.estimate_tx( safe_address, to, value, data, operation, gas_token) self.assertEqual(transaction_estimation.last_used_nonce, None) self.assertGreater(transaction_estimation.safe_tx_gas, 0) self.assertGreater(transaction_estimation.base_gas, 0) self.assertGreater(transaction_estimation.data_gas, 0) self.assertGreater(transaction_estimation.gas_price, 0) self.assertEqual(transaction_estimation.operational_gas, 0) self.assertEqual(transaction_estimation.gas_token, NULL_ADDRESS)
def test_sign_safe_tx(self): owners = [Account.create() for _ in range(3)] owners_unsorted = sorted(owners, key=lambda x: int(x.address, 16), reverse=True) owner_addresses = [owner.address for owner in owners_unsorted] threshold = 1 safe = self.deploy_test_safe( owners=owner_addresses, threshold=threshold, initial_funding_wei=self.w3.toWei(0.1, "ether"), ) to = Account().create().address value = self.w3.toWei(0.01, "ether") safe_tx = SafeTx( self.ethereum_client, safe.address, to, value, b"", 0, 200000, 100000, self.gas_price, None, None, safe_nonce=0, ) safe_tx.sign(owners_unsorted[0].key) safe_tx.sign(owners_unsorted[2].key) signers = [owner_addresses[0], owner_addresses[2]] self.assertEqual(safe_tx.signers, safe_tx.sorted_signers) self.assertNotEqual(signers, safe_tx.signers) self.assertEqual(set(signers), set(safe_tx.signers)) self.assertEqual(len(safe_tx.signers), 2) safe_tx.sign(owners_unsorted[1].key) signers = owner_addresses self.assertEqual(safe_tx.signers, safe_tx.sorted_signers) self.assertNotEqual(signers, safe_tx.signers) self.assertEqual(set(signers), set(safe_tx.signers)) self.assertEqual(len(safe_tx.signers), 3) # Sign again safe_tx.sign(owners_unsorted[0].key) self.assertEqual(len(safe_tx.signers), 3) # Sign again safe_tx.unsign(owners_unsorted[1].address) signers = [owner_addresses[0], owner_addresses[2]] self.assertEqual(set(signers), set(safe_tx.signers)) self.assertEqual(len(safe_tx.signers), 2)
def _check_account_from_key(self): try: account = Account() acct = account.from_key(config.PAYER_KEY) self._web3.middleware_onion.add( construct_sign_and_send_raw_middleware(acct)) self._payer_account = Address(acct.address) except: self._logger.fatal(f"Account {config.PAYER_ADDRESS} register key error") return False return True
def test_send_safe_tx(self): owners = [Account.create() for _ in range(2)] owner_addresses = [owner.address for owner in owners] threshold = 1 safe = self.deploy_test_safe( owners=owner_addresses, threshold=threshold, initial_funding_wei=self.w3.toWei(0.1, "ether"), ) to = Account().create().address value = self.w3.toWei(0.01, "ether") safe_tx_gas = 200000 data_gas = 100000 safe_tx = SafeTx( self.ethereum_client, safe.address, to, value, b"", 0, safe_tx_gas, data_gas, self.gas_price, None, None, safe_nonce=0, ) with self.assertRaises(SignaturesDataTooShort): safe_tx.call(tx_sender_address=self.ethereum_test_account.address) # Check signing self.assertFalse(safe_tx.signers) safe_tx.sign(owners[0].key) self.assertIn(owners[0].address, safe_tx.signers) with self.assertRaises(NotEnoughSafeTransactionGas): safe_tx.call( tx_sender_address=self.ethereum_test_account.address, tx_gas=safe_tx_gas // 2, ) self.assertEqual( safe_tx.call(tx_sender_address=self.ethereum_test_account.address), 1) tx_hash, _ = safe_tx.execute( tx_sender_private_key=self.ethereum_test_account.key) self.ethereum_client.get_transaction_receipt(tx_hash, timeout=60) self.assertEqual(self.ethereum_client.get_balance(to), value) safe_tx.unsign(owners[0].address) self.assertFalse(safe_tx.signers)
def read(endpoint, contract_address): w3 = Web3(Web3.HTTPProvider(endpoint)) account = Account() private_key = os.environ["ETH_MSG_PRIVATE_KEY"] address = account.privateKeyToAccount(private_key).address contract = w3.eth.contract(address=contract_address, abi=base_abi) nonce = w3.eth.getTransactionCount(address) tx = contract.functions.text().call({'from': address}) print("Message:") print(tx)
def test_estimate_tx_gas(self): to = Account().create().address value = 123 data = HexBytes("0xabcdef") operation = 1 safe = self.deploy_test_safe(initial_funding_wei=value + 23000) safe_tx_gas = safe.estimate_tx_gas(to, value, data, operation) self.assertGreater(safe_tx_gas, 0) operation = 0 safe_tx_gas = safe.estimate_tx_gas(to, value, data, operation) self.assertGreater(safe_tx_gas, 0)
def test_place_order(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", ) result = self.gnosis_protocol_api.place_order(order, Account().create().key) self.assertEqual( order["feeAmount"], 0) # Cannot estimate, as buy token is the same than sell token self.assertEqual( result, { "description": "Buy token is the same as the sell token.", "errorType": "SameBuyAndSellToken", }, ) order["sellToken"] = self.rinkeby_weth_address order["buyToken"] = self.rinkeby_dai_address self.assertEqual( self.gnosis_protocol_api.place_order(order, Account().create().key), { "description": "order owner must have funds worth at least x in his account", "errorType": "InsufficientBalance", }, )
def test_get_all_txs(self): safe_address = Account().create().address SafeContractFactory(address=safe_address) response = self.client.get( reverse('v1:safe-all-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) db_ethereum_tx = EthereumTxFactory(to=safe_address) response = self.client.get( reverse('v1:safe-all-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()['results']), 1) ethereum_tx = response.json()['results'][0] self.assertEqual(ethereum_tx['from'], db_ethereum_tx._from) self.assertEqual(ethereum_tx['to'], safe_address) self.assertEqual(ethereum_tx['data'], db_ethereum_tx.data.hex()) self.assertEqual(ethereum_tx['gas'], str(db_ethereum_tx.gas)) self.assertEqual(ethereum_tx['gasPrice'], str(db_ethereum_tx.gas_price)) self.assertEqual(ethereum_tx['txHash'], db_ethereum_tx.tx_hash.hex()) self.assertEqual(ethereum_tx['value'], str(db_ethereum_tx.value)) EthereumTxFactory(_from=safe_address) EthereumTxFactory() response = self.client.get( reverse('v1:safe-all-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()['results']), 2) db_internal_tx = InternalTxFactory(to=safe_address) InternalTxFactory(_from=safe_address) InternalTxFactory() InternalTxFactory(contract_address=safe_address) response = self.client.get( reverse('v1:safe-all-txs', args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.json()['results']), 5) at_least_one = False for ethereum_tx in response.json()['results']: if db_internal_tx.ethereum_tx.tx_hash.hex( ) == ethereum_tx['txHash']: self.assertEqual(len(ethereum_tx['internalTxs']), 1) self.assertEqual(ethereum_tx['internalTxs'][0]['from'], db_internal_tx._from) self.assertEqual(ethereum_tx['internalTxs'][0]['to'], safe_address) at_least_one = True self.assertTrue(at_least_one)
def test_estimate_tx_base_gas(self): safe_address = self.deploy_test_safe().safe_address safe = Safe(safe_address, self.ethereum_client) to = Account().create().address value = int('abc', 16) data = HexBytes('0xabcdef') operation = 1 gas_token = NULL_ADDRESS estimate_tx_gas = int('ccdd', 16) base_gas = safe.estimate_tx_base_gas(to, value, data, operation, gas_token, estimate_tx_gas) self.assertGreater(base_gas, 0) data = HexBytes('0xabcdefbb') # A byte that was 00 now is bb, so -4 + GAS_CALL_DATA_BYTE data_gas2 = safe.estimate_tx_base_gas(to, value, data, operation, gas_token, estimate_tx_gas) self.assertEqual(data_gas2, base_gas + GAS_CALL_DATA_BYTE - 4)
def test_get_signed_api_url(self, client): """Test that we can sign api urls using a local private key""" # sign a sample API request signed_url = client.get_signed_api_url( '/v1/devisechain/0055baf8939b9956dcae9175cbf0f5365cfd7348/weights') msg = '/v1/devisechain/0055baf8939b9956dcae9175cbf0f5365cfd7348/weights?address=' + client.address # Verify the signature is correct signature = signed_url.split('&signature=')[1] sign_msg = ("\x19Ethereum Signed Message:\n%s%s" % (len(msg), msg.lower())).encode('utf8') message_hash = sha3.keccak_256(sign_msg).hexdigest() account = Account() address = account.recoverHash(message_hash, signature=signature) assert address.lower() == client.address.lower()
def test_decode_old_execute_transaction(self): safe_address = Account.create().address to = Account().create().address value = self.w3.toWei(0.01, 'ether') safe_tx_gas = 200000 data_gas = 100000 safe_tx = SafeTx(self.ethereum_client, safe_address, to, value, b'', 0, safe_tx_gas, data_gas, self.gas_price, None, None, safe_nonce=0, safe_version='0.0.1') tx_decoder = TxDecoder() data = safe_tx.w3_tx.buildTransaction()['data'] function_name, arguments = tx_decoder.decode_transaction(data) self.assertEqual(function_name, 'execTransaction') # self.assertIn('dataGas', arguments) self.assertIn('baseGas', arguments) # Signature of the tx is the same
def _check_keeper_account(self): with open(config.KEEPER_KEY_FILE) as f: read_key = f.read().replace("\n","") # check account with key try: account = Account() acct = account.from_key(read_key) self.web3.middleware_onion.add(construct_sign_and_send_raw_middleware(acct)) self.keeper_account = Address(acct.address) self.keeper_account_key = read_key except Exception as e: self.logger.warning(f"check private key error: {e}") return False return True
def test_estimate_tx_base_gas(self): safe = self.deploy_test_safe() to = Account().create().address value = int("abc", 16) data = HexBytes("0xabcdef") operation = 1 gas_token = NULL_ADDRESS estimate_tx_gas = int("ccdd", 16) base_gas = safe.estimate_tx_base_gas(to, value, data, operation, gas_token, estimate_tx_gas) self.assertGreater(base_gas, 0) data = HexBytes( "0xabcdefbb" ) # A byte that was 00 now is bb, so -4 + GAS_CALL_DATA_BYTE data_gas2 = safe.estimate_tx_base_gas(to, value, data, operation, gas_token, estimate_tx_gas) self.assertEqual(data_gas2, base_gas + GAS_CALL_DATA_BYTE - 4)
def decrypt_account(keystore_dir: PS, address: StrOrBytes, passphrase: Optional[str] = None) -> bytes: """ Decrypt the keyfile and return the private key """ global PRIVATE_KEY address = str(to_normalized_address(address)) if PRIVATE_KEY is not None and PRIVATE_KEY[0] == address: return PRIVATE_KEY[1] if not passphrase: if not passphrase: passphrase = getpass( "Enter password to decrypt account ({}):".format(address)) account_json = read_account_json(keystore_dir, address) eth_account = Account() PRIVATE_KEY = (address, eth_account.decrypt(account_json, passphrase)) return PRIVATE_KEY[1]
def test_erc721_view(self): safe_address = Account().create().address SafeContractFactory(address=safe_address) response = self.client.get( reverse("v1:erc721-txs", args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) ethereum_erc721_event = EthereumEventFactory(to=safe_address, erc721=True) response = self.client.get( reverse("v1:erc721-txs", args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) response_ethereum_erc721_event = response.json()["results"][0] self.assertEqual( ethereum_erc721_event.token_address, response_ethereum_erc721_event["tokenAddress"], ) self.assertEqual(ethereum_erc721_event.arguments["to"], response_ethereum_erc721_event["to"]) self.assertEqual( ethereum_erc721_event.arguments["from"], response_ethereum_erc721_event["from"], ) self.assertEqual( ethereum_erc721_event.arguments["tokenId"], int(response_ethereum_erc721_event["tokenId"]), ) self.assertEqual( ethereum_erc721_event.ethereum_tx.to, response_ethereum_erc721_event["ethereumTx"]["to"], ) EthereumEventFactory(from_=safe_address, erc721=True) EthereumEventFactory(erc721=True) response = self.client.get( reverse("v1:erc721-txs", args=(safe_address, ))) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.json()["count"], 2)
def __init__(self, network_name: str = None, keystore_dir: str = None, web3: Web3 = None) -> None: """ Init Accounts :param network_name: (:code:`str`) - The name of the network as defined in networks.yml. :param keystore_dir: (:class:`pathlib.Path`) - Path to the keystore. (default: :code:`~/.ethereum/keystore`) :param web3: (:class:`web3.Web3`) - The Web3 instance to use """ self.eth_account = Account() self._accounts: List = [] if keystore_dir: self.keystore_dir = to_path(keystore_dir) else: # Try the session store first. if store.defined(store.Keys.KEYSTORE_DIR): self.keystore_dir = to_path(store.get(store.Keys.KEYSTORE_DIR)) else: # Default to the standard loc self.keystore_dir = to_path('~/.ethereum/keystore') log.debug("Keystore directory: {}".format(self.keystore_dir)) if web3: self.web3 = web3 else: log.warning("Accounts initialized without a web3 instance. Some things like gas price " "estimation might be off or not working.") self.web3 = None if not self.keystore_dir.is_dir(): if self.keystore_dir.exists(): log.error("Provided keystore directory is not a directory") raise SolidbyteException("Invalid keystore directory") else: self.keystore_dir.mkdir(mode=0o700, parents=True)
class Eth(Module): account = Account() defaultAccount = empty defaultBlock = "latest" defaultContractFactory = Contract iban = Iban gasPriceStrategy = None @deprecated_for("doing nothing at all") def enable_unaudited_features(self): pass def namereg(self): raise NotImplementedError() def icapNamereg(self): raise NotImplementedError() @property def protocolVersion(self): return self.web3.manager.request_blocking("eth_protocolVersion", []) @property def syncing(self): return self.web3.manager.request_blocking("eth_syncing", []) @property def coinbase(self): return self.web3.manager.request_blocking("eth_coinbase", []) @property def mining(self): return self.web3.manager.request_blocking("eth_mining", []) @property def hashrate(self): return self.web3.manager.request_blocking("eth_hashrate", []) @property def gasPrice(self): return self.web3.manager.request_blocking("eth_gasPrice", []) @property def accounts(self): return self.web3.manager.request_blocking("eth_accounts", []) @property def blockNumber(self): return self.web3.manager.request_blocking("eth_blockNumber", []) def getBalance(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getBalance", [account, block_identifier], ) def getStorageAt(self, account, position, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getStorageAt", [account, position, block_identifier]) def getCode(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getCode", [account, block_identifier], ) def getBlock(self, block_identifier, full_transactions=False): """ `eth_getBlockByHash` `eth_getBlockByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getBlockByNumber', if_hash='eth_getBlockByHash', if_number='eth_getBlockByNumber', ) return self.web3.manager.request_blocking( method, [block_identifier, full_transactions], ) def getBlockTransactionCount(self, block_identifier): """ `eth_getBlockTransactionCountByHash` `eth_getBlockTransactionCountByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getBlockTransactionCountByNumber', if_hash='eth_getBlockTransactionCountByHash', if_number='eth_getBlockTransactionCountByNumber', ) return self.web3.manager.request_blocking( method, [block_identifier], ) def getUncleCount(self, block_identifier): """ `eth_getUncleCountByBlockHash` `eth_getUncleCountByBlockNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getUncleCountByBlockNumber', if_hash='eth_getUncleCountByBlockHash', if_number='eth_getUncleCountByBlockNumber', ) return self.web3.manager.request_blocking( method, [block_identifier], ) def getUncleByBlock(self, block_identifier, uncle_index): """ `eth_getUncleByBlockHashAndIndex` `eth_getUncleByBlockNumberAndIndex` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getUncleByBlockNumberAndIndex', if_hash='eth_getUncleByBlockHashAndIndex', if_number='eth_getUncleByBlockNumberAndIndex', ) return self.web3.manager.request_blocking( method, [block_identifier, uncle_index], ) def getTransaction(self, transaction_hash): return self.web3.manager.request_blocking( "eth_getTransactionByHash", [transaction_hash], ) @deprecated_for("w3.eth.getTransactionByBlock") def getTransactionFromBlock(self, block_identifier, transaction_index): """ Alias for the method getTransactionByBlock Depreceated to maintain naming consistency with the json-rpc API """ return self.getTransactionByBlock(block_identifier, transaction_index) def getTransactionByBlock(self, block_identifier, transaction_index): """ `eth_getTransactionByBlockHashAndIndex` `eth_getTransactionByBlockNumberAndIndex` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getTransactionByBlockNumberAndIndex', if_hash='eth_getTransactionByBlockHashAndIndex', if_number='eth_getTransactionByBlockNumberAndIndex', ) return self.web3.manager.request_blocking( method, [block_identifier, transaction_index], ) def waitForTransactionReceipt(self, transaction_hash, timeout=120): try: return wait_for_transaction_receipt(self.web3, transaction_hash, timeout) except Timeout: raise TimeExhausted( "Transaction {} is not in the chain, after {} seconds".format( transaction_hash, timeout, )) def getTransactionReceipt(self, transaction_hash): return self.web3.manager.request_blocking( "eth_getTransactionReceipt", [transaction_hash], ) def getTransactionCount(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getTransactionCount", [ account, block_identifier, ], ) def replaceTransaction(self, transaction_hash, new_transaction): current_transaction = get_required_transaction(self.web3, transaction_hash) return replace_transaction(self.web3, current_transaction, new_transaction) def modifyTransaction(self, transaction_hash, **transaction_params): assert_valid_transaction_params(transaction_params) current_transaction = get_required_transaction(self.web3, transaction_hash) current_transaction_params = extract_valid_transaction_params( current_transaction) new_transaction = merge(current_transaction_params, transaction_params) return replace_transaction(self.web3, current_transaction, new_transaction) def sendTransaction(self, transaction): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move gas estimation in middleware if 'gas' not in transaction: transaction = assoc( transaction, 'gas', get_buffered_gas_estimate(self.web3, transaction), ) return self.web3.manager.request_blocking( "eth_sendTransaction", [transaction], ) def sendRawTransaction(self, raw_transaction): return self.web3.manager.request_blocking( "eth_sendRawTransaction", [raw_transaction], ) def sign(self, account, data=None, hexstr=None, text=None): message_hex = to_hex(data, hexstr=hexstr, text=text) return self.web3.manager.request_blocking( "eth_sign", [account, message_hex], ) @apply_to_return_value(HexBytes) def call(self, transaction, block_identifier=None): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move to middleware if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_call", [transaction, block_identifier], ) def estimateGas(self, transaction, block_identifier=None): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) if block_identifier is None: params = [transaction] else: params = [transaction, block_identifier] return self.web3.manager.request_blocking( "eth_estimateGas", params, ) def filter(self, filter_params=None, filter_id=None): if filter_id and filter_params: raise TypeError( "Ambiguous invocation: provide either a `filter_params` or a `filter_id` argument. " "Both were supplied.") if is_string(filter_params): if filter_params == "latest": filter_id = self.web3.manager.request_blocking( "eth_newBlockFilter", [], ) return BlockFilter(self.web3, filter_id) elif filter_params == "pending": filter_id = self.web3.manager.request_blocking( "eth_newPendingTransactionFilter", [], ) return TransactionFilter(self.web3, filter_id) else: raise ValueError( "The filter API only accepts the values of `pending` or " "`latest` for string based filters") elif isinstance(filter_params, dict): _filter_id = self.web3.manager.request_blocking( "eth_newFilter", [filter_params], ) return LogFilter(self.web3, _filter_id) elif filter_id and not filter_params: return LogFilter(self.web3, filter_id) else: raise TypeError( "Must provide either filter_params as a string or " "a valid filter object, or a filter_id as a string " "or hex.") def getFilterChanges(self, filter_id): return self.web3.manager.request_blocking( "eth_getFilterChanges", [filter_id], ) def getFilterLogs(self, filter_id): return self.web3.manager.request_blocking( "eth_getFilterLogs", [filter_id], ) def getLogs(self, filter_params): return self.web3.manager.request_blocking( "eth_getLogs", [filter_params], ) def uninstallFilter(self, filter_id): return self.web3.manager.request_blocking( "eth_uninstallFilter", [filter_id], ) def contract(self, address=None, **kwargs): ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) if address: return ContractFactory(address) else: return ContractFactory def setContractFactory(self, contractFactory): self.defaultContractFactory = contractFactory def getCompilers(self): return self.web3.manager.request_blocking("eth_getCompilers", []) def getWork(self): return self.web3.manager.request_blocking("eth_getWork", []) def generateGasPrice(self, transaction_params=None): if self.gasPriceStrategy: return self.gasPriceStrategy(self.web3, transaction_params) def setGasPriceStrategy(self, gas_price_strategy): self.gasPriceStrategy = gas_price_strategy
class Eth(Module): account = Account() defaultAccount = empty defaultBlock: Literal["latest"] = "latest" # noqa: E704 defaultContractFactory: Type[Union[Contract, ConciseContract, ContractCaller]] = Contract # noqa: E704,E501 iban = Iban gasPriceStrategy = None def namereg(self) -> NoReturn: raise NotImplementedError() def icapNamereg(self) -> NoReturn: raise NotImplementedError() @property def protocolVersion(self) -> str: return self.web3.manager.request_blocking(RPC.eth_protocolVersion, []) @property def syncing(self) -> Union[SyncStatus, bool]: return self.web3.manager.request_blocking(RPC.eth_syncing, []) @property def coinbase(self) -> ChecksumAddress: return self.web3.manager.request_blocking(RPC.eth_coinbase, []) @property def mining(self) -> bool: return self.web3.manager.request_blocking(RPC.eth_mining, []) @property def hashrate(self) -> int: return self.web3.manager.request_blocking(RPC.eth_hashrate, []) @property def gasPrice(self) -> Wei: return self.web3.manager.request_blocking(RPC.eth_gasPrice, []) @property def accounts(self) -> Tuple[ChecksumAddress]: return self.web3.manager.request_blocking(RPC.eth_accounts, []) @property def blockNumber(self) -> BlockNumber: return self.web3.manager.request_blocking(RPC.eth_blockNumber, []) @property def chainId(self) -> int: return self.web3.manager.request_blocking(RPC.eth_chainId, []) def getBalance( self, account: Union[Address, ChecksumAddress, ENS], block_identifier: BlockIdentifier=None ) -> Wei: if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( RPC.eth_getBalance, [account, block_identifier], ) def getStorageAt( self, account: Union[Address, ChecksumAddress, ENS], position: int, block_identifier: BlockIdentifier=None ) -> bytes: if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( RPC.eth_getStorageAt, [account, position, block_identifier] ) def getProof( self, account: Union[Address, ChecksumAddress, ENS], positions: Sequence[int], block_identifier: BlockIdentifier=None ) -> MerkleProof: if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( RPC.eth_getProof, [account, positions, block_identifier] ) def getCode( self, account: Union[Address, ChecksumAddress, ENS], block_identifier: BlockIdentifier=None ) -> HexBytes: if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( RPC.eth_getCode, [account, block_identifier], ) def getBlock( self, block_identifier: BlockIdentifier, full_transactions: bool=False ) -> BlockData: """ `eth_getBlockByHash` `eth_getBlockByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined=RPC.eth_getBlockByNumber, if_hash=RPC.eth_getBlockByHash, if_number=RPC.eth_getBlockByNumber, ) result = self.web3.manager.request_blocking( method, [block_identifier, full_transactions], ) if result is None: raise BlockNotFound(f"Block with id: {block_identifier} not found.") return result def getBlockTransactionCount(self, block_identifier: BlockIdentifier) -> int: """ `eth_getBlockTransactionCountByHash` `eth_getBlockTransactionCountByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined=RPC.eth_getBlockTransactionCountByNumber, if_hash=RPC.eth_getBlockTransactionCountByHash, if_number=RPC.eth_getBlockTransactionCountByNumber, ) result = self.web3.manager.request_blocking( method, [block_identifier], ) if result is None: raise BlockNotFound(f"Block with id: {block_identifier} not found.") return result def getUncleCount(self, block_identifier: BlockIdentifier) -> int: """ `eth_getUncleCountByBlockHash` `eth_getUncleCountByBlockNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined=RPC.eth_getUncleCountByBlockNumber, if_hash=RPC.eth_getUncleCountByBlockHash, if_number=RPC.eth_getUncleCountByBlockNumber, ) result = self.web3.manager.request_blocking( method, [block_identifier], ) if result is None: raise BlockNotFound(f"Block with id: {block_identifier} not found.") return result def getUncleByBlock(self, block_identifier: BlockIdentifier, uncle_index: int) -> Uncle: """ `eth_getUncleByBlockHashAndIndex` `eth_getUncleByBlockNumberAndIndex` """ method = select_method_for_block_identifier( block_identifier, if_predefined=RPC.eth_getUncleByBlockNumberAndIndex, if_hash=RPC.eth_getUncleByBlockHashAndIndex, if_number=RPC.eth_getUncleByBlockNumberAndIndex, ) result = self.web3.manager.request_blocking( method, [block_identifier, uncle_index], ) if result is None: raise BlockNotFound( f"Uncle at index: {uncle_index} of block with id: {block_identifier} not found." ) return result def getTransaction(self, transaction_hash: _Hash32) -> TxData: result = self.web3.manager.request_blocking( RPC.eth_getTransactionByHash, [transaction_hash], ) if result is None: raise TransactionNotFound(f"Transaction with hash: {transaction_hash} not found.") return result def getTransactionFromBlock( self, block_identifier: BlockIdentifier, transaction_index: int ) -> NoReturn: """ Alias for the method getTransactionByBlock Deprecated to maintain naming consistency with the json-rpc API """ raise DeprecationWarning("This method has been deprecated as of EIP 1474.") def getTransactionByBlock( self, block_identifier: BlockIdentifier, transaction_index: int ) -> TxData: """ `eth_getTransactionByBlockHashAndIndex` `eth_getTransactionByBlockNumberAndIndex` """ method = select_method_for_block_identifier( block_identifier, if_predefined=RPC.eth_getTransactionByBlockNumberAndIndex, if_hash=RPC.eth_getTransactionByBlockHashAndIndex, if_number=RPC.eth_getTransactionByBlockNumberAndIndex, ) result = self.web3.manager.request_blocking( method, [block_identifier, transaction_index], ) if result is None: raise TransactionNotFound( f"Transaction index: {transaction_index} " f"on block id: {block_identifier} not found." ) return result def waitForTransactionReceipt( self, transaction_hash: _Hash32, timeout: int=120, poll_latency: float=0.1 ) -> TxReceipt: try: return wait_for_transaction_receipt(self.web3, transaction_hash, timeout, poll_latency) except Timeout: raise TimeExhausted( "Transaction {} is not in the chain, after {} seconds".format( to_hex(transaction_hash), timeout, ) ) def getTransactionReceipt(self, transaction_hash: _Hash32) -> TxReceipt: result = self.web3.manager.request_blocking( RPC.eth_getTransactionReceipt, [transaction_hash], ) if result is None: raise TransactionNotFound(f"Transaction with hash: {transaction_hash} not found.") return result def getTransactionCount( self, account: Union[Address, ChecksumAddress, ENS], block_identifier: BlockIdentifier=None ) -> Nonce: if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( RPC.eth_getTransactionCount, [account, block_identifier], ) def replaceTransaction(self, transaction_hash: _Hash32, new_transaction: TxParams) -> HexBytes: current_transaction = get_required_transaction(self.web3, transaction_hash) return replace_transaction(self.web3, current_transaction, new_transaction) # todo: Update Any to stricter kwarg checking with TxParams # https://github.com/python/mypy/issues/4441 def modifyTransaction( self, transaction_hash: _Hash32, **transaction_params: Any ) -> HexBytes: assert_valid_transaction_params(cast(TxParams, transaction_params)) current_transaction = get_required_transaction(self.web3, transaction_hash) current_transaction_params = extract_valid_transaction_params(current_transaction) new_transaction = merge(current_transaction_params, transaction_params) return replace_transaction(self.web3, current_transaction, new_transaction) def sendTransaction(self, transaction: TxParams) -> HexBytes: # TODO: move to middleware if 'from' not in transaction and is_checksum_address(self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move gas estimation in middleware if 'gas' not in transaction: transaction = assoc( transaction, 'gas', get_buffered_gas_estimate(self.web3, transaction), ) return self.web3.manager.request_blocking( RPC.eth_sendTransaction, [transaction], ) def sendRawTransaction(self, raw_transaction: HexStr) -> HexBytes: return self.web3.manager.request_blocking( RPC.eth_sendRawTransaction, [raw_transaction], ) def sign( self, account: Union[Address, ChecksumAddress, ENS], data: Union[int, bytes]=None, hexstr: HexStr=None, text: str=None ) -> HexStr: message_hex = to_hex(data, hexstr=hexstr, text=text) return self.web3.manager.request_blocking( RPC.eth_sign, [account, message_hex], ) def signTransaction(self, transaction: TxParams) -> SignedTx: return self.web3.manager.request_blocking( RPC.eth_signTransaction, [transaction], ) def signTypedData( self, account: Union[Address, ChecksumAddress, ENS], jsonMessage: Dict[Any, Any] ) -> HexStr: return self.web3.manager.request_blocking( RPC.eth_signTypedData, [account, jsonMessage], ) @apply_to_return_value(HexBytes) def call(self, transaction: TxParams, block_identifier: BlockIdentifier=None) -> Sequence[Any]: # TODO: move to middleware if 'from' not in transaction and is_checksum_address(self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move to middleware if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( RPC.eth_call, [transaction, block_identifier], ) def estimateGas(self, transaction: TxParams, block_identifier: BlockIdentifier=None) -> Wei: # TODO: move to middleware if 'from' not in transaction and is_checksum_address(self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) if block_identifier is None: params: Sequence[Union[TxParams, BlockIdentifier]] = [transaction] else: params = [transaction, block_identifier] return self.web3.manager.request_blocking( RPC.eth_estimateGas, params, ) def filter( self, filter_params: Union[str, FilterParams]=None, filter_id: HexStr=None ) -> Filter: if filter_id and filter_params: raise TypeError( "Ambiguous invocation: provide either a `filter_params` or a `filter_id` argument. " "Both were supplied." ) if is_string(filter_params): if filter_params == "latest": filter_id = self.web3.manager.request_blocking( RPC.eth_newBlockFilter, [], ) return BlockFilter(self.web3, filter_id) elif filter_params == "pending": filter_id = self.web3.manager.request_blocking( RPC.eth_newPendingTransactionFilter, [], ) return TransactionFilter(self.web3, filter_id) else: raise ValueError( "The filter API only accepts the values of `pending` or " "`latest` for string based filters" ) elif isinstance(filter_params, dict): _filter_id = self.web3.manager.request_blocking( RPC.eth_newFilter, [filter_params], ) return LogFilter(self.web3, _filter_id) elif filter_id and not filter_params: return LogFilter(self.web3, filter_id) else: raise TypeError("Must provide either filter_params as a string or " "a valid filter object, or a filter_id as a string " "or hex.") def getFilterChanges(self, filter_id: HexStr) -> List[LogReceipt]: return self.web3.manager.request_blocking( RPC.eth_getFilterChanges, [filter_id], ) def getFilterLogs(self, filter_id: HexStr) -> List[LogReceipt]: return self.web3.manager.request_blocking( RPC.eth_getFilterLogs, [filter_id], ) def getLogs(self, filter_params: FilterParams) -> List[LogReceipt]: return self.web3.manager.request_blocking( RPC.eth_getLogs, [filter_params], ) def submitHashrate(self, hashrate: int, node_id: _Hash32) -> bool: return self.web3.manager.request_blocking( RPC.eth_submitHashrate, [hashrate, node_id], ) def submitWork(self, nonce: int, pow_hash: _Hash32, mix_digest: _Hash32) -> bool: return self.web3.manager.request_blocking( RPC.eth_submitWork, [nonce, pow_hash, mix_digest], ) def uninstallFilter(self, filter_id: HexStr) -> bool: return self.web3.manager.request_blocking( RPC.eth_uninstallFilter, [filter_id], ) @overload def contract(self, address: None=None, **kwargs: Any) -> Type[Contract]: ... # noqa: E704,E501 @overload # noqa: F811 def contract(self, address: Union[Address, ChecksumAddress, ENS], **kwargs: Any) -> Contract: ... # noqa: E704,E501 def contract( # noqa: F811 self, address: Union[Address, ChecksumAddress, ENS]=None, **kwargs: Any ) -> Union[Type[Contract], Contract]: ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) if address: return ContractFactory(address) else: return ContractFactory def setContractFactory( self, contractFactory: Type[Union[Contract, ConciseContract, ContractCaller]] ) -> None: self.defaultContractFactory = contractFactory def getCompilers(self) -> NoReturn: raise DeprecationWarning("This method has been deprecated as of EIP 1474.") def getWork(self) -> List[HexBytes]: return self.web3.manager.request_blocking(RPC.eth_getWork, []) def generateGasPrice(self, transaction_params: TxParams=None) -> Optional[Wei]: if self.gasPriceStrategy: return self.gasPriceStrategy(self.web3, transaction_params) return None def setGasPriceStrategy(self, gas_price_strategy: GasPriceStrategy) -> None: self.gasPriceStrategy = gas_price_strategy
def _create_account(passwd): acct = Account().create() priKey = acct.privateKey key_json = create_keyfile_json(priKey, passwd) return key_json, acct.address
assert w3.isConnected() # load the contract-abi from the .abi file with open("potato/potato.abi") as abi_file: contract_abi = json.load(abi_file) # load the compiled binary of the contract from the .bin file with open("potato/potato.bin") as bin_file: contract_bin = "0x" + bin_file.read() # init the token_contract object token_contract = w3.eth.contract(abi=contract_abi, bytecode=contract_bin) # open the wallet we generated with open("wallet/private.key", "rb") as key_file: account = Account().privateKeyToAccount(key_file.read()) # set transaction parameters tx_param = { "from": account.address, "to": sys.argv[1], "nonce": w3.eth.getTransactionCount(account.address), "gas": 1728712, "gasPrice": w3.toWei("21", "gwei") } # call the constructor # - give it the token_name as parameter # build a transaction from that # - give it the transaction parameters tx = token_contract.functions.to_vodka().buildTransaction(tx_param)
from eth_account import Account Signer = Account() # these tests were used trying to chase a bug relating to who sent the authorisation, and mirror some of the scenarios # in the big 'test_various_transfers' test def _common_setup_code(fullwallet_deploy, accounts, invoke_data): full_wallet, fw_rcpt, fw_accounts = fullwallet_deploy() a_addr = accounts[4] new_cosigner_addr = a_addr random_addr = accounts[5] b_addr = accounts[6] # Let's try some common modifications # First do recovery to random without cosigner full_wallet.functions.emergencyRecovery(random_addr, int(random_addr, 0)).transact({'from': fw_accounts['recovery']}) # Then set A as authorized (without cosign args_encoded = full_wallet.encodeABI( fn_name='setAuthorized', args=[a_addr, int(a_addr, 0)] ) authorized_data = invoke_data(1, full_wallet.address, 0, bytes.fromhex(args_encoded[2:])) full_wallet.functions.invoke0(authorized_data).transact({'from': random_addr}) # Then set Random to have A as cosigner # We call thrice.
class Eth(BaseEth, Module): account = Account() _default_block: BlockIdentifier = "latest" defaultContractFactory: Type[ Union[Contract, ConciseContract, ContractCaller]] = Contract # noqa: E704,E501 iban = Iban def namereg(self) -> NoReturn: raise NotImplementedError() def icapNamereg(self) -> NoReturn: raise NotImplementedError() _protocol_version: Method[Callable[[], str]] = Method( RPC.eth_protocolVersion, mungers=None, ) @property def protocol_version(self) -> str: warnings.warn( "This method has been deprecated in some clients.", category=DeprecationWarning, ) return self._protocol_version() @property def protocolVersion(self) -> str: warnings.warn( 'protocolVersion is deprecated in favor of protocol_version', category=DeprecationWarning, ) return self.protocol_version is_syncing: Method[Callable[[], Union[SyncStatus, bool]]] = Method( RPC.eth_syncing, mungers=None, ) @property def syncing(self) -> Union[SyncStatus, bool]: return self.is_syncing() @property def coinbase(self) -> ChecksumAddress: return self.get_coinbase() is_mining: Method[Callable[[], bool]] = Method( RPC.eth_mining, mungers=None, ) @property def mining(self) -> bool: return self.is_mining() get_hashrate: Method[Callable[[], int]] = Method( RPC.eth_hashrate, mungers=None, ) @property def hashrate(self) -> int: return self.get_hashrate() @property def gas_price(self) -> Wei: return self._gas_price() @property def gasPrice(self) -> Wei: warnings.warn( 'gasPrice is deprecated in favor of gas_price', category=DeprecationWarning, ) return self.gas_price get_accounts: Method[Callable[[], Tuple[ChecksumAddress]]] = Method( RPC.eth_accounts, mungers=None, ) @property def accounts(self) -> Tuple[ChecksumAddress]: return self.get_accounts() @property def block_number(self) -> BlockNumber: return self.get_block_number() @property def blockNumber(self) -> BlockNumber: warnings.warn( 'blockNumber is deprecated in favor of block_number', category=DeprecationWarning, ) return self.block_number _chain_id: Method[Callable[[], int]] = Method( RPC.eth_chainId, mungers=None, ) @property def chain_id(self) -> int: return self._chain_id() @property def chainId(self) -> int: warnings.warn( 'chainId is deprecated in favor of chain_id', category=DeprecationWarning, ) return self.chain_id """ property default_account """ @property def default_account(self) -> Union[ChecksumAddress, Empty]: return self._default_account @default_account.setter def default_account(self, account: Union[ChecksumAddress, Empty]) -> None: self._default_account = account @property def defaultAccount(self) -> Union[ChecksumAddress, Empty]: warnings.warn( 'defaultAccount is deprecated in favor of default_account', category=DeprecationWarning, ) return self._default_account @defaultAccount.setter def defaultAccount(self, account: Union[ChecksumAddress, Empty]) -> None: warnings.warn( 'defaultAccount is deprecated in favor of default_account', category=DeprecationWarning, ) self._default_account = account """ property default_block """ @property def default_block(self) -> BlockIdentifier: return self._default_block @default_block.setter def default_block(self, value: BlockIdentifier) -> None: self._default_block = value @property def defaultBlock(self) -> BlockIdentifier: warnings.warn( 'defaultBlock is deprecated in favor of default_block', category=DeprecationWarning, ) return self._default_block @defaultBlock.setter def defaultBlock(self, value: BlockIdentifier) -> None: warnings.warn( 'defaultBlock is deprecated in favor of default_block', category=DeprecationWarning, ) self._default_block = value def block_id_munger( self, account: Union[Address, ChecksumAddress, ENS], block_identifier: Optional[BlockIdentifier] = None ) -> Tuple[Union[Address, ChecksumAddress, ENS], BlockIdentifier]: if block_identifier is None: block_identifier = self.default_block return (account, block_identifier) get_balance: Method[Callable[..., Wei]] = Method( RPC.eth_getBalance, mungers=[block_id_munger], ) def get_storage_at_munger( self, account: Union[Address, ChecksumAddress, ENS], position: int, block_identifier: Optional[BlockIdentifier] = None ) -> Tuple[Union[Address, ChecksumAddress, ENS], int, BlockIdentifier]: if block_identifier is None: block_identifier = self.default_block return (account, position, block_identifier) get_storage_at: Method[Callable[..., HexBytes]] = Method( RPC.eth_getStorageAt, mungers=[get_storage_at_munger], ) def get_proof_munger( self, account: Union[Address, ChecksumAddress, ENS], positions: Sequence[int], block_identifier: Optional[BlockIdentifier] = None ) -> Tuple[Union[Address, ChecksumAddress, ENS], Sequence[int], Optional[BlockIdentifier]]: if block_identifier is None: block_identifier = self.default_block return (account, positions, block_identifier) get_proof: Method[Callable[[ Tuple[Union[Address, ChecksumAddress, ENS], Sequence[int], Optional[BlockIdentifier]] ], MerkleProof]] = Method( RPC.eth_getProof, mungers=[get_proof_munger], ) get_code: Method[Callable[..., HexBytes]] = Method(RPC.eth_getCode, mungers=[block_id_munger]) def get_block(self, block_identifier: BlockIdentifier, full_transactions: bool = False) -> BlockData: return self._get_block(block_identifier, full_transactions) """ `eth_getBlockTransactionCountByHash` `eth_getBlockTransactionCountByNumber` """ get_block_transaction_count: Method[Callable[ [BlockIdentifier], int]] = Method( method_choice_depends_on_args=select_method_for_block_identifier( if_predefined=RPC.eth_getBlockTransactionCountByNumber, if_hash=RPC.eth_getBlockTransactionCountByHash, if_number=RPC.eth_getBlockTransactionCountByNumber, ), mungers=[default_root_munger]) """ `eth_getUncleCountByBlockHash` `eth_getUncleCountByBlockNumber` """ get_uncle_count: Method[Callable[[BlockIdentifier], int]] = Method( method_choice_depends_on_args=select_method_for_block_identifier( if_predefined=RPC.eth_getUncleCountByBlockNumber, if_hash=RPC.eth_getUncleCountByBlockHash, if_number=RPC.eth_getUncleCountByBlockNumber, ), mungers=[default_root_munger]) """ `eth_getUncleByBlockHashAndIndex` `eth_getUncleByBlockNumberAndIndex` """ get_uncle_by_block: Method[Callable[ [BlockIdentifier, int], Uncle]] = Method( method_choice_depends_on_args=select_method_for_block_identifier( if_predefined=RPC.eth_getUncleByBlockNumberAndIndex, if_hash=RPC.eth_getUncleByBlockHashAndIndex, if_number=RPC.eth_getUncleByBlockNumberAndIndex, ), mungers=[default_root_munger]) def get_transaction(self, transaction_hash: _Hash32) -> TxData: return self._get_transaction(transaction_hash) def getTransactionFromBlock(self, block_identifier: BlockIdentifier, transaction_index: int) -> NoReturn: """ Alias for the method getTransactionByBlock Deprecated to maintain naming consistency with the json-rpc API """ raise DeprecationWarning( "This method has been deprecated as of EIP 1474.") get_transaction_by_block: Method[Callable[ [BlockIdentifier, int], TxData]] = Method( method_choice_depends_on_args=select_method_for_block_identifier( if_predefined=RPC.eth_getTransactionByBlockNumberAndIndex, if_hash=RPC.eth_getTransactionByBlockHashAndIndex, if_number=RPC.eth_getTransactionByBlockNumberAndIndex, ), mungers=[default_root_munger]) @deprecated_for("wait_for_transaction_receipt") def waitForTransactionReceipt(self, transaction_hash: _Hash32, timeout: int = 120, poll_latency: float = 0.1) -> TxReceipt: return self.wait_for_transaction_receipt(transaction_hash, timeout, poll_latency) def wait_for_transaction_receipt(self, transaction_hash: _Hash32, timeout: int = 120, poll_latency: float = 0.1) -> TxReceipt: try: return wait_for_transaction_receipt(self.web3, transaction_hash, timeout, poll_latency) except Timeout: raise TimeExhausted( "Transaction {} is not in the chain, after {} seconds".format( to_hex(transaction_hash), timeout, )) get_transaction_receipt: Method[Callable[[_Hash32], TxReceipt]] = Method( RPC.eth_getTransactionReceipt, mungers=[default_root_munger]) get_transaction_count: Method[Callable[..., Nonce]] = Method( RPC.eth_getTransactionCount, mungers=[block_id_munger], ) @deprecated_for("replace_transaction") def replaceTransaction(self, transaction_hash: _Hash32, new_transaction: TxParams) -> HexBytes: return self.replace_transaction(transaction_hash, new_transaction) def replace_transaction(self, transaction_hash: _Hash32, new_transaction: TxParams) -> HexBytes: current_transaction = get_required_transaction(self.web3, transaction_hash) return replace_transaction(self.web3, current_transaction, new_transaction) # todo: Update Any to stricter kwarg checking with TxParams # https://github.com/python/mypy/issues/4441 @deprecated_for("modify_transaction") def modifyTransaction(self, transaction_hash: _Hash32, **transaction_params: Any) -> HexBytes: return self.modify_transaction(transaction_hash, **transaction_params) def modify_transaction(self, transaction_hash: _Hash32, **transaction_params: Any) -> HexBytes: assert_valid_transaction_params(cast(TxParams, transaction_params)) current_transaction = get_required_transaction(self.web3, transaction_hash) current_transaction_params = extract_valid_transaction_params( current_transaction) new_transaction = merge(current_transaction_params, transaction_params) return replace_transaction(self.web3, current_transaction, new_transaction) def send_transaction(self, transaction: TxParams) -> HexBytes: return self._send_transaction(transaction) send_raw_transaction: Method[Callable[[Union[HexStr, bytes]], HexBytes]] = Method( RPC.eth_sendRawTransaction, mungers=[default_root_munger], ) def sign_munger( self, account: Union[Address, ChecksumAddress, ENS], data: Union[int, bytes] = None, hexstr: HexStr = None, text: str = None ) -> Tuple[Union[Address, ChecksumAddress, ENS], HexStr]: message_hex = to_hex(data, hexstr=hexstr, text=text) return (account, message_hex) sign: Method[Callable[..., HexStr]] = Method( RPC.eth_sign, mungers=[sign_munger], ) sign_transaction: Method[Callable[[TxParams], SignedTx]] = Method( RPC.eth_signTransaction, mungers=[default_root_munger], ) sign_typed_data: Method[Callable[..., HexStr]] = Method( RPC.eth_signTypedData, mungers=[default_root_munger], ) def call_munger( self, transaction: TxParams, block_identifier: Optional[BlockIdentifier] = None, state_override: Optional[CallOverrideParams] = None, ) -> Union[Tuple[TxParams, BlockIdentifier], Tuple[ TxParams, BlockIdentifier, CallOverrideParams]]: # noqa-E501 # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.default_account): transaction = assoc(transaction, 'from', self.default_account) # TODO: move to middleware if block_identifier is None: block_identifier = self.default_block if state_override is None: return (transaction, block_identifier) else: return (transaction, block_identifier, state_override) call: Method[Callable[..., Union[bytes, bytearray]]] = Method(RPC.eth_call, mungers=[call_munger]) def estimate_gas( self, transaction: TxParams, block_identifier: Optional[BlockIdentifier] = None) -> Wei: return self._estimate_gas(transaction, block_identifier) def filter_munger( self, filter_params: Optional[Union[str, FilterParams]] = None, filter_id: Optional[HexStr] = None ) -> Union[List[FilterParams], List[HexStr], List[str]]: if filter_id and filter_params: raise TypeError( "Ambiguous invocation: provide either a `filter_params` or a `filter_id` argument. " "Both were supplied.") if isinstance(filter_params, dict): return [filter_params] elif is_string(filter_params): if filter_params in ['latest', 'pending']: return [filter_params] else: raise ValueError( "The filter API only accepts the values of `pending` or " "`latest` for string based filters") elif filter_id and not filter_params: return [filter_id] else: raise TypeError( "Must provide either filter_params as a string or " "a valid filter object, or a filter_id as a string " "or hex.") filter: Method[Callable[..., Any]] = Method( method_choice_depends_on_args=select_filter_method( if_new_block_filter=RPC.eth_newBlockFilter, if_new_pending_transaction_filter=RPC. eth_newPendingTransactionFilter, if_new_filter=RPC.eth_newFilter, ), mungers=[filter_munger], ) get_filter_changes: Method[Callable[[HexStr], List[LogReceipt]]] = Method( RPC.eth_getFilterChanges, mungers=[default_root_munger]) get_filter_logs: Method[Callable[[HexStr], List[LogReceipt]]] = Method( RPC.eth_getFilterLogs, mungers=[default_root_munger]) get_logs: Method[Callable[[FilterParams], List[LogReceipt]]] = Method( RPC.eth_getLogs, mungers=[default_root_munger]) submit_hashrate: Method[Callable[[int, _Hash32], bool]] = Method( RPC.eth_submitHashrate, mungers=[default_root_munger], ) submit_work: Method[Callable[[int, _Hash32, _Hash32], bool]] = Method( RPC.eth_submitWork, mungers=[default_root_munger], ) uninstall_filter: Method[Callable[[HexStr], bool]] = Method( RPC.eth_uninstallFilter, mungers=[default_root_munger], ) @overload def contract(self, address: None = None, **kwargs: Any) -> Type[Contract]: ... # noqa: E704,E501 @overload # noqa: F811 def contract(self, address: Union[Address, ChecksumAddress, ENS], **kwargs: Any) -> Contract: ... # noqa: E704,E501 def contract( # noqa: F811 self, address: Optional[Union[Address, ChecksumAddress, ENS]] = None, **kwargs: Any) -> Union[Type[Contract], Contract]: ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) if address: return ContractFactory(address) else: return ContractFactory @deprecated_for("set_contract_factory") def setContractFactory( self, contractFactory: Type[Union[Contract, ConciseContract, ContractCaller]] ) -> None: return self.set_contract_factory(contractFactory) def set_contract_factory( self, contractFactory: Type[Union[Contract, ConciseContract, ContractCaller]] ) -> None: self.defaultContractFactory = contractFactory def getCompilers(self) -> NoReturn: raise DeprecationWarning( "This method has been deprecated as of EIP 1474.") get_work: Method[Callable[[], List[HexBytes]]] = Method( RPC.eth_getWork, mungers=None, ) @deprecated_for("generate_gas_price") def generateGasPrice( self, transaction_params: Optional[TxParams] = None) -> Optional[Wei]: return self._generate_gas_price(transaction_params) def generate_gas_price( self, transaction_params: Optional[TxParams] = None) -> Optional[Wei]: return self._generate_gas_price(transaction_params) @deprecated_for("set_gas_price_strategy") def setGasPriceStrategy(self, gas_price_strategy: GasPriceStrategy) -> None: return self.set_gas_price_strategy(gas_price_strategy) # Deprecated Methods getBalance = DeprecatedMethod(get_balance, 'getBalance', 'get_balance') getStorageAt = DeprecatedMethod(get_storage_at, 'getStorageAt', 'get_storage_at') getBlock = DeprecatedMethod(get_block, 'getBlock', 'get_block') # type: ignore getBlockTransactionCount = DeprecatedMethod(get_block_transaction_count, 'getBlockTransactionCount', 'get_block_transaction_count') getCode = DeprecatedMethod(get_code, 'getCode', 'get_code') getProof = DeprecatedMethod(get_proof, 'getProof', 'get_proof') getTransaction = DeprecatedMethod( get_transaction, # type: ignore 'getTransaction', 'get_transaction') getTransactionByBlock = DeprecatedMethod(get_transaction_by_block, 'getTransactionByBlock', 'get_transaction_by_block') getTransactionCount = DeprecatedMethod(get_transaction_count, 'getTransactionCount', 'get_transaction_count') getUncleByBlock = DeprecatedMethod(get_uncle_by_block, 'getUncleByBlock', 'get_uncle_by_block') getUncleCount = DeprecatedMethod(get_uncle_count, 'getUncleCount', 'get_uncle_count') sendTransaction = DeprecatedMethod( send_transaction, # type: ignore 'sendTransaction', 'send_transaction') signTransaction = DeprecatedMethod(sign_transaction, 'signTransaction', 'sign_transaction') signTypedData = DeprecatedMethod(sign_typed_data, 'signTypedData', 'sign_typed_data') submitHashrate = DeprecatedMethod(submit_hashrate, 'submitHashrate', 'submit_hashrate') submitWork = DeprecatedMethod(submit_work, 'submitWork', 'submit_work') getLogs = DeprecatedMethod(get_logs, 'getLogs', 'get_logs') estimateGas = DeprecatedMethod(estimate_gas, 'estimateGas', 'estimate_gas') # type: ignore sendRawTransaction = DeprecatedMethod(send_raw_transaction, 'sendRawTransaction', 'send_raw_transaction') getTransactionReceipt = DeprecatedMethod(get_transaction_receipt, 'getTransactionReceipt', 'get_transaction_receipt') uninstallFilter = DeprecatedMethod(uninstall_filter, 'uninstallFilter', 'uninstall_filter') getFilterLogs = DeprecatedMethod(get_filter_logs, 'getFilterLogs', 'get_filter_logs') getFilterChanges = DeprecatedMethod(get_filter_changes, 'getFilterChanges', 'get_filter_changes') getWork = DeprecatedMethod(get_work, 'getWork', 'get_work')
class Eth(Module): account = Account() defaultAccount = empty defaultBlock = "latest" defaultContractFactory = Contract iban = Iban gasPriceStrategy = None @deprecated_for("doing nothing at all") def enable_unaudited_features(self): pass def namereg(self): raise NotImplementedError() def icapNamereg(self): raise NotImplementedError() @property def protocolVersion(self): return self.web3.manager.request_blocking("platon_protocolVersion", []) @property def syncing(self): return self.web3.manager.request_blocking("platon_syncing", []) # @property # def coinbase(self): # return self.web3.manager.request_blocking("platon_coinbase", []) # @property # def mining(self): # return self.web3.manager.request_blocking("platon_mining", []) # @property # def hashrate(self): # return self.web3.manager.request_blocking("platon_hashrate", []) @property def gasPrice(self): return self.web3.manager.request_blocking("platon_gasPrice", []) @property def accounts(self): return self.web3.manager.request_blocking("platon_accounts", []) @property def blockNumber(self): return self.web3.manager.request_blocking("platon_blockNumber", []) @property def evidences(self): data = self.web3.manager.request_blocking("platon_evidences", []) return json.loads(data) @property def consensusStatus(self): return self.web3.manager.request_blocking("platon_consensusStatus", []) def getPrepareQC(self, block_number): return self.web3.manager.request_blocking("platon_getPrepareQC", [block_number]) def getBalance(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "platon_getBalance", [account, block_identifier], ) def getStorageAt(self, account, position, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "platon_getStorageAt", [account, position, block_identifier]) def getCode(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "platon_getCode", [account, block_identifier], ) def getBlock(self, block_identifier, full_transactions=False): """ `platon_getBlockByHash` `platon_getBlockByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='platon_getBlockByNumber', if_hash='platon_getBlockByHash', if_number='platon_getBlockByNumber', ) return self.web3.manager.request_blocking( method, [block_identifier, full_transactions], ) def getBlockTransactionCount(self, block_identifier): """ `platon_getBlockTransactionCountByHash` `platon_getBlockTransactionCountByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='platon_getBlockTransactionCountByNumber', if_hash='platon_getBlockTransactionCountByHash', if_number='platon_getBlockTransactionCountByNumber', ) return self.web3.manager.request_blocking( method, [block_identifier], ) # def getUncleCount(self, block_identifier): # """ # `platon_getUncleCountByBlockHash` # `platon_getUncleCountByBlockNumber` # """ # method = select_method_for_block_identifier( # block_identifier, # if_predefined='platon_getUncleCountByBlockNumber', # if_hash='platon_getUncleCountByBlockHash', # if_number='platon_getUncleCountByBlockNumber', # ) # return self.web3.manager.request_blocking( # method, # [block_identifier], # ) # def getUncleByBlock(self, block_identifier, uncle_index): # """ # `platon_getUncleByBlockHashAndIndex` # `platon_getUncleByBlockNumberAndIndex` # """ # method = select_method_for_block_identifier( # block_identifier, # if_predefined='platon_getUncleByBlockNumberAndIndex', # if_hash='platon_getUncleByBlockHashAndIndex', # if_number='platon_getUncleByBlockNumberAndIndex', # ) # return self.web3.manager.request_blocking( # method, # [block_identifier, uncle_index], # ) def getTransaction(self, transaction_hash): return self.web3.manager.request_blocking( "platon_getTransactionByHash", [transaction_hash], ) def getRawTransaction(self, transaction_hash): return self.web3.manager.request_blocking( "platon_getRawTransactionByHash", [transaction_hash], ) @deprecated_for("w3.eth.getTransactionByBlock") def getTransactionFromBlock(self, block_identifier, transaction_index): """ Alias for the method getTransactionByBlock Depreceated to maintain naming consistency with the json-rpc API """ return self.getTransactionByBlock(block_identifier, transaction_index) def getTransactionByBlock(self, block_identifier, transaction_index): """ `platon_getTransactionByBlockHashAndIndex` `platon_getTransactionByBlockNumberAndIndex` """ method = select_method_for_block_identifier( block_identifier, if_predefined='platon_getTransactionByBlockNumberAndIndex', if_hash='platon_getTransactionByBlockHashAndIndex', if_number='platon_getTransactionByBlockNumberAndIndex', ) return self.web3.manager.request_blocking( method, [block_identifier, transaction_index], ) def waitForTransactionReceipt(self, transaction_hash, timeout=120): return wait_for_transaction_receipt(self.web3, transaction_hash, timeout) def getTransactionReceipt(self, transaction_hash): return self.web3.manager.request_blocking( "platon_getTransactionReceipt", [transaction_hash], ) def getTransactionCount(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "platon_getTransactionCount", [ account, block_identifier, ], ) def replaceTransaction(self, transaction_hash, new_transaction): current_transaction = get_required_transaction(self.web3, transaction_hash) return replace_transaction(self.web3, current_transaction, new_transaction) def modifyTransaction(self, transaction_hash, **transaction_params): assert_valid_transaction_params(transaction_params) current_transaction = get_required_transaction(self.web3, transaction_hash) current_transaction_params = extract_valid_transaction_params( current_transaction) new_transaction = merge(current_transaction_params, transaction_params) return replace_transaction(self.web3, current_transaction, new_transaction) def sendTransaction(self, transaction): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move gas estimation in middleware if 'gas' not in transaction: transaction = assoc( transaction, 'gas', get_buffered_gas_estimate(self.web3, transaction), ) return self.web3.manager.request_blocking( "platon_sendTransaction", [transaction], ) def sendRawTransaction(self, raw_transaction): return self.web3.manager.request_blocking( "platon_sendRawTransaction", [raw_transaction], ) def sign(self, account, data=None, hexstr=None, text=None): message_hex = to_hex(data, hexstr=hexstr, text=text) return self.web3.manager.request_blocking( "platon_sign", [account, message_hex], ) @apply_to_return_value(HexBytes) def call(self, transaction, block_identifier=None): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move to middleware if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "platon_call", [transaction, block_identifier], ) def estimateGas(self, transaction): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) return self.web3.manager.request_blocking( "platon_estimateGas", [transaction], ) def filter(self, filter_params=None, filter_id=None): if filter_id and filter_params: raise TypeError( "Ambiguous invocation: provide either a `filter_params` or a `filter_id` argument. " "Both were supplied.") if is_string(filter_params): if filter_params == "latest": filter_id = self.web3.manager.request_blocking( "platon_newBlockFilter", [], ) return BlockFilter(self.web3, filter_id) elif filter_params == "pending": filter_id = self.web3.manager.request_blocking( "platon_newPendingTransactionFilter", [], ) return TransactionFilter(self.web3, filter_id) else: raise ValueError( "The filter API only accepts the values of `pending` or " "`latest` for string based filters") elif isinstance(filter_params, dict): _filter_id = self.web3.manager.request_blocking( "platon_newFilter", [filter_params], ) return LogFilter(self.web3, _filter_id) elif filter_id and not filter_params: return LogFilter(self.web3, filter_id) else: raise TypeError( "Must provide either filter_params as a string or " "a valid filter object, or a filter_id as a string " "or hex.") def getFilterChanges(self, filter_id): return self.web3.manager.request_blocking( "platon_getFilterChanges", [filter_id], ) def getFilterLogs(self, filter_id): return self.web3.manager.request_blocking( "platon_getFilterLogs", [filter_id], ) def getLogs(self, filter_params): return self.web3.manager.request_blocking( "platon_getLogs", [filter_params], ) def uninstallFilter(self, filter_id): return self.web3.manager.request_blocking( "platon_uninstallFilter", [filter_id], ) def contract(self, address=None, **kwargs): ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) if address: return ContractFactory(address) else: return ContractFactory def setContractFactory(self, contractFactory): self.defaultContractFactory = contractFactory # @deprecated_in_v5 # def getCompilers(self): # return self.web3.manager.request_blocking("platon_getCompilers", []) # def getWork(self): # return self.web3.manager.request_blocking("platon_getWork", []) def generateGasPrice(self, transaction_params=None): if self.gasPriceStrategy: return self.gasPriceStrategy(self.web3, transaction_params) def setGasPriceStrategy(self, gas_price_strategy): self.gasPriceStrategy = gas_price_strategy # add to platon def analyzeReceiptByHash(self, tx_hash): receipt = self.waitForTransactionReceipt(tx_hash) return self.analyzeReceipt(receipt) def analyzeReceipt(self, transaction_receipt): return self.web3.analyzeReceipt(transaction_receipt) def ecrecover(self, block_identifier): block = self.getBlock(block_identifier) extra = block.proofOfAuthorityData[0:32] sign = block.proofOfAuthorityData[32:] raw_data = [ bytes.fromhex(remove_0x_prefix(block.parentHash.hex())), bytes.fromhex(remove_0x_prefix(block.miner)), bytes.fromhex(remove_0x_prefix(block.stateRoot.hex())), bytes.fromhex(remove_0x_prefix(block.transactionsRoot.hex())), bytes.fromhex(remove_0x_prefix(block.receiptsRoot.hex())), bytes.fromhex(remove_0x_prefix(block.logsBloom.hex())), block.number, block.gasLimit, block.gasUsed, block.timestamp, extra, bytes.fromhex(remove_0x_prefix(block.nonce)) ] message_hash = sha3.keccak_256(rlp.encode(raw_data)).digest() hash_bytes = HexBytes(message_hash) signature_bytes = HexBytes(sign) signature_bytes_standard = to_standard_signature_bytes(signature_bytes) signature_obj = self.account._keys.Signature( signature_bytes=signature_bytes_standard) return remove_0x_prefix( signature_obj.recover_public_key_from_msg_hash( hash_bytes).to_hex())
class Eth(Module): account = Account() defaultAccount = empty defaultBlock = "latest" defaultContractFactory = Contract iban = Iban gasPriceStrategy = None def namereg(self): raise NotImplementedError() def icapNamereg(self): raise NotImplementedError() @property def protocolVersion(self): return self.web3.manager.request_blocking("eth_protocolVersion", []) @property def syncing(self): return self.web3.manager.request_blocking("eth_syncing", []) @property def coinbase(self): return self.web3.manager.request_blocking("eth_coinbase", []) @property def mining(self): return self.web3.manager.request_blocking("eth_mining", []) @property def hashrate(self): return self.web3.manager.request_blocking("eth_hashrate", []) @property def gasPrice(self): return self.web3.manager.request_blocking("eth_gasPrice", []) @property def accounts(self): return self.web3.manager.request_blocking("eth_accounts", []) @property def blockNumber(self): return self.web3.manager.request_blocking("eth_blockNumber", []) def getBalance(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getBalance", [account, block_identifier], ) def getStorageAt(self, account, position, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getStorageAt", [account, position, block_identifier]) def getCode(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getCode", [account, block_identifier], ) def getBlock(self, block_identifier, full_transactions=False): """ `eth_getBlockByHash` `eth_getBlockByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getBlockByNumber', if_hash='eth_getBlockByHash', if_number='eth_getBlockByNumber', ) return self.web3.manager.request_blocking( method, [block_identifier, full_transactions], ) def getBlockTransactionCount(self, block_identifier): """ `eth_getBlockTransactionCountByHash` `eth_getBlockTransactionCountByNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getBlockTransactionCountByNumber', if_hash='eth_getBlockTransactionCountByHash', if_number='eth_getBlockTransactionCountByNumber', ) return self.web3.manager.request_blocking( method, [block_identifier], ) def getUncleCount(self, block_identifier): """ `eth_getUncleCountByBlockHash` `eth_getUncleCountByBlockNumber` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getUncleCountByBlockNumber', if_hash='eth_getUncleCountByBlockHash', if_number='eth_getUncleCountByBlockNumber', ) return self.web3.manager.request_blocking( method, [block_identifier], ) def getTransaction(self, transaction_hash): return self.web3.manager.request_blocking( "eth_getTransactionByHash", [transaction_hash], ) def getTransactionFromBlock(self, block_identifier, transaction_index): """ `eth_getTransactionByBlockHashAndIndex` `eth_getTransactionByBlockNumberAndIndex` """ method = select_method_for_block_identifier( block_identifier, if_predefined='eth_getTransactionByBlockNumberAndIndex', if_hash='eth_getTransactionByBlockHashAndIndex', if_number='eth_getTransactionByBlockNumberAndIndex', ) return self.web3.manager.request_blocking( method, [block_identifier, transaction_index], ) def getTransactionReceipt(self, transaction_hash): return self.web3.manager.request_blocking( "eth_getTransactionReceipt", [transaction_hash], ) def getTransactionCount(self, account, block_identifier=None): if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_getTransactionCount", [ account, block_identifier, ], ) def replaceTransaction(self, transaction_hash, new_transaction): current_transaction = get_required_transaction(self.web3, transaction_hash) return replace_transaction(self.web3, current_transaction, new_transaction) def modifyTransaction(self, transaction_hash, **transaction_params): assert_valid_transaction_params(transaction_params) current_transaction = get_required_transaction(self.web3, transaction_hash) current_transaction_params = extract_valid_transaction_params( current_transaction) new_transaction = merge(current_transaction_params, transaction_params) return replace_transaction(self.web3, current_transaction, new_transaction) def sendTransaction(self, transaction): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move gas estimation in middleware if 'gas' not in transaction: transaction = assoc( transaction, 'gas', get_buffered_gas_estimate(self.web3, transaction), ) return self.web3.manager.request_blocking( "eth_sendTransaction", [transaction], ) def sendRawTransaction(self, raw_transaction): return self.web3.manager.request_blocking( "eth_sendRawTransaction", [raw_transaction], ) def sign(self, account, data=None, hexstr=None, text=None): message_hex = to_hex(data, hexstr=hexstr, text=text) return self.web3.manager.request_blocking( "eth_sign", [account, message_hex], ) @apply_to_return_value(HexBytes) def call(self, transaction, block_identifier=None): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) # TODO: move to middleware if block_identifier is None: block_identifier = self.defaultBlock return self.web3.manager.request_blocking( "eth_call", [transaction, block_identifier], ) def estimateGas(self, transaction): # TODO: move to middleware if 'from' not in transaction and is_checksum_address( self.defaultAccount): transaction = assoc(transaction, 'from', self.defaultAccount) return self.web3.manager.request_blocking( "eth_estimateGas", [transaction], ) def filter(self, filter_params): if is_string(filter_params): if filter_params == "latest": filter_id = self.web3.manager.request_blocking( "eth_newBlockFilter", [], ) return BlockFilter(self.web3, filter_id) elif filter_params == "pending": filter_id = self.web3.manager.request_blocking( "eth_newPendingTransactionFilter", [], ) return TransactionFilter(self.web3, filter_id) else: raise ValueError( "The filter API only accepts the values of `pending` or " "`latest` for string based filters") elif isinstance(filter_params, dict): filter_id = self.web3.manager.request_blocking( "eth_newFilter", [filter_params], ) return LogFilter(self.web3, filter_id) else: raise ValueError( "Must provide either a string or a valid filter object") def getFilterChanges(self, filter_id): return self.web3.manager.request_blocking( "eth_getFilterChanges", [filter_id], ) def getFilterLogs(self, filter_id): return self.web3.manager.request_blocking( "eth_getFilterLogs", [filter_id], ) def getLogs(self, filter_params): return self.web3.manager.request_blocking( "eth_getLogs", [filter_params], ) def uninstallFilter(self, filter_id): return self.web3.manager.request_blocking( "eth_uninstallFilter", [filter_id], ) def contract(self, address=None, **kwargs): ContractFactoryClass = kwargs.pop('ContractFactoryClass', self.defaultContractFactory) ContractFactory = ContractFactoryClass.factory(self.web3, **kwargs) if address: return ContractFactory(address) else: return ContractFactory def setContractFactory(self, contractFactory): self.defaultContractFactory = contractFactory def getCompilers(self): return self.web3.manager.request_blocking("eth_getCompilers", []) def getWork(self): return self.web3.manager.request_blocking("eth_getWork", []) def generateGasPrice(self, transaction_params=None): if self.gasPriceStrategy: return self.gasPriceStrategy(self.web3, transaction_params) def setGasPriceStrategy(self, gas_price_strategy): self.gasPriceStrategy = gas_price_strategy