chainlib-eth

Ethereum implementation of the chainlib interface
Info | Log | Files | Refs | README | LICENSE

get.py (4730B)


      1 # SPDX-License-Identifier: GPL-3.0-or-later
      2 
      3 # standard imports
      4 import sys
      5 import os
      6 import json
      7 import argparse
      8 import logging
      9 import enum
     10 import select
     11 
     12 # external imports
     13 from potaahto.symbols import snake_and_camel
     14 from hexathon import (
     15         add_0x,
     16         strip_0x,
     17         )
     18 import sha3
     19 from chainlib.jsonrpc import (
     20         JSONRPCRequest,
     21         jsonrpc_result,
     22         IntSequenceGenerator,
     23         )
     24 from chainlib.chain import ChainSpec
     25 from chainlib.status import Status
     26 from chainlib.settings import ChainSettings
     27 
     28 # local imports
     29 from chainlib.eth.connection import EthHTTPConnection
     30 from chainlib.eth.tx import (
     31         Tx,
     32         pack,
     33         transaction,
     34         receipt,
     35         )
     36 from chainlib.eth.address import (
     37         to_checksum_address,
     38         is_checksum_address,
     39         )
     40 from chainlib.eth.block import (
     41         Block,
     42         block_by_hash,
     43         )
     44 from chainlib.eth.jsonrpc import to_blockheight_param
     45 import chainlib.eth.cli
     46 from chainlib.eth.cli.arg import (
     47         Arg,
     48         ArgFlag,
     49         process_args,
     50         stdin_arg,
     51         )
     52 from chainlib.eth.cli.config import (
     53         Config,
     54         process_config,
     55         )
     56 from chainlib.eth.contract import code
     57 from chainlib.eth.cli.log import process_log
     58 from chainlib.eth.settings import process_settings
     59 
     60 
     61 logg = logging.getLogger()
     62 
     63 script_dir = os.path.dirname(os.path.realpath(__file__)) 
     64 config_dir = os.path.join(script_dir, '..', 'data', 'config')
     65 
     66 
     67 def process_config_local(config, arg, args, flags):
     68     item = config.get('_POSARG')
     69     try:
     70         item = strip_0x(item)
     71     except TypeError:
     72         item = stdin_arg()
     73         item = strip_0x(item)
     74 
     75     config.add(item, '_ITEM', False)
     76     return config
     77 
     78 
     79 def process_settings_local(settings, config):
     80     item = config.get('_ITEM')
     81     if len(item) == 40:
     82         config.add(item, '_RECIPIENT', False)
     83     elif len(item) == 64:
     84         config.add(item, '_HASH', False)
     85 
     86     return process_settings(settings, config)
     87 
     88 
     89 arg_flags = ArgFlag()
     90 arg = Arg(arg_flags)
     91 flags = arg_flags.STD_BASE_READ | arg_flags.TARGET | arg_flags.TAB
     92 flags = arg_flags.less(flags, arg_flags.CHAIN_SPEC)
     93 
     94 argparser = chainlib.eth.cli.ArgumentParser()
     95 argparser = process_args(argparser, arg, flags)
     96 argparser.add_argument('item', type=str, help='Address or transaction to retrieve data for')
     97 args = argparser.parse_args()
     98 
     99 logg = process_log(args, logg)
    100 
    101 config = Config()
    102 config = process_config(config, arg, args, flags, positional_name='item')
    103 config = process_config_local(config, arg, args, flags)
    104 logg.debug('config loaded:\n{}'.format(config))
    105 
    106 settings = ChainSettings()
    107 settings = process_settings_local(settings, config)
    108 logg.debug('settings loaded:\n{}'.format(settings))
    109 
    110 
    111 def get_transaction(conn, chain_spec, tx_hash, id_generator):
    112     o = transaction(tx_hash, id_generator=id_generator)
    113     tx_src = conn.do(o)
    114     if tx_src == None:
    115         logg.error('Transaction {} not found'.format(tx_hash))
    116         sys.exit(1)
    117 
    118     if config.true('_RAW') and config.get('_OUTARG') == None:
    119         tx_src = Tx.src_normalize(tx_src)
    120         return pack(tx_src, chain_spec).hex()
    121 
    122     tx = None
    123     status = -1
    124     rcpt = None
    125 
    126     o = receipt(tx_hash, id_generator=id_generator)
    127     rcpt = conn.do(o)
    128 
    129     if tx == None:
    130         tx = Tx(tx_src, dialect_filter=settings.get('RPC_DIALECT_FILTER'))
    131     if rcpt != None:
    132         tx.apply_receipt(rcpt)
    133         rcpt = snake_and_camel(rcpt)
    134         o = block_by_hash(rcpt['block_hash'])
    135         r = conn.do(o)
    136         block = Block(r, dialect_filter=settings.get('RPC_DIALECT_FILTER'))
    137         tx.apply_block(block)
    138     tx.generate_wire(chain_spec)
    139     return tx
    140     
    141 
    142 
    143 def get_address(conn, address, id_generator, height):
    144     o = code(address, height, id_generator=id_generator)
    145     r = conn.do(o)
    146     
    147     content = strip_0x(r, allow_empty=True)
    148     if len(content) == 0:
    149         return None
    150 
    151     return content
    152 
    153 
    154 def main():
    155     r = None
    156     if settings.get('HASH') != None:
    157         hsh = settings.get('HASH')[0]
    158         r = get_transaction(
    159                 settings.get('CONN'),
    160                 settings.get('CHAIN_SPEC'),
    161                 hsh,
    162                 settings.get('RPC_ID_GENERATOR'),
    163                 )
    164         if not config.true('_RAW') or config.get('_OUTARG') != None:
    165             r = r.to_human(fields=config.get('_OUTARG'), skip_keys=config.true('_RAW'))
    166     else:
    167         r = get_address(
    168             settings.get('CONN'),
    169             settings.get('RECIPIENT'),
    170             settings.get('RPC_ID_GENERATOR'),
    171             settings.get('HEIGHT'),
    172             )
    173     if r != None:
    174         sys.stdout.write(r)
    175         if not config.true('_NOLINE'):
    176             sys.stdout.write('\n')
    177 
    178 
    179 if __name__ == '__main__':
    180     main()