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()