Skip to content

Commit

Permalink
add custom exception for online lookup
Browse files Browse the repository at this point in the history
expose timeout/proxies arguments for the online lookup
ignore missing signatures in abi.json
fix example
version bump
  • Loading branch information
tintinweb committed Jul 4, 2018
1 parent 20783ba commit aa96623
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 18 deletions.
8 changes: 5 additions & 3 deletions ethereum_input_decoder/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: UTF-8 -*-

from ethereum_input_decoder import ContractAbi,AbiMethod, Utils
import sys
import os
import argparse
import json
import sys, os
from ethereum_input_decoder import ContractAbi,AbiMethod, Utils


def main():
parser = argparse.ArgumentParser(description='Ethereum Input decoder')
Expand Down Expand Up @@ -58,4 +60,4 @@ def main():


if __name__ == '__main__':
main()
main()
37 changes: 28 additions & 9 deletions ethereum_input_decoder/decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@
import requests


class InputDecoderException(Exception):
pass


class FourByteDirectoryException(InputDecoderException):
pass


class FourByteDirectoryOnlineLookupError(FourByteDirectoryException):
pass


class Utils:

@staticmethod
Expand Down Expand Up @@ -38,28 +50,32 @@ def parse_text_signature(text_signature):
'outputs': []}

@staticmethod
def lookup_signatures(sighash):
resp = requests.get("https://www.4byte.directory/api/v1/signatures/?hex_signature=%s" % sighash).json()
for sig in resp["results"]:
yield sig["text_signature"]
def lookup_signatures(sighash, timeout=None, proxies=None):
try:
resp = requests.get("https://www.4byte.directory/api/v1/signatures/?hex_signature=%s" % sighash,
timeout=timeout, proxies=proxies).json()
for sig in resp["results"]:
yield sig["text_signature"]
except (requests.exceptions.RequestException) as re:
raise FourByteDirectoryOnlineLookupError(re)

@staticmethod
def get_pseudo_abi_for_sighash(sighash):
for text_signature in FourByteDirectory.lookup_signatures(sighash):
def get_pseudo_abi_for_sighash(sighash, timeout=None, proxies=None):
for text_signature in FourByteDirectory.lookup_signatures(sighash, timeout=timeout, proxies=proxies):
pseudo_abi = FourByteDirectory.parse_text_signature(text_signature)
pseudo_abi['signature'] = sighash
yield pseudo_abi

@staticmethod
def get_pseudo_abi_for_input(s):
def get_pseudo_abi_for_input(s, timeout=None, proxies=None):
"""
Lookup sighash from 4bytes.directory, create a pseudo api and try to decode it with the parsed abi.
May return multiple results as sighashes may collide.
:param s: bytes input
:return: pseudo abi for method
"""
sighash = Utils.bytes_to_str(s[:4])
for pseudo_abi in FourByteDirectory.get_pseudo_abi_for_sighash(sighash):
for pseudo_abi in FourByteDirectory.get_pseudo_abi_for_sighash(sighash, timeout=timeout, proxies=proxies):
types = [ti["type"] for ti in pseudo_abi['inputs']]
try:
# test decoding
Expand Down Expand Up @@ -98,7 +114,10 @@ def _prepare_abi(self, jsonabi):
abi_e.setdefault("inputs", [])
self.signatures[b"__fallback__"] = abi_e
elif abi_e["type"] == "function":
self.signatures[Utils.str_to_bytes(abi_e["signature"])] = abi_e
# function and signature present
# todo: we could generate the sighash ourselves? requires keccak256
if abi_e.get("signature"):
self.signatures[Utils.str_to_bytes(abi_e["signature"])] = abi_e
elif abi_e["type"] == "event":
self.signatures[b"__event__"] = abi_e
else:
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def read(fname):

setup(
name="ethereum_input_decoder",
version="0.2.1",
version="0.2.2",
packages=["ethereum_input_decoder"],
author="tintinweb",
author_email="tintinweb@oststrom.com",
Expand All @@ -18,7 +18,7 @@ def read(fname):
license="GPLv3",
keywords=["ethereum", "blockchain", "input", "transaction", "decoder"],
url="https://github.com/tintinweb/ethereum-input-decoder/",
download_url="https://github.com/tintinweb/ethereum-input-decoder/tarball/v0.2.1",
download_url="https://github.com/tintinweb/ethereum-input-decoder/tarball/v0.2.2",
#python setup.py register -r https://testpypi.python.org/pypi
long_description=read("README.rst") if os.path.isfile("README.rst") else read("README.md"),
install_requires=["eth-abi", "requests"],
Expand Down
8 changes: 4 additions & 4 deletions test/example.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ethereum_input_decoder import ContractAbi
from ethereum_input_decoder import ContractAbi, Utils
import json

if __name__ == "__main__":
Expand All @@ -11,13 +11,13 @@

# This is the constructor arguments:
# https://etherscan.io/address/0xab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code
print(ca.describe_constructor(ContractAbi.str_to_bytes(
print(ca.describe_constructor(Utils.str_to_bytes(
"000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000002903cadbe271e057edef157340b52a5898d7424f000000000000000000000000ba7ca1bcf210c1b37cf5818816c4a819c3040ea700000000000000000000000014cd6536d449e3f6878f2d6859e1ff92ae0990e60000000000000000000000000c24441e42277445e38e02dfc3494577c05ba46b")))
# constructor None ((address[]) _owners = ('0x2903cadbe271e057edef157340b52a5898d7424f', '0xba7ca1bcf210c1b37cf5818816c4a819c3040ea7', '0x14cd6536d449e3f6878f2d6859e1ff92ae0990e6', '0x0c24441e42277445e38e02dfc3494577c05ba46b'), (uint256) _required = 2, (uint256) _daylimit = 1000000000000000000) returns ()


# This is one input transaction:
# https://www.etherchain.org/tx/1e9ed6236afb884fe7cad9a807886ba61b9e9a2fc944a991e3e8725d2158c7b2
print(ca.describe_input(ContractAbi.str_to_bytes(
"0x797af62798d790d3133e0049215669e09b55a0b59d586c95f94c2d56b2812040133d7707")))
print(ca.describe_input(Utils.str_to_bytes(
"0xfedd60920000000000000000000000000595d187cac88f04466371eff3a6b6d1b12fb013b92dd9476601c067bcd9730c83d54263fbc0da1c2c01f05a834199427aa3fad40000000000000000000000005c3766a9a906aa17e16dbbdaac0c93d41c0d057f")))
# f

0 comments on commit aa96623

Please sign in to comment.