Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
751self.hashMerkleRoot = header.hashMerkleRoot752self.nTime = header.nTime753self.nBits = header.nBits754self.nNonce = header.nNonce756def set_null(self):757self.nVersion = 4758self.hashPrevBlock = 0759self.hashMerkleRoot = 0760self.nTime = 0761self.nBits = 0762self.nNonce = 0764def deserialize(self, f):765self.nVersion = int.from_bytes(f.read(4), "little", signed=True)766self.hashPrevBlock = deser_uint256(f)767self.hashMerkleRoot = deser_uint256(f)768self.nTime = int.from_bytes(f.read(4), "little")769self.nBits = int.from_bytes(f.read(4), "little")770self.nNonce = int.from_bytes(f.read(4), "little")772def serialize(self):773return self._serialize_header()775def _serialize_header(self):776r = b""777r += self.nVersion.to_bytes(4, "little", signed=True)778r += ser_uint256(self.hashPrevBlock)779r += ser_uint256(self.hashMerkleRoot)780r += self.nTime.to_bytes(4, "little")781r += self.nBits.to_bytes(4, "little")782r += self.nNonce.to_bytes(4, "little")783return r785@property786def hash_hex(self):787"""Return block header hash as hex string."""788return hash256(self._serialize_header())[::-1].hex()790@property791def hash_int(self):792"""Return block header hash as integer."""793return uint256_from_str(hash256(self._serialize_header()))795def __repr__(self):796return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x)" \797% (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,798time.ctime(self.nTime), self.nBits, self.nNonce)800BLOCK_HEADER_SIZE = len(CBlockHeader().serialize())801assert_equal(BLOCK_HEADER_SIZE, 80)803class CBlock(CBlockHeader):804__slots__ = ("vtx",)806def __init__(self, header=None):807super().__init__(header)808self.vtx = []810def deserialize(self, f):811super().deserialize(f)812self.vtx = deser_vector(f, CTransaction)814def serialize(self, with_witness=True):815r = b""816r += super().serialize()817if with_witness:818r += ser_vector(self.vtx, "serialize_with_witness")819else:820r += ser_vector(self.vtx, "serialize_without_witness")821return r823# Calculate the merkle root given a vector of transaction hashes824@classmethod825def get_merkle_root(cls, hashes):826while len(hashes) > 1:827newhashes = []828for i in range(0, len(hashes), 2):829i2 = min(i+1, len(hashes)-1)830newhashes.append(hash256(hashes[i] + hashes[i2]))831hashes = newhashes832return uint256_from_str(hashes[0])834def calc_merkle_root(self):835hashes = []836for tx in self.vtx:837hashes.append(ser_uint256(tx.txid_int))838return self.get_merkle_root(hashes)840def calc_witness_merkle_root(self):841# For witness root purposes, the hash of the842# coinbase, with witness, is defined to be 0...0843hashes = [ser_uint256(0)]845for tx in self.vtx[1:]:846# Calculate the hashes with witness data847hashes.append(ser_uint256(tx.wtxid_int))849return self.get_merkle_root(hashes)851def is_valid(self):852target = uint256_from_compact(self.nBits)853if self.hash_int > target:854return False855for tx in self.vtx:856if not tx.is_valid():857return False858if self.calc_merkle_root() != self.hashMerkleRoot:859return False860return True862def solve(self):863target = uint256_from_compact(self.nBits)864while self.hash_int > target:865self.nNonce += 1867# Calculate the block weight using witness and non-witness868# serialization size (does NOT use sigops).869def get_weight(self):870with_witness_size = len(self.serialize(with_witness=True))871without_witness_size = len(self.serialize(with_witness=False))872return (WITNESS_SCALE_FACTOR - 1) * without_witness_size + with_witness_size874def __repr__(self):875return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \876% (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,877time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))880class PrefilledTransaction:881__slots__ = ("index", "tx")883def __init__(self, index=0, tx = None):884self.index = index885self.tx = tx887def deserialize(self, f):888self.index = deser_compact_size(f)889self.tx = CTransaction()890self.tx.deserialize(f)892def serialize(self, with_witness=True):893r = b""894r += ser_compact_size(self.index)895if with_witness:896r += self.tx.serialize_with_witness()897else:898r += self.tx.serialize_without_witness()899return r901def serialize_without_witness(self):902return self.serialize(with_witness=False)904def serialize_with_witness(self):905return self.serialize(with_witness=True)907def __repr__(self):908return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx))911# This is what we send on the wire, in a cmpctblock message.912class P2PHeaderAndShortIDs:913__slots__ = ("header", "nonce", "prefilled_txn", "prefilled_txn_length",914"shortids", "shortids_length")916def __init__(self):917self.header = CBlockHeader()918self.nonce = 0919self.shortids_length = 0920self.shortids = []921self.prefilled_txn_length = 0922self.prefilled_txn = []924def deserialize(self, f):925self.header.deserialize(f)926self.nonce = int.from_bytes(f.read(8), "little")927self.shortids_length = deser_compact_size(f)928for _ in range(self.shortids_length):929# shortids are defined to be 6 bytes in the spec, so append930# two zero bytes and read it in as an 8-byte number931self.shortids.append(int.from_bytes(f.read(6) + b'\x00\x00', "little"))932self.prefilled_txn = deser_vector(f, PrefilledTransaction)933self.prefilled_txn_length = len(self.prefilled_txn)935# When using version 2 compact blocks, we must serialize with_witness.936def serialize(self, with_witness=False):937r = b""938r += self.header.serialize()939r += self.nonce.to_bytes(8, "little")940r += ser_compact_size(self.shortids_length)941for x in self.shortids:942# We only want the first 6 bytes943r += x.to_bytes(8, "little")[0:6]944if with_witness:945r += ser_vector(self.prefilled_txn, "serialize_with_witness")946else:947r += ser_vector(self.prefilled_txn, "serialize_without_witness")948return r950def __repr__(self):951return "P2PHeaderAndShortIDs(header=%s, nonce=%d, shortids_length=%d, shortids=%s, prefilled_txn_length=%d, prefilledtxn=%s" % (repr(self.header), self.nonce, self.shortids_length, repr(self.shortids), self.prefilled_txn_length, repr(self.prefilled_txn))954# P2P version of the above that will use witness serialization (for compact955# block version 2)956class P2PHeaderAndShortWitnessIDs(P2PHeaderAndShortIDs):957__slots__ = ()958def serialize(self):959return super().serialize(with_witness=True)961# Calculate the BIP 152-compact blocks shortid for a given transaction hash962def calculate_shortid(k0, k1, tx_hash):963expected_shortid = siphash256(k0, k1, tx_hash)964expected_shortid &= 0x0000ffffffffffff965return expected_shortid968# This version gets rid of the array lengths, and reinterprets the differential969# encoding into indices that can be used for lookup.970class HeaderAndShortIDs:971__slots__ = ("header", "nonce", "prefilled_txn", "shortids", "use_witness")973def __init__(self, p2pheaders_and_shortids = None):974self.header = CBlockHeader()975self.nonce = 0976self.shortids = []977self.prefilled_txn = []978self.use_witness = False980if p2pheaders_and_shortids is not None:981self.header = p2pheaders_and_shortids.header982self.nonce = p2pheaders_and_shortids.nonce983self.shortids = p2pheaders_and_shortids.shortids984last_index = -1985for x in p2pheaders_and_shortids.prefilled_txn:986self.prefilled_txn.append(PrefilledTransaction(x.index + last_index + 1, x.tx))987last_index = self.prefilled_txn[-1].index989def to_p2p(self):990if self.use_witness:991ret = P2PHeaderAndShortWitnessIDs()992else:993ret = P2PHeaderAndShortIDs()994ret.header = self.header995ret.nonce = self.nonce996ret.shortids_length = len(self.shortids)997ret.shortids = self.shortids998ret.prefilled_txn_length = len(self.prefilled_txn)999ret.prefilled_txn = []1000last_index = -1
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.