Created
June 1, 2018 10:41
-
-
Save porobov/9b23da509e64665f71e78d311f512020 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from ethjsonrpc import EthJsonRpc | |
from ethjsonrpc.utils import hex_to_dec | |
import json | |
import ethereum.abi | |
from sha3 import sha3_256 | |
import logging | |
from operator import itemgetter | |
# from requests.exceptions import ConnectionError as RequestsConnectionError | |
from ethjsonrpc.exceptions import (ConnectionError, BadStatusCodeError, | |
BadJsonError, BadResponseError) | |
class MyContract: | |
ADDRESS = "0x15dbdB25f870f21eaf9105e68e249E0426DaE916" | |
EVENTS = { | |
"NewUser": { | |
"signature": "0x9d35dcac34f1dc50826c04b0cf8282b0764ff89463320a8401c9add280b92ebd", | |
"params": ["uint256", "address", "address", "uint32"], | |
"dict": ["id", "address", "referral", "activation_datetime", "block_number", "transaction_index"] | |
}, | |
"NewAreaStatus": { | |
"signature": "0x46cffffd9f27bb4e759b47d034705eda06243dd60eb47be11a2c9b02ae16b89d", | |
"params": ["uint256", "uint8", "uint8", "uint8", "uint8", "uint256"], | |
"dict": ["id", "x1", "y1", "x2", "y2", "price", "block_number", "transaction_index"] | |
}, | |
"NewImage": { | |
"signature": "0x542d3e34836f8b331e8441364480130cf7077e9b6ae9dab76dc285dd3961b0a6", | |
"params": ["uint256", "uint8", "uint8", "uint8", "uint8", "string", "string", "string"], | |
"dict": ["id", "x1", "y1", "x2", "y2", "src", "href", "alt", "block_number", "transaction_index"] | |
} | |
} | |
def __init__(self): | |
self.client = EthJsonRpc('mainnet.infura.io/5GyJwkluzWFwhA7RI9XY',443,True) | |
# self.calculate_event_signatures() | |
# curl -X POST --data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"0x1","toBlock":"latest","address":"0x15dbdB25f870f21eaf9105e68e249E0426DaE916","topics":["0x9d35dcac34f1dc50826c04b0cf8282b0764ff89463320a8401c9add280b92ebd"]}],"id":73}' https://mainnet.infura.io/5GyJwkluzWFwhA7RI9XY | |
#https://api.etherscan.io/api?module=logs&action=getLogs&fromBlock=0&toBlock=latest&address=0x15dbdB25f870f21eaf9105e68e249E0426DaE916&topic0=0x9d35dcac34f1dc50826c04b0cf8282b0764ff89463320a8401c9add280b92ebd | |
#&apikey=YourApiKeyToken | |
def calculate_event_signatures(self): | |
for key, value in self.EVENTS.iteritems(): | |
params = "" | |
for param in value["params"]: | |
params += param + "," | |
params = params[:-1] | |
decl = key + "(" + params + ")" | |
value["signature"] = "0x" + sha3_256(decl.encode("utf-8")).hexdigest().lower() | |
logging.info(key + ": " + value["signature"]) | |
def data_to_dict(self, data, event_dict): | |
values = {} | |
keys = event_dict | |
i = 0 | |
for value in data: | |
values[keys[i]] = value | |
i += 1 | |
return values | |
def decode_logs(self, logs, event_definition): | |
decoded_logs = [] | |
if logs == []: return [] | |
#print json.dumps(logs, sort_keys=True, indent=2, separators=(',', ': ')) | |
#print event_definition["signature"] | |
for log in logs: | |
logdata_hex = log[u'data'][2:] | |
logdata = logdata_hex.decode('hex') | |
topic = log[u'topics'][0] | |
if event_definition["signature"] == topic: | |
event_abi = event_definition["params"] | |
data = ethereum.abi.decode_abi(event_abi, logdata) | |
block_number = hex_to_dec(log[u'blockNumber']) | |
transaction_index = hex_to_dec(log[u'transactionIndex']) | |
data.append(block_number) | |
data.append(transaction_index) | |
decoded_logs.append(dict(zip(event_definition["dict"], data))) | |
# decoded_logs.append(self.data_to_dict(data, event_definition["dict"])) | |
decoded_logs.sort(key=itemgetter('id')) | |
return decoded_logs | |
def get_events(self, event_name, from_block): | |
event_definition = self.EVENTS[event_name] | |
params = { | |
"fromBlock": hex(from_block), | |
"toBlock": "latest", | |
"address": self.ADDRESS, | |
"topics": [event_definition["signature"]] | |
} | |
try: | |
logs = self.client.eth_getLogs(params) | |
except (ConnectionError, BadStatusCodeError, BadJsonError, BadResponseError) as e: | |
logs = [] | |
logging.fatal("Ethereum. Client error. " + str(e.message)) | |
decoded_logs = self.decode_logs(logs, event_definition) | |
if len(logs) > 0 or len(decoded_logs) > 0: | |
logging.info(event_name + " events (from_block: " + str(from_block) + | |
") recieved: " + str(len(logs)) + | |
", decoded: " + str(len(decoded_logs))) | |
return decoded_logs | |
def main(): | |
logging.basicConfig(level=logging.DEBUG) | |
my_contract = MyContract() | |
''' | |
all_events = my_contract.get_events(event_name='NewUser', from_block=0) | |
print json.dumps(all_events, sort_keys=True, indent=1, separators=(',', ': ')) | |
all_events = my_contract.get_events(event_name='NewAreaStatus', from_block=0) | |
print json.dumps(all_events, sort_keys=True, indent=1, separators=(',', ': ')) | |
''' | |
all_events = my_contract.get_events(event_name='NewImage', from_block=3277456) | |
print json.dumps(all_events, sort_keys=True, indent=1, separators=(',', ': ')) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment