Exemplo n.º 1
0
def test_send_transaction_with_contract(test_app):
    serpent_code = '''
def main(a,b):
    return(a ^ b)
'''
    tx_to = b''
    evm_code = serpent.compile(serpent_code)
    chainservice = test_app.services.chain
    chain = test_app.services.chain.chain
    state = State(chainservice.head_candidate.state_root, chain.env)
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert state.get_balance(sender) > 0
    tx = {
        'from': address_encoder(sender),
        'to': address_encoder(tx_to),
        'data': encode_hex(evm_code)
    }
    data_decoder(test_app.client.call('eth_sendTransaction', tx))
    assert len(chainservice.head_candidate.transactions) == 1
    creates = chainservice.head_candidate.transactions[0].creates

    candidate_state_dict = State(chainservice.head_candidate.state_root,
                                 chain.env).to_dict()
    code = candidate_state_dict[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'

    test_app.mine_next_block()

    assert len(chain.head.transactions) == 1
    creates = chain.head.transactions[0].creates
    state_dict = State(chain.head.state_root, chain.env).to_dict()
    code = state_dict[encode_hex(creates)]['code']
    assert len(code) > 2
    assert code != '0x'
Exemplo n.º 2
0
def test_send_raw_transaction_with_contract(test_app):
    serpent_code = '''
def main(a,b):
    return(a ^ b)
'''
    tx_to = b''
    evm_code = serpent.compile(serpent_code)
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance(tx_to) == 0
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert chain.head_candidate.get_balance(sender) > 0
    nonce = chain.head_candidate.get_nonce(sender)
    tx = ethereum.transactions.Transaction(nonce, default_gasprice, default_startgas, tx_to, 0, evm_code, 0, 0, 0)
    test_app.services.accounts.sign_tx(sender, tx)
    raw_transaction = data_encoder(rlp.codec.encode(tx, ethereum.transactions.Transaction))
    data_decoder(test_app.client.call('eth_sendRawTransaction', raw_transaction))
    creates = chain.head_candidate.get_transaction(0).creates

    code = chain.head_candidate.account_to_dict(creates)['code']
    assert len(code) > 2
    assert code != '0x'

    test_app.mine_next_block()

    creates = chain.head.get_transaction(0).creates
    code = chain.head.account_to_dict(creates)['code']
    assert len(code) > 2
    assert code != '0x'
Exemplo n.º 3
0
def test_send_transaction_with_contract(test_app):
    serpent_code = '''
def main(a,b):
    return(a ^ b)
'''
    tx_to = b''
    evm_code = serpent.compile(serpent_code)
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance(tx_to) == 0
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert chain.head_candidate.get_balance(sender) > 0
    tx = {
        'from': address_encoder(sender),
        'to': address_encoder(tx_to),
        'data': evm_code.encode('hex')
    }
    data_decoder(test_app.client.call('eth_sendTransaction', tx))
    creates = chain.head_candidate.get_transaction(0).creates

    code = chain.head_candidate.account_to_dict(creates)['code']
    assert len(code) > 2
    assert code != '0x'

    test_app.mine_next_block()

    creates = chain.head.get_transaction(0).creates
    code = chain.head.account_to_dict(creates)['code']
    assert len(code) > 2
    assert code != '0x'
Exemplo n.º 4
0
    def eth_call(self, sender='', to='', value=0, data='',
                 startgas=default_startgas, gasprice=default_gasprice,
                 block_number='latest'):
        """ Executes a new message call immediately without creating a
        transaction on the block chain.

        Args:
            from: The address the transaction is send from.
            to: The address the transaction is directed to.
            gas (int): Gas provided for the transaction execution. eth_call
                consumes zero gas, but this parameter may be needed by some
                executions.
            gasPrice (int): gasPrice used for each paid gas.
            value (int): Integer of the value send with this transaction.
            data (bin): Hash of the method signature and encoded parameters.
                For details see Ethereum Contract ABI.
            block_number: Determines the state of ethereum used in the
                call.
        """

        json_data = self._format_call(
            sender,
            to,
            value,
            data,
            startgas,
            gasprice,
        )
        res = self.call('eth_call', json_data, block_number)

        return data_decoder(res)
Exemplo n.º 5
0
    def eth_sendTransaction(
        self,
        nonce=None,
        sender="",
        to="",
        value=0,
        data="",
        gasprice=default_gasprice,
        startgas=default_startgas,
        v=None,
        r=None,
        s=None,
    ):
        encoders = dict(
            nonce=quantity_encoder,
            sender=address_encoder,
            to=data_encoder,
            value=quantity_encoder,
            gasprice=quantity_encoder,
            startgas=quantity_encoder,
            data=data_encoder,
            v=quantity_encoder,
            r=quantity_encoder,
            s=quantity_encoder,
        )
        data = {k: encoders[k](v) for k, v in locals().items() if k not in ("self", "encoders") and v is not None}
        data["from"] = data.pop("sender")
        assert data.get("from") or (v and r and s)

        res = self.call("eth_sendTransaction", data)
        return data_decoder(res)
Exemplo n.º 6
0
    def changes(self):
        filter_changes = self.client.call(
            'eth_getFilterChanges',
            self.filter_id_raw,
        )

        # geth could return None
        if filter_changes is None:
            return []

        result = list()
        for log_event in filter_changes:
            address = address_decoder(log_event['address'])
            data = data_decoder(log_event['data'])
            topics = [
                decode_topic(topic)
                for topic in log_event['topics']
            ]

            result.append({
                'topics': topics,
                'data': data,
                'address': address,
            })

        return result
Exemplo n.º 7
0
    def changes(self):
        filter_changes = self.client.call(
            'eth_getFilterChanges',
            self.filter_id_raw,
        )

        # geth could return None
        if filter_changes is None:
            return []

        result = list()
        for log_event in filter_changes:
            address = address_decoder(log_event['address'])
            data = data_decoder(log_event['data'])
            topics = [
                decode_topic(topic)
                for topic in log_event['topics']
            ]

            result.append({
                'topics': topics,
                'data': data,
                'address': address,
            })

        return result
Exemplo n.º 8
0
 def eth_sendTransaction(self,
                         nonce=None,
                         sender='',
                         to='',
                         value=0,
                         data='',
                         gasPrice=default_gasprice,
                         gas=default_startgas,
                         v=None,
                         r=None,
                         s=None,
                         secret=None):
     to = address20(to)
     encoders = dict(nonce=quantity_encoder,
                     sender=address_encoder,
                     to=data_encoder,
                     value=quantity_encoder,
                     gasPrice=quantity_encoder,
                     gas=quantity_encoder,
                     data=data_encoder,
                     v=quantity_encoder,
                     r=quantity_encoder,
                     s=quantity_encoder,
                     secret=secret_encoder)
     data = {
         k: encoders[k](v)
         for k, v in locals().items()
         if k not in ('self', 'encoders') and v is not None
     }
     data['from'] = data.pop('sender')
     assert data.get('from') or (v and r and s)
     res = self.call('eth_sendTransaction', data)
     return data_decoder(res)
Exemplo n.º 9
0
    def _query_filter(self, function):
        filter_changes = self.client.call(function, self.filter_id_raw)

        # geth could return None
        if filter_changes is None:
            return []

        result = list()
        for log_event in filter_changes:
            address = address_decoder(log_event['address'])
            data = data_decoder(log_event['data'])
            topics = [decode_topic(topic) for topic in log_event['topics']]
            block_number = log_event.get('blockNumber')
            if not block_number:
                block_number = 0
            else:
                block_number = int(block_number, 0)

            result.append({
                'topics': topics,
                'data': data,
                'address': address,
                'block_number': block_number,
            })

        return result
Exemplo n.º 10
0
def all_contract_events(rpc,
                        contract_address,
                        abi,
                        start_block=None,
                        end_block=None):
    """Find and decode all events for a deployed contract given its `contract_address` and `abi`.

    Args:
        rpc (pyethapp.rpc_client.JSONRPCClient): client instance.
        contract_address (string): hex encoded contract address.
        abi (list(dict)): the contract's ABI.
        start_block (int): read event-logs starting from this block number.
        end_block (int): read event-logs up to this block number.
    Returns:
        events (list)
    """

    translator = ContractTranslator(abi)

    events_raw = all_contract_events_raw(
        rpc,
        contract_address,
        start_block=start_block,
        end_block=end_block,
    )

    events = list()
    for event_encoded in events_raw:
        topics_ids = [decode_topic(topic) for topic in event_encoded['topics']]
        event_data = data_decoder(event_encoded['data'])

        event = translator.decode_event(topics_ids, event_data)
        events.append(event)
    return events
Exemplo n.º 11
0
def all_contract_events(rpc, contract_address, abi, start_block=None, end_block=None):
    """Find and decode all events for a deployed contract given its `contract_address` and `abi`.

    Args:
        rpc (pyethapp.rpc_client.JSONRPCClient): client instance.
        contract_address (string): hex encoded contract address.
        abi (list(dict)): the contract's ABI.
        start_block (int): read event-logs starting from this block number.
        end_block (int): read event-logs up to this block number.
    Returns:
        events (list)
    """

    translator = ContractTranslator(abi)

    events_raw = all_contract_events_raw(
        rpc,
        contract_address,
        start_block=start_block,
        end_block=end_block,
    )

    events = list()
    for event_encoded in events_raw:
        topics_ids = [
            decode_topic(topic)
            for topic in event_encoded['topics']
        ]
        event_data = data_decoder(event_encoded['data'])

        event = translator.decode_event(topics_ids, event_data)
        events.append(event)
    return events
Exemplo n.º 12
0
    def eth_sendTransaction(self, nonce=None, sender='', to='', value=0, data='',
                            gasPrice=default_gasprice, gas=default_startgas,
                            v=None, r=None, s=None):
        """ Creates new message call transaction or a contract creation, if the
        data field contains code.

        Note:
            The support for local signing through the variables v,r,s is not
            part of the standard spec, a extended server is required.

        Args:
            from (address): The 20 bytes address the transaction is send from.
            to (address): DATA, 20 Bytes - (optional when creating new
                contract) The address the transaction is directed to.
            gas (int): Gas provided for the transaction execution. It will
                return unused gas.
            gasPrice (int): gasPrice used for each paid gas.
            value (int): Value send with this transaction.
            data (bin): The compiled code of a contract OR the hash of the
                invoked method signature and encoded parameters.
            nonce (int): This allows to overwrite your own pending transactions
                that use the same nonce.
        """

        if to == '' and data.isalnum():
            warnings.warn(
                'Verify that the data parameter is _not_ hex encoded, if this is the case '
                'the data will be double encoded and result in unexpected '
                'behavior.'
            )

        if to == '0' * 40:
            warnings.warn('For contract creating the empty string must be used.')

        json_data = {
            'to': data_encoder(normalize_address(to, allow_blank=True)),
            'value': quantity_encoder(value),
            'gasPrice': quantity_encoder(gasPrice),
            'gas': quantity_encoder(gas),
            'data': data_encoder(data),
        }

        if not sender and not (v and r and s):
            raise ValueError('Either sender or v, r, s needs to be informed.')

        if sender is not None:
            json_data['from'] = address_encoder(sender)

        if v and r and s:
            json_data['v'] = quantity_encoder(v)
            json_data['r'] = quantity_encoder(r)
            json_data['s'] = quantity_encoder(s)

        if nonce is not None:
            json_data['nonce'] = quantity_encoder(nonce)

        res = self.call('eth_sendTransaction', json_data)

        return data_decoder(res)
Exemplo n.º 13
0
def test_send_transaction(test_app):
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance("\xff" * 20) == 0
    sender = test_app.services.accounts.unlocked_accounts()[0].address
    assert chain.head_candidate.get_balance(sender) > 0
    tx = {"from": address_encoder(sender), "to": address_encoder("\xff" * 20), "value": quantity_encoder(1)}
    tx_hash = data_decoder(test_app.rpc_request("eth_sendTransaction", tx))
    assert tx_hash == chain.head_candidate.get_transaction(0).hash
    assert chain.head_candidate.get_balance("\xff" * 20) == 1
    test_app.mine_next_block()
    assert tx_hash == chain.head.get_transaction(0).hash
    assert chain.head.get_balance("\xff" * 20) == 1

    # send transactions from account which can't pay gas
    tx["from"] = address_encoder(test_app.services.accounts.unlocked_accounts()[1].address)
    tx_hash = data_decoder(test_app.rpc_request("eth_sendTransaction", tx))
    assert chain.head_candidate.get_transactions() == []
Exemplo n.º 14
0
def test_send_transaction(test_app):
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance('\xff' * 20) == 0
    tx = {
        'from': address_encoder(test_app.services.accounts.unlocked_accounts()[0].address),
        'to': address_encoder('\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert tx_hash == chain.head_candidate.get_transaction(0).hash
    assert chain.head_candidate.get_balance('\xff' * 20) == 1
    test_app.mine_next_block()
    assert tx_hash == chain.head.get_transaction(0).hash
    assert chain.head.get_balance('\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(test_app.services.accounts.unlocked_accounts()[1].address)
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert chain.head_candidate.get_transactions() == []
Exemplo n.º 15
0
def test_send_transaction(test_app):
    chain = test_app.services.chain.chain
    assert chain.head_candidate.get_balance('\xff' * 20) == 0
    tx = {
        'from': address_encoder(test_app.services.accounts.unlocked_accounts()[0].address),
        'to': address_encoder('\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert tx_hash == chain.head_candidate.get_transaction(0).hash
    assert chain.head_candidate.get_balance('\xff' * 20) == 1
    test_app.mine_next_block()
    assert tx_hash == chain.head.get_transaction(0).hash
    assert chain.head.get_balance('\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(test_app.services.accounts.unlocked_accounts()[1].address)
    tx_hash = data_decoder(test_app.rpc_request('eth_sendTransaction', tx))
    assert chain.head_candidate.get_transactions() == []
Exemplo n.º 16
0
 def filter_changes(self, fid):
     changes = self.call('eth_getFilterChanges', quantity_encoder(fid))
     if not changes:
         return None
     elif isinstance(changes, bytes):
         return data_decoder(changes)
     else:
         decoders = dict(blockHash=data_decoder, transactionHash=data_decoder, data=data_decoder,
                         address=address_decoder, topics=lambda x: [topic_decoder(t) for t in x],
                         blockNumber=quantity_decoder, logIndex=quantity_decoder, transactionIndex=quantity_decoder)
         return [{k: decoders[k](v) for k, v in c.items() if v is not None} for c  in changes]
Exemplo n.º 17
0
 def eth_call(self, sender='', to='', value=0, data='',
              startgas=default_startgas, gasprice=default_gasprice):
     "call on pending block"
     encoders = dict(sender=address_encoder, to=data_encoder,
                     value=quantity_encoder, gasprice=quantity_encoder,
                     startgas=quantity_encoder, data=data_encoder)
     data = {k: encoders[k](v) for k, v in locals().items()
             if k not in ('self', 'encoders') and v is not None}
     for k, v in dict(gasprice='gasPrice', startgas='gas', sender='from').items():
         data[v] = data.pop(k)
     res = self.call('eth_call', data)
     return data_decoder(res)
Exemplo n.º 18
0
 def eth_sendTransaction(self, nonce=None, sender='', to='', value=0, data='',
                         gasPrice=default_gasprice, gas=default_startgas,
                         v=None, r=None, s=None):
     encoders = dict(nonce=quantity_encoder, sender=address_encoder, to=data_encoder,
                     value=quantity_encoder, gasPrice=quantity_encoder,
                     gas=quantity_encoder, data=data_encoder,
                     v=quantity_encoder, r=quantity_encoder, s=quantity_encoder)
     data = {k: encoders[k](v) for k, v in locals().items()
             if k not in ('self', 'encoders') and v is not None}
     data['from'] = data.pop('sender')
     assert data.get('from') or (v and r and s)
     res = self.call('eth_sendTransaction', data)
     return data_decoder(res)
Exemplo n.º 19
0
    def send_transaction(self, sender, to, value=0, data='', startgas=0,
                         gasprice=10 * denoms.szabo, nonce=None):
        """ Helper to send signed messages.

        This method will use the `privkey` provided in the constructor to
        locally sign the transaction. This requires an extended server
        implementation that accepts the variables v, r, and s.
        """

        if not self.privkey and not sender:
            raise ValueError('Either privkey or sender needs to be supplied.')

        if self.privkey and not sender:
            sender = privtoaddr(self.privkey)

            if nonce is None:
                nonce = self.nonce(sender)
        elif self.privkey:
            if sender != privtoaddr(self.privkey):
                raise ValueError('sender for a different privkey.')

            if nonce is None:
                nonce = self.nonce(sender)
        else:
            if nonce is None:
                nonce = 0

        if not startgas:
            startgas = self.gaslimit() - 1

        tx = Transaction(nonce, gasprice, startgas, to=to, value=value, data=data)

        if self.privkey:
            # add the fields v, r and s
            tx.sign(self.privkey)

        tx_dict = tx.to_dict()
        # Transaction.to_dict() encodes 'data', so we need to decode it here.
        tx_dict['data'] = data_decoder(tx_dict['data'])

        # rename the fields to match the eth_sendTransaction signature
        tx_dict.pop('hash')
        tx_dict['sender'] = sender
        tx_dict['gasPrice'] = tx_dict.pop('gasprice')
        tx_dict['gas'] = tx_dict.pop('startgas')

        res = self.eth_sendTransaction(**tx_dict)
        assert len(res) in (20, 32)
        return encode_hex(res)
Exemplo n.º 20
0
def tester_state(deploy_key, private_keys, tester_blockgas_limit):
    tester_state = tester.state()

    # special addresses 1 to 5
    alloc = {
        int_to_addr(i): {'wei': 1}
        for i in range(1, 5)
    }

    for privkey in [deploy_key] + private_keys:
        address = privatekey_to_address(privkey)
        alloc[address] = {
            'balance': DEFAULT_BALANCE,
        }

    for account in tester.accounts:
        alloc[account] = {
            'balance': DEFAULT_BALANCE,
        }

    db = ethereum.db.EphemDB()
    env = ethereum.config.Env(
        db,
        ethereum.config.default_config,
    )
    genesis_overwrite = {
        'nonce': zpad(data_decoder('0x00006d6f7264656e'), 8),
        'difficulty': quantity_decoder('0x20000'),
        'mixhash': zpad(b'\x00', 32),
        'coinbase': address_decoder('0x0000000000000000000000000000000000000000'),
        'timestamp': 0,
        'extra_data': b'',
        'gas_limit': tester_blockgas_limit,
        'start_alloc': alloc,
    }
    genesis_block = ethereum.blocks.genesis(
        env,
        **genesis_overwrite
    )

    # enable DELEGATECALL opcode
    genesis_block.number = genesis_block.config['HOMESTEAD_FORK_BLKNUM'] + 1

    tester_state.db = db
    tester_state.env = env
    tester_state.block = genesis_block
    tester_state.blocks = [genesis_block]

    return tester_state
Exemplo n.º 21
0
def tester_state(deploy_key, private_keys, tester_blockgas_limit):
    tester_state = tester.state()

    # special addresses 1 to 5
    alloc = {
        int_to_addr(i): {'wei': 1}
        for i in range(1, 5)
    }

    for privkey in [deploy_key] + private_keys:
        address = privatekey_to_address(privkey)
        alloc[address] = {
            'balance': DEFAULT_BALANCE,
        }

    for account in tester.accounts:
        alloc[account] = {
            'balance': DEFAULT_BALANCE,
        }

    db = ethereum.db.EphemDB()
    env = ethereum.config.Env(
        db,
        ethereum.config.default_config,
    )
    genesis_overwrite = {
        'nonce': zpad(data_decoder('0x00006d6f7264656e'), 8),
        'difficulty': quantity_decoder('0x20000'),
        'mixhash': zpad(b'\x00', 32),
        'coinbase': address_decoder('0x0000000000000000000000000000000000000000'),
        'timestamp': 0,
        'extra_data': b'',
        'gas_limit': tester_blockgas_limit,
        'start_alloc': alloc,
    }
    genesis_block = ethereum.blocks.genesis(
        env,
        **genesis_overwrite
    )

    # enable DELEGATECALL opcode
    genesis_block.number = genesis_block.config['HOMESTEAD_FORK_BLKNUM'] + 1

    tester_state.db = db
    tester_state.env = env
    tester_state.block = genesis_block
    tester_state.blocks = [genesis_block]

    return tester_state
Exemplo n.º 22
0
def test_send_transaction(test_app):
    chainservice = test_app.services.chain
    chain = chainservice.chain
    hc = chainservice.head_candidate
    state = State(hc.state_root, chain.env)
    assert state.get_balance(b'\xff' * 20) == 0
    sender = test_app.services.accounts.unlocked_accounts[0].address
    assert state.get_balance(sender) > 0
    tx = {
        'from': address_encoder(sender),
        'to': address_encoder(b'\xff' * 20),
        'value': quantity_encoder(1)
    }
    tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx))
    test_app.mine_next_block()
    assert len(chain.head.transactions) == 1
    assert tx_hash == chain.head.transactions[0].hash
    assert chain.state.get_balance(b'\xff' * 20) == 1

    # send transactions from account which can't pay gas
    tx['from'] = address_encoder(
        test_app.services.accounts.unlocked_accounts[1].address)
    tx_hash = data_decoder(test_app.client.call('eth_sendTransaction', tx))
    assert chainservice.head_candidate.transactions == []
Exemplo n.º 23
0
    def eth_call(self,
                 sender='',
                 to='',
                 value=0,
                 data='',
                 startgas=default_startgas,
                 gasprice=default_gasprice,
                 block_number='latest'):
        """ Executes a new message call immediately without creating a
        transaction on the block chain.

        Args:
            from: The address the transaction is send from.
            to: The address the transaction is directed to.
            gas (int): Gas provided for the transaction execution. eth_call
                consumes zero gas, but this parameter may be needed by some
                executions.
            gasPrice (int): gasPrice used for each paid gas.
            value (int): Integer of the value send with this transaction.
            data (bin): Hash of the method signature and encoded parameters.
                For details see Ethereum Contract ABI.
            block_number: Determines the state of ethereum used in the
                call.
        """

        json_data = dict()

        if sender is not None:
            json_data['from'] = address_encoder(sender)

        if to is not None:
            json_data['to'] = data_encoder(to)

        if value is not None:
            json_data['value'] = quantity_encoder(value)

        if gasprice is not None:
            json_data['gasPrice'] = quantity_encoder(gasprice)

        if startgas is not None:
            json_data['gas'] = quantity_encoder(startgas)

        if data is not None:
            json_data['data'] = data_encoder(data)

        res = self.call('eth_call', json_data, block_number)

        return data_decoder(res)
Exemplo n.º 24
0
 def filter_changes(self, fid):
     changes = self.call('eth_getFilterChanges', quantity_encoder(fid))
     if not changes:
         return None
     elif isinstance(changes, bytes):
         return data_decoder(changes)
     else:
         decoders = dict(blockHash=data_decoder,
                         transactionHash=data_decoder,
                         data=data_decoder,
                         address=address_decoder,
                         topics=lambda x: [topic_decoder(t) for t in x],
                         blockNumber=quantity_decoder,
                         logIndex=quantity_decoder,
                         transactionIndex=quantity_decoder)
         return [{k: decoders[k](v) for k, v in list(c.items()) if v is not None} for c in changes]
Exemplo n.º 25
0
def get_filter_events(jsonrpc_client,
                      contract_address,
                      topics,
                      from_block=None,
                      to_block=None):
    """ Custom new filter implementation to handle bad encoding from geth rpc. """
    if isinstance(from_block, int):
        from_block = hex(from_block)

    if isinstance(to_block, int):
        to_block = hex(to_block)

    json_data = {
        'fromBlock': from_block or hex(0),
        'toBlock': to_block or 'latest',
        'address': address_encoder(normalize_address(contract_address)),
    }

    if topics is not None:
        json_data['topics'] = [topic_encoder(topic) for topic in topics]

    filter_changes = jsonrpc_client.call('eth_getLogs', json_data)

    # geth could return None
    if filter_changes is None:
        return []

    result = []
    for log_event in filter_changes:
        address = address_decoder(log_event['address'])
        data = data_decoder(log_event['data'])
        topics = [decode_topic(topic) for topic in log_event['topics']]
        block_number = log_event.get('blockNumber')
        if not block_number:
            block_number = 0
        else:
            block_number = int(block_number, 0)

        result.append({
            'topics': topics,
            'data': data,
            'address': address,
            'block_number': block_number,
        })

    return result
Exemplo n.º 26
0
    def _query_filter(self, function):
        filter_changes = self.client.call(function, self.filter_id_raw)

        # geth could return None
        if filter_changes is None:
            return []

        result = list()
        for log_event in filter_changes:
            address = address_decoder(log_event['address'])
            data = data_decoder(log_event['data'])
            topics = [decode_topic(topic) for topic in log_event['topics']]

            result.append({
                'topics': topics,
                'data': data,
                'address': address,
            })

        return result
Exemplo n.º 27
0
 def eth_call(self,
              sender='',
              to='',
              value=0,
              data='',
              startgas=default_startgas,
              gasprice=default_gasprice):
     "call on pending block"
     encoders = dict(sender=address_encoder,
                     to=data_encoder,
                     value=quantity_encoder,
                     gasprice=quantity_encoder,
                     startgas=quantity_encoder,
                     data=data_encoder)
     data = {
         k: encoders[k](v)
         for k, v in locals().items()
         if k not in ('self', 'encoders') and v is not None
     }
     for k, v in dict(gasprice='gasPrice', startgas='gas',
                      sender='from').items():
         data[v] = data.pop(k)
     res = self.call('eth_call', data)
     return data_decoder(res)
Exemplo n.º 28
0
 def _deserialize(self, value, attr, obj):
     return data_decoder(value)
Exemplo n.º 29
0
def topic_decoder(t):
    return big_endian_to_int(data_decoder(t))
Exemplo n.º 30
0
def topic_decoder(t):
    return big_endian_to_int(data_decoder(t))