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.
1001for x in self.prefilled_txn:1002ret.prefilled_txn.append(PrefilledTransaction(x.index - last_index - 1, x.tx))1003last_index = x.index1004return ret1006def get_siphash_keys(self):1007header_nonce = self.header.serialize()1008header_nonce += self.nonce.to_bytes(8, "little")1009hash_header_nonce_as_str = sha256(header_nonce)1010key0 = int.from_bytes(hash_header_nonce_as_str[0:8], "little")1011key1 = int.from_bytes(hash_header_nonce_as_str[8:16], "little")1012return [ key0, key1 ]1014# Version 2 compact blocks use wtxid in shortids (rather than txid)1015def initialize_from_block(self, block, nonce=0, prefill_list=None, use_witness=False):1016if prefill_list is None:1017prefill_list = [0]1018self.header = CBlockHeader(block)1019self.nonce = nonce1020self.prefilled_txn = [ PrefilledTransaction(i, block.vtx[i]) for i in prefill_list ]1021self.shortids = []1022self.use_witness = use_witness1023[k0, k1] = self.get_siphash_keys()1024for i in range(len(block.vtx)):1025if i not in prefill_list:1026tx_hash = block.vtx[i].txid_int1027if use_witness:1028tx_hash = block.vtx[i].wtxid_int1029self.shortids.append(calculate_shortid(k0, k1, tx_hash))1031def __repr__(self):1032return "HeaderAndShortIDs(header=%s, nonce=%d, shortids=%s, prefilledtxn=%s" % (repr(self.header), self.nonce, repr(self.shortids), repr(self.prefilled_txn))1035class BlockTransactionsRequest:1036__slots__ = ("blockhash", "indexes")1038def __init__(self, blockhash=0, indexes = None):1039self.blockhash = blockhash1040self.indexes = indexes if indexes is not None else []1042def deserialize(self, f):1043self.blockhash = deser_uint256(f)1044indexes_length = deser_compact_size(f)1045for _ in range(indexes_length):1046self.indexes.append(deser_compact_size(f))1048def serialize(self):1049r = b""1050r += ser_uint256(self.blockhash)1051r += ser_compact_size(len(self.indexes))1052for x in self.indexes:1053r += ser_compact_size(x)1054return r1056# helper to set the differentially encoded indexes from absolute ones1057def from_absolute(self, absolute_indexes):1058self.indexes = []1059last_index = -11060for x in absolute_indexes:1061self.indexes.append(x-last_index-1)1062last_index = x1064def to_absolute(self):1065absolute_indexes = []1066last_index = -11067for x in self.indexes:1068absolute_indexes.append(x+last_index+1)1069last_index = absolute_indexes[-1]1070return absolute_indexes1072def __repr__(self):1073return "BlockTransactionsRequest(hash=%064x indexes=%s)" % (self.blockhash, repr(self.indexes))1076class BlockTransactions:1077__slots__ = ("blockhash", "transactions")1079def __init__(self, blockhash=0, transactions = None):1080self.blockhash = blockhash1081self.transactions = transactions if transactions is not None else []1083def deserialize(self, f):1084self.blockhash = deser_uint256(f)1085self.transactions = deser_vector(f, CTransaction)1087def serialize(self, with_witness=True):1088r = b""1089r += ser_uint256(self.blockhash)1090if with_witness:1091r += ser_vector(self.transactions, "serialize_with_witness")1092else:1093r += ser_vector(self.transactions, "serialize_without_witness")1094return r1096def __repr__(self):1097return "BlockTransactions(hash=%064x transactions=%s)" % (self.blockhash, repr(self.transactions))1100class CPartialMerkleTree:1101__slots__ = ("nTransactions", "vBits", "vHash")1103def __init__(self):1104self.nTransactions = 01105self.vHash = []1106self.vBits = []1108def deserialize(self, f):1109self.nTransactions = int.from_bytes(f.read(4), "little")1110self.vHash = deser_uint256_vector(f)1111vBytes = deser_string(f)1112self.vBits = []1113for i in range(len(vBytes) * 8):1114self.vBits.append(vBytes[i//8] & (1 << (i % 8)) != 0)1116def serialize(self):1117r = b""1118r += self.nTransactions.to_bytes(4, "little")1119r += ser_uint256_vector(self.vHash)1120vBytesArray = bytearray([0x00] * ((len(self.vBits) + 7)//8))1121for i in range(len(self.vBits)):1122vBytesArray[i // 8] |= self.vBits[i] << (i % 8)1123r += ser_string(bytes(vBytesArray))1124return r1126def __repr__(self):1127return "CPartialMerkleTree(nTransactions=%d, vHash=%s, vBits=%s)" % (self.nTransactions, repr(self.vHash), repr(self.vBits))1130class CMerkleBlock:1131__slots__ = ("header", "txn")1133def __init__(self):1134self.header = CBlockHeader()1135self.txn = CPartialMerkleTree()1137def deserialize(self, f):1138self.header.deserialize(f)1139self.txn.deserialize(f)1141def serialize(self):1142r = b""1143r += self.header.serialize()1144r += self.txn.serialize()1145return r1147def __repr__(self):1148return "CMerkleBlock(header=%s, txn=%s)" % (repr(self.header), repr(self.txn))1151# Objects that correspond to messages on the wire1152class msg_version:1153__slots__ = ("addrFrom", "addrTo", "nNonce", "relay", "nServices",1154"nStartingHeight", "nTime", "nVersion", "strSubVer")1155msgtype = b"version"1157def __init__(self):1158self.nVersion = 01159self.nServices = 01160self.nTime = int(time.time())1161self.addrTo = CAddress()1162self.addrFrom = CAddress()1163self.nNonce = random.getrandbits(64)1164self.strSubVer = ''1165self.nStartingHeight = -11166self.relay = 01168def deserialize(self, f):1169self.nVersion = int.from_bytes(f.read(4), "little", signed=True)1170self.nServices = int.from_bytes(f.read(8), "little")1171self.nTime = int.from_bytes(f.read(8), "little", signed=True)1172self.addrTo = CAddress()1173self.addrTo.deserialize(f, with_time=False)1175self.addrFrom = CAddress()1176self.addrFrom.deserialize(f, with_time=False)1177self.nNonce = int.from_bytes(f.read(8), "little")1178self.strSubVer = deser_string(f).decode('utf-8')1180self.nStartingHeight = int.from_bytes(f.read(4), "little", signed=True)1182# Relay field is optional for version 70001 onwards1183# But, unconditionally check it to match behaviour in bitcoind1184self.relay = int.from_bytes(f.read(1), "little") # f.read(1) may return an empty b''1186def serialize(self):1187r = b""1188r += self.nVersion.to_bytes(4, "little", signed=True)1189r += self.nServices.to_bytes(8, "little")1190r += self.nTime.to_bytes(8, "little", signed=True)1191r += self.addrTo.serialize(with_time=False)1192r += self.addrFrom.serialize(with_time=False)1193r += self.nNonce.to_bytes(8, "little")1194r += ser_string(self.strSubVer.encode('utf-8'))1195r += self.nStartingHeight.to_bytes(4, "little", signed=True)1196r += self.relay.to_bytes(1, "little")1197return r1199def __repr__(self):1200return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i relay=%i)' \1201% (self.nVersion, self.nServices, time.ctime(self.nTime),1202repr(self.addrTo), repr(self.addrFrom), self.nNonce,1203self.strSubVer, self.nStartingHeight, self.relay)1206class msg_verack:1207__slots__ = ()1208msgtype = b"verack"1210def __init__(self):1211pass1213def deserialize(self, f):1214pass1216def serialize(self):1217return b""1219def __repr__(self):1220return "msg_verack()"1223class msg_addr:1224__slots__ = ("addrs",)1225msgtype = b"addr"1227def __init__(self):1228self.addrs = []1230def deserialize(self, f):1231self.addrs = deser_vector(f, CAddress)1233def serialize(self):1234return ser_vector(self.addrs)1236def __repr__(self):1237return "msg_addr(addrs=%s)" % (repr(self.addrs))1240class msg_addrv2:1241__slots__ = ("addrs",)1242msgtype = b"addrv2"1244def __init__(self):1245self.addrs = []1247def deserialize(self, f):1248self.addrs = deser_vector(f, CAddress, "deserialize_v2")1250def serialize(self):
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.