pylibswarm

Python3 wrapper for libswarm-ng
git clone git://git.defalsify.org/pylibswarm.git
Log | Files | Refs | Submodules | README | LICENSE

soc.py (6028B)


      1 # standard imports
      2 import argparse
      3 import sys
      4 import logging
      5 import os
      6 
      7 # external imports
      8 from hexathon import (
      9         pad as hex_pad,
     10         strip_0x,
     11         )
     12 
     13 # local imports
     14 from pylibswarm.soc import from_str as soc_meta_from_str
     15 from pylibswarm.sign import DefaultSigner
     16 from pylibswarm.arg import stdin_arg
     17 from pylibswarm.io import Outputter
     18 
     19 
     20 logging.basicConfig(level=logging.WARNING)
     21 logg = logging.getLogger()
     22 
     23 argparser = argparse.ArgumentParser()
     24 argparser.add_argument('-n', action='store_true', help='skip newline at end of output. (stdout output only)')
     25 argparser.add_argument('-b', action='store_true', help='output raw bytes.')
     26 argparser.add_argument('-v', action='store_true', help='verbose output')
     27 argparser.add_argument('-vv', action='store_true', help='very verbose output')
     28 argparser.add_argument('-y', type=str, help='key provider (path to keyfile)')
     29 argparser.add_argument('-o', type=str, help='chunk output location')
     30 argparser.add_argument('-f', type=str, help='data input location')
     31 argparser.add_argument('-l', dest='data_length', type=int, help='length of data represented by preimage')
     32 argparser.add_argument('-u', action='store_true', help='treat input as utf-8 string')
     33 argparser.add_argument('--topic-string', dest='topic_string', type=str, help='string to use as soc topic.')
     34 argparser.add_argument('-t', '--topic', type=str, help='hex value to use as soc topic. overrides --topic-string.')
     35 argparser.add_argument('--index-string', dest='index_string', type=str, help='string to use as soc index.')
     36 argparser.add_argument('-i', '--index', type=str, help='hex value to use as soc index. overrides --index-string.')
     37 argparser.add_argument('--id', action='store_true', help='output identifier only')
     38 argparser.add_argument('--prepend-hash', dest='prepend_hash', action='store_true', help='prepend hash bytes to chunk output (no effect without -o)')
     39 argparser.add_argument('data', nargs='?', type=str, help='data to embed in soc.')
     40 largs = argparser.parse_args(sys.argv[1:])
     41 
     42 
     43 if largs.vv:
     44     logg.setLevel(logging.DEBUG)
     45 elif largs.v:
     46     logg.setLevel(logging.INFO)
     47 
     48 filepath = None
     49 input_data = None
     50 if largs.id == None:
     51     if largs.f:
     52         filepath = os.path.realpath(largs.f)
     53         f = open(filepath, 'rb')
     54         data = f.read()
     55         f.close()
     56         logg.info('data read from file: {}'.format(filepath))
     57     else:
     58         data = largs.data
     59         if data == None:
     60             data = stdin_arg()
     61             logg.info('data read from positional argument'.format(filepath))
     62         else:
     63             logg.info('data read from stdin'.format(filepath))
     64 
     65 
     66     input_data = data
     67     if not largs.u:
     68         input_data.rstrip()
     69         if isinstance(input_data, str):
     70             input_data = data.encode('utf-8')
     71 
     72     input_data_length = len(input_data)
     73     data_length = input_data_length
     74     if largs.data_length != None:
     75         data_length = largs.data_length
     76     logg.debug('input length {}'.format(input_data_length))
     77     logg.debug('span length {}'.format(data_length))
     78 
     79 src_topic = None
     80 src_index = None
     81 soc_topic = None
     82 soc_index = None
     83 
     84 if largs.topic:
     85     src_topic = largs.topic
     86     soc_topic = hex_pad(largs.topic, 20)
     87 elif largs.topic_string:
     88     src_topic = largs.topic_string
     89     try:
     90         soc_topic = soc_meta_from_str(largs.topic_string, 20, 'topic')
     91     except ValueError as e:
     92         sys.stderr.write(str(e))
     93         sys.exit(1)
     94 logg.debug('topic "{}" parsed as {}'.format(src_topic, soc_topic))
     95 
     96 if largs.index:
     97     src_index = largs.index
     98     soc_index = hex_pad(largs.index, 32)
     99 elif largs.index_string:
    100     src_index = largs.index_string
    101     try:
    102         soc_index = soc_meta_from_str(largs.index_string, 32, 'index')
    103     except ValueError as e:
    104         sys.stderr.write(str(e))
    105         sys.exit(1)
    106 logg.debug('index "{}" parsed as {}'.format(src_index, soc_index))
    107 
    108 
    109 if not largs.id:
    110     keystore = DefaultSigner()
    111     keystore.from_keyfile(largs.y, os.environ.get('WALLET_PASSPHRASE', ''))
    112     address = keystore.get_signer_address()
    113     logg.info('using keyfile wallet for address {}'.format(address))
    114 
    115 
    116 outputter = None
    117 if largs.o:
    118     outputter = Outputter(largs.o, prepend_hash=largs.prepend_hash)
    119 
    120 
    121 def outputter_noop(*args, **kwargs):
    122     pass
    123 
    124 def main():
    125     soc_topic_bytes = bytes.fromhex(soc_topic)
    126     soc_index_bytes = bytes.fromhex(soc_index)
    127     out_data = None
    128 
    129     import swarm
    130     soc_identifier_bytes = swarm.soc_identifier(soc_topic_bytes, soc_index_bytes)
    131     #soc_identifier_bytes = bytes(32)
    132     logg.info('generated identifier {}'.format(soc_identifier_bytes.hex()))
    133     if largs.id:
    134         out_data = soc_identifier_bytes
    135     else:
    136         soc_sig = None
    137         soc_hash = None
    138         soc_chunk = None
    139         if outputter:
    140             (soc_sig, soc_hash, soc_chunk) = swarm.soc_create(
    141                     soc_identifier_bytes,
    142                     bytes.fromhex(strip_0x(address)),
    143                     input_data,
    144                     input_data_length,
    145                     data_length,
    146                     keystore.sign,
    147                     outputter.dump,
    148                     )
    149         else:
    150             (soc_sig, soc_hash, soc_chunk) = swarm.soc_create(
    151                     soc_identifier_bytes,
    152                     bytes.fromhex(strip_0x(address)),
    153                     input_data,
    154                     input_data_length,
    155                     data_length,
    156                     keystore.sign,
    157                     outputter_noop,
    158                     )
    159 
    160         #logg.debug('signature {}'.format(soc_sig.hex()))
    161         #logg.debug('hash {}'.format(soc_hash.hex()))
    162         #logg.debug('chunk {}'.format(soc_chunk.hex()))
    163         logg.debug('signature {}'.format(soc_sig))
    164         logg.debug('hash {}'.format(soc_hash))
    165         logg.debug('chunk {}'.format(soc_chunk))
    166 
    167         out_data = soc_hash
    168 
    169     if largs.b:
    170         sys.stdout.buffer.write(out_data)
    171     else:
    172         s = '{}'.format(out_data.hex())
    173         if not largs.n:
    174             s += '\n'
    175         sys.stdout.write(s)
    176 
    177 
    178 if __name__ == '__main__':
    179     main()