Ich mache eine Analyse des UTXO-Sets, indem ich aus der Chainstate-Datenbank lese.
Ich habe die Dokumente von https://github.com/bitcoin/bitcoin/blob/d4a42334d447cad48fb3996cad0fd5c945b75571/src/coins.h#L19-L34 befolgt
/** pruned version of CTransaction: only retains metadata and unspent transaction outputs
*
* Serialized format:
* - VARINT(nVersion)
* - VARINT(nCode)
* - unspentness bitvector, for vout[2] and further; least significant byte first
* - the non-spent CTxOuts (via CTxOutCompressor)
* - VARINT(nHeight)
*
* The nCode value consists of:
* - bit 1: IsCoinBase()
* - bit 2: vout[0] is not spent
* - bit 4: vout[1] is not spent
* - The higher bits encode N, the number of non-zero bytes in the following bitvector.
* - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at
* least one non-spent output).
Der Parser hat gut funktioniert, wenn die Anzahl der UTXO klein ist. Für den folgenden TX (mit 2501 Ausgängen) ist dies jedoch fehlgeschlagen:
2540b961f4a0b231db3bc5a23608307394eae037d8afd0462e9b794e02f00000
Für den Schlüssel 'c' + 2540b961f4a0b231db3bc5a23608307394eae037d8afd0462e9b794e02f00000
sieht der (deobfuskierte) Wert in Chainstate so aus:
01907050e140254150443a0c280004...
Wo 01
ist die Version, 9070
ist die , die angibt, nCode
ob es sich um einen Coinbase-TX handelt, die Unverbrauchtheit von vout[0]
, vout[1]
, und die Länge des folgenden Unverbrauchtheits-Bitvektors für vout[2:]
. Wenn Sie sich blockchain.info ansehen, gibt es 2501 Ausgaben, also sollten (2501 - 2)/8 = 312
Bytes folgen. Das Parsen 9070
als Varint, das Entfernen der letzten Bits und +1 geben mir jedoch nur 2288 / 8 + 1 = 287
. (Ich habe 2288 von (0x90 - 0x80 + 1) * 0x80 + 0x70
erhalten, was die MSB-128-Variante ist, die im Bitcoin-Protokoll verwendet wird.)
Habe ich hier etwas verpasst? Wie genau analysiert man die Variante?
Sie haben Recht, interpretieren das Ergebnis jedoch nicht richtig. Der Wert ist tatsächlich 287
, das heißt (2288 >> 3) + 1
, aber das bedeutet nicht, dass der Bitvektor enthält 287 bytes
, sondern dass er enthält 287 non-zero bytes
, also sollten Sie beim Analysieren des Bitvektors den Bytezähler nur dann verringern, wenn Sie einen Wert ungleich Null finden. Hier haben Sie einen Code, der sich damit befasst ( n
ist 287
in diesem Fall):
# If n is set, the encoded value contains a bitvector. The following bytes are parsed until n non-zero bytes have
# been extracted. (If a 00 is found, the parsing continues but n is not decreased)
if n > 0:
bitvector = ""
while n:
data = utxo[offset:offset+2]
if data != "00":
n -= 1
bitvector += data
offset += 2
Beachten Sie, dass dies nur ein Fragment des Codes ist. Ich habe kürzlich einen vollständigen Decoder in Python codiert, Sie können den Code auf github überprüfen .
h__
h__
CTxOuts
serialisiert werden? Ich verstehe, dass die meisten davon die FormCompressedAmount + 00 + hash160 of pubkey
haben, aber es gibt viele nicht standardmäßige Transaktionen, die schwer zu analysieren sind.Pieter Wuille
sr-gi
h__
sr-gi