Esempio n. 1
0
class TxMessageSerializer(Serializer):
    def __init__(self):
        self.txencoder = TxSerializer()

    def serialize(self, txmsg):
        return self.txencoder.serialize(txmsg.tx)

    def deserialize(self, data, cursor=0):
        tx, cursor = self.txencoder.deserialize(data, cursor)
        return (TxMessage(tx), cursor)
Esempio n. 2
0
class TxMessageSerializer(Serializer):
    def __init__(self):    
        self.txencoder = TxSerializer()
     
    def serialize(self, txmsg):
        return (self.txencoder.serialize(txmsg.tx))

    def deserialize(self, data, cursor=0):
        tx, cursor = self.txencoder.deserialize(data, cursor)
        return (TxMessage(tx), cursor)
Esempio n. 3
0
def sign_transaction_input(tx,
                           input_index,
                           txout_script,
                           intput_script_type,
                           secret,
                           compressed_pubkey=True):
    # Set all txin to empty
    txin_scripts_save = [txin.script for txin in tx.in_list]
    for txin in tx.in_list:
        txin.script = Script([])
    # Set the current input script to the outpoint's script value
    tx.in_list[input_index].script = txout_script
    # Serialize and append hash type
    enctx = TxSerializer().serialize(tx) + b"\x01\x00\x00\x00"
    # Get hash and Sign
    txhash = doublesha256(enctx)
    key = KEY()
    key.set_secret(secret, compressed_pubkey)
    signature = key.sign(txhash) + "\x01"  # append hash_type SIGHASH_ALL
    # Restore Txin scripts
    for txin, script_save in zip(tx.in_list, txin_scripts_save):
        txin.script = script_save
    # Set the signed script
    if intput_script_type == TX_PUBKEYHASH:
        tx.in_list[input_index].script = make_script_pubkeyhash_sig(
            key.get_pubkey(), signature)
    if intput_script_type == TX_PUBKEY:
        tx.in_list[input_index].script = make_script_pubkey_sig(signature)
Esempio n. 4
0
class TxVerifier():
    def __init__(self, runmode):
        self.runmode = runmode
        self.tx_serializer = TxSerializer()
        self.script_serializer = ScriptSerializer()

    """
        basic_check: run tests that don't require any context.
    """

    def basic_checks(self, tx):
        self.check_size_limit(tx)
        self.check_vin_empty(tx)
        self.check_vout_empty(tx)
        self.check_money_range(tx)
        self.check_dupplicate_inputs(tx)
        self.check_coinbase_script_size(tx)
        self.check_null_inputs(tx)

    def check_size_limit(self, tx):
        if not tx.rawdata:
            tx.rawdata = self.tx_serializer.serialize(tx)
        if len(tx.rawdata) > MAX_BLOCK_SIZE:
            raise Exception("Transaction too large : %d bytes" %
                            (len(tx.rawdata)))

    def check_vin_empty(self, tx):
        if (not tx.in_list):
            raise Exception("vin empty")

    def check_vout_empty(self, tx):
        if (not tx.out_list):
            raise Exception("vout empty")

    def check_money_range(self, tx):
        for txout in tx.out_list:
            if not is_money_range(txout.value):
                raise Exception("txout not in money range")
        if not is_money_range(sum(txout.value for txout in tx.out_list)):
            raise Exception("txout total not in money range")

    def check_dupplicate_inputs(self, tx):
        inputs = set()
        for txin in tx.in_list:
            if txin.previous_output in inputs:
                raise Exception("dupplicate txin")
            inputs.add(txin.previous_output)

    def check_coinbase_script_size(self, tx):
        if tx.iscoinbase():
            bin_script = self.script_serializer.serialize(tx.in_list[0].script)
            if (len(bin_script) < 2 or len(bin_script) > 100):
                raise Exception("incorrect coinbase script size : %d" %
                                (len(bin_script)))

    def check_null_inputs(self, tx):
        if not tx.iscoinbase():
            for txin in tx.in_list:
                if (txin.previous_output.is_null()):
                    raise Exception("null prevout")
Esempio n. 5
0
class TxVerifier():
    def __init__(self, runmode):
        self.runmode = runmode
        self.tx_serializer = TxSerializer()
        self.script_serializer = ScriptSerializer()
    """
        basic_check: run tests that don't require any context.
    """
    def basic_checks(self, tx):
        self.check_size_limit(tx)
        self.check_vin_empty(tx)
        self.check_vout_empty(tx)
        self.check_money_range(tx)
        self.check_dupplicate_inputs(tx)
        self.check_coinbase_script_size(tx)
        self.check_null_inputs(tx)
    
    def check_size_limit(self, tx):
        if not tx.rawdata:
            tx.rawdata = self.tx_serializer.serialize(tx)
        if len(tx.rawdata) > MAX_BLOCK_SIZE:
            raise Exception("Transaction too large : %d bytes" % (len(tx.rawdata)))
    
    def check_vin_empty(self, tx):
        if (not tx.in_list):
            raise Exception("vin empty" )
        
    def check_vout_empty(self, tx):
        if (not tx.out_list):
            raise Exception("vout empty" )
                
    def check_money_range(self, tx):
        for txout in tx.out_list:
            if not is_money_range(txout.value):
                raise Exception("txout not in money range")
        if not is_money_range(sum(txout.value for txout in tx.out_list)):
            raise Exception("txout total not in money range")

    def check_dupplicate_inputs(self, tx):
        inputs = set()
        for txin in tx.in_list:
            if txin.previous_output in inputs:
                raise Exception("dupplicate txin")
            inputs.add(txin.previous_output)

    def check_coinbase_script_size(self, tx):
        if tx.iscoinbase():
            bin_script = self.script_serializer.serialize(tx.in_list[0].script)
            if (len(bin_script) < 2 or len(bin_script) > 100):
                raise Exception("incorrect coinbase script size : %d" % (len(bin_script)))
            
    def check_null_inputs(self, tx):
        if not tx.iscoinbase():
            for txin in tx.in_list:
                if (txin.previous_output.is_null()):
                    raise Exception("null prevout")
Esempio n. 6
0
 def _index_transactions(self, blockhash, block=None):
     block_handle = self.get_block_handle(blockhash)
     #Add all transactions to the indexdb
     if not block:
         block = block_handle.get_block()
     size_blockheader = BlockheaderSerializer().get_size(block.blockheader)
     size_tx_size = VarintSerializer().get_size(len(block.transactions))
     tx_serializer = TxSerializer()
     blockpos = block_handle.blockindex.blockpos
     txpos = block_handle.blockindex.blockpos + size_blockheader + size_tx_size 
     
     for i, tx in enumerate(block.transactions):
         txindex = DbTxIndex(1, DiskTxPos(1, blockpos, txpos), [DiskTxPos() for _ in range(tx.output_count())])
         self.indexdb.set_transactionindex(hash_tx(tx), txindex)
         #TODO: speed this up...
         if tx.rawdata:
             txpos += len(tx.rawdata)
         else:
             txpos += tx_serializer.get_size(tx)
Esempio n. 7
0
 def test_tx_deserialize(self):
     tx, _ = TxSerializer().deserialize(
         decodehexstr(
             "01000000010e0907321e9fcb500c20eb658667b40ac721870ddc2ce165ab53a47b68cbc517000000008b483045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c014104b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3effffffff02802385d1050000001976a9144d8b17fbce571614be89df4bd872de892a47984488ac00f2052a010000001976a914fadad27c40adbe230f5e3c04d44a29297508483188ac00000000"
         ))
     tx_expected = Tx(
         version=1,
         in_list=[
             TxIn(previous_output=Outpoint(hash=Uint256.from_hexstr(
                 "17c5cb687ba453ab65e12cdc0d8721c70ab4678665eb200c50cb9f1e3207090e"
             ),
                                           index=0),
                  script=Script([
                      Instruction(
                          72,
                          decodehexstr(
                              "3045022100ab2dc8932ca1d26f4cdac1feae09020a60ccc4d17b14e5fc5b21f3ab8c3a9cee022040a7208c172d19a19902280d66201c7fe2c3d8b2df7e23cc4e5b70fd52ecba2c01"
                          )),
                      Instruction(
                          65,
                          decodehexstr(
                              "04b77dd1f3a21cb3d067a7e76982a609d7310f8692f5d61346f3225323c425604a0c12862755335c49e392673106adfc5dfdee1e4d367f10353e8911fac687db3e"
                          ))
                  ]),
                  sequence=TxIn.NSEQUENCE_FINAL)
         ],
         out_list=[
             TxOut(value=24990000000,
                   script=Script([
                       Instruction(OP_DUP),
                       Instruction(OP_HASH160),
                       Instruction(
                           20,
                           decodehexstr(
                               "4d8b17fbce571614be89df4bd872de892a479844")),
                       Instruction(OP_EQUALVERIFY),
                       Instruction(OP_CHECKSIG)
                   ])),
             TxOut(value=5000000000,
                   script=Script([
                       Instruction(OP_DUP),
                       Instruction(OP_HASH160),
                       Instruction(
                           20,
                           decodehexstr(
                               "fadad27c40adbe230f5e3c04d44a292975084831")),
                       Instruction(OP_EQUALVERIFY),
                       Instruction(OP_CHECKSIG)
                   ]))
         ],
         locktime=0)
     self.assertEquals(tx, tx_expected)
Esempio n. 8
0
 def test_validate_pubkeyhash(self):
     # tx 5 of block 506 on testnet 3 (2 PUBKEYHASH inputs)
     # tx: e79d5732b9914a511c0ad002c930271aa843ae64ed0abf54bff2869596c04a59
     tx, _ = TxSerializer().deserialize(
         decodehexstr(
             "010000000202f630b1641c6988224295e4299c14d176fb4446d0f62a682efc6adbd049de77000000006b483045022100cb6600d5be418a84e3f5c7e7ece2836de358ccbdb26fc1a4e4c262c0db117cf2022058cceb2e810ed5c7c3a4d47c0fec4e09e2672490645767579893ce89c0c50087012102de4a86f3c045cfa9460dbe867ebedab96df36aa662800e2f1d8645374f0d10a4ffffffff3b7de9fe37b52af96fd4f7134df83c91358c40687430812f8e29841085363a87000000006a47304402205b26712719619a2d8510d888a2e2cd65ceba00b104f95d1bc46da04f71814a7d022046af82c57609914a855de48ea0036a09fdbccc7996c79406a6eef383242f994301210321b73cc97e906155d3c5bf65e5a2ee75f6792c97916f1c6ceda59777baa0dcc5ffffffff02b3c40e00000000001976a9146d9ad15ddc32b1f96d9f496a4a8a89a77ab88fa388ac87200f00000000001976a914431143b62421c12c1149f1252ae1e181547b0e5d88ac00000000"
         ))
     outscript1 = ScriptSerializer().deserialize(
         decodehexstr("76a9141b05d1cc4b3158519041814fdac587326422865b88ac"))
     outscript2 = ScriptSerializer().deserialize(
         decodehexstr("76a914b5d23a56ad5657163698a6817420f17b47cf3c4588ac"))
     vm = TxValidationVM()
     valid, reason = vm.validate(tx, 0, outscript1, tx.in_list[0].script)
     assert valid, reason
     vm = TxValidationVM()
     valid, reason = vm.validate(tx, 1, outscript2, tx.in_list[1].script)
     assert valid, reason
Esempio n. 9
0
    def test_validate_scripthash_multisig(self):
        # tx 1 of block 504 on testnet 3, 2 TX_SCRIPTHASH inputs, 2 PUBKEYHASH outputs
        # SCRIPTHASH of 1-of-2 and 2-of-3 multisig transactions
        # tx: 1915695f1de19d9a2e1fb1bd9c5e2f816022ec41a58e9f298396c8a4586a8c5e
        tx, _ = TxSerializer().deserialize(
            decodehexstr(
                "0100000002c142078d793bb5b4aadba6009e2b142872b1ed3a7f0f7336ebe0e38180d8d682010000009200483045022100d6868ef86978ffad889a312be2991cbfe2c2d27b40fed038dc65da83565f5b0f02205f7019af9b75a5e9ba9c394f6ce883fa72e8e0951cf2ca5011af5888026663f3014751210341d8a934cfca197c7acaa358a1c39b3317a3e6d80b808ad367278ddb6661d16f210220108eea941a69b20d320e9a82c4bc5f096edb7e7c74638810227594a8033c1d52aeffffffff3f2dc10288706fe1c3116bec01dc2a259bfc2802b60d9b13787195fa8205f0cf01000000b400473044022066952731f8c5663fd61b2cbc33361e79e27a8c0937c32b42cc2dd125215b98bb02202c90d8022337c868c1f00ab59a9cd833cad2522de4b703264e9b4e271d11cd12014c6951210220108eea941a69b20d320e9a82c4bc5f096edb7e7c74638810227594a8033c1d210386380591c6fe54fe67d54e809d38d2db63886c1d228beb744abc9327bee392882102c4c0101075ed2d413dd328841c87f7a39ff5a75d793decab1da9fb1128082c3b53aeffffffff02c11e1400000000001976a914724192ac202d067d06635dc043b84abdad14de0088ac2b540400000000001976a914342e5d1f2eb9c6e99fda90c85ca05aa36616644c88ac00000000"
            ))
        outscript1 = ScriptSerializer().deserialize(
            decodehexstr("a914d9f26cca817fa116dc76e1be7a17067eb843625087"))
        outscript2 = ScriptSerializer().deserialize(
            decodehexstr("a9145fc04212c7fb1103d99dd7ff454797a281ef92f587"))

        vm = TxValidationVM()
        valid, reason = vm.validate(tx, 0, outscript1, tx.in_list[0].script)
        assert valid, reason
        valid, reason = vm.validate(tx, 1, outscript2, tx.in_list[1].script)
        assert valid, reason
Esempio n. 10
0
class MerkleTxSerializer(Serializer):
    MERKLE_TX = Structure([
        TxSerializer(),
        Uint256Serializer(),
        VarsizelistSerializer(VarintSerializer(), Uint256Serializer()),
        Field("<I", "nindex")
    ], "tx")

    def get_size(self, tx):
        return (self.MERKLE_TX.get_size(
            [tx.tx, tx.blockhash, tx.merkle_branch, tx.nindex]))

    def serialize(self, tx):
        return (self.MERKLE_TX.serialize(
            [tx.tx, tx.blockhash, tx.merkle_branch, tx.nindex]))

    def deserialize(self, data, cursor=0):
        (tx, blockhash, merkle_branch,
         nindex), cursor = self.MERKLE_TX.deserialize(data, cursor)
        return (MerkleTx(tx, blockhash, merkle_branch, nindex), cursor)
Esempio n. 11
0
    def test_validate_pubkey(self):
        # tx 1 of block 383 on testnet 3 (2 PUBKEY inputs)
        # tx: 43cd28c3b56543298ee264e3c01ef2dd8189276bd0c1cf6b86269018c710ce28
        tx, _ = TxSerializer().deserialize(
            decodehexstr(
                "01000000028e3430573cfde2f3e1eece8aefe661dd841bcb665d35832415bab4f75267852200000000494830450221009cca8fb1c4a34982c4e9a59fd15856404c02085f926043cfc6664924a5b9e36d02205811f85b395c43492164b8b33867d745211d8c7ffdcd1b288e56f74dbdaed15b01ffffffffe3abf5981a1bd6457ec0cdcab76cc2a176dc0d7e16f6d3781aebc684f13cc4fd00000000484730440220387bbcee99e370ea2115eaccfd8c48eb380653303b66c6946e0903fb0bbc6f8602202b2ef048519d45525413f64b727a1d85ff2cf7d91ab4607308224b4c30d5846801ffffffff0240f1f23a000000001976a9142203ca59edf66969757e6cc9238b1b36f4dc35b888acc0f218190200000017a9149eb21980dc9d413d8eac27314938b9da920ee53e8700000000"
            ))
        outscript1 = ScriptSerializer().deserialize(
            decodehexstr(
                "2102547b223d58eb5da7c7690748f70a3bab1509cb7578faac9032399f0b6bce31d6ac"
            ))
        outscript2 = ScriptSerializer().deserialize(
            decodehexstr(
                "2103fcc9ce029ad74af9fecacce68bcc775cc6efcb000a0b8cc2b3aacad4850bc4b0ac"
            ))

        vm = TxValidationVM()
        valid, reason = vm.validate(tx, 0, outscript1, tx.in_list[0].script)
        assert valid, reason
        valid, reason = vm.validate(tx, 1, outscript2, tx.in_list[1].script)
        assert valid, reason
Esempio n. 12
0
 def __init__(self, runmode):
     self.runmode = runmode
     self.tx_serializer = TxSerializer()
     self.script_serializer = ScriptSerializer()
Esempio n. 13
0
 def __init__(self):    
     self.txencoder = TxSerializer()
Esempio n. 14
0
 def __init__(self):
     self.txencoder = TxSerializer()
Esempio n. 15
0
 def __init__(self, flags=0):
     self.BLOCK = Structure([
         BlockheaderSerializer(flags),
         VarsizelistSerializer(VarintSerializer("txn_count"),
                               TxSerializer())
     ], "block")
Esempio n. 16
0
 def __init__(self, runmode):
     self.runmode = runmode
     self.tx_serializer = TxSerializer()
     self.script_serializer = ScriptSerializer()
Esempio n. 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)
Esempio n. 18
0
from coinpy.tools.bitcoin.sha256 import doublesha256
from coinpy.lib.serialization.structures.s11n_tx import TxSerializer
from coinpy.model.protocol.structures.uint256 import Uint256

TX_SERIALIZE = TxSerializer()

def hash_tx(tx):
    if tx.hash:
        return tx.hash
    if not tx.rawdata:
        tx.rawdata = TX_SERIALIZE.serialize(tx)
    tx.hash = Uint256.from_bytestr(doublesha256(tx.rawdata))
    return tx.hash