def deploy_erc20(w3: Web3, name: str, symbol: str, owner: str, amount: int, decimals: int = 18, deployer: str = None, account: LocalAccount = None) -> Contract: if account: erc20_contract = get_example_erc20_contract(w3) tx = erc20_contract.constructor( name, symbol, decimals, owner, amount).buildTransaction({ 'nonce': w3.eth.get_transaction_count(account.address, block_identifier='pending') }) signed_tx = account.sign_transaction(tx) tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction) else: deployer = deployer or w3.eth.accounts[0] erc20_contract = get_example_erc20_contract(w3) tx_hash = erc20_contract.constructor( name, symbol, decimals, owner, amount).transact({'from': deployer}) tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) erc20_address = tx_receipt.contractAddress deployed_erc20 = get_example_erc20_contract(w3, erc20_address) assert deployed_erc20.functions.balanceOf(owner).call() == amount return deployed_erc20
def submit_vote( network: str, oracle: LocalAccount, encoded_data: bytes, vote: Union[RewardVote, DistributorVote, ValidatorVote], name: str, ) -> None: """Submits vote to the votes' aggregator.""" network_config = NETWORKS[network] aws_bucket_name = network_config["AWS_BUCKET_NAME"] s3_client = boto3.client( "s3", aws_access_key_id=network_config["AWS_ACCESS_KEY_ID"], aws_secret_access_key=network_config["AWS_SECRET_ACCESS_KEY"], ) # generate candidate ID candidate_id: bytes = Web3.keccak(primitive=encoded_data) message = encode_defunct(primitive=candidate_id) signed_message = oracle.sign_message(message) vote["signature"] = signed_message.signature.hex() # TODO: support more aggregators (GCP, Azure, etc.) bucket_key = f"{oracle.address}/{name}" s3_client.put_object( Bucket=aws_bucket_name, Key=bucket_key, Body=json.dumps(vote), ACL="public-read", ) s3_client.get_waiter("object_exists").wait(Bucket=aws_bucket_name, Key=bucket_key)
def privateKeyToAccount(self, private_key): ''' Returns a convenient object for working with the given private key. :param private_key: The raw private key :type private_key: hex str or bytes or int :return: object with methods for signing and encrypting :rtype: LocalAccount .. code-block:: python >>> acct = Account.privateKeyToAccount( 0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364) >>> acct.address '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' >>> acct.privateKey b"\\xb2\\}\\xb3\\x1f\\xee\\xd9\\x12''\\xbf\\t9\\xdcv\\x9a\\x96VK-\\xe4\\xc4rm\\x03[6\\xec\\xf1\\xe5\\xb3d" # These methods are also available: signHash(), signTransaction(), encrypt() # They correspond to the same-named methods in Account.* # but without the private key argument ''' key_bytes = HexBytes(private_key) try: key_obj = self._keys.PrivateKey(key_bytes) return LocalAccount(key_obj, self) except ValidationError as original_exception: raise ValueError( "The private key must be exactly 32 bytes long, instead of " "%d bytes." % len(key_bytes)) from original_exception
def deploy_example_erc20(w3, amount: int, owner: str, deployer: str = None, account: LocalAccount = None): if account: erc20_contract = get_example_erc20_contract(w3) tx = erc20_contract.constructor(amount, owner).buildTransaction() if 'nonce' not in tx: tx['nonce'] = w3.eth.getTransactionCount( account.address, block_identifier='pending') signed_tx = account.sign_transaction(tx) tx_hash = w3.eth.sendRawTransaction(signed_tx.rawTransaction) tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) erc20_address = tx_receipt.contractAddress deployed_erc20 = get_example_erc20_contract(w3, erc20_address) assert deployed_erc20.functions.balanceOf(owner).call() == amount return deployed_erc20 deployer = deployer or w3.eth.accounts[0] erc20_contract = get_example_erc20_contract(w3) tx_hash = erc20_contract.constructor(amount, owner).transact({'from': deployer}) tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) erc20_address = tx_receipt.contractAddress deployed_erc20 = get_example_erc20_contract(w3, erc20_address) assert deployed_erc20.functions.balanceOf(owner).call() == amount return deployed_erc20
def remove_delegate( self, safe_address: str, delegate_address: str, signer_account: LocalAccount ): hash_to_sign = self.create_delegate_message_hash(delegate_address) signature = signer_account.signHash(hash_to_sign) remove_payload = {"signature": signature.signature.hex()} response = self._delete_request( f"/api/v1/safes/{safe_address}/delegates/{delegate_address}/", remove_payload, ) if not response.ok: raise BaseAPIException(f"Cannot remove delegate: {response.content}")
def send_tx(w3: Web3, tx, account: LocalAccount) -> bytes: tx['from'] = account.address if 'nonce' not in tx: tx['nonce'] = w3.eth.get_transaction_count(account.address, block_identifier='pending') if 'gasPrice' not in tx: tx['gasPrice'] = w3.eth.gas_price if 'gas' not in tx: tx['gas'] = w3.eth.estimateGas(tx) else: tx['gas'] *= 2 signed_tx = account.sign_transaction(tx) tx_hash = w3.eth.send_raw_transaction(bytes(signed_tx.rawTransaction)) tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash) assert tx_receipt.status == 1, 'Error with tx %s - %s' % (tx_hash.hex(), tx) return tx_hash
def add_delegate( self, safe_address: str, delegate_address: str, label: str, signer_account: LocalAccount, ): hash_to_sign = self.create_delegate_message_hash(delegate_address) signature = signer_account.signHash(hash_to_sign) add_payload = { "safe": safe_address, "delegate": delegate_address, "signature": signature.signature.hex(), "label": label, } response = self._post_request( f"/api/v1/safes/{safe_address}/delegates/", add_payload ) if not response.ok: raise BaseAPIException(f"Cannot add delegate: {response.content}")
def send_tx(w3: Web3, tx: TxParams, account: LocalAccount) -> bytes: tx["from"] = account.address if "nonce" not in tx: tx["nonce"] = w3.eth.get_transaction_count(account.address, block_identifier="pending") if "gasPrice" not in tx and "maxFeePerGas" not in tx: tx["gasPrice"] = w3.eth.gas_price if "gas" not in tx: tx["gas"] = w3.eth.estimate_gas(tx) else: tx["gas"] *= 2 signed_tx = account.sign_transaction(tx) tx_hash = w3.eth.send_raw_transaction(bytes(signed_tx.rawTransaction)) tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash) assert tx_receipt.status == 1, "Error with tx %s - %s" % (tx_hash.hex(), tx) return tx_hash
def from_mnemonic(self, mnemonic: str, passphrase: str = "", account_path: str = ETHEREUM_DEFAULT_PATH): """ Generate an account from a mnemonic. .. CAUTION:: This feature is experimental, unaudited, and likely to change soon :param str mnemonic: space-separated list of BIP39 mnemonic seed words :param str passphrase: Optional passphrase used to encrypt the mnemonic :param str account_path: Specify an alternate HD path for deriving the seed using BIP32 HD wallet key derivation. :return: object with methods for signing and encrypting :rtype: LocalAccount .. doctest:: python >>> from eth_account import Account >>> Account.enable_unaudited_hdwallet_features() >>> acct = Account.from_mnemonic( ... "coral allow abandon recipe top tray caught video climb similar prepare bracket " ... "antenna rubber announce gauge volume hub hood burden skill immense add acid") >>> acct.address '0x9AdA5dAD14d925f4df1378409731a9B71Bc8569d' # These methods are also available: sign_message(), sign_transaction(), encrypt() # They correspond to the same-named methods in Account.* # but without the private key argument """ if not self._use_unaudited_hdwallet_features: raise AttributeError( "The use of the Mnemonic features of Account is disabled by default until " "its API stabilizes. To use these features, please enable them by running " "`Account.enable_unaudited_hdwallet_features()` and try again." ) seed = seed_from_mnemonic(mnemonic, passphrase) private_key = key_from_seed(seed, account_path) key = self._parsePrivateKey(private_key) return LocalAccount(key, self)
def from_key(self, private_key): r""" Returns a convenient object for working with the given private key. :param private_key: The raw private key :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey` :return: object with methods for signing and encrypting :rtype: LocalAccount .. doctest:: python >>> acct = Account.from_key( ... 0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364) >>> acct.address '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' >>> acct.key HexBytes('0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364') # These methods are also available: sign_message(), sign_transaction(), encrypt() # They correspond to the same-named methods in Account.* # but without the private key argument """ key = self._parsePrivateKey(private_key) return LocalAccount(key, self)
def privateKeyToAccount(self, private_key): ''' Returns a convenient object for working with the given private key. :param private_key: The raw private key :type private_key: hex str, bytes, int or :class:`eth_keys.datatypes.PrivateKey` :return: object with methods for signing and encrypting :rtype: LocalAccount .. code-block:: python >>> acct = Account.privateKeyToAccount( 0xb25c7db31feed9122727bf0939dc769a96564b2de4c4726d035b36ecf1e5b364) >>> acct.address '0x5ce9454909639D2D17A3F753ce7d93fa0b9aB12E' >>> acct.privateKey b"\\xb2\\}\\xb3\\x1f\\xee\\xd9\\x12''\\xbf\\t9\\xdcv\\x9a\\x96VK-\\xe4\\xc4rm\\x03[6\\xec\\xf1\\xe5\\xb3d" # These methods are also available: signHash(), signTransaction(), encrypt() # They correspond to the same-named methods in Account.* # but without the private key argument ''' key = self._parsePrivateKey(private_key) return LocalAccount(key, self)