Estoy haciendo un análisis en el conjunto UTXO leyendo de la base de datos chainstate.
Estaba siguiendo los documentos proporcionados por https://github.com/bitcoin/bitcoin/blob/d4a42334d447cad48fb3996cad0fd5c945b75571/src/coins.h#L19-L34
/** 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).
El analizador funcionó bien cuando el número de UTXO es pequeño. Sin embargo, para el siguiente tx (que tiene 2501 salidas), falló:
2540b961f4a0b231db3bc5a23608307394eae037d8afd0462e9b794e02f00000
Para la clave 'c' + 2540b961f4a0b231db3bc5a23608307394eae037d8afd0462e9b794e02f00000
, el valor (desofuscado) en chainstate se ve así:
01907050e140254150443a0c280004...
Donde 01
está la versión, 9070
es la nCode
que indica si es un tx de base de monedas, la cantidad no gastada de vout[0]
, vout[1]
y la longitud del siguiente vector de bits no gastado para vout[2:]
. Al mirar blockchain.info, hay 2501 salidas, por lo que habrá (2501 - 2)/8 = 312
bytes a continuación. Sin embargo, analizar 9070
como una variante, eliminar los últimos bits y +1 solo me da 2288 / 8 + 1 = 287
. (Obtuve 2288 por (0x90 - 0x80 + 1) * 0x80 + 0x70
, que es la variante MSB-128 utilizada en el protocolo bitcoin).
¿Me perdí algo aquí? ¿Cómo se analiza exactamente la variante?
Tienes razón, sin embargo no estás interpretando el resultado correctamente. 287
De hecho , el valor es , es decir (2288 >> 3) + 1
, sin embargo, esto no significa que el vector de bits contiene 287 bytes
, sino que contiene 287 non-zero bytes
, por lo que al analizar el vector de bits, debe disminuir el contador de bytes solo cuando encuentre un valor distinto de cero. Aquí tienes un fragmento de código que se ocupa de esto ( n
es 287
en este caso):
# 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
Tenga en cuenta que esto es solo un fragmento del código. He codificado un decodificador completo en Python recientemente, puede consultar el código en github .
h__
h__
CTxOuts
serializan? Entiendo que la mayoría son de la formaCompressedAmount + 00 + hash160 of pubkey
, pero hay muchas transacciones no estándar que son difíciles de analizar.pieter wuille
sr-gi
h__
sr-gi