比特币创世块的Python脚本

来自技术流笔记
跳转至: 导航搜索

源代码可以从这里:https://github.com/lhartikk/GenesisH0

下面是转移过来的

  1 import hashlib, binascii, struct, array, os, time, sys, optparse
  2 import scrypt
  3 
  4 from construct import *
  5 
  6 
  7 def main():
  8   options = get_args()
  9 
 10   algorithm = get_algorithm(options)
 11 
 12   input_script  = create_input_script(options.timestamp)
 13   output_script = create_output_script(options.pubkey)
 14   # hash merkle root is the double sha256 hash of the transaction(s) 
 15   tx = create_transaction(input_script, output_script,options)
 16   hash_merkle_root = hashlib.sha256(hashlib.sha256(tx).digest()).digest()
 17   print_block_info(options, hash_merkle_root)
 18 
 19   block_header        = create_block_header(hash_merkle_root, options.time, options.bits, options.nonce)
 20   genesis_hash, nonce = generate_hash(block_header, algorithm, options.nonce, options.bits)
 21   announce_found_genesis(genesis_hash, nonce)
 22 
 23 
 24 def get_args():
 25   parser = optparse.OptionParser()
 26   parser.add_option("-t", "--time", dest="time", default=int(time.time()), 
 27                    type="int", help="the (unix) time when the genesisblock is created")
 28   parser.add_option("-z", "--timestamp", dest="timestamp", default="The Times 03/Jan/2009 Chancellor on brink of second bailout for banks",
 29                    type="string", help="the pszTimestamp found in the coinbase of the genesisblock")
 30   parser.add_option("-n", "--nonce", dest="nonce", default=0,
 31                    type="int", help="the first value of the nonce that will be incremented when searching the genesis hash")
 32   parser.add_option("-a", "--algorithm", dest="algorithm", default="SHA256",
 33                     help="the PoW algorithm: [SHA256|scrypt|X11|X13|X15]")
 34   parser.add_option("-p", "--pubkey", dest="pubkey", default="04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f",
 35                    type="string", help="the pubkey found in the output script")
 36   parser.add_option("-v", "--value", dest="value", default=5000000000,
 37                    type="int", help="the value in coins for the output, full value (exp. in bitcoin 5000000000 - To get other coins value: Block Value * 100000000)")
 38   parser.add_option("-b", "--bits", dest="bits",
 39                    type="int", help="the target in compact representation, associated to a difficulty of 1")
 40 
 41   (options, args) = parser.parse_args()
 42   if not options.bits:
 43     if options.algorithm == "scrypt" or options.algorithm == "X11" or options.algorithm == "X13" or options.algorithm == "X15":
 44       options.bits = 0x1e0ffff0
 45     else:
 46       options.bits = 0x1d00ffff
 47   return options
 48 
 49 def get_algorithm(options):
 50   supported_algorithms = ["SHA256", "scrypt", "X11", "X13", "X15"]
 51   if options.algorithm in supported_algorithms:
 52     return options.algorithm
 53   else:
 54     sys.exit("Error: Given algorithm must be one of: " + str(supported_algorithms))
 55 
 56 def create_input_script(psz_timestamp):
 57   psz_prefix = ""
 58   #use OP_PUSHDATA1 if required
 59   if len(psz_timestamp) > 76: psz_prefix = '4c'
 60 
 61   script_prefix = '04ffff001d0104' + psz_prefix + chr(len(psz_timestamp)).encode('hex')
 62   print (script_prefix + psz_timestamp.encode('hex'))
 63   return (script_prefix + psz_timestamp.encode('hex')).decode('hex')
 64 
 65 
 66 def create_output_script(pubkey):
 67   script_len = '41'
 68   OP_CHECKSIG = 'ac'
 69   return (script_len + pubkey + OP_CHECKSIG).decode('hex')
 70 
 71 
 72 def create_transaction(input_script, output_script,options):
 73   transaction = Struct("transaction",
 74     Bytes("version", 4),
 75     Byte("num_inputs"),
 76     StaticField("prev_output", 32),
 77     UBInt32('prev_out_idx'),
 78     Byte('input_script_len'),
 79     Bytes('input_script', len(input_script)),
 80     UBInt32('sequence'),
 81     Byte('num_outputs'),
 82     Bytes('out_value', 8),
 83     Byte('output_script_len'),
 84     Bytes('output_script',  0x43),
 85     UBInt32('locktime'))
 86 
 87   tx = transaction.parse('\x00'*(127 + len(input_script)))
 88   tx.version           = struct.pack('<I', 1)
 89   tx.num_inputs        = 1
 90   tx.prev_output       = struct.pack('<qqqq', 0,0,0,0)
 91   tx.prev_out_idx      = 0xFFFFFFFF
 92   tx.input_script_len  = len(input_script)
 93   tx.input_script      = input_script
 94   tx.sequence          = 0xFFFFFFFF
 95   tx.num_outputs       = 1
 96   tx.out_value         = struct.pack('<q' ,options.value)#0x000005f5e100)#012a05f200) #50 coins
 97   #tx.out_value         = struct.pack('<q' ,0x000000012a05f200) #50 coins
 98   tx.output_script_len = 0x43
 99   tx.output_script     = output_script
100   tx.locktime          = 0 
101   return transaction.build(tx)
102 
103 
104 def create_block_header(hash_merkle_root, time, bits, nonce):
105   block_header = Struct("block_header",
106     Bytes("version",4),
107     Bytes("hash_prev_block", 32),
108     Bytes("hash_merkle_root", 32),
109     Bytes("time", 4),
110     Bytes("bits", 4),
111     Bytes("nonce", 4))
112 
113   genesisblock = block_header.parse('\x00'*80)
114   genesisblock.version          = struct.pack('<I', 1)
115   genesisblock.hash_prev_block  = struct.pack('<qqqq', 0,0,0,0)
116   genesisblock.hash_merkle_root = hash_merkle_root
117   genesisblock.time             = struct.pack('<I', time)
118   genesisblock.bits             = struct.pack('<I', bits)
119   genesisblock.nonce            = struct.pack('<I', nonce)
120   return block_header.build(genesisblock)
121 
122 
123 # https://en.bitcoin.it/wiki/Block_hashing_algorithm
124 def generate_hash(data_block, algorithm, start_nonce, bits):
125   print 'Searching for genesis hash..'
126   nonce           = start_nonce
127   last_updated    = time.time()
128   # https://en.bitcoin.it/wiki/Difficulty
129   target = (bits & 0xffffff) * 2**(8*((bits >> 24) - 3))
130 
131   while True:
132     sha256_hash, header_hash = generate_hashes_from_block(data_block, algorithm)
133     last_updated             = calculate_hashrate(nonce, last_updated)
134     if is_genesis_hash(header_hash, target):
135       if algorithm == "X11" or algorithm == "X13" or algorithm == "X15":
136         return (header_hash, nonce)
137       return (sha256_hash, nonce)
138     else:
139      nonce      = nonce + 1
140      data_block = data_block[0:len(data_block) - 4] + struct.pack('<I', nonce)  
141 
142 
143 def generate_hashes_from_block(data_block, algorithm):
144   sha256_hash = hashlib.sha256(hashlib.sha256(data_block).digest()).digest()[::-1]
145   header_hash = ""
146   if algorithm == 'scrypt':
147     header_hash = scrypt.hash(data_block,data_block,1024,1,1,32)[::-1] 
148   elif algorithm == 'SHA256':
149     header_hash = sha256_hash
150   elif algorithm == 'X11':
151     try:
152       exec('import %s' % "xcoin_hash")
153     except ImportError:
154       sys.exit("Cannot run X11 algorithm: module xcoin_hash not found")
155     header_hash = xcoin_hash.getPoWHash(data_block)[::-1]
156   elif algorithm == 'X13':
157     try:
158       exec('import %s' % "x13_hash")
159     except ImportError:
160       sys.exit("Cannot run X13 algorithm: module x13_hash not found")
161     header_hash = x13_hash.getPoWHash(data_block)[::-1]
162   elif algorithm == 'X15':
163     try:
164       exec('import %s' % "x15_hash")
165     except ImportError:
166       sys.exit("Cannot run X15 algorithm: module x15_hash not found")
167     header_hash = x15_hash.getPoWHash(data_block)[::-1]
168   return sha256_hash, header_hash
169 
170 
171 def is_genesis_hash(header_hash, target):
172   return int(header_hash.encode('hex_codec'), 16) < target
173 
174 
175 def calculate_hashrate(nonce, last_updated):
176   if nonce % 1000000 == 999999:
177     now             = time.time()
178     hashrate        = round(1000000/(now - last_updated))
179     generation_time = round(pow(2, 32) / hashrate / 3600, 1)
180     sys.stdout.write("\r%s hash/s, estimate: %s h"%(str(hashrate), str(generation_time)))
181     sys.stdout.flush()
182     return now
183   else:
184     return last_updated
185 
186 
187 def print_block_info(options, hash_merkle_root):
188   print "algorithm: "    + (options.algorithm)
189   print "merkle hash: "  + hash_merkle_root[::-1].encode('hex_codec')
190   print "pszTimestamp: " + options.timestamp
191   print "pubkey: "       + options.pubkey
192   print "time: "         + str(options.time)
193   print "bits: "         + str(hex(options.bits))
194 
195 
196 def announce_found_genesis(genesis_hash, nonce):
197   print "genesis hash found!"
198   print "nonce: "        + str(nonce)
199   print "genesis hash: " + genesis_hash.encode('hex_codec')
200 
201 
202 # GOGOGO!
203 main()


Dependencies 这里是重点,Python的环境,对import是有版本要求的。

sudo pip install scrypt construct==2.5.2

To create geneses based on X11 algorithm you will also need to install the xcoin-hash module. For X13 you will need the x13_hash module and for X15 the x15_hash module. Examples

Create the original genesis hash found in Bitcoin

python genesis.py -z "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" -n 2083236893 -t 1231006505

Output:

algorithm: sha256
merkle hash: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
pszTimestamp: The Times 03/Jan/2009 Chancellor on brink of second bailout for banks
pubkey: 04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f
time: 1231006505
bits: 0x1d00ffff
Searching for genesis hash..
genesis hash found!
nonce: 2083236893
genesis hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

Create the regtest genesis hash found in Bitcoin

python genesis.py -z "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" -n 2 -t 1296688602 -b 0x207fffff

Create the original genesis hash found in Litecoin

python genesis.py -a scrypt -z "NY Times 05/Oct/2011 Steve Jobs, Apple’s Visionary, Dies at 56" -p "040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9" -t 1317972665 -n 2084524493

Create a unique genesis hash with custom pszTimestamp

python genesis.py -a scrypt -z "Time flies like an arrow. Fruit flies like a banana."

Create the original genesis hash found in DarkCoin. (requires xcoin-hash)

python genesis.py -a X11 -z "Wired 09/Jan/2014 The Grand Experiment Goes Live: Overstock.com Is Now Accepting Bitcoins" -t 1317972665 -p "040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9" -n 28917698 -t 1390095618 -v 5000000000

Create the original genesis hash found in HiroCoin (requires xcoin-hash).

python genesis.py -a X11 -z "JapanToday 13/Mar/2014 Ways eyed to make planes easier to find in ocean" -p "040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9" -n 1234746574 -t 1394723131 -v 40000000000

Options

Usage: genesis.py [options]

Options:
  -h, --help show this help message and exit
  -t TIME, --time=TIME  the (unix) time when the genesisblock is created
  -z TIMESTAMP, --timestamp=TIMESTAMP
     the pszTimestamp found in the coinbase of the genesisblock
  -n NONCE, --nonce=NONCE
     the first value of the nonce that will be incremented
     when searching the genesis hash
  -a ALGORITHM, --algorithm=ALGORITHM
     the PoW algorithm: [SHA256|scrypt|X11|X13|X15]
  -p PUBKEY, --pubkey=PUBKEY
     the pubkey found in the output script
  -v VALUE, --value=VALUE
     the value in coins for the output, full value (exp. in bitcoin 5000000000 - To get other coins value: Block Value * 100000000)
  -b BITS, --bits=BITS
     the target in compact representation, associated to a difficulty of 1