Advertisement
Guest User

Untitled

a guest
Jan 18th, 2018
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.87 KB | None | 0 0
  1. import hashlib, os, struct, sys, socket, time
  2.  
  3. N = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fL
  4. R = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141L
  5. A = 0L
  6. B = 7L
  7. gx = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798L
  8. gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
  9.  
  10. b58ab = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
  11.  
  12. def b58csum(s):
  13.     return hashlib.sha256(hashlib.sha256(s).digest()).digest()[0:4]
  14.    
  15. def b58decode(s, checksum=True):
  16.     idx = 0
  17.     while s[idx] == "1":
  18.         idx += 1
  19.        
  20.     n = 0
  21.     for c in s[idx:]:
  22.         n = n * 58 + b58ab.index(c)
  23.        
  24.     res = long2byte(n)
  25.     res = idx * "\x00" + res
  26.    
  27.     if checksum:
  28.         res, cs = res[:-4], res[-4:]
  29.         assert cs == b58csum(res), "base58 checksum failed"
  30.        
  31.     return res
  32.  
  33. def b58encode(s, checksum=True):
  34.     if checksum:
  35.         s += b58csum(s)
  36.        
  37.     idx = 0
  38.     while s[idx] == "\x00":
  39.         idx += 1
  40.        
  41.     n = byte2long(s)
  42.     res = ""
  43.     while n > 0:
  44.         res = b58ab[n % 58] + res
  45.         n /= 58
  46.        
  47.     return "1" * idx + res
  48.    
  49. def byte2long(s):
  50.     res = 0
  51.     for c in s:
  52.         res = (res << 8) | ord(c)
  53.     return res
  54.    
  55. def long2byte(n, sz=None):
  56.     res = ""
  57.     while n > 0:
  58.         res = chr(n & 0xff) + res
  59.         n >>= 8
  60.        
  61.     if sz is not None:
  62.         res = res.rjust(sz, "\x00")
  63.        
  64.     return res
  65.        
  66. def modinv(x, n):
  67.     return pow(x, n-2, n)
  68.  
  69. class Point(object):
  70.     def __init__(self, x, y, inf=False):
  71.         self.x = x
  72.         self.y = y
  73.         self.inf = inf
  74.        
  75. def curve_add(p, q, N):
  76.     if p.inf:
  77.         return q
  78.        
  79.     if q.inf:
  80.         return p
  81.    
  82.     if p.x == q.x:
  83.         if p.y == q.y:
  84.             d1 = (3 * p.x * p.x) % N
  85.             d2 = (2 * p.y) % N
  86.         else:
  87.             return Point(-1, -1, True)
  88.     else:
  89.         d1 = (q.y - p.y) % N
  90.         d2 = (q.x - p.x) % N
  91.  
  92.     d2i = modinv(d2, N)
  93.     d = (d1 * d2i) % N
  94.        
  95.     resx = (d * d - p.x - q.x) % N
  96.     resy = (d * (p.x - resx) - p.y) % N
  97.    
  98.     return Point(resx, resy)
  99.    
  100. def scalar_mul(scalar, p, N):
  101.     t = p
  102.     res = None
  103.     while scalar != 0:
  104.         if scalar & 1 == 1:
  105.             if res is None:
  106.                 res = t
  107.             else:
  108.                 res = curve_add(res, t, N)
  109.        
  110.         t = curve_add(t, t, N)
  111.        
  112.         scalar = scalar >> 1
  113.        
  114.     return res
  115.  
  116. def der_signature(r, s):
  117.     r = long2byte(r)
  118.     if ord(r[0]) >= 0x80:
  119.         r = "\x00" + r
  120.        
  121.     s = long2byte(s)
  122.     if ord(s[0]) >= 0x80:
  123.         s = "\x00" + s
  124.    
  125.     res = "\x02" + chr(len(r)) + r + "\x02" + chr(len(s)) + s
  126.     return "\x30" + chr(len(res)) + res
  127.    
  128. def signdata(privkey, data):
  129.     h = hashlib.sha256(hashlib.sha256(data).digest()).digest()
  130.     z = byte2long(h)
  131.     r, s = sign(privkey, z)
  132.     return der_signature(r, s)
  133.    
  134. def sign(privkey, z):
  135.     while True:
  136.         k = byte2long(os.urandom(256 / 8))
  137.         if k >= 1 and k < R:
  138.             break
  139.    
  140.     p = scalar_mul(k, Point(gx, gy), N)
  141.     r = p.x % R
  142.     assert r != 0
  143.    
  144.     ki = modinv(k, R)
  145.     s = (ki * (z + r * privkey)) % R
  146.     assert s != 0
  147.     if s > (R / 2):
  148.         s = R - s
  149.    
  150.     return r, s
  151.    
  152. def serializepubkey(p, compressed):
  153.     if compressed:
  154.         if p.y & 1 == 1:
  155.             return "\x03" + long2byte(p.x, 32)
  156.         else:
  157.             return "\x02" + long2byte(p.x, 32)
  158.     else:
  159.         return "\x04" + long2byte(p.x, 32) + long2byte(p.y, 32)
  160.  
  161. def pubkey2h160(p, compressed):
  162.     s = serializepubkey(p, compressed)
  163.     s = hashlib.sha256(s).digest()
  164.     h = hashlib.new("ripemd160")
  165.     h.update(s)
  166.     return h.digest()
  167.    
  168. def pubkey2addr(p, compressed):
  169.     s = pubkey2h160(p, compressed)
  170.     return b58encode("\x00" + s)
  171.    
  172. def wif2privkey(s):
  173.     s = b58decode(s)
  174.     assert s.startswith("\x80")
  175.    
  176.     if len(s) == 34 and s[-1] == "\x01":
  177.         return byte2long(s[1:33]), 1
  178.        
  179.     assert len(s) == 33
  180.     return byte2long(s[1:33]), 0
  181.    
  182. def recv_all(s, length):
  183.     ret = ""
  184.     while len(ret) < length:
  185.         temp = s.recv(length - len(ret))
  186.         if len(temp) == 0:
  187.             raise Exception("Connection reset!")
  188.         ret += temp
  189.        
  190.     return ret
  191.    
  192. class Client(object):
  193.     def __init__(self, address):
  194.         self.address = address
  195.        
  196.     def connect(self):
  197.         self.sc = socket.create_connection(self.address)
  198.         print "connected"
  199.        
  200.     def send(self, cmd, msg):
  201.         magic = struct.pack("<L", 0xf9bc0511)
  202.         wrapper = magic + cmd.ljust(12, "\x00") + struct.pack("<L", len(msg)) + hashlib.sha256(hashlib.sha256(msg).digest()).digest()[0:4] + msg
  203.         self.sc.sendall(wrapper)
  204.         print "sent", repr(cmd)
  205.        
  206.     def recv_msg(self):
  207.         header = recv_all(self.sc, 24)
  208.        
  209.         if len(header) != 24:
  210.             print "INVALID HEADER LENGTH", repr(head)
  211.             exit()
  212.  
  213.         cmd = header[4:16].rstrip("\x00")
  214.         payloadlen = struct.unpack("<I", header[16:20])[0]
  215.         payload = recv_all(self.sc, payloadlen)
  216.         return cmd, payload
  217.        
  218. def maketx(sourcetx, sourceidx, wifkey, targetaddr, numsatoshi, originalsatoshi, compressedtype):
  219.     sourceprivkey, compressed = wif2privkey(wifkey)
  220.     if compressedtype in (0, 1):
  221.         compressed = compressedtype
  222.        
  223.     sourcepubkey = scalar_mul(sourceprivkey, Point(gx, gy), N)
  224.     sourceh160 = pubkey2h160(sourcepubkey, compressed)
  225.     targeth160 = b58decode(targetaddr)[1:]
  226.  
  227.     s  = struct.pack("<I", 2)
  228.     s += chr(1)                             # one input
  229.     s += sourcetx.decode("hex")[::-1]       # source TX is in little endian order
  230.     s += struct.pack("<I", sourceidx)       # source ID too
  231.     s += "[[SCRIPT]]"                       # placeholder for script
  232.     s += "\xff\xff\xff\xff"                 # no locktime
  233.     s += chr(1)                             # one output
  234.     s += struct.pack("<Q", numsatoshi)      # hope you got this number correctly!
  235.     s += "\x19\x76\xa9\x14" + targeth160 + "\x88\xac" # standard P2PKH script
  236.     s += "\x00\x00\x00\x00"                 # no locktime
  237.    
  238.     to_sign = ""
  239.     to_sign += struct.pack("<I", 2)
  240.     to_sign += hashlib.sha256(hashlib.sha256(sourcetx.decode("hex")[::-1] + struct.pack("<I", sourceidx)).digest()).digest()
  241.     to_sign += hashlib.sha256(hashlib.sha256("\xff\xff\xff\xff" ).digest()).digest()
  242.     to_sign += sourcetx.decode("hex")[::-1] + struct.pack("<I", sourceidx)
  243.     to_sign += "\x19\x76\xa9\x14" + sourceh160 + "\x88\xac"
  244.     to_sign += struct.pack("<Q", originalsatoshi)
  245.     to_sign += "\xff\xff\xff\xff"
  246.     to_sign += hashlib.sha256(hashlib.sha256(struct.pack("<Q", numsatoshi) + "\x19\x76\xa9\x14" + targeth160 + "\x88\xac").digest()).digest()
  247.     to_sign += "\x00\x00\x00\x00"
  248.     to_sign += struct.pack("<I", 0x11)
  249.    
  250.     signature = signdata(sourceprivkey, to_sign) + "\x11"
  251.     serpubkey = serializepubkey(sourcepubkey, compressed)
  252.  
  253.     script = chr(len(signature)) + signature + chr(len(serpubkey)) + serpubkey
  254.     script = chr(len(script)) + script
  255.  
  256.     tx = s.replace("[[SCRIPT]]", script)
  257.  
  258.     return tx, pubkey2addr(sourcepubkey, compressed)
  259.  
  260. if len(sys.argv) != 8:
  261.     print "Usage: bcxtest.py <source TXID> <source index> <source WIF private key> <target address> <number of satoshis> <number of satoshis at source output> <compressed key type>"
  262.     print "example: bcxtest.py 4adc427d330497992710feaa32f85c389ef5106f74e7006878bd14b54500dfff 0 5K2YUVmWfxbmvsNxCsfvArXdGXm7d5DC9pn4yD75k2UaSYgkXTh 1aa5cmqmvQq8YQTEqcTmW7dfBNuFwgdCD 1853 3053 -1"
  263.     print "compressed key type - use if the 'from' address isn't what you expect it to be"
  264.     print "  -1    parse from WIF private key"
  265.     print "   0    force uncompressed"
  266.     print "   1    force compressed"
  267. else:
  268.     sourcetx = sys.argv[1]
  269.     sourceidx = int(sys.argv[2])
  270.     wifkey = sys.argv[3]
  271.     targetaddr = sys.argv[4]
  272.     numsatoshi = int(sys.argv[5])
  273.     originalsatoshi = int(sys.argv[6])
  274.     compressedtype = int(sys.argv[7])
  275.    
  276.     tx, sourceaddr = maketx(sourcetx, sourceidx, wifkey, targetaddr, numsatoshi, originalsatoshi, compressedtype)
  277.     print "YOU ARE ABOUT TO SEND %.8f BTC (equivalent to %.4f BCX) FROM %s TO %s!" % (numsatoshi / 100000000.0, numsatoshi / 10000.0, sourceaddr, targetaddr)
  278.     print "!!!EVERYTHING ELSE WILL BE EATEN UP AS FEES! CONTINUE AT YOUR OWN RISK!!!"
  279.     print "Write 'I understand' to continue"
  280.    
  281.     answer = raw_input()
  282.     assert answer == "I understand"
  283.    
  284.     txhash = hashlib.sha256(hashlib.sha256(tx).digest()).digest()[::-1]
  285.     print "generated transaction", txhash.encode("hex")
  286.    
  287.     client = Client(("192.169.227.48", 9003))
  288.     client.connect()
  289.    
  290.     versionno = 70015
  291.     services = 0
  292.     localaddr = "\x00" * 8 + "00000000000000000000FFFF".decode("hex") + "\x00" * 6
  293.     nonce = os.urandom(8)
  294.     user_agent = "Scraper"
  295.     msg = struct.pack("<IQQ", versionno, services, int(time.time())) + localaddr + localaddr + nonce + chr(len(user_agent)) + user_agent + struct.pack("<IB", 0, 0)
  296.     client.send("version", msg)
  297.  
  298.     while True:
  299.         cmd, payload = client.recv_msg()
  300.         if cmd == "version":
  301.             print repr(payload)
  302.             client.send("verack", "")
  303.            
  304.         elif cmd == "ping":
  305.             client.send("pong", payload)
  306.             client.send("inv", "\x01" + struct.pack("<I", 1) + txhash)
  307.            
  308.         elif cmd == "getdata":
  309.             if payload == "\x01\x01\x00\x00\x00" + txhash:
  310.                 print "sending txhash, if there is no error response everything probably went well"
  311.                 client.send("tx", tx)
  312.                
  313.         else:
  314.             print repr(cmd)
  315.             print repr(payload)
  316.             print
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement