Raw-Transaction

提取創世塊原始 TX 數據

  • October 4, 2015

RPC 不返回創世塊的原始交易。我需要為其他硬幣獲取這些數據才能將它們添加到 ABE。

<https://github.com/bitcoin-abe/bitcoin-abe/blob/master/Abe/genesis_tx.py>

由於 RPC 不返回它,我認為我需要以某種方式解析實際的區塊鏈文件以提取它,但不知道如何提取它。

關於獲得任何硬幣的原始十六進制 TX 有什麼建議嗎?

  1. 獲取創世塊
  2. 跳過前 80 個字節
  3. 將剩餘字節轉換為十六進制
  4. 就這樣

當然可以 :) 比特幣全節點在本地機器上保存一個區塊鏈數據庫。

這是獲取創世交易資訊的分步說明。

  • 查找塊數據文件.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('&lt;h')
 def read_uint16 (self): return self._read_num('&lt;H')
 def read_int32  (self): return self._read_num('&lt;i')
 def read_uint32 (self): return self._read_num('&lt;I')
 def read_int64  (self): return self._read_num('&lt;q')
 def read_uint64 (self): return self._read_num('&lt;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('&lt;h', val)
 def write_uint16 (self, val): return self._write_num('&lt;H', val)
 def write_int32  (self, val): return self._write_num('&lt;i', val)
 def write_uint32 (self, val): return self._write_num('&lt;I', val)
 def write_int64  (self, val): return self._write_num('&lt;q', val)
 def write_uint64 (self, val): return self._write_num('&lt;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('&lt;H')
   elif size == 254:
     size = self._read_num('&lt;I')
   elif size == 255:
     size = self._read_num('&lt;Q')
   return size

 def write_compact_size(self, size):
   if size &lt; 0:
     raise SerializationError("attempt to write size &lt; 0")
   elif size &lt; 253:
      self.write(chr(size))
   elif size &lt; 2**16:
     self.write('\xfd')
     self._write_num('&lt;H', size)
   elif size &lt; 2**32:
     self.write('\xfe')
     self._write_num('&lt;I', size)
   elif size &lt; 2**64:
     self.write('\xff')
     self._write_num('&lt;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()

引用自:https://bitcoin.stackexchange.com/questions/36321