Parsing the Bitcoin block chain with Go language using Gocoin

Performing Bitcoin block chain analysis with Go language, using Gocoin, a Bitcoin client library for golang.

It's faster to process raw blocks (blkxxxx.dat files) directly than calling bitcoind RPC API, and Go is fast enough for the job.

The code

Here is my code, assuming Gocoin is in your GOPATH:

(gist available here)

package main
import (
    "log"
    "github.com/piotrnar/gocoin/blockdb"
    "github.com/piotrnar/gocoin/btc"
    "encoding/hex"
)

func main() {
    // Set real Bitcoin network
    Magic := [4]byte{0xF9,0xBE,0xB4,0xD9}

    // Specify blocks directory
    BlockDatabase := blockdb.NewBlockDB("/box/bitcoind_data/blocks", Magic)
    
    start_block := 0
    end_block := 275000

    for i := 0; i < end_block + 1; 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
        }

        // Read block till we reach start_block
        if i < start_block {
        	continue
        }

        log.Printf("Current block height: %v", i)

        // Basic block info
        log.Printf("Block hash: %v", bl.Hash)
        log.Printf("Block time: %v", bl.BlockTime)
        log.Printf("Block version: %v", bl.Version)
        log.Printf("Block parent: %v", btc.NewUint256(bl.Parent).String())
        log.Printf("Block merkle root: %v", hex.EncodeToString(bl.MerkleRoot))
        log.Printf("Block bits: %v", bl.Bits)
        log.Printf("Block size: %v", len(bl.Raw))

        // Fetch TXs and iterate over them
        bl.BuildTxList()
        for _, tx := range bl.Txs {
            log.Printf("TxId: %v", tx.Hash.String())
            log.Printf("Tx Size: %v", tx.Size)
            log.Printf("Tx Lock time: %v", tx.Lock_time)
            log.Printf("Tx Version: %v", tx.Version)

            log.Println("TxIns:")

            if tx.IsCoinBase() {
                log.Printf("TxIn coinbase, newly generated coins")
            } else {
                for txin_index, txin := range tx.TxIn {
                    log.Printf("TxIn index: %v", txin_index)
                    log.Printf("TxIn Input: %v", txin.Input.String())
                    log.Printf("TxIn ScriptSig: %v", hex.EncodeToString(txin.ScriptSig))
                    log.Printf("TxIn Sequence: %v", txin.Sequence)
                }
            }

            log.Println("TxOuts:")

            for txo_index, txout := range tx.TxOut {
                log.Printf("TxOut index: %v", txo_index)
                log.Printf("TxOut value: %v", txout.Value)
                log.Printf("TxOut script: %s", hex.EncodeToString(txout.Pk_script))
                txout_addr := btc.NewAddrFromPkScript(txout.Pk_script, false)
                if txout_addr != nil {
                    log.Printf("TxOut address: %v", txout_addr.String())
                } else {
                    log.Printf("TxOut address: can't decode address")
                }
            }
        }
        log.Println()
    }
}

And here is the basic output:

2013/12/17 22:07:46 Current block height: 0
2013/12/17 22:07:46 Block hash: 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
2013/12/17 22:07:46 Block time: 1231006505
2013/12/17 22:07:46 TxId: 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
2013/12/17 22:07:46 TxIns:
2013/12/17 22:07:46 TxIn coinbase, newly generated coins
2013/12/17 22:07:46 TxOuts:
2013/12/17 22:07:46 TxOut index: 0
2013/12/17 22:07:46 TxOut value: 5000000000
2013/12/17 22:07:46 TxOut address: 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
2013/12/17 22:07:46 
2013/12/17 22:07:46 Current block height: 1
2013/12/17 22:07:46 Block hash: 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048
2013/12/17 22:07:46 Block time: 1231469665
2013/12/17 22:07:46 TxId: 0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098
2013/12/17 22:07:46 TxIns:
2013/12/17 22:07:46 TxIn coinbase, newly generated coins
2013/12/17 22:07:46 TxOuts:
2013/12/17 22:07:46 TxOut index: 0
2013/12/17 22:07:46 TxOut value: 5000000000
2013/12/17 22:07:46 TxOut address: 12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX
2013/12/17 22:07:46 
2013/12/17 22:07:46 Current block height: 2
2013/12/17 22:07:46 Block hash: 000000006a625f06636b8bb6ac7b960a8d03705d1ace08b1a19da3fdcc99ddbd
2013/12/17 22:07:46 Block time: 1231469744
2013/12/17 22:07:46 TxId: 9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5
2013/12/17 22:07:46 TxIns:
2013/12/17 22:07:46 TxIn coinbase, newly generated coins
2013/12/17 22:07:46 TxOuts:
2013/12/17 22:07:46 TxOut index: 0
2013/12/17 22:07:46 TxOut value: 5000000000
2013/12/17 22:07:46 TxOut address: 1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1
2013/12/17 22:07:46

Feedback

Let me know if you have any questions/suggestions/improvements!

You should follow me on Twitter

Share this article

Tip with Bitcoin

Tip me with Bitcoin and vote for this post!

1FKdaZ75Ck8Bfc3LgQ8cKA8W7B86fzZBe2

Leave a comment

© Thomas Sileo. Powered by Pelican and hosted by DigitalOcean.