Exemple #1
0
def get_keeper_params(oracles_contract: Contract,
                      multicall_contract: Contract) -> Parameters:
    """Returns keeper params for checking whether to submit the votes."""
    calls = [
        {
            "target": oracles_contract.address,
            "callData": oracles_contract.encodeABI(fn_name="paused"),
        },
        {
            "target": oracles_contract.address,
            "callData":
            oracles_contract.encodeABI(fn_name="currentRewardsNonce"),
        },
        {
            "target":
            oracles_contract.address,
            "callData":
            oracles_contract.encodeABI(fn_name="currentValidatorsNonce"),
        },
        {
            "target":
            oracles_contract.address,
            "callData":
            oracles_contract.encodeABI(fn_name="getRoleMemberCount",
                                       args=[ORACLE_ROLE]),
        },
    ]
    response = multicall_contract.functions.aggregate(calls).call()[1]

    paused = bool(Web3.toInt(primitive=response[0]))
    rewards_nonce = Web3.toInt(primitive=response[1])
    validators_nonce = Web3.toInt(primitive=response[2])
    total_oracles = Web3.toInt(primitive=response[3])
    calls = []
    for i in range(total_oracles):
        calls.append({
            "target":
            oracles_contract.address,
            "callData":
            oracles_contract.encodeABI(fn_name="getRoleMember",
                                       args=[ORACLE_ROLE, i]),
        })
    response = multicall_contract.functions.aggregate(calls).call()[1]
    oracles: List[ChecksumAddress] = []
    for addr in response:
        oracles.append(Web3.toChecksumAddress(Web3.toBytes(Web3.toInt(addr))))

    return Parameters(
        paused=paused,
        rewards_nonce=rewards_nonce,
        validators_nonce=validators_nonce,
        oracles=oracles,
    )
Exemple #2
0
def get_constructor_arguments(contract: Contract,
                              args: Optional[list] = None,
                              kwargs: Optional[dict] = None):
    """Get constructor arguments for Etherscan verify.

    https://etherscanio.freshdesk.com/support/solutions/articles/16000053599-contract-verification-constructor-arguments
    """

    # return contract._encode_constructor_data(args=args, kwargs=kwargs)
    constructor_abi = get_constructor_abi(contract.abi)

    # constructor_abi can be none in case of libraries
    if constructor_abi is None:
        return to_hex(contract.bytecode)

    if args is not None:
        return contract.encodeABI(constructor_abi['name'], args)[2:]  # No 0x
    else:
        constructor_abi = get_constructor_abi(contract.abi)
        kwargs = kwargs or {}
        arguments = merge_args_and_kwargs(constructor_abi, [], kwargs)
        # deploy_data = add_0x_prefix(
        #    contract._encode_abi(constructor_abi, arguments)
        # )

        # TODO: Looks like recent Web3.py ABI change
        deploy_data = encode_abi(contract.web3, constructor_abi, arguments)
        return deploy_data
Exemple #3
0
    def execute(self,
                to_contract: Contract,
                func: str,
                args=None,
                amount_in_eth: Optional[Decimal] = None,
                max_gas=300000):
        """Calls a smart contract from the hosted wallet.

        Creates a transaction that is proxyed through hosted wallet execute method. We need to have ABI as Populus Contract instance.

        :param wallet_address: Wallet address
        :param contract: Contract to called as address bound Populus Contract class
        :param func: Method name to be called
        :param args: Arguments passed to the method
        :param value: Additional value carried in the call in ETH
        :param gas: The max amount of gas the coinbase account is allowed to pay for this transaction.
        :return: txid of the execution as hex string
        """

        assert isinstance(to_contract, Contract)

        if amount_in_eth:
            assert isinstance(amount_in_eth,
                              Decimal)  # Don't let floats slip through
            value = to_wei(amount_in_eth)
        else:
            value = 0

        # Encode function arguments
        # function_abi = to_contract._find_matching_fn_abi(func, args)
        # 4 byte function hash
        # function_selector = function_abi_to_4byte_selector(function_abi)

        # data payload passed to the function
        arg_data = to_contract.encodeABI(func, args=args)
        call_data = arg_data  # Latest web3 behavior, no manual function selector needed

        # test_event_execute() call data should look like
        # function selector + random int as 256-bit
        # 0x5093dc7d000000000000000000000000000000000000000000000000000000002a3f58fe

        # web3 takes bytes argument as actual bytes, not hex
        call_data = binascii.unhexlify(call_data[2:])

        tx_info = {
            # The Ethereum account that pays the gas for this operation
            "from": self.contract.web3.eth.coinbase,
            "gas": max_gas,
        }

        txid = self.contract.transact(tx_info).execute(to_contract.address,
                                                       value, max_gas,
                                                       call_data)
        return txid
Exemple #4
0
    def execute(
        self, to_contract: Contract, func: str, args=None, amount_in_eth: Optional[Decimal] = None, max_gas=100000
    ):
        """Calls a smart contract from the hosted wallet.

        Creates a transaction that is proxyed through hosted wallet execute method. We need to have ABI as Populus Contract instance.

        :param wallet_address: Wallet address
        :param contract: Contract to called as address bound Populus Contract class
        :param func: Method name to be called
        :param args: Arguments passed to the method
        :param value: Additional value carried in the call in ETH
        :param gas: The max amount of gas the coinbase account is allowed to pay for this transaction.
        :return: txid of the execution as hex string
        """

        assert isinstance(to_contract, Contract)

        if amount_in_eth:
            assert isinstance(amount_in_eth, Decimal)  # Don't let floats slip through
            value = to_wei(amount_in_eth)
        else:
            value = 0

        # Encode function arguments
        function_abi = to_contract._find_matching_fn_abi(func, args)
        # 4 byte function hash
        function_selector = function_abi_to_4byte_selector(function_abi)

        # data payload passed to the function
        arg_data = to_contract.encodeABI(func, args=args)

        call_data = function_selector + arg_data[2:]

        # test_event_execute() call data should look like
        # function selector + random int as 256-bit
        # 0x5093dc7d000000000000000000000000000000000000000000000000000000002a3f58fe

        # web3 takes bytes argument as actual bytes, not hex
        call_data = binascii.unhexlify(call_data[2:])

        tx_info = {
            # The Ethereum account that pays the gas for this operation
            "from": self.contract.web3.eth.coinbase,
            "gas": max_gas,
        }

        txid = self.contract.transact(tx_info).execute(to_contract.address, value, max_gas, call_data)
        return txid