Exemple #1
0
    def create_and_sign_tx(self, node, in_count, out_count, in_size, out_size,
                           min_confirmations, spam):

        utx = self.create_utxos_value100000(node, in_count, in_size,
                                            min_confirmations)
        sum_values_sats = 0
        assert (len(utx.vout) == in_count)
        tx = CTransaction()
        for i in range(in_count):
            u = utx.vout[i]
            sum_values_sats = sum_values_sats + u.nValue
            tx.vin.append(
                CTxIn(
                    COutPoint(
                        uint256_from_str(hex_str_to_bytes(utx.hash)[::-1]), i),
                    b''))

            flags = bytes(
                bytearray(
                    [SIGHASH_NONE | SIGHASH_ANYONECANPAY | SIGHASH_FORKID]))
            adjust = len(
                bytes_to_hex_str(flags)) + 1  # plus one for one OP_HOP

            while True:
                scriptSig = CScript(
                    [bytes(bytearray([OP_NOP]) * (spam - adjust)) + flags])
                tx.vin[-1].scriptSig = scriptSig

                if len(scriptSig) > spam:
                    adjust = adjust + 1
                    continue
                elif len(scriptSig) < spam:
                    adjust = adjust - 1
                    continue

                break

        assert (len(tx.vin) == in_count)

        x = out_size // out_count
        x_rest = out_size % out_count

        check_size = 0

        for i in range(out_count):

            if i == out_count - 1:
                x = x_rest + x

            scriptPubKey = CScript([OP_NOP] * (x - 1) + [OP_TRUE])
            check_size = check_size + len(scriptPubKey)

            amount = sum_values_sats // (out_count - i)
            tx.vout.append(CTxOut(amount, scriptPubKey))
            sum_values_sats = sum_values_sats - amount

        assert (check_size == out_size)
        tx.rehash()
        return ToHex(tx)
Exemple #2
0
def create_transaction(node, coinbase, to_address, amount):
    from_txid = node.getblock(coinbase)['tx'][0]
    inputs = [{"txid": from_txid, "vout": 0}]
    outputs = {to_address: amount}
    rawtx = node.createrawtransaction(inputs, outputs)
    signresult = node.signrawtransaction(rawtx)
    tx = CTransaction()
    tx.deserialize(BytesIO(hex_str_to_bytes(signresult['hex'])))
    return tx
def cltv_validate(node, tx, height):
    """Modify the signature in vin 0 of the tx to pass CLTV
    Prepends <height> CLTV DROP in the scriptSig, and sets
    the locktime to height"""
    tx.vin[0].nSequence = 0
    tx.nLockTime = height

    # Need to re-sign, since nSequence and nLockTime changed
    signed_result = node.signrawtransaction(to_hex(tx))
    new_tx = CTransaction()
    new_tx.deserialize(BytesIO(hex_str_to_bytes(signed_result['hex'])))

    new_tx.vin[0].scriptSig = CScript([CScriptNum(height), OP_CHECKLOCKTIMEVERIFY, OP_DROP] +
                                  list(CScript(new_tx.vin[0].scriptSig)))
    return new_tx
    def decoderawtransaction_asm_sighashtype(self):
        """Test decoding scripts via RPC command "decoderawtransaction".

        This test is in with the "decodescript" tests because they are testing the same "asm" script decodes.
        """

        # this test case uses a random plain vanilla mainnet transaction with a single P2PKH input and output
        tx = '0100000001696a20784a2c70143f634e95227dbdfdf0ecd51647052e70854512235f5986ca010000008a47304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb014104d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536ffffffff0100e1f505000000001976a914eb6c6e0cdb2d256a32d97b8df1fc75d1920d9bca88ac00000000'
        rpc_result = self.nodes[0].decoderawtransaction(tx)
        assert_equal(
            '304402207174775824bec6c2700023309a168231ec80b82c6069282f5133e6f11cbb04460220570edc55c7c5da2ca687ebd0372d3546ebc3f810516a002350cac72dfe192dfb[ALL] 04d3f898e6487787910a690410b7a917ef198905c27fb9d3b0a42da12aceae0544fc7088d239d9a48f2828a15a09e84043001f27cc80d162cb95404e1210161536',
            rpc_result['vin'][0]['scriptSig']['asm'])

        # this test case uses a mainnet transaction that has a P2SH input and both P2PKH and P2SH outputs.
        # it's from James D'Angelo's awesome introductory videos about multisig: https://www.youtube.com/watch?v=zIbUSaZBJgU and https://www.youtube.com/watch?v=OSA1pwlaypc
        # verify that we have not altered scriptPubKey decoding.
        tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914dc863734a218bfe83ef770ee9d41a27f824a6e5688acee2a02000000000017a9142a5edea39971049a540474c6a99edf0aa4074c588700000000'
        rpc_result = self.nodes[0].decoderawtransaction(tx)
        assert_equal(
            '8e3730608c3b0bb5df54f09076e196bc292a8e39a78e73b44b6ba08c78f5cbb0',
            rpc_result['txid'])
        assert_equal(
            '0 3045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea[ALL] 3045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75[ALL] 5221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53ae',
            rpc_result['vin'][0]['scriptSig']['asm'])
        assert_equal(
            'OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG',
            rpc_result['vout'][0]['scriptPubKey']['asm'])
        assert_equal(
            'OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL',
            rpc_result['vout'][1]['scriptPubKey']['asm'])
        txSave = CTransaction()
        txSave.deserialize(BytesIO(hex_str_to_bytes(tx)))

        # make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type
        tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
        rpc_result = self.nodes[0].decoderawtransaction(tx)
        assert_equal('OP_RETURN 300602010002010001',
                     rpc_result['vout'][0]['scriptPubKey']['asm'])

        # verify that we have not altered scriptPubKey processing even of a specially crafted P2PKH pubkeyhash and P2SH redeem script hash that is made to pass the der signature checks
        tx = '01000000018d1f5635abd06e2c7e2ddf58dc85b3de111e4ad6e0ab51bb0dcf5e84126d927300000000fdfe0000483045022100ae3b4e589dfc9d48cb82d41008dc5fa6a86f94d5c54f9935531924602730ab8002202f88cf464414c4ed9fa11b773c5ee944f66e9b05cc1e51d97abc22ce098937ea01483045022100b44883be035600e9328a01b66c7d8439b74db64187e76b99a68f7893b701d5380220225bf286493e4c4adcf928c40f785422572eb232f84a0b83b0dea823c3a19c75014c695221020743d44be989540d27b1b4bbbcfd17721c337cb6bc9af20eb8a32520b393532f2102c0120a1dda9e51a938d39ddd9fe0ebc45ea97e1d27a7cbd671d5431416d3dd87210213820eb3d5f509d7438c9eeecb4157b2f595105e7cd564b3cdbb9ead3da41eed53aeffffffff02611e0000000000001976a914301102070101010101010102060101010101010188acee2a02000000000017a91430110207010101010101010206010101010101018700000000'
        rpc_result = self.nodes[0].decoderawtransaction(tx)
        assert_equal(
            'OP_DUP OP_HASH160 3011020701010101010101020601010101010101 OP_EQUALVERIFY OP_CHECKSIG',
            rpc_result['vout'][0]['scriptPubKey']['asm'])
        assert_equal(
            'OP_HASH160 3011020701010101010101020601010101010101 OP_EQUAL',
            rpc_result['vout'][1]['scriptPubKey']['asm'])

        # some more full transaction tests of varying specific scriptSigs. used instead of
        # tests in decodescript_script_sig because the decodescript RPC is specifically
        # for working on scriptPubKeys (argh!).
        push_signature = bytes_to_hex_str(
            txSave.vin[0].scriptSig)[2:(0x48 * 2 + 4)]
        signature = push_signature[2:]
        der_signature = signature[:-2]
        signature_sighash_decoded = der_signature + '[ALL]'
        signature_2 = der_signature + '82'
        push_signature_2 = '48' + signature_2
        signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'

        # 1) P2PK scriptSig
        txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature)
        rpc_result = self.nodes[0].decoderawtransaction(
            bytes_to_hex_str(txSave.serialize()))
        assert_equal(signature_sighash_decoded,
                     rpc_result['vin'][0]['scriptSig']['asm'])

        # make sure that the sighash decodes come out correctly for a more complex / lesser used case.
        txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature_2)
        rpc_result = self.nodes[0].decoderawtransaction(
            bytes_to_hex_str(txSave.serialize()))
        assert_equal(signature_2_sighash_decoded,
                     rpc_result['vin'][0]['scriptSig']['asm'])

        # 2) multisig scriptSig
        txSave.vin[0].scriptSig = hex_str_to_bytes('00' + push_signature +
                                                   push_signature_2)
        rpc_result = self.nodes[0].decoderawtransaction(
            bytes_to_hex_str(txSave.serialize()))
        assert_equal(
            '0 ' + signature_sighash_decoded + ' ' +
            signature_2_sighash_decoded,
            rpc_result['vin'][0]['scriptSig']['asm'])

        # 3) test a scriptSig that contains more than push operations.
        # in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
        txSave.vin[0].scriptSig = hex_str_to_bytes(
            '6a143011020701010101010101020601010101010101')
        rpc_result = self.nodes[0].decoderawtransaction(
            bytes_to_hex_str(txSave.serialize()))
        assert_equal('OP_RETURN 3011020701010101010101020601010101010101',
                     rpc_result['vin'][0]['scriptSig']['asm'])
Exemple #5
0
    def create_utxos_value100000(self, node, utxo_count, utxo_size,
                                 min_confirmations):

        utxos = []
        addr = node.getnewaddress()

        # create some confirmed UTXOs
        for i in range(utxo_count):
            txid = node.sendtoaddress(addr, self.utxo_test_bsvs)
            tx = FromHex(CTransaction(), node.getrawtransaction(txid))
            tx.rehash()
            utxos.append(tx)

        node.generate(1)

        # Convert those utxos to new UTXO's in one single transaction that anyone can spend
        tx = None
        fee = 0

        for _ in range(2):  # firs iteration is to calculate the fee
            tx = CTransaction()
            amount = self.utxo_test_sats
            check_size = 0
            for u in utxos:

                # Each UTXO will have two outputs, one for change and another one
                # amounting to roughly 10000 satoshis
                for i in range(len(u.vout)):
                    uu = u.vout[i]
                    if uu.nValue <= self.utxo_test_sats and uu.nValue > self.utxo_test_sats // 2:
                        tx.vin.append(
                            CTxIn(
                                COutPoint(
                                    uint256_from_str(
                                        hex_str_to_bytes(u.hash)[::-1]), i),
                                b''))
                        break

                adjust = 2
                scriptPubKey = CScript([OP_DROP] +
                                       ([OP_NOP] *
                                        ((utxo_size // utxo_count) - adjust)) +
                                       [OP_TRUE])

                if len(tx.vin) == utxo_count:
                    amount = amount - fee

                    while True:
                        scriptPubKey = CScript([OP_DROP] + ([OP_NOP] * (
                            (utxo_size // utxo_count) - adjust)) + [OP_TRUE])

                        if check_size + len(scriptPubKey) > utxo_size:
                            adjust = adjust + 1
                            continue
                        elif check_size + len(scriptPubKey) < utxo_size:
                            adjust = adjust - 1
                            continue
                        break

                check_size = check_size + len(scriptPubKey)
                tx.vout.append(CTxOut(amount, scriptPubKey))

            assert (len(tx.vout) == utxo_count)
            assert (check_size == utxo_size)

            # sign and send transaction
            txHex = node.signrawtransaction(ToHex(tx))['hex']
            tx = FromHex(CTransaction(), txHex)
            tx.rehash()
            tx_size = len(ToHex(tx))
            fee = int(self.blockmintxfee_sats * tx_size / 1000)

        node.sendrawtransaction(ToHex(tx))

        if min_confirmations > 0:
            node.generate(min_confirmations)

        return tx