funga

Signer and keystore daemon and library for cryptocurrency software development
Info | Log | Files | Refs | README | LICENSE

generate.py (4230B)


      1 import uuid
      2 import random
      3 import json
      4 import os
      5 import logging
      6 import time
      7 import sha3
      8 import sys
      9 from urllib.request import Request, urlopen
     10 
     11 from crypto_dev_signer.keystore import keyapi
     12 from crypto_dev_signer.eth.transaction import EIP155Transaction
     13 from crypto_dev_signer.eth.signer.defaultsigner import ReferenceSigner
     14 
     15 logging.basicConfig(level=logging.DEBUG)
     16 logg = logging.getLogger()
     17 
     18 pk_input = sys.argv[1]
     19 
     20 
     21 class pkGetter:
     22 
     23     def __init__(self, pk):
     24         self.pk = pk
     25 
     26     def get(self, address, password=None):
     27         return self.pk
     28 
     29 
     30 def init(pk_hex):
     31     pk_bytes = bytes.fromhex(pk_hex)
     32     pk = keyapi.PrivateKey(pk_bytes)
     33 
     34     pubk = keyapi.private_key_to_public_key(pk)
     35     address_hex = pubk.to_checksum_address()
     36 
     37     pk_getter = pkGetter(pk_bytes)
     38     
     39     signer = ReferenceSigner(pk_getter)
     40 
     41     return (signer, address_hex,)
     42 
     43 
     44 def main():
     45     random.seed()
     46 
     47     (signer, address) = init(pk_input)
     48 
     49     req = Request('http://localhost:63545')
     50     req.add_header('Content-Type', 'application/json')
     51     o = {
     52         'jsonrpc': '2.0',
     53         'method': 'eth_getTransactionCount',
     54         'id': str(uuid.uuid4()),
     55         'params': [
     56             address,
     57             'pending',
     58             ],
     59             }
     60     res = urlopen(req, json.dumps(o).encode('utf-8'))
     61     o = json.loads(res.read().decode('utf-8'))
     62     hx = o['result'][2:]
     63     if len(hx) % 2 != 0:
     64         hx = '0' + hx
     65     nonce = int.from_bytes(bytes.fromhex(hx), 'big')
     66     logg.debug('using nonce {} for {}'.format(nonce, address))
     67 
     68     i = 0
     69     offset = nonce
     70     while True:
     71         gas_price = random.randint(1, 20) * 1000000000
     72         gas_limit = random.randint(21000, 8000000)
     73         to = '0x' + os.urandom(20).hex()
     74         value = random.randint(0, 2) * 100
     75         data = '0x'
     76         if value > 0:
     77             data += os.urandom(128).hex()
     78 
     79         tx = {
     80             'nonce': nonce,
     81             'from': "0xEB014f8c8B418Db6b45774c326A0E64C78914dC0",
     82             'gasPrice': gas_price,
     83             'gas': gas_limit,
     84             'to': to,
     85             'value': value,
     86             'data': data,
     87             'chainId': 8996,
     88         }
     89         
     90         txe = EIP155Transaction(tx, nonce, 8996)
     91 
     92         sign_and_send(signer, txe)
     93 
     94         nonce += 1
     95         i += 1
     96 
     97         logg.debug('tx {} ({}) ok'.format(nonce - offset + 1, nonce))
     98 
     99         if i == 100:
    100             logg.info('waiting a bit for node to catch up')
    101             time.sleep(7)
    102             i = 0
    103 
    104 
    105 def sign_and_send(signer, txe, save=True):
    106 
    107         signer.signTransaction(txe)
    108         tx_raw = txe.rlp_serialize()
    109         
    110         h = sha3.keccak_256()
    111         h.update(tx_raw)
    112         tx_hash = h.digest().hex()
    113 
    114         if save:
    115             f = open(os.path.join('tmp', tx_hash), 'w')
    116             f.write(str(txe.serialize()) + '\n')
    117             f.write(tx_raw.hex())
    118             f.close()
    119         logg.info('sending tx {}'.format(tx_hash))
    120 
    121         req = Request('http://localhost:63545')
    122         req.add_header('Content-Type', 'application/json')
    123         o = {
    124             'jsonrpc': '2.0',
    125             'method': 'eth_sendRawTransaction',
    126             'id': str(uuid.uuid4()),
    127             'params': [
    128                 '0x' + tx_raw.hex(),
    129                 ],
    130                 }
    131         res = urlopen(req, json.dumps(o).encode('utf-8'))
    132         o = json.loads(res.read().decode('utf-8'))
    133         logg.debug('response: {}'.format(o))
    134         if o.get('error') != None:
    135             logg.error('error: {}'.format(o.get('error')))
    136             sys.exit(1)
    137 
    138 
    139 def redo():
    140 
    141         (signer, address) = init(pk_input)
    142 
    143         tx = {'nonce': 510, 'from': '0xEB014f8c8B418Db6b45774c326A0E64C78914dC0', 'gasPrice': 5000000000, 'gas': 6608539, 'to': '0x7fe37d3341b6044a3d9d84607b885db2a8ffda17', 'value': 100, 'data': '0xc2d9656585afddb615816c254fc99810e2b9bce6a27b7366f22c5e929960d7a8ce2d8a87d46826e6cee955d3594c772584712f6e11da929005b3b77bc0168f54ba6d38fbf3f9e9c5bf04abc799af46c34068998e14508135a3e9e6dda73bde0f306bf07c6e6558525f5d2744dc7c5ccc6161c2e7aad39214779a9dfb2ffdd466', 'chainId': 8996}
    144 
    145         txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
    146 
    147         sign_and_send(signer, txe, save=False)
    148                 
    149 
    150 if __name__ == '__main__':
    151     main()
    152     #redo()