Ejemplo n.º 1
0
 def _invoke_contract_method(
     self,
     contract_factory,
     name,
     *args,
     tx_extra_params: Optional[ContractTxExtraParams] = None,
     signer: Optional[BaseAccount] = None,
     dry_run=False,
     estimate_gas=False,
     dry_run_block_id=None,
     node_index=None,
     expectation=TransactionExpectation()):
     tx_params = TxParams(
         **to_dict(tx_extra_params)) if tx_extra_params else None
     dry_run_block_id = 'latest' if dry_run_block_id is None else dry_run_block_id
     node = self._cluster.node(node_index)
     contract = contract_factory(node.eth)
     method = contract.constructor if not name else getattr(
         contract.functions, name)
     bound_method = method(*args)
     if dry_run:
         signer = signer or self.default_tx_signer
         if signer is not None:
             with_from = {'from': signer.address}
             tx_params = TxParams(**with_from, **
                                  tx_params) if tx_params else TxParams(
                                      **with_from)
         if estimate_gas:
             return bound_method.estimateGas(tx_params, dry_run_block_id)
         return bound_method.call(tx_params, dry_run_block_id)
     return self._send_tx(bound_method.buildTransaction(tx_params),
                          node_index=node_index,
                          signer=signer,
                          expectation=expectation)
Ejemplo n.º 2
0
 def _send_tx(self,
              tx: TxParams,
              node_index=None,
              signer: Optional[BaseAccount] = None,
              expectation=TransactionExpectation()):
     signer = signer or self.default_tx_signer
     send_signed = signer is not None
     node = self._cluster.node(node_index)
     orig_params = tx
     tx = dict(**tx)
     if 'nonce' not in tx:
         if send_signed:
             tx['nonce'] = self._nonce_strategy(signer.address)
         else:
             if 'from' in tx:
                 tx['nonce'] = self._nonce_strategy(getattr(tx, 'from'))
             else:
                 tx['from'] = node.account.address
                 tx['nonce'] = self._nonce_strategy(node.account.address)
     if send_signed:
         if 'gasPrice' not in tx:
             tx['gasPrice'] = node.eth.gas_price
         if 'gas' not in tx:
             tx['gas'] = node.eth.estimate_gas(TxParams(**tx))
         tx_hash = node.eth.send_raw_transaction(
             signer.sign_transaction(TxParams(**tx)).rawTransaction)
     else:
         tx_hash = node.eth.send_transaction(TxParams(**tx))
     assert tx_hash not in self._pending_trxs and tx_hash not in self._executed_trxs
     ret = TransactionResultFuture(tx_hash)
     self._pending_trxs[tx_hash] = self._PendingTransaction(
         ret, expectation, orig_params)
     return ret
Ejemplo n.º 3
0
    def sign_transaction(self, raw_tx: TxParams) -> HexStr:
        raw_tx.pop('from', None)
        raw_tx['chainId'] = self._chain_id

        tx = serializable_unsigned_transaction_from_dict(raw_tx)
        tx_hash = tx.hash()

        self._logger.debug(f'Signing transaction hash {tx_hash.hex()}')
        sig = self._generate_signature(tx_hash)
        signed_tx = encode_transaction(tx, vrs=sig)

        return HexStr(signed_tx.hex())
Ejemplo n.º 4
0
    def transact(self, path: str, request: Any) -> None:

        assert self.key is not None

        response = requests.post(
            base_url + path,
            headers={"Content-Type": "application/json"},
            data=json.dumps(request),
        )

        response.raise_for_status()

        for tx in response.json()["transactions"]:

            address = self.key.address._checksummed
            nonce = w3.eth.getTransactionCount(address, "pending")

            params = fill_transaction_defaults(
                w3,
                TxParams({
                    "data": HexStr(tx["data"]),
                    "from": address,
                    "nonce": nonce,
                    "to": Web3.toChecksumAddress(tx["to"]),
                }),
            )

            signed = Account.sign_transaction(params, bytes(self.key))

            tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)
            tx_receipt = w3.eth.waitForTransactionReceipt(tx_hash)

            assert tx_receipt["status"] == 1
Ejemplo n.º 5
0
 async def test_async_send_transaction(
         self, async_w3: "Web3",
         unlockable_account_dual_type: ChecksumAddress,
         unlockable_account_pw: str) -> None:
     tx_params = TxParams()
     tx_params["to"] = unlockable_account_dual_type
     tx_params["from"] = unlockable_account_dual_type
     tx_params["value"] = Wei(123)
     response = await async_w3.geth.personal.send_transaction(  # type: ignore
         tx_params, unlockable_account_pw)
     assert response is not None
Ejemplo n.º 6
0
def extract_valid_transaction_params(transaction_params: TxParams) -> TxParams:
    extracted_params = {key: transaction_params[key]
                        for key in VALID_TRANSACTION_PARAMS if key in transaction_params}

    if extracted_params.get('data') is not None:
        if transaction_params.get('input') is not None:
            if extracted_params['data'] != transaction_params['input']:
                msg = 'failure to handle this transaction due to both "input: {}" and'
                msg += ' "data: {}" are populated. You need to resolve this conflict.'
                err_vals = (transaction_params['input'], extracted_params['data'])
                raise AttributeError(msg.format(*err_vals))
            else:
                return extracted_params
        else:
            return extracted_params
    elif extracted_params.get('data') is None:
        if transaction_params.get('input') is not None:
            return assoc(extracted_params, 'data', transaction_params['input'])
        else:
            return extracted_params
    else:
        raise Exception("Unreachable path: transaction's 'data' is either set or not set")
Ejemplo n.º 7
0
def deploy_contract(
    web3: Web3,
    contracts_manager: ContractManager,
    contract_name: str,
    deployer_key: CCPrivateKey,
    args: List[Any],
) -> Contract:
    deployer_address = private_key_to_address(deployer_key.to_hex())
    json_contract = contracts_manager.get_contract(contract_name)
    contract = web3.eth.contract(abi=json_contract["abi"], bytecode=json_contract["bin"])
    tx_hash = contract.constructor(*args).transact(TxParams({"from": deployer_address}))
    contract_address = web3.eth.get_transaction_receipt(tx_hash)["contractAddress"]

    return contract(contract_address)
Ejemplo n.º 8
0
 def coin_transfer(self,
                   to: Union[Address, ChecksumAddress, str],
                   value: int,
                   tx_extra_params: Optional[CoinTxExtraParams] = None,
                   node_index=None,
                   signer=None,
                   expectation=TransactionExpectation()):
     assert to
     return self._send_tx(TxParams(
         to=to,
         value=value,
         **(to_dict(tx_extra_params) if tx_extra_params else dict())),
                          node_index=node_index,
                          signer=signer,
                          expectation=expectation)
Ejemplo n.º 9
0
def get_transaction_params(network: str, web3_client: Web3) -> TxParams:
    network_config = NETWORKS[network]
    max_fee_per_gas = network_config["KEEPER_MAX_FEE_PER_GAS"]
    account_nonce = web3_client.eth.getTransactionCount(
        web3_client.eth.default_account)
    latest_block = web3_client.eth.get_block("latest")
    max_priority_fee = min(web3_client.eth.max_priority_fee, max_fee_per_gas)

    base_fee = latest_block["baseFeePerGas"]
    priority_fee = int(str(max_priority_fee), 16)
    max_fee_per_gas = priority_fee + 2 * base_fee

    return TxParams(
        nonce=account_nonce,
        maxPriorityFeePerGas=max_priority_fee,
        maxFeePerGas=hex(min(max_fee_per_gas, max_fee_per_gas)),
    )
Ejemplo n.º 10
0
    def __init__(
        self,
        web3: Web3,
        private_key: PrivateKey,
        gas_limit: int,
        gas_price: int,
        wait: int = 10,
        contracts_version: Optional[str] = None,
    ):
        # pylint: disable=E1101
        super(ContractDeployer,
              self).__init__(web3=web3, contracts_version=contracts_version)
        self.wait = wait
        self.owner = private_key_to_address(private_key)
        self.transaction = TxParams({
            "from":
            self.owner,
            "gas":
            Wei(gas_limit),
            "gasPrice":
            Wei(gas_price * int(units["gwei"])),
        })

        self.web3.middleware_onion.add(
            construct_sign_and_send_raw_middleware(private_key))

        # Check that the precompiled data matches the source code
        # Only for current version, because this is the only one with source code
        if self.contracts_version in [None, CONTRACTS_VERSION]:
            contract_manager_source = ContractSourceManager(
                contracts_source_path(contracts_version=contracts_version))
            contract_manager_source.verify_precompiled_checksums(
                self.precompiled_path)
        else:
            LOG.info(
                "Skipped checks against the source code because it is not available."
            )