I’ve an issue with studying tx out from the Bitcoin Core LevelDB chainstate storage. I do know that the construction of the present model of the chainstate is key => worth
the place the secret is a prefix (0x43) | tx_id | coin_n
(https://github.com/bitcoin/bitcoin/blob/0d509bab45d292caeaf34600e57b5928757c6005/src/txdb.cpp#L39) and the worth is obfuscated by the obfuscation key by the Coin XOR obfuscation_key
worth of the Coin
.
Ref: https://github.com/bitcoin/bitcoin/blob/0d509bab45d292caeaf34600e57b5928757c6005/src/txdb.cpp#L68
So, i’ve efficiently learn the prefix, obfuscation key and the txId with the output_n
key:
prefix: [1]byte
(COutPoint)
txID: [32]byte
outN: VARINT
The Coin construction (https://github.com/bitcoin/bitcoin/blob/0d509bab45d292caeaf34600e57b5928757c6005/src/cash.h#L24)
code: VARINT((coinbase ? 1 : 0) | (peak << 1))
txOut: CTxOut (by way of TxOutCompression)
Now i stucked on the studying the code. In some values, i’ve a legitimate code with true block peak and coinbase boolean. However in some values i’ve invalid information the place the block peak isn’t the identical with the transaction’s block peak.
How one can reproduce this to assist me?
My enter (LevelDB view):
Key | Worth
0e006f62667573636174655f6b6579 | 08f05564aa8317fe24
42 | bde0dff15a88e0eb3d71c37fd986c4cdfd8916bd0b8d0b13343afef66829284d
4300c4626bf6dc028730d3a1f3951d398a71a164d8a898965d11bb8a699091144c00 | 8f6778aa979ddbbc669c187cbf11ad2e30ca53025f3f3b961e
43047ae5966a25bdc32ab4a258c57e28ffa763fc273c08b38fe85839e99e71402500 | ef6778aa979ddbbc669c187cbf11ad2e30ca53025f3f3b961e
430e3afb85bb66cc8a5edfd96f4aad1e65e4e6cf38f1dcc584c525d0b25b89599c00 | 706e56b68303740168c3add6552bf877fa95fb9d2bcbd6e142bb
When i’m studying the primary values and deobfuscate them, i get true block peak and coinbase. However when i’m studying the final worth, i get this:
~ 706e56b68303740168c3add6552bf877fa95fb9d2bcbd6e142bb XOR f05564aa8317fe24
~ 803b321c00148a259896c97cd63c06530ac09f37a8dc28c5b2ee
So, when i’m attempting to learn the uvarint from this, i get an invalid code with invalid block peak:
bundle essential
import (
"bytes"
"encoding/binary"
"encoding/hex"
"log"
)
func essential() 1 == 1
log.Println("isCoinbase", isCoinbase)
Consequence
2024/04/03 15:24:06 code 7552
2024/04/03 15:24:06 blockHeight 3776
2024/04/03 15:24:06 isCoinbase false
Anticipated outcome: blockHeight should be 93
, coinbase false
.
Different data. My deobfuscate perform code:
func deobfuscateValue(obfuscationKey, worth []byte) []byte {
deobfuscatedValue := make([]byte, len(worth))
copy(deobfuscatedValue, worth)
for i, c := vary worth {
deobfuscatedValue[i] = c ^ obfuscationKey[i%len(obfuscationKey)]
}
return deobfuscatedValue
}
I’m operating the personal regtest community on the Bitcoin Core v0.21 (i’ve tried on the 24 model and have the identical outcomes). I’m use bitcoin-testnet-box docker picture to check my program. Additionally, i’ve examined on the mainnet, however have the identical downside too. My blockchain now have solely 105 blocks.
Thanks for serving to. I believe I missed one thing easy and simply do not know one thing in regards to the chainstate or C++ realization or Golang 🙂