From 23b795ccc76e6d4f8c6e554e5c9348a0bf6109aa Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Thu, 8 Mar 2018 19:39:21 +0100 Subject: [PATCH] Add base for ZCash support --- bchain/coins/blockchain.go | 2 ++ bchain/coins/btc/bitcoinrpc.go | 48 +++++++++++++++++----------------- bchain/coins/zec/zcashrpc.go | 22 ++++++++++++++++ 3 files changed, 48 insertions(+), 24 deletions(-) create mode 100644 bchain/coins/zec/zcashrpc.go diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index e4d78716..f3a4ab34 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -3,6 +3,7 @@ package coins import ( "blockbook/bchain" "blockbook/bchain/coins/btc" + "blockbook/bchain/coins/zec" "fmt" "reflect" "time" @@ -16,6 +17,7 @@ var blockChainFactories = make(map[string]blockChainFactory) func init() { blockChainFactories["btc"] = btc.NewBitcoinRPC + blockChainFactories["zec"] = zec.NewZCashRPC } // NewBlockChain creates bchain.BlockChain of type defined by parameter coin diff --git a/bchain/coins/btc/bitcoinrpc.go b/bchain/coins/btc/bitcoinrpc.go index 3aa28a73..3fdceb4d 100644 --- a/bchain/coins/btc/bitcoinrpc.go +++ b/bchain/coins/btc/bitcoinrpc.go @@ -23,11 +23,11 @@ type BitcoinRPC struct { rpcURL string user string password string - parser *BitcoinBlockParser - testnet bool - network string - mempool *bchain.Mempool - parseBlocks bool + Parser *BitcoinBlockParser + Testnet bool + Network string + Mempool *bchain.Mempool + ParseBlocks bool } // NewBitcoinRPC returns new BitcoinRPC instance. @@ -42,7 +42,7 @@ func NewBitcoinRPC(url string, user string, password string, timeout time.Durati rpcURL: url, user: user, password: password, - parseBlocks: parse, + ParseBlocks: parse, } chainName, err := s.GetBlockChainInfo() if err != nil { @@ -50,31 +50,31 @@ func NewBitcoinRPC(url string, user string, password string, timeout time.Durati } // always create parser - s.parser = &BitcoinBlockParser{ + s.Parser = &BitcoinBlockParser{ Params: GetChainParams(chainName), } // parameters for getInfo request - if s.parser.Params.Net == wire.MainNet { - s.testnet = false - s.network = "livenet" + if s.Parser.Params.Net == wire.MainNet { + s.Testnet = false + s.Network = "livenet" } else { - s.testnet = true - s.network = "testnet" + s.Testnet = true + s.Network = "testnet" } - s.mempool = bchain.NewMempool(s) + s.Mempool = bchain.NewMempool(s) - glog.Info("rpc: block chain ", s.parser.Params.Name) + glog.Info("rpc: block chain ", s.Parser.Params.Name) return s, nil } func (b *BitcoinRPC) IsTestnet() bool { - return b.testnet + return b.Testnet } func (b *BitcoinRPC) GetNetworkName() string { - return b.network + return b.Network } // getblockhash @@ -338,7 +338,7 @@ func (b *BitcoinRPC) GetBlockHeader(hash string) (*bchain.BlockHeader, error) { // GetBlock returns block with given hash. func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) { - if !b.parseBlocks { + if !b.ParseBlocks { return b.GetBlockFull(hash) } header, err := b.GetBlockHeader(hash) @@ -349,7 +349,7 @@ func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) { if err != nil { return nil, err } - block, err := b.parser.ParseBlock(data) + block, err := b.Parser.ParseBlock(data) if err != nil { return nil, errors.Annotatef(err, "hash %v", hash) } @@ -360,14 +360,14 @@ func (b *BitcoinRPC) GetBlock(hash string) (*bchain.Block, error) { // GetBlockWithoutHeader is an optimization - it does not call GetBlockHeader to get prev, next hashes // instead it sets to header only block hash and height passed in parameters func (b *BitcoinRPC) GetBlockWithoutHeader(hash string, height uint32) (*bchain.Block, error) { - if !b.parseBlocks { + if !b.ParseBlocks { return b.GetBlockFull(hash) } data, err := b.GetBlockRaw(hash) if err != nil { return nil, err } - block, err := b.parser.ParseBlock(data) + block, err := b.Parser.ParseBlock(data) if err != nil { return nil, errors.Annotatef(err, "%v %v", height, hash) } @@ -486,17 +486,17 @@ func (b *BitcoinRPC) GetTransaction(txid string) (*bchain.Tx, error) { // ResyncMempool gets mempool transactions and maps output scripts to transactions. // ResyncMempool is not reentrant, it should be called from a single thread. func (b *BitcoinRPC) ResyncMempool(onNewTxAddr func(txid string, addr string)) error { - return b.mempool.Resync(onNewTxAddr) + return b.Mempool.Resync(onNewTxAddr) } // GetMempoolTransactions returns slice of mempool transactions for given output script. func (b *BitcoinRPC) GetMempoolTransactions(outputScript []byte) ([]string, error) { - return b.mempool.GetTransactions(outputScript) + return b.Mempool.GetTransactions(outputScript) } // GetMempoolSpentOutput returns transaction in mempool which spends given outpoint func (b *BitcoinRPC) GetMempoolSpentOutput(outputTxid string, vout uint32) string { - return b.mempool.GetSpentOutput(outputTxid, vout) + return b.Mempool.GetSpentOutput(outputTxid, vout) } // EstimateSmartFee returns fee estimation. @@ -586,5 +586,5 @@ func (b *BitcoinRPC) call(req interface{}, res interface{}) error { // GetChainParser returns BlockChainParser func (b *BitcoinRPC) GetChainParser() bchain.BlockChainParser { - return b.parser + return b.Parser } diff --git a/bchain/coins/zec/zcashrpc.go b/bchain/coins/zec/zcashrpc.go new file mode 100644 index 00000000..1188190d --- /dev/null +++ b/bchain/coins/zec/zcashrpc.go @@ -0,0 +1,22 @@ +package zec + +import ( + "blockbook/bchain" + "blockbook/bchain/coins/btc" + "time" +) + +type ZCashRPC struct { + *btc.BitcoinRPC +} + +func NewZCashRPC(url string, user string, password string, timeout time.Duration, parse bool) (bchain.BlockChain, error) { + b, err := btc.NewBitcoinRPC(url, user, password, timeout, parse) + if err != nil { + return nil, err + } + z := &ZCashRPC{ + BitcoinRPC: b.(*btc.BitcoinRPC), + } + return z, nil +}