Exemplo n.º 1
0
 def __call_by_default(self, args):
     # If function is constant in ABI, then call by default, else transact
     function_abi = find_matching_fn_abi(self._function.contract_abi,
                                         fn_name=self._function.method_name,
                                         args=args)
     return function_abi['constant'] if 'constant' in function_abi.keys(
     ) else False
Exemplo n.º 2
0
 def get_transaction_data(abi: Dict, function_name: str, args: Any = None, kwargs: Any = None):
     """Get encoded transaction data"""
     args = args or list()
     fn_abi = find_matching_fn_abi(abi, function_name, args=args, kwargs=kwargs)
     return encode_transaction_data(
         None, function_name, contract_abi=abi, fn_abi=fn_abi, args=args, kwargs=kwargs
     )
Exemplo n.º 3
0
 def get_transaction_data(abi: Dict,
                          function_name: str,
                          args: List = list()):
     """Get encoded transaction data"""
     fn_abi = find_matching_fn_abi(abi, function_name, args)
     args = ContractProxy.sanitize_args(fn_abi, args)
     return encode_transaction_data(abi, None, function_name, args)
Exemplo n.º 4
0
    def extract_secret_from_redeem_transaction(self, tx_address: str) -> str:
        '''
        Extracting secret from redeem transaction.

        Args:
            tx_address (str): address of the redeem transaction

        Returns:
            str,: Secret string

        Raises:
            ValueError: When given transaction was not a redeem type transaction

        Example:
            >>> from clove.network import EthereumTestnet
            >>> network = EthereumTestnet()
            >>> network.extract_secret_from_redeem_transaction('0x9e41847c3cc780e4cb59902cf55657f0ee92642d9dee4145e090cbf206d4748f')  # noqa: E501
            b2eefaadbbefeb9d9467092b612464db7c6724f71b5c1d70c85853845728f0e9
        '''
        tx_dict = self.get_transaction(tx_address)
        method_id = self.extract_method_id(tx_dict['input'])
        if method_id != self.redeem:
            logger.debug('Not a redeem transaction.')
            raise ValueError('Not a redeem transaction.')
        method_name = self.get_method_name(method_id)
        input_types = get_abi_input_types(
            find_matching_fn_abi(self.abi, fn_identifier=method_name))
        input_values = decode_abi(input_types,
                                  Web3.toBytes(hexstr=tx_dict['input'][10:]))
        return input_values[0].hex()
Exemplo n.º 5
0
    def __call_by_default(self, args):
        function_abi = find_matching_fn_abi(
            self._function.contract_abi,
            fn_identifier=self._function.function_identifier,
            args=args)

        return function_abi['constant'] if 'constant' in function_abi.keys(
        ) else False
Exemplo n.º 6
0
    def __init__(self, network, tx_dict):

        self.network = network
        self.tx_dict = tx_dict
        self.method_id = self.network.extract_method_id(tx_dict['input'])
        self.type = self.network.get_method_name(self.method_id)
        self.token = None

        if not self.is_initiate:
            logger.warning('Not a contract transaction.')
            raise ValueError('Not a contract transaction.')

        if self.is_token_contract:
            self.abi = self.network.token_abi
        else:
            self.abi = self.network.abi

        input_types = get_abi_input_types(
            find_matching_fn_abi(self.abi, fn_identifier=self.type))
        input_names = get_abi_input_names(
            find_matching_fn_abi(self.abi, fn_identifier=self.type))
        input_values = decode_abi(
            input_types, Web3.toBytes(hexstr=self.tx_dict['input'][10:]))
        self.inputs = dict(zip(input_names, input_values))

        self.locktime = datetime.utcfromtimestamp(self.inputs['_expiration'])
        self.recipient_address = Web3.toChecksumAddress(
            self.inputs['_participant'])
        self.refund_address = self.tx_dict['from']
        self.secret_hash = self.inputs['_hash'].hex()
        self.contract_address = Web3.toChecksumAddress(self.tx_dict['to'])
        self.confirmations = self.network.latest_block - self.tx_dict[
            'blockNumber']

        if self.is_token_contract:
            self.value_base_units = self.inputs['_value']
            self.token_address = Web3.toChecksumAddress(self.inputs['_token'])
            self.token = self.network.get_token_by_address(self.token_address)
            self.value = self.token.value_from_base_units(
                self.value_base_units)
            self.symbol = self.token.symbol
        else:
            self.value_base_units = self.tx_dict['value']
            self.value = self.network.value_from_base_units(
                self.value_base_units)
            self.symbol = self.network.default_symbol
Exemplo n.º 7
0
 def extract_secret_from_redeem_transaction(self, tx_address: str) -> str:
     tx_dict = self.get_transaction(tx_address)
     method_id = self.extract_method_id(tx_dict['input'])
     if method_id != self.redeem:
         logger.debug('Not a redeem transaction.')
         raise ValueError('Not a redeem transaction.')
     method_name = self.get_method_name(method_id)
     input_types = get_abi_input_types(find_matching_fn_abi(self.abi, fn_identifier=method_name))
     input_values = decode_abi(input_types, Web3.toBytes(hexstr=tx_dict['input'][10:]))
     return input_values[0].hex()
Exemplo n.º 8
0
def call_contract_function(abi, web3, address, normalizers, function_name,
                           transaction, *args, **kwargs):
    """
    Helper function for interacting with a contract function using the
    `eth_call` API.
    """
    call_transaction = prepare_transaction(
        abi,
        address,
        web3,
        fn_name=function_name,
        fn_args=args,
        fn_kwargs=kwargs,
        transaction=transaction,
    )

    return_data = web3.eth.call(call_transaction)

    function_abi = find_matching_fn_abi(abi, function_name, args, kwargs)

    output_types = get_abi_output_types(function_abi)

    try:
        output_data = decode_abi(output_types, return_data)
    except DecodingError as e:
        # Provide a more helpful error message than the one provided by
        # eth-abi-utils
        is_missing_code_error = (return_data in ACCEPTABLE_EMPTY_STRINGS
                                 and web3.eth.getCode(address)
                                 in ACCEPTABLE_EMPTY_STRINGS)
        if is_missing_code_error:
            msg = (
                "Could not transact with/call contract function, is contract "
                "deployed correctly and chain synced?")
        else:
            msg = (
                "Could not decode contract function call {} return data {} for "
                "output_types {}".format(function_name, return_data,
                                         output_types))
        raise BadFunctionCallOutput(msg) from e

    _normalizers = itertools.chain(
        BASE_RETURN_NORMALIZERS,
        normalizers,
    )
    normalized_data = map_abi_data(_normalizers, output_types, output_data)

    if len(normalized_data) == 1:
        return normalized_data[0]
    else:
        return normalized_data
Exemplo n.º 9
0
    def _set_function_info(self):
        self.abi = find_matching_fn_abi(self.contract_abi,
                                        self.function_identifier,
                                        self.args,
                                        self.kwargs)

        if self.function_identifier is FallbackFn:
            self.selector = encode_hex(b'')
        elif is_text(self.function_identifier):
            self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
        else:
            raise TypeError("Unsupported function identifier")

        self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs)
Exemplo n.º 10
0
    def _set_function_info(self):
        self.abi = find_matching_fn_abi(self.contract_abi,
                                        self.function_identifier,
                                        self.args,
                                        self.kwargs)

        if self.function_identifier is FallbackFn:
            self.selector = encode_hex(b'')
        elif is_text(self.function_identifier):
            self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
        else:
            raise TypeError("Unsupported function identifier")

        self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs)
Exemplo n.º 11
0
 def get_transaction_data(abi: Dict, function_name: str, args: List = None):
     """Get encoded transaction data"""
     args = args or list()
     fn_abi = find_matching_fn_abi(
         abi,
         function_name,
         args,
     )
     args = ContractProxy.sanitize_args(fn_abi, args)
     return encode_transaction_data(
         None,
         function_name,
         contract_abi=abi,
         fn_abi=fn_abi,
         args=args,
     )
Exemplo n.º 12
0
 def get_transaction_data(abi: Dict, function_name: str, args: List = None):
     """Get encoded transaction data"""
     args = args or list()
     fn_abi = find_matching_fn_abi(
         abi,
         function_name,
         args,
     )
     args = ContractProxy.sanitize_args(fn_abi, args)
     return encode_transaction_data(
         None,
         function_name,
         contract_abi=abi,
         fn_abi=fn_abi,
         args=args,
     )
Exemplo n.º 13
0
    def call(self, function_name: str, *args, **kargs):
        self._check_function_name_and_kargs(function_name, kargs)
        data = self.get_transaction_data(self.abi, function_name, args)

        res = self.call_function(sender=self.sender,
                                 to=self.contract_address,
                                 value=kargs.pop('value', 0),
                                 data=decode_hex(data),
                                 **kargs)

        if res:
            fn_abi = find_matching_fn_abi(self.abi, function_name, args)
            output_types = get_abi_output_types(fn_abi)
            res = decode_abi(output_types, res)
            if len(res) == 1:
                res = res[0]

        return res
Exemplo n.º 14
0
def encode_function_call(abi: Dict, function: str, args: List = list()):
    fn_abi = find_matching_fn_abi(abi, function, args)
    fn_types = get_abi_input_types(fn_abi)
    return encode_abi(fn_types, args)
Exemplo n.º 15
0
 def _find_matching_fn_abi(cls, fn_identifier=None, args=None, kwargs=None):
     return find_matching_fn_abi(cls.abi,
                                 fn_identifier=fn_identifier,
                                 args=args,
                                 kwargs=kwargs)
Exemplo n.º 16
0
    def __call_by_default(self, args):
        function_abi = find_matching_fn_abi(self._function.contract_abi,
                                            fn_identifier=self._function.function_identifier,
                                            args=args)

        return function_abi['constant'] if 'constant' in function_abi.keys() else False
Exemplo n.º 17
0
def call_contract_function(abi,
                           web3,
                           address,
                           normalizers,
                           function_name,
                           transaction,
                           *args,
                           **kwargs):
    """
    Helper function for interacting with a contract function using the
    `eth_call` API.
    """
    call_transaction = prepare_transaction(
        abi,
        address,
        web3,
        fn_name=function_name,
        fn_args=args,
        fn_kwargs=kwargs,
        transaction=transaction,
    )

    return_data = web3.eth.call(call_transaction)

    function_abi = find_matching_fn_abi(abi, function_name, args, kwargs)

    output_types = get_abi_output_types(function_abi)

    try:
        output_data = decode_abi(output_types, return_data)
    except DecodingError as e:
        # Provide a more helpful error message than the one provided by
        # eth-abi-utils
        is_missing_code_error = (
            return_data in ACCEPTABLE_EMPTY_STRINGS and
            web3.eth.getCode(address) in ACCEPTABLE_EMPTY_STRINGS
        )
        if is_missing_code_error:
            msg = (
                "Could not transact with/call contract function, is contract "
                "deployed correctly and chain synced?"
            )
        else:
            msg = (
                "Could not decode contract function call {} return data {} for "
                "output_types {}".format(
                    function_name,
                    return_data,
                    output_types
                )
            )
        raise BadFunctionCallOutput(msg) from e

    _normalizers = itertools.chain(
        BASE_RETURN_NORMALIZERS,
        normalizers,
    )
    normalized_data = map_abi_data(_normalizers, output_types, output_data)

    if len(normalized_data) == 1:
        return normalized_data[0]
    else:
        return normalized_data
Exemplo n.º 18
0
 def _set_function_info(self):
     self.abi = find_matching_fn_abi(self.contract_abi, self.fn_name, self.args, self.kwargs)
     self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
     self.arguments = merge_args_and_kwargs(self.abi, self.args, self.kwargs)
Exemplo n.º 19
0
 def __call_by_default(self, args):
     # If function is constant in ABI, then call by default, else transact
     function_abi = find_matching_fn_abi(self._function.contract_abi,
                                         fn_name=self._function.function_name,
                                         args=args)
     return function_abi['constant'] if 'constant' in function_abi.keys() else False
Exemplo n.º 20
0
 def _find_matching_fn_abi(cls, fn_name=None, args=None, kwargs=None):
     return find_matching_fn_abi(cls.abi,
                                 fn_name=fn_name,
                                 args=args,
                                 kwargs=kwargs)
Exemplo n.º 21
0
 def _set_function_info(self):
     self.abi = find_matching_fn_abi(self.contract_abi, self.fn_name,
                                     self.args, self.kwargs)
     self.selector = encode_hex(function_abi_to_4byte_selector(self.abi))
     self.arguments = merge_args_and_kwargs(self.abi, self.args,
                                            self.kwargs)
Exemplo n.º 22
0
 def _find_matching_fn_abi(cls, fn_name=None, args=None, kwargs=None):
     return find_matching_fn_abi(cls.abi,
                                 fn_name=fn_name,
                                 args=args,
                                 kwargs=kwargs)
Exemplo n.º 23
0
 def _find_matching_fn_abi(cls, fn_identifier=None, args=None, kwargs=None):
     return find_matching_fn_abi(cls.abi,
                                 fn_identifier=fn_identifier,
                                 args=args,
                                 kwargs=kwargs)