mirror of
https://github.com/bitcoin/bips.git
synced 2025-01-18 05:12:47 +01:00
BIP-0158: regenerate test vectors for fp=19, new reg filter, no ext filter
In this commit, we simplify the code that generates the test vectors to only generate filters for a target fp of 19, and also only for the regular filter, as it's the only filter type currently defined. The test vectors have also been updated to include the previous output scripts for all input within a block as these are now required to construct the regular filter. Finally, the generation code has been updated to properly fetch the previous input scripts to the generation code can verify the filter it generates manually against the end server.
This commit is contained in:
parent
6a4e819829
commit
ac76644533
@ -15,13 +15,15 @@ import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||
"github.com/roasbeef/btcd/rpcclient"
|
||||
"github.com/roasbeef/btcd/wire"
|
||||
"github.com/roasbeef/btcutil/gcs"
|
||||
"github.com/roasbeef/btcutil/gcs/builder"
|
||||
"github.com/btcsuite/btcd/blockchain"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcutil"
|
||||
"github.com/btcsuite/btcutil/gcs/builder"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -29,13 +31,19 @@ var (
|
||||
// vectors. Any new entries must be added in sorted order.
|
||||
testBlockHeights = []testBlockCase{
|
||||
{0, "Genesis block"},
|
||||
{1, "Extended filter is empty"},
|
||||
{2, ""},
|
||||
{3, ""},
|
||||
{926485, "Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"},
|
||||
{987876, "Coinbase tx has unparseable output script"},
|
||||
{1263442, "Includes witness data"},
|
||||
}
|
||||
|
||||
defaultBtcdDir = btcutil.AppDataDir("btcd", false)
|
||||
defaultBtcdRPCCertFile = filepath.Join(defaultBtcdDir, "rpc.cert")
|
||||
)
|
||||
|
||||
const (
|
||||
fp = 19
|
||||
)
|
||||
|
||||
type testBlockCase struct {
|
||||
@ -86,41 +94,78 @@ func (w *JSONTestWriter) Close() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func fetchPrevOutputScripts(client *rpcclient.Client, block *wire.MsgBlock) ([][]byte, error) {
|
||||
var prevScripts [][]byte
|
||||
|
||||
txCache := make(map[chainhash.Hash]*wire.MsgTx)
|
||||
for _, tx := range block.Transactions {
|
||||
if blockchain.IsCoinBaseTx(tx) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, txIn := range tx.TxIn {
|
||||
prevOp := txIn.PreviousOutPoint
|
||||
|
||||
tx, ok := txCache[prevOp.Hash]
|
||||
if !ok {
|
||||
originTx, err := client.GetRawTransaction(
|
||||
&prevOp.Hash,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get "+
|
||||
"txid=%v: %v", prevOp.Hash, err)
|
||||
}
|
||||
|
||||
txCache[prevOp.Hash] = originTx.MsgTx()
|
||||
|
||||
tx = originTx.MsgTx()
|
||||
}
|
||||
|
||||
index := prevOp.Index
|
||||
|
||||
prevScripts = append(
|
||||
prevScripts, tx.TxOut[index].PkScript,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return prevScripts, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := os.Mkdir("gcstestvectors", os.ModeDir|0755)
|
||||
if err != nil { // Don't overwrite existing output if any
|
||||
fmt.Println("Couldn't create directory: ", err)
|
||||
var (
|
||||
writerFile *JSONTestWriter
|
||||
prevBasicHeader chainhash.Hash
|
||||
)
|
||||
fName := fmt.Sprintf("testnet-%02d.json", fp)
|
||||
file, err := os.Create(fName)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating output file: ", err.Error())
|
||||
return
|
||||
}
|
||||
files := make([]*JSONTestWriter, 33)
|
||||
prevBasicHeaders := make([]chainhash.Hash, 33)
|
||||
prevExtHeaders := make([]chainhash.Hash, 33)
|
||||
for i := 1; i <= 32; i++ { // Min 1 bit of collision space, max 32
|
||||
fName := fmt.Sprintf("gcstestvectors/testnet-%02d.json", i)
|
||||
file, err := os.Create(fName)
|
||||
if err != nil {
|
||||
fmt.Println("Error creating output file: ", err.Error())
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
defer file.Close()
|
||||
|
||||
writer := &JSONTestWriter{writer: file}
|
||||
defer writer.Close()
|
||||
|
||||
err = writer.WriteComment("Block Height,Block Hash,Block,Previous Basic Header,Previous Ext Header,Basic Filter,Ext Filter,Basic Header,Ext Header,Notes")
|
||||
if err != nil {
|
||||
fmt.Println("Error writing to output file: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
files[i] = writer
|
||||
writer := &JSONTestWriter{
|
||||
writer: file,
|
||||
}
|
||||
cert, err := ioutil.ReadFile(
|
||||
path.Join(os.Getenv("HOME"), "/.btcd/rpc.cert"))
|
||||
defer writer.Close()
|
||||
|
||||
err = writer.WriteComment("Block Height,Block Hash,Block," +
|
||||
"[Prev Output Scripts for Block],Previous Basic Header," +
|
||||
"Basic Filter,Basic Header,Notes")
|
||||
if err != nil {
|
||||
fmt.Println("Error writing to output file: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
writerFile = writer
|
||||
|
||||
cert, err := ioutil.ReadFile(defaultBtcdRPCCertFile)
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't read RPC cert: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
conf := rpcclient.ConnConfig{
|
||||
Host: "127.0.0.1:18334",
|
||||
Endpoint: "ws",
|
||||
@ -134,19 +179,20 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
var testBlockIndex int = 0
|
||||
var testBlockIndex int
|
||||
for height := 0; testBlockIndex < len(testBlockHeights); height++ {
|
||||
fmt.Printf("Height: %d\n", height)
|
||||
blockHash, err := client.GetBlockHash(int64(height))
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get block hash: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
block, err := client.GetBlock(blockHash)
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get block hash: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var blockBuf bytes.Buffer
|
||||
err = block.Serialize(&blockBuf)
|
||||
if err != nil {
|
||||
@ -154,208 +200,98 @@ func main() {
|
||||
return
|
||||
}
|
||||
blockBytes := blockBuf.Bytes()
|
||||
for i := 1; i <= 32; i++ {
|
||||
basicFilter, err := buildBasicFilter(block, uint8(i))
|
||||
|
||||
prevOutputScripts, err := fetchPrevOutputScripts(client, block)
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't fetch prev output scipts: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
basicFilter, err := builder.BuildBasicFilter(block, prevOutputScripts)
|
||||
if err != nil {
|
||||
fmt.Println("Error generating basic filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
basicHeader, err := builder.MakeHeaderForFilter(basicFilter, prevBasicHeader)
|
||||
if err != nil {
|
||||
fmt.Println("Error generating header for filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// We'll now ensure that we've constructed the same filter as
|
||||
// the chain server we're fetching blocks form.
|
||||
filter, err := client.GetCFilter(
|
||||
blockHash, wire.GCSFilterRegular,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("Error getting basic filter: ",
|
||||
err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
nBytes, err := basicFilter.NBytes()
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get NBytes(): ", err)
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(filter.Data, nBytes) {
|
||||
// Don't error on empty filters
|
||||
fmt.Printf("basic filter doesn't match: generated "+
|
||||
"%x, rpc returns %x, block %v", nBytes,
|
||||
filter.Data, spew.Sdump(block))
|
||||
return
|
||||
}
|
||||
|
||||
header, err := client.GetCFilterHeader(
|
||||
blockHash, wire.GCSFilterRegular,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("Error getting basic header: ", err.Error())
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(header.PrevFilterHeader[:], basicHeader[:]) {
|
||||
fmt.Println("Basic header doesn't match!")
|
||||
return
|
||||
}
|
||||
|
||||
if height%1000 == 0 {
|
||||
fmt.Printf("Verified height %v against server\n", height)
|
||||
}
|
||||
|
||||
if uint32(height) == testBlockHeights[testBlockIndex].height {
|
||||
var bfBytes []byte
|
||||
bfBytes, err = basicFilter.NBytes()
|
||||
if err != nil {
|
||||
fmt.Println("Error generating basic filter: ", err.Error())
|
||||
fmt.Println("Couldn't get NBytes(): ", err)
|
||||
return
|
||||
}
|
||||
basicHeader, err := builder.MakeHeaderForFilter(basicFilter,
|
||||
prevBasicHeaders[i])
|
||||
if err != nil {
|
||||
fmt.Println("Error generating header for filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
if basicFilter == nil {
|
||||
basicFilter = &gcs.Filter{}
|
||||
}
|
||||
extFilter, err := buildExtFilter(block, uint8(i))
|
||||
if err != nil {
|
||||
fmt.Println("Error generating ext filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
extHeader, err := builder.MakeHeaderForFilter(extFilter,
|
||||
prevExtHeaders[i])
|
||||
if err != nil {
|
||||
fmt.Println("Error generating header for filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
if extFilter == nil {
|
||||
extFilter = &gcs.Filter{}
|
||||
}
|
||||
if i == builder.DefaultP { // This is the default filter size so we can check against the server's info
|
||||
filter, err := client.GetCFilter(blockHash, wire.GCSFilterRegular)
|
||||
if err != nil {
|
||||
fmt.Println("Error getting basic filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
nBytes, err := basicFilter.NBytes()
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get NBytes(): ", err)
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(filter.Data, nBytes) {
|
||||
// Don't error on empty filters
|
||||
fmt.Println("Basic filter doesn't match!\n", filter.Data, "\n", nBytes)
|
||||
return
|
||||
}
|
||||
filter, err = client.GetCFilter(blockHash, wire.GCSFilterExtended)
|
||||
if err != nil {
|
||||
fmt.Println("Error getting extended filter: ", err.Error())
|
||||
return
|
||||
}
|
||||
nBytes, err = extFilter.NBytes()
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get NBytes(): ", err)
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(filter.Data, nBytes) {
|
||||
fmt.Println("Extended filter doesn't match!")
|
||||
return
|
||||
}
|
||||
header, err := client.GetCFilterHeader(blockHash, wire.GCSFilterRegular)
|
||||
if err != nil {
|
||||
fmt.Println("Error getting basic header: ", err.Error())
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(header.PrevFilterHeader[:], basicHeader[:]) {
|
||||
fmt.Println("Basic header doesn't match!")
|
||||
return
|
||||
}
|
||||
header, err = client.GetCFilterHeader(blockHash, wire.GCSFilterExtended)
|
||||
if err != nil {
|
||||
fmt.Println("Error getting extended header: ", err.Error())
|
||||
return
|
||||
}
|
||||
if !bytes.Equal(header.PrevFilterHeader[:], extHeader[:]) {
|
||||
fmt.Println("Extended header doesn't match!")
|
||||
return
|
||||
}
|
||||
fmt.Println("Verified against server")
|
||||
}
|
||||
|
||||
if uint32(height) == testBlockHeights[testBlockIndex].height {
|
||||
var bfBytes []byte
|
||||
var efBytes []byte
|
||||
bfBytes, err = basicFilter.NBytes()
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get NBytes(): ", err)
|
||||
return
|
||||
}
|
||||
efBytes, err = extFilter.NBytes()
|
||||
if err != nil {
|
||||
fmt.Println("Couldn't get NBytes(): ", err)
|
||||
return
|
||||
}
|
||||
row := []interface{}{
|
||||
height,
|
||||
blockHash.String(),
|
||||
hex.EncodeToString(blockBytes),
|
||||
prevBasicHeaders[i].String(),
|
||||
prevExtHeaders[i].String(),
|
||||
hex.EncodeToString(bfBytes),
|
||||
hex.EncodeToString(efBytes),
|
||||
basicHeader.String(),
|
||||
extHeader.String(),
|
||||
testBlockHeights[testBlockIndex].comment,
|
||||
}
|
||||
err = files[i].WriteTestCase(row)
|
||||
if err != nil {
|
||||
fmt.Println("Error writing test case to output: ", err.Error())
|
||||
return
|
||||
}
|
||||
prevScriptStrings := make([]string, len(prevOutputScripts))
|
||||
for i, prevScript := range prevOutputScripts {
|
||||
prevScriptStrings[i] = hex.EncodeToString(prevScript)
|
||||
}
|
||||
|
||||
row := []interface{}{
|
||||
height,
|
||||
blockHash.String(),
|
||||
hex.EncodeToString(blockBytes),
|
||||
prevScriptStrings,
|
||||
prevBasicHeader.String(),
|
||||
hex.EncodeToString(bfBytes),
|
||||
basicHeader.String(),
|
||||
testBlockHeights[testBlockIndex].comment,
|
||||
}
|
||||
err = writerFile.WriteTestCase(row)
|
||||
if err != nil {
|
||||
fmt.Println("Error writing test case to output: ", err.Error())
|
||||
return
|
||||
}
|
||||
prevBasicHeaders[i] = basicHeader
|
||||
prevExtHeaders[i] = extHeader
|
||||
}
|
||||
|
||||
prevBasicHeader = basicHeader
|
||||
|
||||
if uint32(height) == testBlockHeights[testBlockIndex].height {
|
||||
testBlockIndex++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// buildBasicFilter builds a basic GCS filter from a block. A basic GCS filter
|
||||
// will contain all the previous outpoints spent within a block, as well as the
|
||||
// data pushes within all the outputs created within a block. p is specified as
|
||||
// an argument in order to create test vectors with various values for p.
|
||||
func buildBasicFilter(block *wire.MsgBlock, p uint8) (*gcs.Filter, error) {
|
||||
blockHash := block.BlockHash()
|
||||
b := builder.WithKeyHashP(&blockHash, p)
|
||||
|
||||
// If the filter had an issue with the specified key, then we force it
|
||||
// to bubble up here by calling the Key() function.
|
||||
_, err := b.Key()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// In order to build a basic filter, we'll range over the entire block,
|
||||
// adding the outpoint data as well as the data pushes within the
|
||||
// pkScript.
|
||||
for i, tx := range block.Transactions {
|
||||
// First we'll compute the bash of the transaction and add that
|
||||
// directly to the filter.
|
||||
txHash := tx.TxHash()
|
||||
b.AddHash(&txHash)
|
||||
|
||||
// Skip the inputs for the coinbase transaction
|
||||
if i != 0 {
|
||||
// Each each txin, we'll add a serialized version of
|
||||
// the txid:index to the filters data slices.
|
||||
for _, txIn := range tx.TxIn {
|
||||
b.AddOutPoint(txIn.PreviousOutPoint)
|
||||
}
|
||||
}
|
||||
|
||||
// For each output in a transaction, we'll add each of the
|
||||
// individual data pushes within the script.
|
||||
for _, txOut := range tx.TxOut {
|
||||
b.AddEntry(txOut.PkScript)
|
||||
}
|
||||
}
|
||||
|
||||
return b.Build()
|
||||
}
|
||||
|
||||
// buildExtFilter builds an extended GCS filter from a block. An extended
|
||||
// filter supplements a regular basic filter by include all the _witness_ data
|
||||
// found within a block. This includes all the data pushes within any signature
|
||||
// scripts as well as each element of an input's witness stack. Additionally,
|
||||
// the _hashes_ of each transaction are also inserted into the filter. p is
|
||||
// specified as an argument in order to create test vectors with various values
|
||||
// for p.
|
||||
func buildExtFilter(block *wire.MsgBlock, p uint8) (*gcs.Filter, error) {
|
||||
blockHash := block.BlockHash()
|
||||
b := builder.WithKeyHashP(&blockHash, p)
|
||||
|
||||
// If the filter had an issue with the specified key, then we force it
|
||||
// to bubble up here by calling the Key() function.
|
||||
_, err := b.Key()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// In order to build an extended filter, we add the hash of each
|
||||
// transaction as well as each piece of witness data included in both
|
||||
// the sigScript and the witness stack of an input.
|
||||
for i, tx := range block.Transactions {
|
||||
// Skip the inputs for the coinbase transaction
|
||||
if i != 0 {
|
||||
// Next, for each input, we'll add the sigScript (if
|
||||
// it's present), and also the witness stack (if it's
|
||||
// present)
|
||||
for _, txIn := range tx.TxIn {
|
||||
if txIn.SignatureScript != nil {
|
||||
b.AddScript(txIn.SignatureScript)
|
||||
}
|
||||
|
||||
if len(txIn.Witness) != 0 {
|
||||
b.AddWitness(txIn.Witness)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return b.Build()
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
[
|
||||
["Block Height,Block Hash,Block,Previous Basic Header,Previous Ext Header,Basic Filter,Ext Filter,Basic Header,Ext Header,Notes"],
|
||||
[0,"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943","0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000","0000000000000000000000000000000000000000000000000000000000000000","0000000000000000000000000000000000000000000000000000000000000000","0285c7cdbe33a0","00","c0589c7f567cffaf7bc0c9f6ad61710b78d3c1afef5d65a2a08e8a753173aa54","753e0d1c28585269ab770b166ca2cd1b32f9bc918750547941ed4849d5a80ba8","Genesis block"],
|
||||
[1,"00000000b873e79784647a6c82962c70d228557d24a747ea4d1b8bbe878e1206","0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000","c0589c7f567cffaf7bc0c9f6ad61710b78d3c1afef5d65a2a08e8a753173aa54","753e0d1c28585269ab770b166ca2cd1b32f9bc918750547941ed4849d5a80ba8","026929d09bee00","00","81e4f3e934488be62758f0b88037aa558262da3190ca018329997a319a0f8b5b","31b674ab635e074717329dabdb25d3cb0e14cb2526000cc2cedac7b5f2595110","Extended filter is empty"],
|
||||
[2,"000000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820","0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d235340101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0432e7494d010e062f503253482fffffffff0100f2052a010000002321038a7f6ef1c8ca0c588aa53fa860128077c9e6c11e6830f4d7ee4e763a56b7718fac00000000","81e4f3e934488be62758f0b88037aa558262da3190ca018329997a319a0f8b5b","31b674ab635e074717329dabdb25d3cb0e14cb2526000cc2cedac7b5f2595110","0278fc41168ec0","00","ec48f9f8a625bd8adb2d2684867a05baafebf935553e0b78b386da98179dcf49","0dd53b407c3f242f1838e39e2fc0cfb89cdca27de07ec230568a08d1872f9e01",""],
|
||||
[3,"000000008b896e272758da5297bcd98fdc6d97c9b765ecec401e286dc1fdbe10","0100000020782a005255b657696ea057d5b98f34defcf75196f64f6eeac8026c0000000041ba5afc532aae03151b8aa87b65e1594f97504a768e010c98c0add79216247186e7494dffff001d058dc2b60101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0486e7494d0151062f503253482fffffffff0100f2052a01000000232103f6d9ff4c12959445ca5549c811683bf9c88e637b222dd2e0311154c4c85cf423ac00000000","ec48f9f8a625bd8adb2d2684867a05baafebf935553e0b78b386da98179dcf49","0dd53b407c3f242f1838e39e2fc0cfb89cdca27de07ec230568a08d1872f9e01","022ce4b3256540","00","060b7e1be150cc3cabd9e96b00af217132b387f31fd2bd9adfb0c7f5a09a3356","5b2a59bc476d52b45de1398ee34ed10d0cccd2a4b19ba502a456c7356b35be0d",""],
|
||||
[926485,"000000000000015d6077a411a8f5cc95caf775ccf11c54e27df75ce58d187313","0000002060bbab0edbf3ef8a49608ee326f8fd75c473b7e3982095e2d100000000000000c30134f8c9b6d2470488d7a67a888f6fa12f8692e0c3411fbfb92f0f68f67eedae03ca57ef13021acc22dc4105010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2f0315230e0004ae03ca57043e3d1e1d0c8796bf579aef0c0000000000122f4e696e6a61506f6f6c2f5345475749542fffffffff038427a112000000001976a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac0000000000000000266a24aa21a9ed5c748e121c0fe146d973a4ac26fa4a68b0549d46ee22d25f50a5e46fe1b377ee00000000000000002952534b424c4f434b3acd16772ad61a3c5f00287480b720f6035d5e54c9efc71be94bb5e3727f10909001200000000000000000000000000000000000000000000000000000000000000000000000000100000000010145310e878941a1b2bc2d33797ee4d89d95eaaf2e13488063a2aa9a74490f510a0100000023220020b6744de4f6ec63cc92f7c220cdefeeb1b1bed2b66c8e5706d80ec247d37e65a1ffffffff01002d3101000000001976a9143ebc40e411ed3c76f86711507ab952300890397288ac0400473044022001dd489a5d4e2fbd8a3ade27177f6b49296ba7695c40dbbe650ea83f106415fd02200b23a0602d8ff1bdf79dee118205fc7e9b40672bf31563e5741feb53fb86388501483045022100f88f040e90cc5dc6c6189d04718376ac19ed996bf9e4a3c29c3718d90ffd27180220761711f16c9e3a44f71aab55cbc0634907a1fa8bb635d971a9a01d368727bea10169522103b3623117e988b76aaabe3d63f56a4fc88b228a71e64c4cc551d1204822fe85cb2103dd823066e096f72ed617a41d3ca56717db335b1ea47a1b4c5c9dbdd0963acba621033d7c89bd9da29fa8d44db7906a9778b53121f72191184a9fee785c39180e4be153ae00000000010000000120925534261de4dcebb1ed5ab1b62bfe7a3ef968fb111dc2c910adfebc6e3bdf010000006b483045022100f50198f5ae66211a4f485190abe4dc7accdabe3bc214ebc9ea7069b97097d46e0220316a70a03014887086e335fc1b48358d46cd6bdc9af3b57c109c94af76fc915101210316cff587a01a2736d5e12e53551b18d73780b83c3bfb4fcf209c869b11b6415effffffff0220a10700000000001976a91450333046115eaa0ac9e0216565f945070e44573988ac2e7cd01a000000001976a914c01a7ca16b47be50cbdbc60724f701d52d75156688ac00000000010000000203a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322010000006a47304402204efc3d70e4ca3049c2a425025edf22d5ca355f9ec899dbfbbeeb2268533a0f2b02204780d3739653035af4814ea52e1396d021953f948c29754edd0ee537364603dc012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff03a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322000000006a47304402202d96defdc5b4af71d6ba28c9a6042c2d5ee7bc6de565d4db84ef517445626e03022022da80320e9e489c8f41b74833dfb6a54a4eb5087cdb46eb663eef0b25caa526012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a914b7e6f7ff8658b2d1fb107e3d7be7af4742e6b1b3876f88fc00000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac0000000001000000043ffd60d3818431c495b89be84afac205d5d1ed663009291c560758bbd0a66df5010000006b483045022100f344607de9df42049688dcae8ff1db34c0c7cd25ec05516e30d2bc8f12ac9b2f022060b648f6a21745ea6d9782e17bcc4277b5808326488a1f40d41e125879723d3a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffffa5379401cce30f84731ef1ba65ce27edf2cc7ce57704507ebe8714aa16a96b92010000006a473044022020c37a63bf4d7f564c2192528709b6a38ab8271bd96898c6c2e335e5208661580220435c6f1ad4d9305d2c0a818b2feb5e45d443f2f162c0f61953a14d097fd07064012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff70e731e193235ff12c3184510895731a099112ffca4b00246c60003c40f843ce000000006a473044022053760f74c29a879e30a17b5f03a5bb057a5751a39f86fa6ecdedc36a1b7db04c022041d41c9b95f00d2d10a0373322a9025dba66c942196bc9d8adeb0e12d3024728012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff66b7a71b3e50379c8e85fc18fe3f1a408fc985f257036c34702ba205cef09f6f000000006a4730440220499bf9e2db3db6e930228d0661395f65431acae466634d098612fd80b08459ee022040e069fc9e3c60009f521cef54c38aadbd1251aee37940e6018aadb10f194d6a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a9148fc37ad460fdfbd2b44fe446f6e3071a4f64faa6878f447f0b000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac00000000","5c169b91332e661a4ebf684d6dffcf64aa139e1e736096ce462609b2e0783c55","5f3cd111e10ed28b7c2bc138fe4bc62e5df1cdc292c010b78c84e5111a5daaa6","16040c63f7ddea293f2d9c13690c0ba7b2910228c38b0fe542ce525021e49b598ada05f83bb9c37c711a02b1850265991c34c4fea6261d22a4b84596c0","0e6651beff00ee7a3be424a90e98450727b304558434c8d53781d469131ad21d399376c151ca28","c8f83ffbc9781c2bd4b7e3c055e888b00d3e2fea14e93b3c4f3adee86b063374","61f8ee615258981089be9f98337f53f44b14cc1532aa469a348fdee547117b80","Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"],
|
||||
[987876,"0000000000000c00901f2049055e2a437c819d79a3d54fd63e6af796cd7b8a79","000000202694f74969fdb542090e95a56bc8aa2d646e27033850e32f1c5f000000000000f7e53676b3f12d5beb524ed617f2d25f5a93b5f4f52c1ba2678260d72712f8dd0a6dfe5740257e1a4b1768960101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1603e4120ff9c30a1c216900002f424d4920546573742fffffff0001205fa012000000001e76a914c486de584a735ec2f22da7cd9681614681f92173d83d0aa68688ac00000000","37bf9e681888b3cd204ca4e0c995aad68cd0ecb86bdf19dd0fa2e72dbabcda28","c4c5051dd741c11840ef3f11fb4f372a16bb5aac1dc66576e89e8e6835d667e0","021016dc7a6a20","00","156e9bf3ec5be367f0a829858e9ee182cc3a6531bedced491a52fcfed841c6cb","cab50aab93410cb150fd761f2067a909d35c8a9c0114578efd9590e2d381ee02","Coinbase tx has unparseable output script"],
|
||||
[1263442,"000000006f27ddfe1dd680044a34548f41bed47eba9e6f0b310da21423bc5f33","000000201c8d1a529c39a396db2db234d5ec152fa651a2872966daccbde028b400000000083f14492679151dbfaa1a825ef4c18518e780c1f91044180280a7d33f4a98ff5f45765aaddc001d38333b9a02010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff230352471300fe5f45765afe94690a000963676d696e6572343208000000000000000000ffffffff024423a804000000001976a914f2c25ac3d59f3d674b1d1d0a25c27339aaac0ba688ac0000000000000000266a24aa21a9edcb26cb3052426b9ebb4d19c819ef87c19677bbf3a7c46ef0855bd1b2abe83491012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101d20978463906ba4ff5e7192494b88dd5eb0de85d900ab253af909106faa22cc5010000000004000000014777ff000000000016001446c29eabe8208a33aa1023c741fa79aa92e881ff0347304402207d7ca96134f2bcfdd6b536536fdd39ad17793632016936f777ebb32c22943fda02206014d2fb8a6aa58279797f861042ba604ebd2f8f61e5bddbd9d3be5a245047b201004b632103eeaeba7ce5dc2470221e9517fb498e8d6bd4e73b85b8be655196972eb9ccd5566754b2752103a40b74d43df244799d041f32ce1ad515a6cd99501701540e38750d883ae21d3a68ac00000000","da6984906c48525f1d800b0e9b480b5fde1a3a32ad7e4cac6a0566d86b9b01a5","7820f3d2397d77068f0f0c824c4f403db89682e5ab6e82d027cb84d7beb8a08c","06970f05e70c2ec63508cdf07609cb8434","03049063c6b4e9a028","5a369775edcb1dcde9bbc88f0897bd3fd9ab0317d2906e8c10b62641c2104c54","73cee3d4b37b689f5da7251f175ff4630f2c142d7399b407d5cac65bc593b68d","Includes witness data"]
|
||||
["Block Height,Block Hash,Block,[Prev Output Scripts for Block],Previous Basic Header,Basic Filter,Basic Header,Notes"],
|
||||
[0,"000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943","0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae180101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",[],"0000000000000000000000000000000000000000000000000000000000000000","019dfca8","21584579b7eb08997773e5aeff3a7f932700042d0ed2a6129012b7d7ae81b750","Genesis block"],
|
||||
[2,"000000006c02c8ea6e4ff69651f7fcde348fb9d557a06e6957b65552002a7820","0100000006128e87be8b1b4dea47a7247d5528d2702c96826c7a648497e773b800000000e241352e3bec0a95a6217e10c3abb54adfa05abb12c126695595580fb92e222032e7494dffff001d00d235340101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0432e7494d010e062f503253482fffffffff0100f2052a010000002321038a7f6ef1c8ca0c588aa53fa860128077c9e6c11e6830f4d7ee4e763a56b7718fac00000000",[],"d7bdac13a59d745b1add0d2ce852f1a0442e8945fc1bf3848d3cbffd88c24fe1","0174a170","186afd11ef2b5e7e3504f2e8cbf8df28a1fd251fe53d60dff8b1467d1b386cf0",""],
|
||||
[3,"000000008b896e272758da5297bcd98fdc6d97c9b765ecec401e286dc1fdbe10","0100000020782a005255b657696ea057d5b98f34defcf75196f64f6eeac8026c0000000041ba5afc532aae03151b8aa87b65e1594f97504a768e010c98c0add79216247186e7494dffff001d058dc2b60101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0486e7494d0151062f503253482fffffffff0100f2052a01000000232103f6d9ff4c12959445ca5549c811683bf9c88e637b222dd2e0311154c4c85cf423ac00000000",[],"186afd11ef2b5e7e3504f2e8cbf8df28a1fd251fe53d60dff8b1467d1b386cf0","016cf7a0","8d63aadf5ab7257cb6d2316a57b16f517bff1c6388f124ec4c04af1212729d2a",""],
|
||||
[926485,"000000000000015d6077a411a8f5cc95caf775ccf11c54e27df75ce58d187313","0000002060bbab0edbf3ef8a49608ee326f8fd75c473b7e3982095e2d100000000000000c30134f8c9b6d2470488d7a67a888f6fa12f8692e0c3411fbfb92f0f68f67eedae03ca57ef13021acc22dc4105010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff2f0315230e0004ae03ca57043e3d1e1d0c8796bf579aef0c0000000000122f4e696e6a61506f6f6c2f5345475749542fffffffff038427a112000000001976a914876fbb82ec05caa6af7a3b5e5a983aae6c6cc6d688ac0000000000000000266a24aa21a9ed5c748e121c0fe146d973a4ac26fa4a68b0549d46ee22d25f50a5e46fe1b377ee00000000000000002952534b424c4f434b3acd16772ad61a3c5f00287480b720f6035d5e54c9efc71be94bb5e3727f10909001200000000000000000000000000000000000000000000000000000000000000000000000000100000000010145310e878941a1b2bc2d33797ee4d89d95eaaf2e13488063a2aa9a74490f510a0100000023220020b6744de4f6ec63cc92f7c220cdefeeb1b1bed2b66c8e5706d80ec247d37e65a1ffffffff01002d3101000000001976a9143ebc40e411ed3c76f86711507ab952300890397288ac0400473044022001dd489a5d4e2fbd8a3ade27177f6b49296ba7695c40dbbe650ea83f106415fd02200b23a0602d8ff1bdf79dee118205fc7e9b40672bf31563e5741feb53fb86388501483045022100f88f040e90cc5dc6c6189d04718376ac19ed996bf9e4a3c29c3718d90ffd27180220761711f16c9e3a44f71aab55cbc0634907a1fa8bb635d971a9a01d368727bea10169522103b3623117e988b76aaabe3d63f56a4fc88b228a71e64c4cc551d1204822fe85cb2103dd823066e096f72ed617a41d3ca56717db335b1ea47a1b4c5c9dbdd0963acba621033d7c89bd9da29fa8d44db7906a9778b53121f72191184a9fee785c39180e4be153ae00000000010000000120925534261de4dcebb1ed5ab1b62bfe7a3ef968fb111dc2c910adfebc6e3bdf010000006b483045022100f50198f5ae66211a4f485190abe4dc7accdabe3bc214ebc9ea7069b97097d46e0220316a70a03014887086e335fc1b48358d46cd6bdc9af3b57c109c94af76fc915101210316cff587a01a2736d5e12e53551b18d73780b83c3bfb4fcf209c869b11b6415effffffff0220a10700000000001976a91450333046115eaa0ac9e0216565f945070e44573988ac2e7cd01a000000001976a914c01a7ca16b47be50cbdbc60724f701d52d75156688ac00000000010000000203a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322010000006a47304402204efc3d70e4ca3049c2a425025edf22d5ca355f9ec899dbfbbeeb2268533a0f2b02204780d3739653035af4814ea52e1396d021953f948c29754edd0ee537364603dc012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff03a25f58630d7a1ea52550365fd2156683f56daf6ca73a4b4bbd097e66516322000000006a47304402202d96defdc5b4af71d6ba28c9a6042c2d5ee7bc6de565d4db84ef517445626e03022022da80320e9e489c8f41b74833dfb6a54a4eb5087cdb46eb663eef0b25caa526012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a914b7e6f7ff8658b2d1fb107e3d7be7af4742e6b1b3876f88fc00000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac0000000001000000043ffd60d3818431c495b89be84afac205d5d1ed663009291c560758bbd0a66df5010000006b483045022100f344607de9df42049688dcae8ff1db34c0c7cd25ec05516e30d2bc8f12ac9b2f022060b648f6a21745ea6d9782e17bcc4277b5808326488a1f40d41e125879723d3a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffffa5379401cce30f84731ef1ba65ce27edf2cc7ce57704507ebe8714aa16a96b92010000006a473044022020c37a63bf4d7f564c2192528709b6a38ab8271bd96898c6c2e335e5208661580220435c6f1ad4d9305d2c0a818b2feb5e45d443f2f162c0f61953a14d097fd07064012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff70e731e193235ff12c3184510895731a099112ffca4b00246c60003c40f843ce000000006a473044022053760f74c29a879e30a17b5f03a5bb057a5751a39f86fa6ecdedc36a1b7db04c022041d41c9b95f00d2d10a0373322a9025dba66c942196bc9d8adeb0e12d3024728012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff66b7a71b3e50379c8e85fc18fe3f1a408fc985f257036c34702ba205cef09f6f000000006a4730440220499bf9e2db3db6e930228d0661395f65431acae466634d098612fd80b08459ee022040e069fc9e3c60009f521cef54c38aadbd1251aee37940e6018aadb10f194d6a012103f7a897e4dbecab2264b21917f90664ea8256189ea725d28740cf7ba5d85b5763ffffffff0200e1f5050000000017a9148fc37ad460fdfbd2b44fe446f6e3071a4f64faa6878f447f0b000000001976a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac00000000",["a914feb8a29635c56d9cd913122f90678756bf23887687","76a914c01a7ca16b47be50cbdbc60724f701d52d75156688ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac","76a914913bcc2be49cb534c20474c4dee1e9c4c317e7eb88ac"],"da49977ba1ee0d620a2c4f8f646b03cd0d230f5c6c994722e3ba884889f0be1a","09027acea61b6cc3fb33f5d52f7d088a6b2f75d234e89ca800","4cd9dd007a325199102f1fc0b7d77ca25ee3c84d46018c4353ecfcb56c0d3e7a","Duplicate pushdata 913bcc2be49cb534c20474c4dee1e9c4c317e7eb"],
|
||||
[987876,"0000000000000c00901f2049055e2a437c819d79a3d54fd63e6af796cd7b8a79","000000202694f74969fdb542090e95a56bc8aa2d646e27033850e32f1c5f000000000000f7e53676b3f12d5beb524ed617f2d25f5a93b5f4f52c1ba2678260d72712f8dd0a6dfe5740257e1a4b1768960101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1603e4120ff9c30a1c216900002f424d4920546573742fffffff0001205fa012000000001e76a914c486de584a735ec2f22da7cd9681614681f92173d83d0aa68688ac00000000",[],"e9d729b72d533c29abe5276d5cf6c152f3723f10efe000b1e0c9ca5265a8beb6","010c0b40","e6137ae5a8424c40da1e5023c16975cc97b09300b4c050e6b1c713add3836c40","Coinbase tx has unparseable output script"],
|
||||
[1263442,"000000006f27ddfe1dd680044a34548f41bed47eba9e6f0b310da21423bc5f33","000000201c8d1a529c39a396db2db234d5ec152fa651a2872966daccbde028b400000000083f14492679151dbfaa1a825ef4c18518e780c1f91044180280a7d33f4a98ff5f45765aaddc001d38333b9a02010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff230352471300fe5f45765afe94690a000963676d696e6572343208000000000000000000ffffffff024423a804000000001976a914f2c25ac3d59f3d674b1d1d0a25c27339aaac0ba688ac0000000000000000266a24aa21a9edcb26cb3052426b9ebb4d19c819ef87c19677bbf3a7c46ef0855bd1b2abe83491012000000000000000000000000000000000000000000000000000000000000000000000000002000000000101d20978463906ba4ff5e7192494b88dd5eb0de85d900ab253af909106faa22cc5010000000004000000014777ff000000000016001446c29eabe8208a33aa1023c741fa79aa92e881ff0347304402207d7ca96134f2bcfdd6b536536fdd39ad17793632016936f777ebb32c22943fda02206014d2fb8a6aa58279797f861042ba604ebd2f8f61e5bddbd9d3be5a245047b201004b632103eeaeba7ce5dc2470221e9517fb498e8d6bd4e73b85b8be655196972eb9ccd5566754b2752103a40b74d43df244799d041f32ce1ad515a6cd99501701540e38750d883ae21d3a68ac00000000",["002027a5000c7917f785d8fc6e5a55adfca8717ecb973ebb7743849ff956d896a7ed"],"a4a4d6c6034da8aa06f01fe71f1fffbd79e032006b07f6c7a2c60a66aa310c01","0385acb4f0fe889ef0","3588f34fbbc11640f9ed40b2a66a4e096215d50389691309c1dac74d4268aa81","Includes witness data"]
|
||||
]
|
Loading…
Reference in New Issue
Block a user