def _get_extra_info(self): s = self.api.session.get("/account/%s" % self.address).text try: self.abi = ContractAbi(json.loads(self.api._extract_account_info_from_code_tag("abi", s))) except ValueError: self.abi = None logger.debug("could not retrieve contract abi; maybe its just not a contract") try: self.swarm_hash = self.api._extract_account_info_from_code_tag("swarmHash", s) except ValueError: self.swarm_hash = None logger.debug("could not retrieve swarm hash") try: self.source = self.api._extract_account_info_from_code_tag("source", s) except ValueError: self.soruce = None logger.debug("could not retrieve contract source code") try: self.code = self.api._extract_account_info_from_code_tag("contractCode", s) except ValueError: self.code = None logger.debug("could not retrieve contract bytecode") try: self.constructor_args = self.api._extract_account_info_from_code_tag("constructorArgs", s) except ValueError: self.constructor_args = None logger.debug("could not retrieve contract constructor args") try: self.compiler_settings = self.api._extract_compiler_settings(s) except ValueError: self.compiler_settings = None logger.debug("could not retrieve contract compiler settings")
def main(): parser = argparse.ArgumentParser(description='Ethereum Input decoder') inputs = parser.add_argument_group('inputs') inputs.add_argument('-t', '--tx-input', nargs='*', help='Decode transaction input to contract (hexstr)') inputs.add_argument('-c', '--constructor-input', help='Decode constructor argument to contract (hexstr)') definition = parser.add_argument_group('abi definition') # if abi is not set we try to lookup the sighash from 4bytes.directory definition.add_argument('-a', '--abi', help='ABI definition in json. Expected input: String or path to json file') args = parser.parse_args() if not args.tx_input and not args.constructor_input: print("missing required argument --tx-input or --constructor-input") parser.print_help(sys.stderr) sys.exit(1) if args.abi: # abi provided - use abi to decode. if os.path.isfile(args.abi): with open(args.abi, 'r') as f: jsonabi = json.load(f) else: jsonabi = json.loads(args.abi) c = ContractAbi(jsonabi) if args.constructor_input: description = c.describe_constructor(Utils.str_to_bytes(args.constructor_input)) print("\n==[Constructor]==") print(" Raw: %r" % args.constructor_input) print(" Description: %s" % description) for txinput in args.tx_input: description = c.describe_input(Utils.str_to_bytes(txinput)) print("\n==[Input]==") print(" Raw: %r" % txinput) print(" Description: %s" % description) else: # abi not set, try to lookup sighash print("\n**online lookup**\n") for txinput in args.tx_input: description = AbiMethod.from_input_lookup(Utils.str_to_bytes(txinput)) print("\n==[Input]==") print(" Raw: %r" % txinput) print(" Description: %s" % description)
def contract_from_address(address, as_web3=True): """ Create a contract from an address using Etherscan API """ if not address: address = settings.BANCOR_MONITOR_ADDRESSES[0] params = { 'module': 'contract', 'action': 'getabi', 'address': settings.WEB3.toChecksumAddress(address), 'apikey': settings.ETHERSCAN_API_KEY } resp = requests.get('http://api.etherscan.io/api', params) abi = resp.json()['result'] contract = settings.WEB3.eth.contract(abi=abi, address=address) if not as_web3: contract = ContractAbi(contract.abi) return contract
def main(): parser = argparse.ArgumentParser(description='Ethereum Input decoder') inputs = parser.add_argument_group('inputs') inputs.add_argument('-t', '--tx-input', nargs='*', help='Decode transaction input to contract (hexstr)') inputs.add_argument( '-c', '--constructor-input', help='Decode constructor argument to contract (hexstr)') definition = parser.add_argument_group('abi definition') definition.add_argument( '-a', '--abi', required=True, help= 'ABI definition in json. Expected input: String or path to json file') args = parser.parse_args() if not args.tx_input and not args.constructor_input: print("missing required argument --tx-input or --constructor-input") parser.print_help(sys.stderr) sys.exit(1) if os.path.isfile(args.abi): with open(args.abi, 'r') as f: jsonabi = json.load(f) else: jsonabi = json.loads(args.abi) c = ContractAbi(jsonabi) if args.constructor_input: description = c.describe_constructor( ContractAbi.str_to_bytes(args.constructor_input)) print("\n==[Constructor]==") print(" Raw: %r" % args.constructor_input) print(" Description: %s" % description) for txinput in args.tx_input: description = c.describe_input(ContractAbi.str_to_bytes(txinput)) print("\n==[Input]==") print(" Raw: %r" % txinput) print(" Description: %s" % description)
def main(): parser = argparse.ArgumentParser(description='Ethereum Input decoder') inputs = parser.add_argument_group('inputs') inputs.add_argument('-t', '--tx-input', nargs='*', help='Decode transaction input to contract (hexstr)') inputs.add_argument( '-c', '--constructor-input', help='Decode constructor argument to contract (hexstr)') definition = parser.add_argument_group('abi definition') # if abi is not set we try to lookup the sighash from 4bytes.directory definition.add_argument( '-a', '--abi', help= 'ABI definition in json. Expected input: String or path to json file') args = parser.parse_args() if not args.tx_input and not args.constructor_input: print("missing required argument --tx-input or --constructor-input") parser.print_help(sys.stderr) sys.exit(1) if args.abi: # abi provided - use abi to decode. if os.path.isfile(args.abi): with open(args.abi, 'r') as f: jsonabi = json.load(f) else: jsonabi = json.loads(args.abi) c = ContractAbi(jsonabi) if args.constructor_input: description = c.describe_constructor( Utils.str_to_bytes(args.constructor_input)) print("\n==[Constructor]==") print(" Raw: %r" % args.constructor_input) print(" Description: %s" % description) for txinput in args.tx_input: description = c.describe_input(Utils.str_to_bytes(txinput)) print("\n==[Input]==") print(" Raw: %r" % txinput) print(" Description: %s" % description) else: # abi not set, try to lookup sighash print("\n**online lookup**\n") for txinput in args.tx_input: description = AbiMethod.from_input_lookup( Utils.str_to_bytes(txinput)) print("\n==[Input]==") print(" Raw: %r" % txinput) print(" Description: %s" % description)
def set_abi(self, json_abi): self.abi = ContractAbi(json_abi)
from ethereum_input_decoder import ContractAbi, Utils import json if __name__ == "__main__": # This is our example contract: # https://www.etherchain.org/account/ab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code with open('contract_abi_ab7c74abc0c4d48d1bdad5dcb26153fc8780f83e.json', 'r') as f: abi = f.read() ca = ContractAbi(json.loads(abi)) # This is the constructor arguments: # https://etherscan.io/address/0xab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code 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(Utils.str_to_bytes( "0xfedd60920000000000000000000000000595d187cac88f04466371eff3a6b6d1b12fb013b92dd9476601c067bcd9730c83d54263fbc0da1c2c01f05a834199427aa3fad40000000000000000000000005c3766a9a906aa17e16dbbdaac0c93d41c0d057f"))) # f
class EtherChainAccount(DictLikeInterface): """ Interface class of an EtherChain account/contract """ TX_TYPE_ALL = 1 TX_TYPE_INCOMING = 2 TX_TYPE_OUTGOING = 3 TX_TYPE_CREATE = 4 TX_TYPE_CREATION = 5 def __init__(self, address, api=None): self.address = address #self.abi, self.swarm_hash, self.source, self.code, self.constructor_args = None, None, None, None, None self.api = api or EtherChainApi() # prepare lazy loading self.data = None # lazy loading funcs def __getattr__(self, item): if item in ("abi", "swarm_hash", "source", "code", "constructor_args", "compiler_settings"): self._get_extra_info() # creates attributes return self.__getattribute__(item) def __str__(self): self.data = self._get() return super().__str__() def __repr__(self): self.data = self._get() return super().__repr__() def __getitem__(self, item): try: return super().__getitem__(item) except (AttributeError, KeyError, TypeError): self.data = self._get() return self.data[item] def keys(self): self.data = self.data or self._get() return self.data.keys() def values(self): self.data = self.data or self._get() return self.data.values() def _get(self): return self.api.get_account(self.address) def history(self): return self.api.get_account_history(self.address) def transactions(self, start=0, length=10, direction=None): txs = self.api.get_account_transactions(account=self.address, start=start, length=length) if not direction: return txs if direction.lower()=="in": txs["data"] = [tx for tx in txs['data'] if "in" in tx["direction"].lower()] elif direction.lower()=="out": txs["data"] = [tx for tx in txs['data'] if "out" in tx["direction"].lower()] return txs def _get_extra_info(self): s = self.api.session.get("/account/%s" % self.address).text try: self.abi = ContractAbi(json.loads(self.api._extract_account_info_from_code_tag("abi", s))) except ValueError: self.abi = None logger.debug("could not retrieve contract abi; maybe its just not a contract") try: self.swarm_hash = self.api._extract_account_info_from_code_tag("swarmHash", s) except ValueError: self.swarm_hash = None logger.debug("could not retrieve swarm hash") try: self.source = self.api._extract_account_info_from_code_tag("source", s) except ValueError: self.soruce = None logger.debug("could not retrieve contract source code") try: self.code = self.api._extract_account_info_from_code_tag("contractCode", s) except ValueError: self.code = None logger.debug("could not retrieve contract bytecode") try: self.constructor_args = self.api._extract_account_info_from_code_tag("constructorArgs", s) except ValueError: self.constructor_args = None logger.debug("could not retrieve contract constructor args") try: self.compiler_settings = self.api._extract_compiler_settings(s) except ValueError: self.compiler_settings = None logger.debug("could not retrieve contract compiler settings") def set_abi(self, json_abi): self.abi = ContractAbi(json_abi) def describe_constructor(self): return self.abi.describe_constructor(Utils.str_to_bytes(self.constructor_args)) def describe_transactions(self, length=10000): reslt = [] for tx in self.transactions(direction="in", length=length)["data"]: tx_obj = EtherChainTransaction(tx["parenthash"], api=self.api)[0] reslt.append((tx_obj["hash"], self.abi.describe_input(Utils.str_to_bytes(tx_obj["input"])))) return reslt def describe_contract(self, nr_of_transactions_to_include=0): header = """//*********************************************************** // // created with pyetherchain.EtherChainAccount(address).describe_contract() // see: https://github.com/tintinweb/pyetherchain // // Date: %s // // Name: %s // Address: %s // Swarm: %s // // // Constructor Args: %s // // // Transactions %s: %s // //*************************** """ % (time.ctime(), self["name"], self["address"], self.swarm_hash, self.describe_constructor(), "(last %d)" % nr_of_transactions_to_include if nr_of_transactions_to_include else "", "\n// " + "\n// ".join(("[IN] %s : %s" % (txhash, txdata) for txhash, txdata in self.describe_transactions( nr_of_transactions_to_include))) if nr_of_transactions_to_include else "<disabled>") return "%s%s" % (header, self.source)
def describe_transactions(self, length=10000): reslt = [] for tx in self.transactions(direction="in", length=length)["data"]: tx_obj = EtherChainTransaction(tx["parenthash"], api=self.api)[0] reslt.append((tx_obj["hash"], self.abi.describe_input(ContractAbi.str_to_bytes(tx_obj["input"])))) return reslt
def describe_constructor(self): return self.abi.describe_constructor(ContractAbi.str_to_bytes(self.constructor_args))
from ethereum_input_decoder import ContractAbi import json if __name__ == "__main__": # This is our example contract: # https://www.etherchain.org/account/ab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code with open('contract_abi_ab7c74abc0c4d48d1bdad5dcb26153fc8780f83e.json', 'r') as f: abi = f.read() ca = ContractAbi(json.loads(abi)) # This is the constructor arguments: # https://etherscan.io/address/0xab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code print( ca.describe_constructor( ContractAbi.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" ))) # f
def loader(s): with open('abi.txt', 'r') as f: abi = f.read() return ContractAbi(json.loads(abi))
from ethereum_input_decoder import ContractAbi, Utils import json if __name__ == "__main__": # This is our example contract: # https://www.etherchain.org/account/ab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code with open('contract_abi_ab7c74abc0c4d48d1bdad5dcb26153fc8780f83e.json', 'r') as f: abi = f.read() ca = ContractAbi(json.loads(abi)) # This is the constructor arguments: # https://etherscan.io/address/0xab7c74abc0c4d48d1bdad5dcb26153fc8780f83e#code 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( Utils.str_to_bytes( "0xfedd60920000000000000000000000000595d187cac88f04466371eff3a6b6d1b12fb013b92dd9476601c067bcd9730c83d54263fbc0da1c2c01f05a834199427aa3fad40000000000000000000000005c3766a9a906aa17e16dbbdaac0c93d41c0d057f" ))) # f