Пример #1
0
def make_btc_block_merkle_tree(blk_txids):
    assert len(blk_txids) > 0

    digests = blk_txids
    while len(digests) > 1:
        # The famously broken Satoshi algorithm: if the # of digests at this
        # level is odd, double the last one.
        if len(digests) % 2:
            digests.append(digests[-1].msg)

        next_level = []
        for i in range(0, len(digests), 2):
            next_level.append(cat_sha256d(digests[i], digests[i + 1]))

        digests = next_level

    return digests[0]
Пример #2
0
def make_timestamp_from_block_tx(confirmed_tx, block, blockheight):

    commitment_tx = confirmed_tx.tx
    serialized_tx = commitment_tx.serialize(params={'include_witness': False})
    digest = confirmed_tx.tip_timestamp.msg

    try:
        i = serialized_tx.index(digest)
    except ValueError:
        assert False, "can't build a block_timestamp from my tx, this is not supposed to happen, exiting"

    prefix = serialized_tx[0:i]
    suffix = serialized_tx[i + len(digest):]

    digest_timestamp = Timestamp(digest)

    # Add the commitment ops necessary to go from the digest to the txid op
    prefix_stamp = digest_timestamp.ops.add(OpPrepend(prefix))
    txid_stamp = cat_sha256d(prefix_stamp, suffix)

    assert commitment_tx.GetTxid() == txid_stamp.msg

    # Create the txid list, with our commitment txid op in the appropriate
    # place
    block_txid_stamps = []
    for tx in block.vtx:
        if tx.GetTxid() != txid_stamp.msg:
            block_txid_stamps.append(Timestamp(tx.GetTxid()))
        else:
            block_txid_stamps.append(txid_stamp)

    # Build the merkle tree
    merkleroot_stamp = make_btc_block_merkle_tree(block_txid_stamps)
    assert merkleroot_stamp.msg == block.hashMerkleRoot

    if bitcoin.params.NAME.lower() == "testnet":
        attestation = BitcoinTestnetBlockHeaderAttestation(blockheight)
    else:
        attestation = BitcoinBlockHeaderAttestation(blockheight)
    merkleroot_stamp.attestations.add(attestation)

    return digest_timestamp