def rebuild_template(self): """Rebuild a version 2 blockheader and serialize it. oldest satoshi client coinbase script contains: nBits, bnExtraNonce (nBits = GetNextWorkRequired(pindexPrev);) later timestamp was used instead of "bits" to ensure coinbase txn is unique even if address is the same (github:83f4cd156e9d52bd7c4351336dfa4806a43ee4e4=. now in version 2 blocks the height is included instead of the timestamp. """ coinbase_script = Script([push_bignum_instruction(self.block_height)] + [push_bignum_instruction(self.extra_nonce)] + [push_data_instruction(flag) for flag in self.coinbase_flags]) coinbase_txin = TxIn(Outpoint.null(), coinbase_script, sequence=TxIn.NSEQUENCE_FINAL) coinbase_tx = Tx(version=1, in_list=[coinbase_txin], out_list=self.coinbase_txout_list, locktime=0) self.block_transactions = [coinbase_tx] + self.transactions self.blockheader = BlockHeader(version=2, hash_prev=self.hash_prev, hash_merkle=compute_merkle_root(self.block_transactions), time=self.time, bits=self.bits, nonce=self.nonce) self.serialized = self.serializer.serialize(self.blockheader)
def rebuild_template(self): """Rebuild a version 2 blockheader and serialize it. oldest satoshi client coinbase script contains: nBits, bnExtraNonce (nBits = GetNextWorkRequired(pindexPrev);) later timestamp was used instead of "bits" to ensure coinbase txn is unique even if address is the same (github:83f4cd156e9d52bd7c4351336dfa4806a43ee4e4=. now in version 2 blocks the height is included instead of the timestamp. """ coinbase_script = Script( [push_bignum_instruction(self.block_height)] + [push_bignum_instruction(self.extra_nonce)] + [push_data_instruction(flag) for flag in self.coinbase_flags]) coinbase_txin = TxIn(Outpoint.null(), coinbase_script, sequence=TxIn.NSEQUENCE_FINAL) coinbase_tx = Tx(version=1, in_list=[coinbase_txin], out_list=self.coinbase_txout_list, locktime=0) self.block_transactions = [coinbase_tx] + self.transactions self.blockheader = BlockHeader(version=2, hash_prev=self.hash_prev, hash_merkle=compute_merkle_root( self.block_transactions), time=self.time, bits=self.bits, nonce=self.nonce) self.serialized = self.serializer.serialize(self.blockheader)
def get_script(self): return Script([ Instruction(OP_DUP), Instruction(OP_HASH160), push_data_instruction(data=self.pubkey_hash), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG) ])
def make_script_pubkeyhash(pubkey_hash): #Improve to take a BitcoinAddress? instructions = [Instruction(OP_DUP), Instruction(OP_HASH160), push_data_instruction(data=pubkey_hash), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG)] return Script(instructions)
def make_script_pubkeyhash(pubkey_hash): #Improve to take a BitcoinAddress? instructions = [ Instruction(OP_DUP), Instruction(OP_HASH160), push_data_instruction(data=pubkey_hash), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG) ] return Script(instructions)
def test_mine_genesis_block(self): """ Mine the unitnet GENESIS block """ time_source = MockTimeSource(time=1356446436) miner = BitcoinMiner() block, template = miner.mine_block(hash_prev=Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), block_height=0, time_source=time_source, difficulty_bits=524287999, transactions=[], coinbase_txout_list=[TxOut(5000000000, Script([push_data_instruction(decodehexstr("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")),Instruction(OP_CHECKSIG)]))], coinbase_flags=["/P2SH/", "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"]) self.assertEquals(block.blockheader.nonce, 1260) self.assertEquals(block.blockheader.hash_merkle, Uint256.from_hexstr("cf7ac9a3b387cf5e9fc14e03e2a5bbfc16d1ba00d2af6c96869ab4da949bd240")) self.assertEquals(hash_block(block), Uint256.from_hexstr("003ee3cf880906caa5662f10d4b4fb1c86c1853230dee8a7b8a62f434c73da5f"))
def parse_instruction(inst_str): serializer = InstructionSerializer() if re.match("^-?[0-9]+$", inst_str): i = int(inst_str) if (i == -1 or (1 <= i <= 16)): return serializer.serialize(Instruction(i + OP_1 - 1)) else: return serializer.serialize(push_bignum_instruction(i)) return serializer.serialize(push_bignum_instruction(i)) if re.match("^'[^']*'$", inst_str): return serializer.serialize(push_data_instruction(str(inst_str[1:-1]))) elif re.match("^0x[0-9A-Fa-f]+$", inst_str): return decodehexstr(inst_str[2:]) elif inst_str in OPCODES_BY_NAME: return serializer.serialize(Instruction(OPCODES_BY_NAME[inst_str])) elif ("OP_" + inst_str) in OPCODES_BY_NAME: return serializer.serialize(Instruction(OPCODES_BY_NAME["OP_" + inst_str])) raise Exception("Wrong format: '" + inst_str + "'")
def parse_instruction(inst_str): serializer = InstructionSerializer() if re.match("^-?[0-9]+$", inst_str): i = int(inst_str) if (i == -1 or (1 <= i <= 16)): return serializer.serialize(Instruction(i + OP_1 - 1)) else: return serializer.serialize(push_bignum_instruction(i)) return serializer.serialize(push_bignum_instruction(i)) if re.match("^'[^']*'$", inst_str): return serializer.serialize(push_data_instruction(str(inst_str[1:-1]))) elif re.match("^0x[0-9A-Fa-f]+$", inst_str): return decodehexstr(inst_str[2:]) elif inst_str in OPCODES_BY_NAME: return serializer.serialize(Instruction(OPCODES_BY_NAME[inst_str])) elif ("OP_" + inst_str) in OPCODES_BY_NAME: return serializer.serialize( Instruction(OPCODES_BY_NAME["OP_" + inst_str])) raise Exception("Wrong format: '" + inst_str + "'")
def test_mine_genesis_block(self): """ Mine the unitnet GENESIS block """ time_source = MockTimeSource(time=1356446436) miner = BitcoinMiner() block, template = miner.mine_block( hash_prev=Uint256.from_hexstr( "0000000000000000000000000000000000000000000000000000000000000000" ), block_height=0, time_source=time_source, difficulty_bits=524287999, transactions=[], coinbase_txout_list=[ TxOut( 5000000000, Script([ push_data_instruction( decodehexstr( "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f" )), Instruction(OP_CHECKSIG) ])) ], coinbase_flags=[ "/P2SH/", "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" ]) self.assertEquals(block.blockheader.nonce, 1260) self.assertEquals( block.blockheader.hash_merkle, Uint256.from_hexstr( "cf7ac9a3b387cf5e9fc14e03e2a5bbfc16d1ba00d2af6c96869ab4da949bd240" )) self.assertEquals( hash_block(block), Uint256.from_hexstr( "003ee3cf880906caa5662f10d4b4fb1c86c1853230dee8a7b8a62f434c73da5f" ))
def get_script(self): return Script([push_data_instruction(data=self.pubkey), Instruction(OP_CHECKSIG)])
def get_script(self): return Script( [push_smallint(self.m)] + [push_data_instruction(pubkey) for pubkey in self.public_keys] + [push_smallint(len(self.public_keys))] + [Instruction(OP_CHECKMULTISIG)])
def make_script_pubkeyhash_sig(pubkey, sig): return Script([push_data_instruction(data=sig), push_data_instruction(data=pubkey)])
def make_script_pubkey(pubkey): instructions = [push_data_instruction(data=pubkey), Instruction(OP_CHECKSIG)] return Script(instructions)
def make_script_pubkey_sig(sig): return Script([push_data_instruction(data=sig)])
def make_script_pubkey(pubkey): instructions = [ push_data_instruction(data=pubkey), Instruction(OP_CHECKSIG) ] return Script(instructions)
def get_script(self): return Script([push_smallint(self.m)] + [push_data_instruction(pubkey) for pubkey in self.public_keys] + [push_smallint(len(self.public_keys))] + [Instruction(OP_CHECKMULTISIG)])
def checksig(vm, sig_param, pubkey_param): transaction, inputindex, unspent_script = vm.checksig_data #Hash type is the last byte of the signature hash_type, sig = ord(sig_param[-1]), sig_param[:-1] # last 5 bits of hash_type : 1=SIGHASH_ALL,2=SIGHASH_NONE, 3=SIGHASH_SINGLE # SIGHASH_ANYONECANPAY = 0x80 # For performance reasons no full copy is made of the transaction # although it would be simpler to read. # e.g. tx_tmp = copy.deepcopy(transaction) # The input scripts are saved and then restored. tx_tmp = Tx(transaction.version, [ TxIn(txin.previous_output, txin.script, txin.sequence) for txin in transaction.in_list ], [TxOut(txout.value, txout.script) for txout in transaction.out_list], transaction.locktime) #Save input scripts to restore them later #inlist = transaction.in_list #outlist = transaction.out_list #inscripts = [txin.script for txin in transaction.in_list] #TODO: blank out ouputs depending of hash_type (SIGHASH_NONE, SIGHASH_SINGLE) if (hash_type & SIGHASH_MASK == SIGHASH_NONE): tx_tmp.out_list = [] if (hash_type & SIGHASH_MASK == SIGHASH_SINGLE): if (inputindex > len(tx_tmp.out_list)): raise Exception( "OP_CHECKSIG: no corresponding output for input %d using SIGHASH_SINGLE " % (inputindex)) #n-1 empty TxOuts + original Txout tx_tmp.out_list = [TxOut(-1, Script([])) for _ in range(inputindex)] + \ [tx_tmp.out_list[inputindex]] if (hash_type & SIGHASH_MASK == SIGHASH_SINGLE or hash_type & SIGHASH_MASK == SIGHASH_NONE): # let others update at will for i in range(len(tx_tmp.in_list)): if i != inputindex: tx_tmp.in_list[i].sequence = 0 #blank out other inputs in case of SIGHASH_ANYONECANPAY if (hash_type & SIGHASH_ANYONECANPAY): tx_tmp.in_list = [tx_tmp.in_list[inputindex]] inputindex = 0 #blank out input scripts for txin in tx_tmp.in_list: txin.script = Script([]) #except the current one that is replaced by the signed part (e.g. from the last OP_CODESEPARATOR) # of current_script with signature push_data removed # note: only 'optimal' push_data instructions with the same signature are removed current_script = Script( filter(lambda instr: instr != push_data_instruction(sig_param), vm.current_script.signed_part().instructions)) tx_tmp.in_list[inputindex].script = current_script #serialize and append hash type enctx = TxSerializer().serialize(tx_tmp) + chr(hash_type) + b"\x00\x00\x00" #print "enctx:", hexstr(enctx) #print "sig:", hexstr(sig) #print "pubkey:", hexstr(pubkey_param) #Get hash hash = doublesha256(enctx) #Verify key = KEY() key.set_pubkey(pubkey_param) #ECDSA_verify: 1 = OK, 0=NOK, -1=ERROR result = key.verify(hash, sig) == 1 if not result: pass #Restore transaction scripts #for txin, script in zip(inlist,inscripts): # txin.script = script #transaction.in_list = inlist return (result)
def get_script(self): return Script([Instruction(OP_DUP), Instruction(OP_HASH160), push_data_instruction(data=self.pubkey_hash), Instruction(OP_EQUALVERIFY), Instruction(OP_CHECKSIG)])
def get_script(self): return Script([ push_data_instruction(data=self.pubkey), Instruction(OP_CHECKSIG) ])
def make_script_pubkeyhash_sig(pubkey, sig): return Script( [push_data_instruction(data=sig), push_data_instruction(data=pubkey)])
def get_script(self): return Script([Instruction(OP_HASH160), push_data_instruction(data=self.hash), Instruction(OP_EQUAL)])
def checksig(vm, sig_param, pubkey_param): transaction, inputindex, unspent_script = vm.checksig_data #Hash type is the last byte of the signature hash_type, sig = ord(sig_param[-1]), sig_param[:-1] # last 5 bits of hash_type : 1=SIGHASH_ALL,2=SIGHASH_NONE, 3=SIGHASH_SINGLE # SIGHASH_ANYONECANPAY = 0x80 # For performance reasons no full copy is made of the transaction # although it would be simpler to read. # e.g. tx_tmp = copy.deepcopy(transaction) # The input scripts are saved and then restored. tx_tmp = Tx(transaction.version, [TxIn(txin.previous_output, txin.script, txin.sequence) for txin in transaction.in_list], [TxOut(txout.value, txout.script) for txout in transaction.out_list], transaction.locktime) #Save input scripts to restore them later #inlist = transaction.in_list #outlist = transaction.out_list #inscripts = [txin.script for txin in transaction.in_list] #TODO: blank out ouputs depending of hash_type (SIGHASH_NONE, SIGHASH_SINGLE) if (hash_type & SIGHASH_MASK == SIGHASH_NONE): tx_tmp.out_list = [] if (hash_type & SIGHASH_MASK == SIGHASH_SINGLE): if (inputindex > len(tx_tmp.out_list)): raise Exception("OP_CHECKSIG: no corresponding output for input %d using SIGHASH_SINGLE " % (inputindex)) #n-1 empty TxOuts + original Txout tx_tmp.out_list = [TxOut(-1, Script([])) for _ in range(inputindex)] + \ [tx_tmp.out_list[inputindex]] if (hash_type & SIGHASH_MASK == SIGHASH_SINGLE or hash_type & SIGHASH_MASK == SIGHASH_NONE): # let others update at will for i in range(len(tx_tmp.in_list)): if i != inputindex: tx_tmp.in_list[i].sequence = 0 #blank out other inputs in case of SIGHASH_ANYONECANPAY if (hash_type & SIGHASH_ANYONECANPAY): tx_tmp.in_list = [tx_tmp.in_list[inputindex]] inputindex = 0 #blank out input scripts for txin in tx_tmp.in_list: txin.script = Script([]) #except the current one that is replaced by the signed part (e.g. from the last OP_CODESEPARATOR) # of current_script with signature push_data removed # note: only 'optimal' push_data instructions with the same signature are removed current_script = Script(filter(lambda instr: instr!=push_data_instruction(sig_param), vm.current_script.signed_part().instructions)) tx_tmp.in_list[inputindex].script = current_script #serialize and append hash type enctx = TxSerializer().serialize(tx_tmp) + chr(hash_type) + b"\x00\x00\x00" #print "enctx:", hexstr(enctx) #print "sig:", hexstr(sig) #print "pubkey:", hexstr(pubkey_param) #Get hash hash = doublesha256(enctx) #Verify key = KEY() key.set_pubkey(pubkey_param) #ECDSA_verify: 1 = OK, 0=NOK, -1=ERROR result = key.verify(hash, sig) == 1 if not result: pass #Restore transaction scripts #for txin, script in zip(inlist,inscripts): # txin.script = script #transaction.in_list = inlist return (result)
def get_script(self): return Script([ Instruction(OP_HASH160), push_data_instruction(data=self.hash), Instruction(OP_EQUAL) ])
push_data_instruction from coinpy.lib.transactions.merkle_tree import compute_merkle_root from coinpy.lib.serialization.scripts.serialize import ScriptSerializer GENESIS_MAIN = Block( BlockHeader(1, Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), #hash_prev Uint256.from_hexstr("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), #merkle 1231006505, #time 486604799, #bits 2083236893), #nonce [Tx(1, #version [TxIn(Outpoint(Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), 4294967295), Script([push_bignum_instruction(486604799), #bits push_bignum_instruction(4), #extra_nonce push_data_instruction("The Times 03/Jan/2009 Chancellor on brink of second bailout for banks")]), #script 4294967295) ], #inlist [TxOut(5000000000, #value Script([push_data_instruction(decodehexstr("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")),Instruction(OP_CHECKSIG)]))], 0) #locktime ]) GENESIS_TESTNET = Block( BlockHeader(1, Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), #hash_prev Uint256.from_hexstr("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"), #merkle 1296688602, #time 487063544, #bits 384568319), #nonce [Tx(1, #version [TxIn(Outpoint(Uint256.from_hexstr("0000000000000000000000000000000000000000000000000000000000000000"), 4294967295),