Skip to content

Instantly share code, notes, and snippets.

@tsileo
Created December 17, 2013 16:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsileo/8008319 to your computer and use it in GitHub Desktop.
Save tsileo/8008319 to your computer and use it in GitHub Desktop.
package main
import (
"log"
"fmt"
"strconv"
"github.com/jmhodges/levigo"
"github.com/piotrnar/gocoin/blockdb"
"github.com/piotrnar/gocoin/btc"
)
var (
Magic [4]byte
BtcRootDir string
GenesisBlock *btc.Uint256
s string
txo_addr string
)
func main() {
// Setup LevelDB
opts := levigo.NewOptions()
opts.SetCreateIfMissing(true)
filter := levigo.NewBloomFilter(10)
opts.SetFilterPolicy(filter)
db, err := levigo.Open("/work/opensource/blockchain_playground_golang/tmpdat2", opts)
defer db.Close()
if err != nil {
fmt.Printf("failed to load db: %s\n", err)
}
wo := levigo.NewWriteOptions()
//wo.SetSync(true)
defer wo.Close()
ro := levigo.NewReadOptions()
defer ro.Close()
wb := levigo.NewWriteBatch()
defer wb.Close()
// Real network magic byte
Magic = [4]byte{0xF9,0xBE,0xB4,0xD9}
BlockDatabase := blockdb.NewBlockDB("/box/bitcoind_data/blocks", Magic)
for i := uint(0); i < 275000; i++ {
log.Println(i)
dat, er := BlockDatabase.FetchNextBlock()
if dat==nil || er!=nil {
log.Println("END of DB file")
break
}
bl, er := btc.NewBlock(dat[:])
if er != nil {
println("Block inconsistent:", er.Error())
break
}
if i <= 128238 {
continue
}
bl.BuildTxList()
for _, tx := range bl.Txs {
//tx.IsCoinBase()
block_time := strconv.Itoa(int(bl.BlockTime))
tx_block_info := fmt.Sprintf("%s:%s", block_time, strconv.Itoa(int(i)))
wb.Put([]byte(fmt.Sprintf("tx-block!%s", tx.Hash.String())), []byte(tx_block_info))
for txo_index, txo := range tx.TxOut {
if !(tx.Hash.String() == "a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc" && txo_index == 1) &&
!(tx.Hash.String() == "2a0597e665ac3d1cabeede95cedf907934db7f639e477b3c77b242140d8cf728" && txo_index == 1) &&
!(tx.Hash.String() == "e411dbebd2f7d64dafeef9b14b5c59ec60c36779d43f850e5e347abee1e1a455" && txo_index == 1) &&
!(tx.Hash.String() == "0adfc9f9ace87a2956626777c2e2637c789ca4919a77c314d53ffc1d0bc8ad38" && txo_index == 0) &&
!(tx.Hash.String() == "cee16a9b222f636cd27d734da0a131cee5dd7a1d09cb5f14f4d1330b22aaa38e" && txo_index == 0) &&
!(tx.Hash.String() == "5492a05f1edfbd29c525a3dbf45f654d0fc45a805ccd620d0a4dff47de63f90b" && txo_index == 0) {
txo_index_str := strconv.Itoa(int(txo_index))
txo_addr = btc.NewAddrFromPkScript(txo.Pk_script, false).String()
wb.Put([]byte(fmt.Sprintf("txo-addr!%s!%s", tx.Hash.String(), txo_index_str)), []byte(txo_addr))
value_str := strconv.Itoa(int(txo.Value))
wb.Put([]byte(fmt.Sprintf("%s-txo!%s!%s", txo_addr, tx.Hash.String(), txo_index_str)), []byte(value_str))
//Set this TXO id + index unspent (once the txo is spent, we update this value with the block height of the TX that spent it)
wb.Put([]byte(fmt.Sprintf("%s-txo!%s!%s", txo_addr, tx.Hash.String(), txo_index_str)), []byte("0"))
}
}
err := db.Write(wo, wb)
if err != nil {
log.Fatalf("Err write batch: %v", err)
}
wb.Clear()
if !tx.IsCoinBase() {
for txi_index, txi := range tx.TxIn {
txi_index_str := strconv.Itoa(int(txi_index))
txi_vout_str := strconv.Itoa(int(txi.Input.Vout))
s = ""
for i := 0; i<32; i++ {
s+= fmt.Sprintf("%02x", txi.Input.Hash[31-i])
}
// We fetch the previously set corresponding addr for the TXO id + index pointer
txi_addr, err := db.Get(ro, []byte(fmt.Sprintf("txo-addr!%s!%s", s, txi_vout_str)))
if err != nil {
log.Fatalf("Err get addr for txid/vout: %v", err)
}
// We need to store some infos about TXIs for each TXOs, so we iterate them for each TXI
for txo_index, txo := range tx.TxOut {
if !(tx.Hash.String() == "a288fec5559c3f73fd3d93db8e8460562ebfe2fcf04a5114e8d0f2920a6270dc" && txo_index == 1) &&
!(tx.Hash.String() == "2a0597e665ac3d1cabeede95cedf907934db7f639e477b3c77b242140d8cf728" && txo_index == 1) &&
!(tx.Hash.String() == "e411dbebd2f7d64dafeef9b14b5c59ec60c36779d43f850e5e347abee1e1a455" && txo_index == 1) &&
!(tx.Hash.String() == "0adfc9f9ace87a2956626777c2e2637c789ca4919a77c314d53ffc1d0bc8ad38" && txo_index == 0) &&
!(tx.Hash.String() == "cee16a9b222f636cd27d734da0a131cee5dd7a1d09cb5f14f4d1330b22aaa38e" && txo_index == 0) &&
!(tx.Hash.String() == "5492a05f1edfbd29c525a3dbf45f654d0fc45a805ccd620d0a4dff47de63f90b" && txo_index == 0) {
txo_index_str := strconv.Itoa(int(txo_index))
txo_addr = btc.NewAddrFromPkScript(txo.Pk_script, false).String()
wb_key := []byte(fmt.Sprintf("%s-txo-in!%s!%s!%s", txo_addr, tx.Hash.String(), txo_index_str, txi_index_str))
wb.Put(wb_key, []byte(txi_addr))
wb_key = []byte(fmt.Sprintf("%s-txo-in-txid!%s!%s!%s", txo_addr, tx.Hash.String(), txo_index_str, txi_index_str))
wb.Put(wb_key, []byte(s))
wb_key = []byte(fmt.Sprintf("%s-txo-in-vout!%s!%s!%s", txo_addr, tx.Hash.String(), txo_index_str, txi_index_str))
txi_vout_str := strconv.Itoa(int(txi.Input.Vout))
wb.Put(wb_key, []byte(txi_vout_str))
wb_key = []byte(fmt.Sprintf("%s-txi!%s!%s!%s", txi_addr, tx.Hash.String(), txo_index_str))
wb.Put(wb_key, []byte(txo_addr))
wb_key = []byte(fmt.Sprintf("%s-txo-spent!%s!%s", txi_addr, s, txi.Input.Vout))
block_index_str := strconv.Itoa(int(i))
wb.Put(wb_key, []byte(block_index_str))
}
}
}
err = db.Write(wo, wb)
if err != nil {
log.Fatalf("Err write batch: %v", err)
}
wb.Clear()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment