Raw-Transaction
提取創世塊原始 TX 數據
RPC 不返回創世塊的原始交易。我需要為其他硬幣獲取這些數據才能將它們添加到 ABE。
<https://github.com/bitcoin-abe/bitcoin-abe/blob/master/Abe/genesis_tx.py>
由於 RPC 不返回它,我認為我需要以某種方式解析實際的區塊鏈文件以提取它,但不知道如何提取它。
關於獲得任何硬幣的原始十六進制 TX 有什麼建議嗎?
- 獲取創世塊
- 跳過前 80 個字節
- 將剩餘字節轉換為十六進制
- 就這樣
當然可以 :) 比特幣全節點在本地機器上保存一個區塊鏈數據庫。
這是獲取創世交易資訊的分步說明。
查找塊數據文件.s 在mac中,它位於**“~/Library/Application Support/Bitcoin/blocks/blkxxxxx.dat”**
使用給定的以下程式碼來解碼創世塊
現在得到了創世區塊和創世區塊中coinbase交易的所有細節,包括tx_version、tx_input_num、tx_prev_output、script_length、scriptsig、sequence、tx_output_num …
import struct # make conversation between Python values and C structsrepresented as Python strings import StringIO # Reads and writes a string buffer import mmap # mutable string class BCDataStream(object): def __init__(self): self.input = None self.read_cursor = 0 def clear(self): self.input = None self.read_cursor = 0 def write(self, bytes): # Initialize with string of bytes if self.input is None: self.input = bytes else: self.input += bytes def map_file(self, file, start): # Initialize with bytes from file self.input = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ) self.read_cursor = start def seek_file(self, position): self.read_cursor = position def close_file(self): self.input.close() def read_string(self): # Strings are encoded depending on length: # 0 to 252 : 1-byte-length followed by bytes (if any) # 253 to 65,535 : byte'253' 2-byte-length followed by bytes # 65,536 to 4,294,967,295 : byte '254' 4-byte-length followed by bytes # ... and the Bitcoin client is coded to understand: # greater than 4,294,967,295 : byte '255' 8-byte-length followed by bytes of string # ... but I don't think it actually handles any strings that big. if self.input is None: raise SerializationError("call write(bytes) before trying to deserialize") try: length = self.read_compact_size() except IndexError: raise SerializationError("attempt to read past end of buffer") return self.read_bytes(length) def write_string(self, string): # Length-encoded as with read-string self.write_compact_size(len(string)) self.write(string) def read_bytes(self, length): try: result = self.input[self.read_cursor:self.read_cursor+length] self.read_cursor += length return result except IndexError: raise SerializationError("attempt to read past end of buffer") return '' def read_boolean(self): return self.read_bytes(1)[0] != chr(0) def read_int16 (self): return self._read_num('<h') def read_uint16 (self): return self._read_num('<H') def read_int32 (self): return self._read_num('<i') def read_uint32 (self): return self._read_num('<I') def read_int64 (self): return self._read_num('<q') def read_uint64 (self): return self._read_num('<Q') def write_boolean(self, val): return self.write(chr(1) if val else chr(0)) def write_int16 (self, val): return self._write_num('<h', val) def write_uint16 (self, val): return self._write_num('<H', val) def write_int32 (self, val): return self._write_num('<i', val) def write_uint32 (self, val): return self._write_num('<I', val) def write_int64 (self, val): return self._write_num('<q', val) def write_uint64 (self, val): return self._write_num('<Q', val) def read_compact_size(self): size = ord(self.input[self.read_cursor]) self.read_cursor += 1 if size == 253: size = self._read_num('<H') elif size == 254: size = self._read_num('<I') elif size == 255: size = self._read_num('<Q') return size def write_compact_size(self, size): if size < 0: raise SerializationError("attempt to write size < 0") elif size < 253: self.write(chr(size)) elif size < 2**16: self.write('\xfd') self._write_num('<H', size) elif size < 2**32: self.write('\xfe') self._write_num('<I', size) elif size < 2**64: self.write('\xff') self._write_num('<Q', size) def _read_num(self, format): (i,) = struct.unpack_from(format, self.input, self.read_cursor) self.read_cursor += struct.calcsize(format) return i def _write_num(self, format, num): s = struct.pack(format, num) self.write(s) def import_blkdat(): pass ds = BCDataStream() file = open("/Users/junton/Library/Application Support/Bitcoin/blocks/blk00000.dat", "rb") ds.map_file(file, 0) # Read file # https://bitcoin.org/en/developer-reference#block-headers # https://en.bitcoin.it/wiki/Protocol_specification#block magic = ds.read_bytes(4).encode('hex') block_size = int(ds.read_bytes(4).encode('hex'), 16) version = ds.read_bytes(4).encode('hex') prev_header_hash = ds.read_bytes(32).encode('hex') merkle_root_hash = ds.read_bytes(32).encode('hex') timestamp = ds.read_bytes(4).encode('hex') nBits = ds.read_bytes(4).encode('hex') nonce = ds.read_bytes(4).encode('hex') num_of_transaction = ds.read_bytes(1).encode('hex') tx_version = ds.read_bytes(4).encode('hex') tx_input = ds.read_bytes(1).encode('hex') tx_prev_output = ds.read_bytes(36).encode('hex') script_length = ds.read_bytes(1).encode('hex') scriptsig = ds.read_bytes(int((script_length), 16)).encode('hex') sequence = ds.read_bytes(4).encode('hex') tx_output = ds.read_bytes(1).encode('hex') BTC_num = ds.read_bytes(8).encode('hex') pk_script_len = ds.read_bytes(1).encode('hex') pk_script = ds.read_bytes(int(pk_script_len, 16)).encode('hex') lock_time = ds.read_bytes(4).encode('hex') print 'magic: ' + magic print 'block_size: ' + str(block_size) print 'version: ' + version print 'prevHash: ' + prev_header_hash print 'merkle_root: ' + merkle_root_hash print 'timestamp: ' + timestamp print 'nBits: ' + nBits print 'nonce: ' + nonce print '--------------------- Transaction Details: ---------------------' print 'num_of_transaction: ' + num_of_transaction print 'tx_version: ' + tx_version print 'tx_input_num: ' + tx_input print 'tx_prev_output: ' + tx_prev_output print 'script_length: ' + script_length print 'scriptsig: ' + scriptsig print 'sequence: ' + sequence print 'tx_ouput_num: ' + tx_output print 'BTC_num: ' + BTC_num print 'pk_script_len: ' + pk_script_len print 'pk_script: ' + pk_script print 'lock_time: ' + lock_time ds.close_file()