Example #1
0
 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)
Example #2
0
 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)
Example #3
0
 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)
     ])
Example #4
0
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)
Example #5
0
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)
Example #6
0
 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 + "'")
Example #8
0
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 + "'")
Example #9
0
 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"
         ))
Example #10
0
 def get_script(self):
     return Script([push_data_instruction(data=self.pubkey),
                    Instruction(OP_CHECKSIG)])
Example #11
0
 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)])
Example #12
0
def make_script_pubkeyhash_sig(pubkey, sig):
    return Script([push_data_instruction(data=sig),
                   push_data_instruction(data=pubkey)])  
Example #13
0
def make_script_pubkey(pubkey):
    instructions = [push_data_instruction(data=pubkey),
                    Instruction(OP_CHECKSIG)]
    return Script(instructions)
Example #14
0
def make_script_pubkey_sig(sig):
    return Script([push_data_instruction(data=sig)])  
Example #15
0
def make_script_pubkey(pubkey):
    instructions = [
        push_data_instruction(data=pubkey),
        Instruction(OP_CHECKSIG)
    ]
    return Script(instructions)
Example #16
0
 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)])
Example #17
0
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)
Example #18
0
 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)])
Example #19
0
def make_script_pubkey_sig(sig):
    return Script([push_data_instruction(data=sig)])
Example #20
0
 def get_script(self):
     return Script([
         push_data_instruction(data=self.pubkey),
         Instruction(OP_CHECKSIG)
     ])
Example #21
0
def make_script_pubkeyhash_sig(pubkey, sig):
    return Script(
        [push_data_instruction(data=sig),
         push_data_instruction(data=pubkey)])
Example #22
0
 def get_script(self):
     return Script([Instruction(OP_HASH160),
                    push_data_instruction(data=self.hash),
                    Instruction(OP_EQUAL)])
Example #23
0
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)
Example #24
0
 def get_script(self):
     return Script([
         Instruction(OP_HASH160),
         push_data_instruction(data=self.hash),
         Instruction(OP_EQUAL)
     ])
Example #25
0
    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),