276 lines
6.4 KiB
Python
276 lines
6.4 KiB
Python
'''Various helper methods. It probably needs some cleanup.'''
|
|
|
|
import struct
|
|
import StringIO
|
|
import binascii
|
|
import settings
|
|
import bitcoin_rpc
|
|
from hashlib import sha256
|
|
|
|
def deser_string(f):
|
|
nit = struct.unpack("<B", f.read(1))[0]
|
|
if nit == 253:
|
|
nit = struct.unpack("<H", f.read(2))[0]
|
|
elif nit == 254:
|
|
nit = struct.unpack("<I", f.read(4))[0]
|
|
elif nit == 255:
|
|
nit = struct.unpack("<Q", f.read(8))[0]
|
|
return f.read(nit)
|
|
|
|
def ser_string(s):
|
|
if len(s) < 253:
|
|
return chr(len(s)) + s
|
|
elif len(s) < 0x10000:
|
|
return chr(253) + struct.pack("<H", len(s)) + s
|
|
elif len(s) < 0x100000000L:
|
|
return chr(254) + struct.pack("<I", len(s)) + s
|
|
return chr(255) + struct.pack("<Q", len(s)) + s
|
|
|
|
def deser_uint256(f):
|
|
r = 0L
|
|
for i in xrange(8):
|
|
t = struct.unpack("<I", f.read(4))[0]
|
|
r += t << (i * 32)
|
|
return r
|
|
|
|
def ser_uint256(u):
|
|
rs = ""
|
|
for i in xrange(8):
|
|
rs += struct.pack("<I", u & 0xFFFFFFFFL)
|
|
u >>= 32
|
|
return rs
|
|
|
|
def uint256_from_str(s):
|
|
r = 0L
|
|
t = struct.unpack("<IIIIIIII", s[:32])
|
|
for i in xrange(8):
|
|
r += t[i] << (i * 32)
|
|
return r
|
|
|
|
def uint256_from_str_be(s):
|
|
r = 0L
|
|
t = struct.unpack(">IIIIIIII", s[:32])
|
|
for i in xrange(8):
|
|
r += t[i] << (i * 32)
|
|
return r
|
|
|
|
def uint256_from_compact(c):
|
|
nbytes = (c >> 24) & 0xFF
|
|
v = (c & 0xFFFFFFL) << (8 * (nbytes - 3))
|
|
return v
|
|
|
|
def deser_vector(f, c):
|
|
nit = struct.unpack("<B", f.read(1))[0]
|
|
if nit == 253:
|
|
nit = struct.unpack("<H", f.read(2))[0]
|
|
elif nit == 254:
|
|
nit = struct.unpack("<I", f.read(4))[0]
|
|
elif nit == 255:
|
|
nit = struct.unpack("<Q", f.read(8))[0]
|
|
r = []
|
|
for i in xrange(nit):
|
|
t = c()
|
|
t.deserialize(f)
|
|
r.append(t)
|
|
return r
|
|
|
|
def ser_vector(l):
|
|
r = ""
|
|
if len(l) < 253:
|
|
r = chr(len(l))
|
|
elif len(l) < 0x10000:
|
|
r = chr(253) + struct.pack("<H", len(l))
|
|
elif len(l) < 0x100000000L:
|
|
r = chr(254) + struct.pack("<I", len(l))
|
|
else:
|
|
r = chr(255) + struct.pack("<Q", len(l))
|
|
for i in l:
|
|
r += i.serialize()
|
|
return r
|
|
|
|
def deser_uint256_vector(f):
|
|
nit = struct.unpack("<B", f.read(1))[0]
|
|
if nit == 253:
|
|
nit = struct.unpack("<H", f.read(2))[0]
|
|
elif nit == 254:
|
|
nit = struct.unpack("<I", f.read(4))[0]
|
|
elif nit == 255:
|
|
nit = struct.unpack("<Q", f.read(8))[0]
|
|
r = []
|
|
for i in xrange(nit):
|
|
t = deser_uint256(f)
|
|
r.append(t)
|
|
return r
|
|
|
|
def ser_uint256_vector(l):
|
|
r = ""
|
|
if len(l) < 253:
|
|
r = chr(len(l))
|
|
elif len(l) < 0x10000:
|
|
r = chr(253) + struct.pack("<H", len(l))
|
|
elif len(l) < 0x100000000L:
|
|
r = chr(254) + struct.pack("<I", len(l))
|
|
else:
|
|
r = chr(255) + struct.pack("<Q", len(l))
|
|
for i in l:
|
|
r += ser_uint256(i)
|
|
return r
|
|
|
|
__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
|
|
__b58base = len(__b58chars)
|
|
|
|
def b58decode(v, length):
|
|
""" decode v into a string of len bytes
|
|
"""
|
|
long_value = 0L
|
|
for (i, c) in enumerate(v[::-1]):
|
|
long_value += __b58chars.find(c) * (__b58base**i)
|
|
|
|
result = ''
|
|
while long_value >= 256:
|
|
div, mod = divmod(long_value, 256)
|
|
result = chr(mod) + result
|
|
long_value = div
|
|
result = chr(long_value) + result
|
|
|
|
nPad = 0
|
|
for c in v:
|
|
if c == __b58chars[0]: nPad += 1
|
|
else: break
|
|
|
|
result = chr(0)*nPad + result
|
|
if length is not None and len(result) != length:
|
|
return None
|
|
|
|
return result
|
|
|
|
def b58encode(value):
|
|
""" encode integer 'value' as a base58 string; returns string
|
|
"""
|
|
encoded = ''
|
|
while value >= __b58base:
|
|
div, mod = divmod(value, __b58base)
|
|
encoded = __b58chars[mod] + encoded # add to left
|
|
value = div
|
|
encoded = __b58chars[value] + encoded # most significant remainder
|
|
return encoded
|
|
|
|
def reverse_hash(h):
|
|
# This only revert byte order, nothing more
|
|
if len(h) != 64:
|
|
raise Exception('hash must have 64 hexa chars')
|
|
|
|
return ''.join([ h[56-i:64-i] for i in range(0, 64, 8) ])
|
|
|
|
def doublesha(b):
|
|
return sha256(sha256(b).digest()).digest()
|
|
|
|
def bits_to_target(bits):
|
|
return struct.unpack('<L', bits[:3] + b'\0')[0] * 2**(8*(int(bits[3], 16) - 3))
|
|
|
|
def address_to_pubkeyhash(addr):
|
|
try:
|
|
addr = b58decode(addr, 25)
|
|
except:
|
|
return None
|
|
|
|
if addr is None:
|
|
return None
|
|
|
|
ver = addr[0]
|
|
cksumA = addr[-4:]
|
|
cksumB = doublesha(addr[:-4])[:4]
|
|
|
|
if cksumA != cksumB:
|
|
return None
|
|
|
|
return (ver, addr[1:-4])
|
|
|
|
def ser_uint256_be(u):
|
|
'''ser_uint256 to big endian'''
|
|
rs = ""
|
|
for i in xrange(8):
|
|
rs += struct.pack(">I", u & 0xFFFFFFFFL)
|
|
u >>= 32
|
|
return rs
|
|
|
|
def deser_uint256_be(f):
|
|
r = 0L
|
|
for i in xrange(8):
|
|
t = struct.unpack(">I", f.read(4))[0]
|
|
r += t << (i * 32)
|
|
return r
|
|
|
|
def ser_number(n):
|
|
# For encoding nHeight into coinbase
|
|
s = bytearray(b'\1')
|
|
while n > 127:
|
|
s[0] += 1
|
|
s.append(n % 256)
|
|
n //= 256
|
|
s.append(n)
|
|
return bytes(s)
|
|
|
|
|
|
def isPrime( n )
|
|
if pow( 2, n-1, n ) == 1:
|
|
return True
|
|
return False
|
|
|
|
def riecoinPoW( hash_bin, diff, nNonce )
|
|
base = 1 << 8
|
|
for i in range(256)
|
|
base = base << 1
|
|
base = base | (hash_bin & 1)
|
|
hash_bin = hash_bin >> 1
|
|
trailingZeros = diff - 1 - 8 - 256
|
|
if trailingZeros < 16 or trailingZeros > 20000
|
|
return 0
|
|
base = base << trailingZeros
|
|
|
|
base += nNonce
|
|
primes = 0
|
|
|
|
if (base % 210) != 97:
|
|
return 0
|
|
|
|
if !isPrime( base ):
|
|
return primes
|
|
primes++
|
|
|
|
base += 4
|
|
if !isPrime( base ):
|
|
return primes
|
|
primes++
|
|
|
|
base += 2
|
|
if isPrime( base ):
|
|
primes++
|
|
|
|
base += 4
|
|
if !isPrime( base ):
|
|
primes++
|
|
|
|
base += 2
|
|
if !isPrime( base ):
|
|
primes++
|
|
|
|
base += 4
|
|
if !isPrime( base ):
|
|
primes++
|
|
|
|
return primes
|
|
|
|
#if settings.COINDAEMON_Reward == 'POW':
|
|
def script_to_address(addr):
|
|
d = address_to_pubkeyhash(addr)
|
|
if not d:
|
|
raise ValueError('invalid address')
|
|
(ver, pubkeyhash) = d
|
|
return b'\x76\xa9\x14' + pubkeyhash + b'\x88\xac'
|
|
#else:
|
|
def script_to_pubkey(key):
|
|
if len(key) == 66: key = binascii.unhexlify(key)
|
|
if len(key) != 33: raise Exception('Invalid Address')
|
|
return b'\x21' + key + b'\xac'
|