Ejemplo n.º 1
0
def get_preimage(tx, input_index, utxo_value, utxo_script, sighash_flag=None):
    if not sighash_flag:
        sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)

    txin = tx.inputs[input_index]
    hash_prevouts = hash_sequence = hash_outputs = bitcoinx.consts.ZERO

    sighash_not_single_none = sighash_flag.base not in (SigHash.SINGLE, SigHash.NONE)
    if not sighash_flag.anyone_can_pay:
        hash_prevouts = tx._hash_prevouts()
        if sighash_not_single_none:
            hash_sequence = tx._hash_sequence()
    if sighash_not_single_none:
        hash_outputs = tx._hash_outputs()
    elif (sighash_flag.base == SigHash.SINGLE and input_index < len(tx.outputs)):
        hash_outputs = double_sha256(tx.outputs[input_index].to_bytes())

    preimage = b''.join((
        pack_le_int32(tx.version),
        hash_prevouts,
        hash_sequence,
        txin.to_bytes_for_signature(utxo_value, utxo_script),
        hash_outputs,
        pack_le_uint32(tx.locktime),
        pack_le_uint32(sighash_flag),
    ))
    return preimage
Ejemplo n.º 2
0
 def to_bytes(self):
     return b''.join((
         pack_le_int32(self.version),
         pack_list(self.inputs, XTxInput.to_bytes),
         pack_list(self.outputs, XTxOutput.to_bytes),
         pack_le_uint32(self.locktime),
     ))
Ejemplo n.º 3
0
def random_header(prev_hash=None, height=-1, good_bits=None):
    good_bits = good_bits or some_good_bits
    raw_header = bytearray(urandom(80))
    raw_header[72:76] = pack_le_uint32(random.choice(good_bits))
    if prev_hash:
        raw_header[4:36] = prev_hash
    return Bitcoin.deserialized_header(bytes(raw_header), height)
Ejemplo n.º 4
0
def setup_compressed_headers(tmpdir, headers_file, ts_offset, network):
    with open(os.path.join(data_dir, headers_file), 'rb') as f:
        raw_data = f.read()

    all_times = array.array('I')
    all_bits = array.array('I')
    read = io.BytesIO(raw_data).read

    first_height, = unpack_le_uint32(read(4))
    header_count, = unpack_le_uint32(read(4))

    # Timestamps
    first_time, = unpack_le_uint32(read(4))
    all_times.append(first_time)
    for n in range(1, header_count):
        diff, = unpack_le_uint16(read(2))
        all_times.append(all_times[-1] + diff - ts_offset)
    # Bits
    while True:
        raw = read(4)
        if not raw:
            break
        bits, = unpack_le_uint32(raw)
        if bits < 2016 * 2:
            count = bits
            bits, = unpack_le_uint32(read(4))
            all_bits.extend(array.array('I', [bits]) * count)
        else:
            all_bits.append(bits)

    assert len(all_times) == header_count
    assert len(all_bits) == header_count

    raw_header = bytearray(80)
    raw_header[0] = 1

    checkpoint = CheckPoint(raw_header, first_height + header_count - 1, 0)
    headers = create_headers(tmpdir, checkpoint, network=network)

    for height, (bits, timestamp) in enumerate(zip(all_bits, all_times),
                                               start=first_height):
        raw_header[68:72] = pack_le_uint32(timestamp)
        raw_header[72:76] = pack_le_uint32(bits)
        headers.set_one(height, raw_header)

    return headers
Ejemplo n.º 5
0
def get_push_item(item_bytes):
    '''
    Returns script bytes to push item on the stack. ALL data is length prefixed.
    '''
    dlen = len(item_bytes)
    if dlen < Ops.OP_PUSHDATA1:
        return pack_byte(dlen) + item_bytes
    elif dlen <= 0xff:
        return pack_byte(Ops.OP_PUSHDATA1) + pack_byte(dlen) + item_bytes
    elif dlen <= 0xffff:
        return pack_byte(Ops.OP_PUSHDATA2) + pack_le_uint16(dlen) + item_bytes
    return pack_byte(Ops.OP_PUSHDATA4) + pack_le_uint32(dlen) + item_bytes
Ejemplo n.º 6
0
def test_mainnet_2016_headers(tmpdir):
    # Mainnet headers 0, 2015, 2016, 4031, 4032, ... 4249808
    headers = setup_headers(tmpdir, 'mainnet-headers-2016')

    chain = headers.chains()[0]
    for height in range(0, len(headers), 2016):
        header = headers.header_at_height(chain, height)
        assert headers.required_bits(chain, height, None) == header.bits
        assert headers.required_bits(chain, height + 1, None) == header.bits

    assert header.difficulty() == 860_221_984_436.2223

    bounded_bits = 403011440
    # Test // 4 is lower bound for the last one
    raw_header = bytearray(headers.raw_header_at_height(chain, height - 2016))
    timestamp = Bitcoin.header_timestamp(raw_header)
    # Add 8 weeks and a 14 seconds; the minimum to trigger it
    raw_header[68:72] = pack_le_uint32(timestamp + 4 * 2016 * 600 + 14)
    headers.set_one(height - 1, raw_header)
    assert headers.required_bits(chain, height, ) == bounded_bits
Ejemplo n.º 7
0
def ref_sighash(script_code, tx, input_index, hash_type):
    assert input_index < len(tx.inputs)

    # In case concatenating two scripts ends up with two codeseparators, or an
    # extra one at the end, this prevents all those possible incompatibilities.
    script_code = script_code.find_and_delete(Script() << OP_CODESEPARATOR)

    # Blank out other inputs' signatures
    empty_script = Script()
    for tx_in in tx.inputs:
        tx_in.script_sig = empty_script
    tx.inputs[input_index].script_sig = script_code

    # Blank out some of the outputs
    if (hash_type & 0x1f) == SigHash.NONE:
        # Wildcard payee
        tx.outputs.clear()
        # Let the others update at will:
        for n, tx_in in enumerate(tx.inputs):
            if n != input_index:
                tx_in.sequence = 0
    elif (hash_type & 0x1f) == SigHash.SINGLE:
        if input_index >= len(tx.outputs):
            return ONE
        tx_output = tx.outputs[input_index]
        tx.outputs = [TxOutput.null() for _ in range(input_index)]
        tx.outputs.append(tx_output)
        # Let the others update at will:
        for n, tx_in in enumerate(tx.inputs):
            if n != input_index:
                tx_in.sequence = 0

    # Blank out other inputs completely; not recommended for open transactions
    if hash_type & SigHash.ANYONE_CAN_PAY:
        tx.inputs = [tx.inputs[input_index]]

    preimage = tx.to_bytes() + pack_le_uint32(hash_type)

    return double_sha256(preimage)
Ejemplo n.º 8
0
    def test_connect(self, tmpdir):
        testnet_genesis_checkpoint = CheckPoint(BitcoinTestnet.genesis_header,
                                                0, 0)
        headers_obj = create_headers(tmpdir, testnet_genesis_checkpoint)

        header1 = bytes.fromhex(
            '0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa'
            '927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b672'
        )
        header2 = bytes.fromhex(
            '0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e'
            '3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d23534'
        )

        # Test cache-clearing
        headers_obj.max_cache_size = 1

        # Test they connect
        headers_obj.connect(header1)
        headers_obj.connect(header2)

        # Test re-adding is OK
        headers_obj.connect(header1)

        # Test bad bits raises
        bad_header = bytearray(header1)
        bad_header[72:76] = pack_le_uint32(472518933)
        with pytest.raises(IncorrectBits) as e:
            headers_obj.connect(bad_header)
        assert str(e.value).endswith('requires bits 0x486604799')

        # Test insufficient PoW raises
        bad_header = bytearray(header1)
        bad_header[0] = 2
        with pytest.raises(InsufficientPoW) as e:
            headers_obj.connect(bad_header)
        assert 'exceeds its target' in str(e.value)