SHARE
TWEET

pythonbitcoin

a guest Jun 14th, 2012 131 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # bitcoin.py
  2. #
  3. # I, the copyright holder of this work, hereby release it into the public
  4. # domain. This applies worldwide.
  5. #
  6. # If this is not legally possible:
  7. # I grant any entity the right to use this work for any purpose, without any
  8. # conditions, unless such conditions are required by law.
  9.  
  10. from tools import *
  11. from ecdsa import *
  12.  
  13. # Client version
  14. _cversion = 62000
  15. # Main network magic value. Included in all message headers.
  16. _magicvalue = '\xF9\xBE\xB4\xD9'
  17. # 32 zero bytes
  18. _zerohash = '\0' * 32
  19. # Input index for coinbase tx
  20. _noindex = 0xffffffff
  21. # 1 BTC
  22. _bc = float(100000000)
  23. # Total 21 million BTC
  24. _totalcoins = 2100000000000000
  25. # 50 BTC per block
  26. _startcoinbase = 5000000000
  27. # Coinbase value is halved each 210000 blocks (4 years)
  28. _coinbasechange = 210000
  29. # Highest possible target (bits 1d00ffff)
  30. _maxtarget = 0x00000000ffff0000000000000000000000000000000000000000000000000000
  31. # Target is changed every 2016 blocks
  32. _targetchange = 2016
  33. # 2 weeks timespan
  34. _targettimespan = _targetchange * 600
  35. # Min and max timespan for target change
  36. _mintimespan = _targettimespan / 4
  37. _maxtimespan = _targettimespan * 4
  38. # Last block key in Db
  39. _lastblock = '\0'
  40.  
  41. class _input:
  42.     """Tx.inputs"""
  43.     prevtx = _zerohash  # Hash of the referenced transaction
  44.     index = _noindex    # Index of the specific output in the transaction
  45.     sig = ''           # Signature script
  46.     sequence = _noindex # Transaction version as defined by sender
  47.  
  48. class _output:
  49.     """Tx.outputs"""
  50.     value =  0  # Transaction value
  51.     pubkey = '' # Public key script
  52.  
  53. class _tx:
  54.     """Bitcoin transaction"""
  55.     version = 1    # Transaction data format version
  56.     inputs = None  # List of sources for coins
  57.     outputs = None # List of destination for coins
  58.     locktime = 0   # Block number or timestamp at whith this tx locked
  59.     o = 0          # New offset (o + length of tx message)
  60.  
  61. def decodetx(p, o = 0):
  62.     """Decode tx message from bytecode. Return tx object"""
  63.     tx = _tx()
  64.     tx.version, o = getint(p, o, 4)
  65.     if tx.version != 1: raise err('tx.version', tx.version)
  66.     incount, o = getvarint(p, o)
  67.     tx.inputs = []
  68.     for i in xrange(incount):
  69.         txinput = _input()
  70.         txinput.prevtx, o = getbin(p, o, 32)
  71.         txinput.index, o = getint(p, o, 4)
  72.         txinput.sig, o = getvarstr(p, o)
  73.         txinput.sequence, o = getint(p, o, 4)
  74.         if txinput.sequence != _noindex:
  75.             raise err('txinput.sequence', i, txinput.sequence)
  76.         tx.inputs.append(txinput)
  77.     outcount, o = getvarint(p, o)
  78.     tx.outputs = []
  79.     for i in xrange(outcount):
  80.         txoutput = _output()
  81.         txoutput.value, o = getint(p, o, 8)
  82.         if txoutput.value < 1 or txoutput.value > _totalcoins:
  83.             raise err('txoutput.value', i, txoutput.value)
  84.         txoutput.pubkey, o = getvarstr(p, o)
  85.         tx.outputs.append(txoutput)
  86.     if not tx.inputs or not tx.outputs: raise err('empty tx')
  87.     tx.locktime, o = getint(p, o, 4)
  88.     if tx.locktime != 0 : raise err('tx.locktime', tx.locktime)
  89.     tx.o = o
  90.     return tx
  91.    
  92. def encodetx(tx):
  93.     """Encode tx object. Return bytecode"""
  94.     b = putint(tx.version, 4) + putvarint(len(tx.inputs))
  95.     for txinput in tx.inputs:
  96.         b += (putbin(txinput.prevtx, 32) + putint(txinput.index, 4)
  97.             + putvarstr(txinput.sig) + putint(txinput.sequence, 4))
  98.     b += putvarint(len(tx.outputs))
  99.     for txoutput in tx.outputs:
  100.         b += putint(txoutput.value, 8) + putvarstr(txoutput.pubkey)
  101.     b += putint(tx.locktime, 4)
  102.     return b
  103.  
  104. class _block:
  105.     """Bitcoin block"""
  106.     version = 1               # Block format version
  107.     prevblock = _zerohash     # Hash of the previous block
  108.     merkleroot = _zerohash    # Hash of transactions in block
  109.     timestamp = 0             # Unix timestamp
  110.     bits = '\xff\xff\x00\x1d' # Difficulty target
  111.     nonce = 0                 # Random nonce
  112.     tx = None                 # List of tx objects
  113.     txb = None                # List of tx in bytecode
  114.     o = 0                     # New offset (o + length of block message)
  115.  
  116. def decodeblock(p, o = 0):
  117.     """Decode block message from bytecode. Return block object"""
  118.     if len(p) < 80: raise err('len block header')
  119.     block = _block()
  120.     block.version, o = getint(p, o, 4)
  121.     if block.version != 1: raise ('block.version', block.version)
  122.     block.prevblock, o = getbin(p, o, 32)
  123.     block.merkleroot, o = getbin(p, o, 32)
  124.     block.timestamp, o = getint(p, o, 4)
  125.     block.bits, o = getbin(p, o, 4)
  126.     block.nonce, o = getint(p, o, 4)
  127.     if len(p) > 81:
  128.         block.tx = []
  129.         block.txb = []
  130.         count, o = getvarint(p, o)
  131.         for i in xrange(count):
  132.             tx = decodetx(p, o)
  133.             block.tx.append(tx)
  134.             block.txb.append(p[o:tx.o])
  135.             o = tx.o
  136.     block.o = o
  137.     return block
  138.  
  139. def encodeblock(block):
  140.     """Encode block object. Return bytecode"""
  141.     b = (putint(block.version, 4) + putbin(block.prevblock, 32)
  142.         + putbin(block.merkleroot, 32) + putint(block.timestamp, 4)
  143.         + putbin(block.bits, 4) + putint(block.nonce, 4))
  144.     if block.tx:
  145.         b += putvarint(len(block.tx))
  146.         for tx in block.tx:
  147.             b += encodetx(tx)
  148.     else:
  149.         b += putvarint(len(block.txb))
  150.         for txb in block.txb:
  151.             b += txb
  152.     return b
  153.  
  154. class _netaddr:
  155.     """Msg.addr"""
  156.     timestamp = 0
  157.     services, ip, port = 1, '10.2.2.2', 8333
  158.  
  159. class _netmsg:
  160.     """Network message"""
  161.     cmd = '' # Message type
  162.     p = ''   # Message bytecode without header
  163.     o = 0    # New offset (o + length of message)
  164.     # Cmd 'version' - exchanged when first connecting
  165.     version = _cversion
  166.     services = 1
  167.     timestamp = 0
  168.     recvservices, recvip, recvport = 1, '10.2.2.2', 8333
  169.     fromservices, fromip, fromport = 1, '10.3.3.3', 8333
  170.     nonce = '\0' * 8
  171.     useragent = ''
  172.     startheight = 0
  173.     # Cmd 'verask' - reply to version
  174.     # Cmd 'getaddr' - request for addr
  175.     # Cmd 'addr' - list of nodes
  176.     addr = None # List of netaddr objects
  177.     # Cmd 'inv' - list of new block or transactions
  178.     blocks = None # List of block hashes
  179.     txs = None    # List of tx hashes
  180.     # Cmd 'getdata' - request for block or tx, same as inv
  181.     # Cmd 'getheaders' - request for headers
  182.     hashes = None        # List of known block hashes
  183.     hashstop = _zerohash # Last block hash
  184.     # Cmd 'getblocks' - request for inv, same as getheaders
  185.     # Cmd 'tx' - see decodetx(), p contain tx bytecode
  186.     # Cmd 'block' - see decodeblock(), p contain block bytecode
  187.     # Cmd 'headers' - list of block headers
  188.     headers = None # List of block headers bytecode, see decodeblock()
  189.    
  190. def decodemsg(m, o = 0):
  191.     """Decode message from bytecode. Return msg object"""
  192.     # For incompleted messages, return None
  193.     # For incorrent checksum, msg.cmd contain '!', msg.o - new offset
  194.     msg = _netmsg()
  195.     while True:
  196.         if o >= len(m): return
  197.         magic, o = getbin(m, o, 4)
  198.         if magic == _magicvalue: break
  199.         o -= 3
  200.     msg.cmd, o = getbin(m, o, 12)
  201.     msg.cmd = msg.cmd.replace('\0', '')
  202.     length, o = getint(m, o, 4)
  203.     checksum, o = getbin(m, o, 4)
  204.     p, o = getbin(m, o, length)
  205.     msg.p = p
  206.     msg.o = o
  207.     if (len(p) != length): return
  208.     if dhash(p)[0:4] != checksum:
  209.         msg.cmd += '!'
  210.         return msg
  211.        
  212.     if msg.cmd == 'version':
  213.         msg.version, o = getint(p, 0, 4)
  214.         msg.services, o = getint(p, o, 8)
  215.         msg.timestamp, o = getint(p, o, 8)
  216.         msg.recvservices, o = getint(p, o, 8)
  217.         msg.recvip, msg.recvport, o = getip(p, o)
  218.         msg.fromservices, o = getint(p, o, 8)
  219.         msg.fromip, msg.fromport, o = getip(p, o)
  220.         msg.nonce, o = getbin(p, o, 8)
  221.         msg.useragent, o = getvarstr(p, o)
  222.         msg.startheight, o = getint(p, o, 4)
  223.     elif msg.cmd == 'addr':
  224.         count, o = getvarint(p, 0)
  225.         msg.addr = []
  226.         for i in xrange(count):
  227.             addr = _netaddr()
  228.             addr.timestamp, o = getint(p, o, 4)
  229.             addr.services, o = getint(p, o, 8)
  230.             addr.ip, addr.port, o = getip(p, o)
  231.             msg.addr.append(addr)
  232.     elif msg.cmd in ('inv', 'getdata'):
  233.         count, o = getvarint(p, 0)
  234.         msg.txs = []
  235.         msg.blocks = []
  236.         for i in xrange(count):
  237.             t, o = getint(p, o, 4)
  238.             h, o = getbin(p, o, 32)
  239.             if t == 1:
  240.                 msg.txs.append(h)
  241.             elif t == 2:
  242.                 msg.blocks.append(h)
  243.     elif msg.cmd in ('getblocks', 'getheaders'):
  244.         msg.version, o = getint(p, 0, 4)
  245.         count, o = getvarint(p, o)
  246.         msg.hashes = []
  247.         for i in xrange(count):
  248.             h, o = getbin(p, o, 32)
  249.             msg.hashes.append(h)
  250.         msg.hashstop, o = getbin(p, o, 32)
  251.     elif msg.cmd == 'headers':
  252.         count, o = getvarint(p, 0)
  253.         msg.headers = []
  254.         for i in xrange(count):
  255.             h, o = getbin(p, o, 81)
  256.             msg.headers.append(h[:80])
  257.     return msg
  258.  
  259. def encodemsg(cmd, msg = ''):
  260.     """Encode msg object or add header to bytecode"""
  261.     if type(msg) == str:
  262.         p = msg
  263.     elif msg.cmd == 'version':
  264.         if not msg.timestamp: msg.timestamp = itime()
  265.         p = (putint(msg.version, 4) + putint(msg.services, 8)
  266.             + putint(msg.timestamp, 8) + putint(msg.recvservices, 8)
  267.             + putip(msg.recvip, msg.recvport) + putint(msg.fromservices, 8)
  268.             + putip(msg.fromip, msg.fromport) + putbin(msg.nonce, 8)
  269.             + putvarstr(msg.useragent) + putint(msg.startheight, 4))
  270.     elif msg.cmd == 'addr':
  271.         p = putvarint(len(msg.addr))
  272.         for addr in msg.addr:
  273.             p += (putint(addr.timestamp, 4) + putint(addr.services, 8)
  274.                 + putip(addr.ip, addr.port))
  275.     elif msg.cmd in ('inv', 'getdata'):
  276.         p = putvarint(len(msg.txs) + len(msg.blocks))
  277.         for h in msg.txs:
  278.              p += putint(1, 4) + putbin(h, 32)
  279.         for h in msg.blocks:
  280.              p += putint(2, 4) + putbin(h, 32)
  281.     elif msg.cmd in ('getblocks', 'getheaders'):
  282.         p = putint(msg.version, 4) + putvarint(len(msg.hashes))
  283.         for h in msg.hashes:
  284.             p += putbin(h, 32)
  285.         p += putbin(msg.hashstop, 32)
  286.     elif msg.cmd == 'headers':
  287.         p = putvarint(len(msg.headers))
  288.         for header in msg.headers:
  289.             p += putbin(header, 81)
  290.     return _magicvalue + putbin(cmd, 12) + putint(len(p), 4) + dhash(p)[0:4] + p
  291.  
  292.  
  293.  
  294. Db = anydbm.open(...)
  295. Db[_lastblock] = _zerohash
  296.  
  297.  
  298.  
  299. def getcoinbase(blocknum):
  300.     """Return coinbase value for given blocknum"""
  301.     w = blocknum // _coinbasechange
  302.     a = _startcoinbase
  303.     for i in xrange(w): a //= 2
  304.     return a
  305.  
  306. def decodebits(b):
  307.     """Convert bits to target"""
  308.     i = leint(b[:3])
  309.     p = ord(b[3])
  310.     return i * 256 ** (p - 3)
  311.  
  312. def getdi(target):
  313.     """Return difficulty for given target"""
  314.     return float(_maxtarget) / target
  315.  
  316. def updatetarget(oldtarget, timespan):
  317.     """Calculate target for given timespan"""
  318.     if timespan < _mintimespan: timespan = _mintimespan
  319.     if timespan > _maxtimespan: timespan = _maxtimespan
  320.     target = oldtarget * timespan / _targettimespan
  321.     # Round value
  322.     p = 0
  323.     while target > 0x7fffff:
  324.         target //= 256
  325.         p += 1
  326.     target *= 256 ** p
  327.     if target > _maxtarget: target = _maxtarget
  328.     return target
  329.  
  330. def verifysig(stpub, txb, i):
  331.     """Verify sig pubkey script pair"""
  332.     txcopy = decodetx(txb)
  333.     stsig = txcopy.inputs[i].sig
  334.     if ord(stsig[0]) == len(stsig) - 1 and stsig[-1] == '\x01':
  335.         sig = stsig[1:-1]
  336.     elif stsig[ord(stsig[0]):ord(stsig[0]) + 2] == '\x01\x41':
  337.         sig = stsig[1:ord(stsig[0])]
  338.         pub = stsig[ord(stsig[0]) + 2:]
  339.     else: raise err('unknown sig format')
  340.     if ord(stpub[0]) == len(stpub) - 2 and stpub[-1] == '\xac':
  341.         pub = stpub[1:-1]
  342.     elif stpub[0:3] == '\x76\xa9\x14' and stpub[23:25] == '\x88\xac':
  343.         hashr = stpub[3:23]
  344.         if hashr != rhash(pub): return 'err rhash'
  345.     else: raise err('unknown pub format')
  346.     for k, cinput in enumerate(txcopy.inputs):
  347.         if i == k: cinput.sig = stpub
  348.         else: cinput.sig = ''
  349.     txcopyhash = dhash(encodetx(txcopy) + putint(1, 4))
  350.     verifydigest(pub, txcopyhash, sig)
  351.  
  352. def decodepub(stpub):
  353.     """Get rhash of pubkey from pubkey script"""
  354.     if ord(stpub[0]) == len(stpub) - 2 and stpub[-1] == '\xac':
  355.         pub = stpub[1:-1]
  356.         hashr = rhash(pub)
  357.     elif stpub[0:3] == '\x76\xa9\x14' and stpub[23:25] == '\x88\xac':
  358.         hashr = stpub[3:23]
  359.     else: raise err('unknown pub format')
  360.     return [hashr]
  361.  
  362. def readblocknum(h):
  363.     """Get block number by block hash"""
  364.     if h not in Db: return
  365.     return leint(Db[h][80:])
  366.  
  367. def readblockhash(n):
  368.     """Get block hash by block number"""
  369.     n = intle(n, 4)
  370.     if n not in Db: return
  371.     return Db[n][:32]
  372.  
  373. def readheader(h):
  374.     """Get block header bytecode by block hash or number"""
  375.     if type(h) == int: h = readblockhash(h)
  376.     if h is None or h not in Db: return
  377.     return Db[h][:80]
  378.  
  379. def readblocktx(n):
  380.     """Get list of tx hashes by block hash or number"""
  381.     if type(n) == str: n = readblocknum(n)
  382.     if n is None: return
  383.     n = intle(n, 4)
  384.     if n not in Db: return
  385.     l = Db[n]
  386.     txs = []
  387.     for i in xrange(32, len(l), 32): txs.append(l[i:i + 32])
  388.     return txs
  389.  
  390. def readtx(h):
  391.     """Get tx bytecode by tx hash"""
  392.     if h not in Db: return
  393.     return Db[h][6:]
  394.  
  395. def readtxblock(h):
  396.     """Get (blocknum, txnum) by tx hash"""
  397.     if h not in Db: return
  398.     return leint(Db[h][:4]), leint(Db[h][4:6])
  399.  
  400. def readblock(h):
  401.     """Get block bytecode by block hash or number"""
  402.     bb = readheader(h)
  403.     if bb is None: return
  404.     txs = readblocktx(h)
  405.     bb += putvarint(len(txs))
  406.     for txhash in txs: bb += readtx(txhash)
  407.     return bb
  408.  
  409. def readspend(prevtx, index):
  410.     """Get new tx hash by prev tx hash and output index"""
  411.     k = prevtx + intle(index, 2)
  412.     if k not in Db: return
  413.     return Db[k]
  414.  
  415. def readaddrtx(baddr):
  416.     """Get list of (blocknum, txnum) by rhash of pubkey"""
  417.     if baddr not in Db: return
  418.     l = Db[baddr]
  419.     txn = []
  420.     for i in xrange(0, len(l), 6):
  421.         txn.append((leint(l[i:i + 4]), leint(l[i + 4:i + 6])))
  422.     return txn
  423.  
  424. def readlasthash():
  425.     """Get hash of last block in blockchain"""
  426.     return Db[_lastblock]
  427.  
  428. def writedat(dat, lastblock):
  429.     """Write dat records to Db"""
  430.     Db[_lastblock] = lastblock
  431.     for k in dat:
  432.         if len(k) == 20 and k in Db: Db[k] += dat[k]
  433.         elif dat[k] is None: del Db[k]
  434.         else: Db[k] = dat[k]
  435.  
  436. def verifyblocktx(b, bb, blockhash, num, dat = None):
  437.     """Verify txs in block. Return dat records"""
  438.     if len(b.tx) < 1: raise err('empty block')
  439.     # Verify Merkle tree
  440.     if len(b.tx) == 1:
  441.         mroot = dhash(b.txb[0])
  442.         txh = [mroot]
  443.     else:
  444.         mtree = []
  445.         for tx in b.txb:
  446.             mtree.append(dhash(tx))
  447.         txh = mtree
  448.         while len(mtree) != 1:
  449.             if len(mtree) % 2: mtree.append(mtree[-1])
  450.             ntree = []
  451.             for i in xrange(1, len(mtree), 2):
  452.                 ntree.append(dhash(mtree[i - 1] + mtree[i]))
  453.             mtree = ntree
  454.         mroot = mtree[0]
  455.     if mroot != b.merkleroot: raise err('merkleroot')
  456.     # Records in dat will be added to Db
  457.     if dat is None: dat = {}
  458.     # Header record. block hash (32) : block header (80) block number (4)
  459.     dat[blockhash] = bb[:80] + intle(num, 4)
  460.     numrec = blockhash
  461.     for n, txb in enumerate(b.txb):
  462.         # Tx record. tx hash (32) : block number (4) tx number (2) tx bytecode
  463.         dat[txh[n]] = intle(num, 4) + intle(n, 2) + txb
  464.         numrec += txh[n]
  465.     # Num record. blocknumber (4) : block hash (32) list of tx hashes (32)
  466.     dat[intle(num, 4)] = numrec
  467.    
  468.     fee = 0
  469.     for n, tx in enumerate(b.tx):
  470.         txvalue = 0
  471.         addrlist = []
  472.         for i, txinput in enumerate(tx.inputs):
  473.             if not n: break
  474.             if txinput.prevtx == _zerohash: raise err('coinbase')
  475.             btx = readtx(txinput.prevtx)
  476.             if not btx and txinput.prevtx in dat: btx = dat[txinput.prevtx][6:]
  477.             if not btx: raise err('no prevtx')
  478.             ptx = decodetx(btx)
  479.             if txinput.index >= len(ptx.outputs): raise err('no index')
  480.             if readspend(txinput.prevtx, txinput.index):
  481.                 raise err('double spend')
  482.             verifysig(ptx.outputs[txinput.index].pubkey, b.txb[n], i)
  483.             # Spend record. prev tx hash (32) prev tx index (2) : new tx hash
  484.             dat[txinput.prevtx + intle(txinput.index, 2)] = txh[n]
  485.             addrlist += decodepub(ptx.outputs[txinput.index].pubkey)
  486.             txvalue += ptx.outputs[txinput.index].value
  487.         for txoutput in tx.outputs:
  488.             addrlist += decodepub(txoutput.pubkey)
  489.             if n: txvalue -= txoutput.value
  490.         if txvalue < 0: raise err('txvalue')
  491.         fee += txvalue
  492.         for baddr in addrlist:
  493.             if baddr not in dat: dat[baddr] = ''
  494.             # Addr record. hashr (20) : list of block number (4) tx number (2)
  495.             dat[baddr] += intle(num, 4) + intle(n, 2)
  496.        
  497.     coinbase = b.tx[0]
  498.     if (len(coinbase.inputs) != 1 or coinbase.inputs[0].prevtx != _zerohash
  499.         or coinbase.inputs[0].index != _noindex): raise err('no coinbase')
  500.     coinbasevalue = 0
  501.     for txoutput in coinbase.outputs: coinbasevalue += txoutput.value
  502.     if coinbasevalue != getcoinbase(num) + fee: raise err('bad coinbase')
  503.    
  504.     return dat
  505.  
  506. def acceptblock(bb):
  507.     """Verify block and add to blockchain"""
  508.     blockhash = dhash(bb[:80])
  509.     if readheader(blockhash): raise err('duplicate')
  510.     b = decodeblock(bb)
  511.     blocktarget = decodebits(b.bits)
  512.     # Hash of the block header must be lower than or equal to the target
  513.     if leint(blockhash) > blocktarget: raise err('blockhash')
  514.     lastblock = readlasthash()
  515.    
  516.     if b.prevblock == lastblock:
  517.         # Add to main branch
  518.         pass
  519.     else: raise err('prevblock')
  520.     if lastblock != _zerohash:
  521.         num = readblocknum(lastblock) + 1
  522.         # Last target change block
  523.         tbnum = (num - 1) // _targetchange * _targetchange
  524.         tb = decodeblock(readheader(tbnum))
  525.         # Current target
  526.         target = decodebits(tb.bits)
  527.         # Update target every 2016 block
  528.         if not num % _targetchange:
  529.             pb = decodeblock(readheader(num - 1))
  530.             target = updatetarget(target, pb.timestamp - tb.timestamp)
  531.     else:
  532.         num = 0
  533.         target = _maxtarget
  534.     # Bits must be equal to the current target
  535.     if blocktarget != target: raise err('bits')
  536.     dat = verifyblocktx(b, bb, blockhash, num)
  537.     """if branch not in Branches: Branches.append(branch)
  538.    if branch is not Mainbranch:
  539.        if branch.di > Mainbranch.di:
  540.            # A side branch becoming the main branch
  541.            del Branches[branchid]
  542.            p = b
  543.            # For blocks in new main branch
  544.            while _sidebranch + p.prevblock in Db:
  545.                del Db[_sidebranch + p.prevblock]
  546.                p = decodeblock(p.prevblock)
  547.            forkblock = p.prevblock
  548.            branchid = len(Branches)
  549.            phash = Mainbranch.lastblock
  550.            # For blocks in old main branch
  551.            while phash != forkblock:
  552.                Db[_sidebranch + phash] = branchid
  553.                p = decodeblock(phash)
  554.                phash = p.prevblock
  555.            Branches.append(Branches[0])
  556.            Branches[0] = branch
  557.        else:
  558.            Db[_sidebranch + blockhash] = branchid"""
  559.     writedat(dat, blockhash)
  560.  
  561. def docommand(c):
  562.     r = ''
  563.     c = c.split(' ')
  564.     if c[0] == 'blocks':
  565.         if len(c) < 3: count = 20
  566.         else: count = int(c[2])
  567.         if len(c) < 2: start = readblocknum(readlasthash()) - 19
  568.         else: start = int(c[1])
  569.         for num in xrange(start, start + count):
  570.             bh = readblockhash(num)
  571.             if not bh: break
  572.             b = decodeblock(readheader(bh))
  573.             r += str(num) + ' ' + stime(b.timestamp) + '\n' + tohexl(bh) + '\n'
  574.    
  575.     if c[0] == 'tx':
  576.         if len(c[1]) == 64:
  577.             txhash = unhexl(c[1])
  578.             blocknum, txnum = readtxblock(txhash)
  579.         else:
  580.             l = c[1].split('.')
  581.             blocknum = int(l[0])
  582.             txnum = int(l[1])
  583.             txs = readblocktx(blocknum)
  584.             txhash = txs[txnum]
  585.         tx = decodetx(readtx(txhash))
  586.         r += str(blocknum) + '.' + str(txnum) + ' ' + tohexl(txhash) + '\n'
  587.         txvalue = 0
  588.         if txnum:
  589.             r += 'From:\n'
  590.             for txinput in tx.inputs:
  591.                 ptx = decodetx(readtx(txinput.prevtx))
  592.                 pb, pt = readtxblock(txinput.prevtx)
  593.                 poutput = ptx.outputs[txinput.index]
  594.                 r += str(poutput.value / _bc) + ' '
  595.                 r += encodeaddr(decodepub(poutput.pubkey)[0]) + ' '
  596.                 r += str(pb) + '.' + str(pt) + '.' + str(txinput.index) + '\n'
  597.                 txvalue += poutput.value
  598.         r += 'To:\n'
  599.         for txoutput in tx.outputs:
  600.             r += str(txoutput.value / _bc) + ' '
  601.             r += encodeaddr(decodepub(txoutput.pubkey)[0]) + '\n'
  602.             txvalue -= txoutput.value
  603.         txvalue /= _bc
  604.         if not txnum: r += 'Generation: ' + str(- txvalue) + '\n'
  605.         elif txvalue: r += 'Fee: ' + str(txvalue) + '\n'
  606.    
  607.     if c[0] == 'block':
  608.         if len(c[1]) == 64:
  609.             bh = unhexl(c[1])
  610.             num = readblocknum(bh)
  611.         else:
  612.             num = int(c[1])
  613.             bh = readblockhash(num)
  614.         r += str(num) + ' ' + tohexl(bh) + '\n'
  615.         b = decodeblock(readheader(bh))
  616.         r += 'Prev block: ' + tohexl(b.prevblock) + '\n'
  617.         nextblock = readblockhash(num + 1)
  618.         if nextblock: r += 'Next block: ' + tohexl(nextblock) + '\n'
  619.         else: r += 'Last block\n'
  620.         r += 'Merkle root: ' + tohexl(b.merkleroot) + '\n'
  621.         r += 'Time: ' + stime(b.timestamp) + ' (' + str(b.timestamp) + ')\n'
  622.         r += 'Difficulty: ' + str(getdi(decodebits(b.bits)))
  623.         r += ' (Bits: ' + tohexl(b.bits) + ')\n'
  624.         r += 'Nonce: ' + str(b.nonce) + '\n'
  625.         txs = readblocktx(bh)
  626.         for txhash in txs: r += '\n' + docommand('tx ' + tohexl(txhash))
  627.    
  628.     if c[0] == 'addr':
  629.         hashr = decodeaddr(c[1])
  630.         txn = readaddrtx(hashr)
  631.         for blocknum, txnum in txn:
  632.             r += '\n' + docommand('tx ' + str(blocknum) + '.' + str(txnum))
  633.     return r
  634.  
  635.  
  636.  
  637.  
  638. def verifydigest(*a): pass
  639.  
  640. def ver():
  641.     count = 2000
  642.     count = -1
  643.     timestart = time()
  644.     try:
  645.         fb =  open('blockchain', 'r')
  646.         o = 0
  647.         bc = 1024 * 1024 * 10
  648.         bs = 1024 * 1024 * 12
  649.         buf = fb.read(bs)
  650.  
  651.         while True:
  652.             if o > bc:
  653.                 buf = buf[o:]
  654.                 o = 0
  655.                 buf += fb.read(bs)
  656.             if o >= len(buf): break
  657.             block = decodeblock(buf, o)
  658.             acceptblock(buf[o:block.o])
  659.             print readblocknum(readlasthash()), \
  660.                 stime(decodeblock(readheader(readlasthash())).timestamp), \
  661.                 len(readblocktx(readlasthash()))
  662.             o = block.o
  663.             count -= 1
  664.             if count == 0: break
  665.     finally:
  666.         timespan = time() - timestart
  667.         fb.close()
  668.         print '-' * 78
  669.         print 'Last block:'
  670.         print readblocknum(readlasthash()), \
  671.             stime(decodeblock(readheader(readlasthash())).timestamp)
  672.         print tohexl(readlasthash())
  673.         print timespan, 'sec'
  674.         print (readblocknum(readlasthash()) + 1) / timespan, 'block/sec'
  675.         print '-' * 80
  676.     from traceback import format_exc
  677.     while True:
  678.         c = raw_input()
  679.         try:
  680.             print docommand(c)
  681.         except:
  682.             print format_exc()
  683.    
  684.  
  685. def testsignmsg():
  686.     timestart = time()
  687.     for i in xrange(100):
  688.         print 'i', i
  689.         priv = genkey()
  690.         print 'priv', tohex(priv)
  691.         msg = repr(urandom(i * 8 + 15))
  692.         print 'msg', msg
  693.         sig = signmsg(priv, msg)
  694.         print 'sig', sig
  695.         pub = getpubkey(priv)
  696.         print 'pub', tohex(pub)
  697.         v = rhash(pub)
  698.         print 'v', tohex(v)
  699.         a = encodeaddr(v)
  700.         print 'a', a
  701.         r = decodeaddr(a)
  702.         print 'r', tohex(r)
  703.         if r != v: raise err('r != v')
  704.         verifymsg(r, msg, sig)
  705.         digest = dhash(msg)
  706.         print 'digest', tohex(digest)
  707.         s = signdigest(priv, digest)
  708.         print 's', tohex(s)
  709.         verifydigest(pub, digest, s)
  710.         for n in xrange(2):
  711.             for m in xrange(3):
  712.                 print 'n:m', str(n) + ':' + str(m)
  713.                 npriv = nprivkey(priv, str(n) + ':' + str(m), pub)
  714.                 print 'npriv', tohex(npriv)
  715.                 d = urandom(32)
  716.                 print 'd', tohex(d)
  717.                 g = signdigest(npriv, d)
  718.                 print 'g', tohex(g)
  719.                 npub = npubkey(pub, str(n) + ':' + str(m))
  720.                 print 'npub', tohex(npub)
  721.                 verifydigest(npub, d, g)
  722.                 vpub = getpubkey(npriv)
  723.                 print 'vpub', tohex(vpub)
  724.                 if vpub != npub: raise err('vpub != npub')
  725.     print time() - timestart, 'sec'
  726.  
  727. # ecdsa.py
  728. #
  729. # I, the copyright holder of this work, hereby release it into the public
  730. # domain. This applies worldwide.
  731. #
  732. # If this is not legally possible:
  733. # I grant any entity the right to use this work for any purpose, without any
  734. # conditions, unless such conditions are required by law.
  735.  
  736. from tools import *
  737.  
  738. _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
  739. _n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
  740. _b = 0x0000000000000000000000000000000000000000000000000000000000000007L
  741. _a = 0x0000000000000000000000000000000000000000000000000000000000000000L
  742. _gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
  743. _gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
  744.  
  745. def randkey():
  746.     while True:
  747.         r = beint(urandom(32)) + 1
  748.         if 1 <= r < _n: return r
  749.  
  750. def inversemod(a, m):
  751.     if a < 0 or m <= a: a = a % m
  752.     c, d = a, m
  753.     uc, vc, ud, vd = 1, 0, 0, 1
  754.     while c != 0:
  755.         q, c, d = divmod(d, c) + (c,)
  756.         uc, vc, ud, vd = ud - q * uc, vd - q * vc, uc, vc
  757.     if d != 1: raise err('d is not 1', a, m)
  758.     if ud > 0: return ud
  759.     else: return ud + m
  760.  
  761. def doublepoint(x, y):
  762.     if x is None: return None, None
  763.     l = ((3 * x * x + _a) * inversemod(2 * y, _p)) % _p
  764.     x3 = (l * l - 2 * x) % _p
  765.     y3 = (l * (x - x3) - y) % _p
  766.     return x3, y3
  767.  
  768. def addpoint(x1, y1, x2, y2):
  769.     if x2 is None: return x1, y1
  770.     if x1 is None: return x2, y2
  771.     if x1 == x2:
  772.         if (y1 + y2) % _p == 0:
  773.             return None, None
  774.         else:
  775.             return doublepoint(x1, y1)
  776.     l = ((y2 - y1) * inversemod(x2 - x1, _p)) % _p
  777.     x3 = (l * l - x1 - x2) % _p
  778.     y3 = (l * (x1 - x3) - y1) % _p
  779.     return x3, y3
  780.  
  781. def mulpoint(x, y, e):
  782.     e = e % _n
  783.     if e <= 0 or x is None: return None, None
  784.     e3 = 3 * e
  785.     i = 1
  786.     while i <= e3: i *= 2
  787.     i //= 2
  788.     x3, y3 = x, y
  789.     i //= 2
  790.     while i > 1:
  791.         x3, y3 = doublepoint(x3, y3)
  792.         if (e3 & i) != 0 and (e & i) == 0: x3, y3 = addpoint(x3, y3, x, y)
  793.         if (e3 & i) == 0 and (e & i) != 0: x3, y3 = addpoint(x3, y3, x, -y)
  794.         i //= 2
  795.     return x3, y3
  796.  
  797. def checkpubkey(x, y):
  798.     if (y * y - (x * x * x + _a * x + _b)) % _p != 0:
  799.         raise err('not on curve', x, y)
  800.     if mulpoint(x, y, _n) != (None, None):
  801.         raise err('mul to _n is not None', x, y)
  802.     return True
  803.  
  804. def sign(key, digest, nonce):
  805.     k = nonce % _n
  806.     r, y = mulpoint(_gx, _gy, k)
  807.     if r == 0: raise err('r is 0', key, digest, nonce)
  808.     s = (inversemod(k, _n) * (digest + (key * r) % _n)) % _n
  809.     if s == 0: return err('s is 0', key, digest, nonce)
  810.     return r, s
  811.  
  812. def verify(x, y, digest, r, s):
  813.     checkpubkey(x, y)
  814.     if r < 1 or r > _n - 1: raise err('incorrect r', r)
  815.     if s < 1 or s > _n - 1: raise err('incorrect s', s)
  816.     c = inversemod(s, _n)
  817.     u1 = (digest * c ) % _n
  818.     u2 = (r * c) % _n
  819.     x1, y1 = mulpoint(_gx, _gy, u1)
  820.     x2, y2 = mulpoint(x, y, u2)
  821.     x, y = addpoint(x1, y1, x2, y2)
  822.     v = x % _n
  823.     if v == r: return True
  824.     else: raise err('signature failed', x, y, digest, r, s)
  825.  
  826. def genkey():
  827.     """Generate random private key"""
  828.     return intbe(randkey(), 32)
  829.  
  830. def getpubkey(privkey):
  831.     """Return public key for given private key"""
  832.     if len(privkey) != 32: raise err('len privkey')
  833.     x, y = mulpoint(_gx, _gy, beint(privkey))
  834.     return '\x04' + intbe(x, 32) + intbe(y, 32)
  835.  
  836. def signdigest(privkey, digest):
  837.     """Sign digest (32 bytes). Return signature in DER format"""
  838.     if len(privkey) != 32 or len(digest) != 32: raise err('len privkey')
  839.     r, s = sign(beint(privkey), beint(digest), randkey())
  840.     r = intbe(r)
  841.     if ord(r[0]) > 0x7f: r = '\0' + r
  842.     sig = '\x02' + chr(len(r)) + r
  843.     s = intbe(s)
  844.     if ord(s[0]) > 0x7f: s = '\0' + s
  845.     sig += '\x02' + chr(len(s)) + s
  846.     sig = '\x30' + chr(len(sig)) + sig
  847.     return sig
  848.  
  849. def verifydigest(pubkey, digest, sig):
  850.     """Check signature (DER)"""
  851.     if len(pubkey) != 65 or pubkey[0] != '\x04': raise err('len pubkey')
  852.     x = beint(pubkey[1:33])
  853.     y = beint(pubkey[33:])
  854.     if len(digest) != 32: raise err('len digest')
  855.     if sig[0] != '\x30' or len(sig) != ord(sig[1]) + 2: raise err('len sig')
  856.     r = beint(sig[4:4 + ord(sig[3])])
  857.     s = beint(sig[6 + ord(sig[3]):])
  858.     return verify(x, y, beint(digest), r, s)
  859.  
  860. def nprivkey(mprivkey, n, mpubkey = None):
  861.     """Get private key from main private key with n sequence (n is str)"""
  862.     if len(mprivkey) != 32: raise err('len privkey')
  863.     if not mpubkey:
  864.         mpubkey = getpubkey(mprivkey)
  865.     h = beint(dhash(n + ':' + mpubkey[1:]))
  866.     return intbe((beint(mprivkey) + h) % _n, 32)
  867.  
  868. def npubkey(mpubkey, n):
  869.     """Get public key from main public key with n sequence (n is str)"""
  870.     if len(mpubkey) != 65 or mpubkey[0] != '\x04': raise err('len pubkey')
  871.     x1 = beint(mpubkey[1:33])
  872.     y1 = beint(mpubkey[33:])
  873.     h = beint(dhash(n + ':' + mpubkey[1:]))
  874.     x2, y2 = mulpoint(_gx, _gy, h)
  875.     x, y = addpoint(x1, y1, x2, y2)
  876.     return '\x04' + intbe(x, 32) + intbe(y, 32)
  877.  
  878. def rspubkey(digest, r, s, k):
  879.     x = r + (k / 2) * _n
  880.     a1 = (x * x * x + _a * x + _b) % _p
  881.     b1 = pow(a1, (_p + 1) / 4, _p)
  882.     if (b1 - k) % 2 == 0:
  883.         y = b1
  884.     else:
  885.         y = _p - b1
  886.     checkpubkey(x, y)
  887.     x1, y1 = mulpoint(x, y, s)
  888.     x2, y2 = mulpoint(_gx, _gy, -digest % _n)
  889.     x, y = addpoint(x1, y1, x2, y2)
  890.     x, y = mulpoint(x, y, inversemod(r, _n))
  891.     return x, y
  892.  
  893. def msgmagic(msg):
  894.     return "\x18Bitcoin Signed Message:\n" + intle(len(msg)) + msg
  895.  
  896. def verifymsg(hashr, msg, sig):
  897.     """Verify message using riperm160 of sha256 hash of public key"""
  898.     if len(hashr) != 20: raise err('len hashr')
  899.     if len(sig) > 65: sig = b64decode(sig)
  900.     if len(sig) == 65:
  901.         ka = [ord(sig[0]) - 27]
  902.         r = beint(sig[1:33])
  903.         s = beint(sig[33:])
  904.     elif len(sig) == 64:
  905.         ka = xrange(2)
  906.         r = beint(sig[:32])
  907.         s = beint(sig[32:])
  908.     else:
  909.         raise err('len sig')
  910.     digest = beint(dhash(msgmagic(msg)))
  911.     for k in ka:
  912.         x, y = rspubkey(digest, r, s, k)
  913.         if hashr == rhash('\x04' + intbe(x, 32) + intbe(y, 32)):
  914.             verify(x, y, digest, r, s)
  915.             return chr(k + 27)
  916.     raise err('verify hashr failed', hashr, msg, sig)
  917.  
  918. def signmsg(privkey, msg):
  919.     """Sign message. Return sig in Base64"""
  920.     if len(privkey) != 32: raise err('len privkey')
  921.     r, s = sign(beint(privkey), beint(dhash(msgmagic(msg))), randkey())
  922.     sig = intbe(r, 32) + intbe(s, 32)
  923.     c = verifymsg(rhash(getpubkey(privkey)), msg, sig)
  924.     return b64encode(c + sig)
  925.  
  926. # tools.py
  927. #
  928. # I, the copyright holder of this work, hereby release it into the public
  929. # domain. This applies worldwide.
  930. #
  931. # If this is not legally possible:
  932. # I grant any entity the right to use this work for any purpose, without any
  933. # conditions, unless such conditions are required by law.
  934.  
  935. from hashlib import sha256, new as hashnew
  936. from time import time, gmtime, strftime
  937. from binascii import b2a_hex as tohex, a2b_hex as unhex
  938. from base64 import b64encode, b64decode
  939. from os import urandom
  940.  
  941. err = RuntimeError
  942.  
  943. def itime():
  944.     """Return current timestamp as int"""
  945.     return int(time())
  946.  
  947. def stime(t):
  948.     """Convert timestamp to string UTC"""
  949.     return strftime('%d.%m.%Y %H:%M:%S', gmtime(t))
  950.  
  951. def intle(i, l = None):
  952.     """Convert int to little endian bytecode"""
  953.     b = ''
  954.     while i != 0:
  955.         b += chr(i % 256)
  956.         i //= 256
  957.     if l:
  958.         b += '\0' * (l - len(b))
  959.         if len(b) != l: raise err('integer overflow', i, l)
  960.     return b
  961.  
  962. def leint(b):
  963.     """Convert little endian bytecode to int"""
  964.     i = 0
  965.     p = 1
  966.     for c in b:
  967.         i += ord(c) * p
  968.         p *= 256
  969.     return i
  970.  
  971. def intbe(i, l = None):
  972.     """Convert int to big endian bytecode"""
  973.     b = ''
  974.     while i != 0:
  975.         b = chr(i % 256) + b
  976.         i //= 256
  977.     if l:
  978.         b = '\0' * (l - len(b)) + b
  979.         if len(b) != l: raise err('integer overflow', i, l)
  980.     return b
  981.  
  982. def beint(b):
  983.     """Convert big endian bytecode to int"""
  984.     i = 0
  985.     for c in b:
  986.         i = ord(c) + i * 256
  987.     return i
  988.  
  989. def tohexl(b):
  990.     """Convert little endian bytecode to hex"""
  991.     return tohex(b[::-1])
  992.  
  993. def unhexl(h):
  994.     """Convert hex to little endian bytecode"""
  995.     return unhex(h)[::-1]
  996.  
  997. def dhash(s):
  998.     """Double sha256"""
  999.     return sha256(sha256(s).digest()).digest()
  1000.  
  1001. def rhash(s):
  1002.     """Ripemd160 of sha256"""
  1003.     r = hashnew('ripemd160')
  1004.     r.update(sha256(s).digest())
  1005.     return r.digest()
  1006.  
  1007. b58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  1008.  
  1009. def encodeaddr(b, v = 0):
  1010.     """Encode Base64Check"""
  1011.     b = chr(v) + b
  1012.     b += dhash(b)[:4]
  1013.    
  1014.     i = beint(b)
  1015.     a = ''
  1016.     while i != 0:
  1017.         a = b58[i % 58] + a
  1018.         i //= 58
  1019.     z = 0
  1020.     for c in b:
  1021.         if c == '\0': z += 1
  1022.         else: break
  1023.    
  1024.     return b58[0] * z + a
  1025.  
  1026. def decodeaddr(a, v = 0):
  1027.     """Decode Base64Check"""
  1028.     i = 0
  1029.     for c in a:
  1030.         i = b58.find(c) + i * 58
  1031.     b = intbe(i)
  1032.     z = 0
  1033.     for c in a:
  1034.         if c == b58[0]: z += 1
  1035.         else: break
  1036.     b = '\0' * z + b
  1037.    
  1038.     if b[0] != chr(v): raise err('version', a, v)
  1039.     if dhash(b[:-4])[:4] != b[-4:]: raise err('checksum', a, v)
  1040.     return b[1:-4]
  1041.  
  1042. def putint(i, l):
  1043.     """Convert int to bytecode integer size l"""
  1044.     return intle(i, l)
  1045.  
  1046. def putvarint(i):
  1047.     """Convert int to bytecode variable length interger"""
  1048.     if i < 0xfd:
  1049.         l = 1
  1050.         f = ''
  1051.     elif i < 0xffff:
  1052.         l = 2
  1053.         f = '\xfd'
  1054.     elif i < 0xffffffff:
  1055.         l = 4
  1056.         f = '\xfe'
  1057.     else:
  1058.         l = 8
  1059.         f = '\xff'
  1060.     return f + intle(i, l)
  1061.  
  1062. def putvarstr(s):
  1063.     """Convert str to bytecode variable length string"""
  1064.     return putvarint(len(s)) + s
  1065.  
  1066. def putbin(s, l):
  1067.     """Convert str to bytecode fixed length string"""
  1068.     while len(s) < l: s += chr(0)
  1069.     if len(s) != l: raise err('string overflow', s, l)
  1070.     return s
  1071.  
  1072. def putip(ip, port):
  1073.     """Convert ip and port to bytecode"""
  1074.     b = '\0' * 10 + '\xFF\xFF'
  1075.     for n in ip.split('.'): b += chr(int(n))
  1076.     return b + chr(port // 256) + chr(port % 256)
  1077.  
  1078. def getint(s, o, l):
  1079.     """Read integer from bytecode offset o size l. Return (int, new_offset)"""
  1080.     return leint(s[o:o + l]), o + l
  1081.  
  1082. def getvarint(s, o):
  1083.     """Read variable length integer from bytecode. Return (int, new_offset)"""
  1084.     if s[o] == '\xfd': l = 2
  1085.     elif s[o] == '\xfe': l = 4
  1086.     elif s[o] == '\xff': l = 8
  1087.     else: l = 1
  1088.     if l > 1: o += 1
  1089.     return leint(s[o:o + l]), o + l
  1090.  
  1091. def getvarstr(s, o):
  1092.     """Read variable length string from bytecode. Return (int, new_offset)"""
  1093.     l, o = getvarint(s, o)
  1094.     return s[o:o + l], o + l
  1095.  
  1096. def getbin(s, o, l):
  1097.     """Read fixed length string from bytecode. Return (str, new_offset)"""
  1098.     return s[o:o + l], o + l
  1099.  
  1100. def getip(s, o):
  1101.     """Read ip and port from bytecode. Return (ip, port, new_offset)"""
  1102.     if s[o:o + 12] == '\0' * 10 + '\xFF\xFF':
  1103.         return (str(ord(s[o + 12])) + '.' + str(ord(s[o + 13])) + '.'
  1104.             + str(ord(s[o + 14])) + '.' + str(ord(s[o + 15])),
  1105.             ord(s[o + 16]) * 256 + ord(s[o + 17]), o + 18)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top