The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/client/btctxiter/btctxiter.go

111 lines
2.7 KiB

// Uses btcd node.
// Use `GetBlockVerboseTx` to get block and tx at once.
// This way is faster
package btctxiter
import (
"io/ioutil"
"log"
"path/filepath"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcutil"
)
// BTCTXIterator is a btc transaction iterator.
type BTCTXIterator struct {
blockIndex int64
block *btcjson.GetBlockVerboseResult
txIndex int
tx *btcjson.TxRawResult
client *rpcclient.Client
}
// Init is an init function of BTCTXIterator.
func (iter *BTCTXIterator) Init() {
btcdHomeDir := btcutil.AppDataDir("btcd", false)
certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert"))
if err != nil {
log.Fatal(err)
}
connCfg := &rpcclient.ConnConfig{
Host: "localhost:8334", // This goes to btcd
Endpoint: "ws",
User: "",
Pass: "",
Certificates: certs,
}
iter.client, err = rpcclient.New(connCfg, nil)
if err != nil {
log.Fatal(err)
}
iter.blockIndex = 0 // the genesis block cannot retrieved. Skip it intentionally.
iter.block = nil
iter.nextBlock()
// defer iter.client.Shutdown()
}
// NextTx is to move to the next transaction.
func (iter *BTCTXIterator) NextTx() *btcjson.TxRawResult {
iter.txIndex++
if iter.txIndex >= len(iter.block.RawTx) {
iter.nextBlock()
iter.txIndex++
}
iter.tx = &iter.block.RawTx[iter.txIndex]
// log.Println(iter.blockIndex, iter.txIndex, hashes[iter.txIndex])
return iter.tx
}
// GetBlockIndex gets the index/height of the current block
func (iter *BTCTXIterator) GetBlockIndex() int64 {
return iter.blockIndex
}
// GetBlock gets the current block
func (iter *BTCTXIterator) GetBlock() *btcjson.GetBlockVerboseResult {
return iter.block
}
// GetTxIndex gets the index of the current transaction
func (iter *BTCTXIterator) GetTxIndex() int {
return iter.txIndex
}
// GetTx gets the current transaction
func (iter *BTCTXIterator) GetTx() *btcjson.TxRawResult {
return iter.tx
}
func (iter *BTCTXIterator) resetTx() {
iter.txIndex = -1
iter.tx = nil
}
// Move to the next block
func (iter *BTCTXIterator) nextBlock() *btcjson.GetBlockVerboseResult {
iter.blockIndex++
hash, err := iter.client.GetBlockHash(iter.blockIndex)
if err != nil {
log.Panic("Failed to get block hash at", iter.blockIndex, err)
}
iter.block, err = iter.client.GetBlockVerboseTx(hash)
if err != nil {
log.Panic("Failed to get block", iter.blockIndex, err)
}
iter.resetTx()
return iter.block
}
// IsCoinBaseTx returns true if tx is a coinbase tx.
func IsCoinBaseTx(tx *btcjson.TxRawResult) bool {
// A coin base must only have one transaction input.
if len(tx.Vin) != 1 {
return false
}
return tx.Vin[0].IsCoinBase()
}