def _query_filter(self, function: str) -> List[Dict]: 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 = [ topic_decoder(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
def handle_tokennetwork_new(raiden, event: Event): """ Handles a `TokenNetworkCreated` event. """ data = event.event_data token_network_address = data['token_network_address'] token_network_proxy = raiden.chain.token_network(token_network_address) raiden.blockchain_events.add_token_network_listener( token_network_proxy=token_network_proxy, contract_manager=raiden.contract_manager, from_block=data['blockNumber'], ) token_address = typing.TokenAddress( data_decoder(event.event_data['args']['token_address']), ) token_network_state = TokenNetworkState( token_network_address, token_address, ) transaction_hash = event.event_data['transactionHash'] assert transaction_hash, 'A mined transaction must have the hash field' new_token_network = ContractReceiveNewTokenNetwork( transaction_hash=transaction_hash, payment_network_identifier=event.originating_contract, token_network=token_network_state, block_number=data['block_number'], ) raiden.handle_state_change(new_token_network)
def get_filter_events( jsonrpc_client: JSONRPCClient, contract_address: address, topics: Optional[List[int]], from_block: Union[str, int] = 0, to_block: Union[str, int] = 'latest') -> List[Dict]: """ Get filter. This handles 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, 'toBlock': to_block, '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 = [ topic_decoder(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
def eth_sendTransaction( self, sender: address = b'', to: address = b'', value: int = 0, data: bytes = b'', gasPrice: int = GAS_PRICE, gas: int = GAS_PRICE, nonce: Optional[int] = None): """ Creates new message call transaction or a contract creation, if the data field contains code. Args: sender: The address the transaction is sent from. to: The address the transaction is directed to. (optional when creating new contract) gas: Gas provided for the transaction execution. It will return unused gas. gasPrice: gasPrice used for each unit of gas paid. value: Value sent with this transaction. data: The compiled code of a contract OR the hash of the invoked method signature and encoded parameters. nonce: This allows to overwrite your own pending transactions that use the same nonce. """ if to == b'' 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 == b'0' * 40: warnings.warn('For contract creation the empty string must be used.') if sender is None: raise ValueError('sender needs to be provided.') json_data = format_data_for_call( sender, to, value, data, gas, gasPrice ) if nonce is not None: json_data['nonce'] = quantity_encoder(nonce) res = self.call('eth_sendTransaction', json_data) return data_decoder(res)
def eth_getCode(self, code_address: address, block: Union[int, str] = 'latest') -> bytes: """ Returns code at a given address. Args: code_address: An address. block: Integer block number, or the string 'latest', 'earliest' or 'pending'. Default is 'latest'. """ if code_address.startswith(b'0x'): warnings.warn( 'address seems to be already encoded, this will result ' 'in unexpected behavior' ) if len(code_address) != 20: raise ValueError( 'address length must be 20 (it might be hex encoded)' ) result = self.call('eth_getCode', address_encoder(code_address), block) return data_decoder(result)
def all_contract_events( rpc: JSONRPCClient, contract_address: str, abi, start_block: Union[str, int] = 0, end_block: Union[str, int] = 'latest') -> List[Dict]: """Find and decode all events for a deployed contract given its `contract_address` and `abi`. Args: rpc: client instance. contract_address: hex encoded contract address. abi: the contract's ABI. start_block: read event-logs starting from this block number (default: 0). end_block: read event-logs up to this block number (default: 'latest'). Returns: A list of all events from the given contract. """ 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 = [ topic_decoder(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
def eth_call( self, sender: address = b'', to: address = b'', value: int = 0, data: bytes = b'', startgas: int = GAS_PRICE, gasprice: int = GAS_PRICE, block_number: Union[str, int] = 'latest'): """ Executes a new message call immediately without creating a transaction on the blockchain. Args: sender: The address the transaction is sent from. to: The address the transaction is directed to. gas: Gas provided for the transaction execution. eth_call consumes zero gas, but this parameter may be needed by some executions. gasPrice: gasPrice used for unit of gas paid. value: Integer of the value sent with this transaction. data: 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 = format_data_for_call( sender, to, value, data, startgas, gasprice, ) res = self.call('eth_call', json_data, block_number) return data_decoder(res)
def eth_call(self, sender='', to='', value=0, data='', startgas=GAS_PRICE, gasprice=GAS_PRICE, block_number='latest'): """ Executes a new message call immediately without creating a transaction on the blockchain. Args: sender: The address the transaction is sent 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 unit of gas paid. value (int): Integer of the value sent 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 = format_data_for_call( sender, to, value, data, startgas, gasprice, ) res = self.call('eth_call', json_data, block_number) return data_decoder(res)
def handle_tokennetwork_new2(raiden, event, current_block_number): """ Handles a `TokenNetworkCreated` event. """ data = event.event_data token_network_address = data['token_network_address'] token_network_registry_address = event.originating_contract token_network_registry_proxy = raiden.chain.token_network_registry( token_network_registry_address, ) token_network_proxy = token_network_registry_proxy.token_network( token_network_address) raiden.blockchain_events.add_token_network_listener(token_network_proxy) token_address = data_decoder(event.event_data['args']['token_address']) token_network_state = TokenNetworkState( token_network_address, token_address, ) new_token_network = ContractReceiveNewTokenNetwork( event.originating_contract, token_network_state, ) raiden.handle_state_change(new_token_network, current_block_number)
def _process_filter_results(self, filter_changes: List) -> List[Dict]: # 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 = [ topic_decoder(add_0x_prefix(encode_hex(topic))) for topic in log_event['topics'] ] block_number = log_event.get('blockNumber') result.append({ 'topics': topics, 'data': data, 'address': address, 'block_number': block_number, 'event_data': log_event }) return result
def _handle_message(self, room, event): """ Handle text messages sent to listening rooms """ if ( event['type'] != 'm.room.message' or event['content']['msgtype'] != 'm.text' or not self._running ): # Ignore non-messages and non-text messages return sender_id = event['sender'] if sender_id == self._client.user_id: # Ignore our own messages return user = self._client.get_user(sender_id) peer_address = self._userids_to_address.get(sender_id) if not peer_address: try: # recover displayname signature peer_address = signing.recover_address( sender_id.encode(), signature=data_decoder(user.get_display_name()), hasher=eth_sign_sha3, ) except AssertionError: self.log.warning('INVALID MESSAGE', sender_id=sender_id) return node_address_hex = to_normalized_address(peer_address) if node_address_hex.lower() not in sender_id: self.log.warning( 'INVALID SIGNATURE', peer_address=node_address_hex, sender_id=sender_id, ) return self._userids_to_address[sender_id] = peer_address data = event['content']['body'] if data.startswith('0x'): message = message_from_bytes(data_decoder(data)) else: try: message_dict = json.loads(data) except (UnicodeDecodeError, JSONDecodeError) as ex: self.log.warning( "Can't parse message data JSON", message_data=data, peer_address=pex(peer_address), exception=ex, ) return self.log.debug('MESSAGE_DATA', data=message_dict) message_dict = json.loads(data) self.log.debug('MESSAGE_DATA', data=message_dict) message = message_from_dict(message_dict) if isinstance(message, SignedMessage) and not message.sender: # FIXME: This can't be right message.sender = peer_address if isinstance(message, Delivered): self._receive_delivered(message) elif isinstance(message, Ping): self.log.warning( 'Not required Ping received', message=data, ) elif isinstance(message, SignedMessage): self._receive_message(message) else: self.log.error( 'Invalid message', message=data, )
def from_dict(cls, data): assert data['type'] == cls.__name__ return cls( message_identifier=data['message_identifier'], secret=data_decoder(data['secret']), )
def from_dict(cls, data): assert data['type'] == cls.__name__ return cls(amount=data['amount'], expiration=data['expiration'], secrethash=data_decoder(data['secrethash']))
def _deserialize(self, value, attr, data): return data_decoder(value)
def _deserialize(value, attr, data): # pylint: disable=unused-argument return data_decoder(value)
def _deserialize(self, value, attr, data): # pylint: disable=no-self-use return data_decoder(value)