From eae9b6b613cfb5a233a02606b3e7d02bd9217dca Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Tue, 21 Sep 2021 23:54:08 +0200 Subject: [PATCH] Handle Bitcoin vout addresses after upgrade to bitcoind 22.0.0 It was necessary to split the composition chain in other coins from BitcoinParser to BitcoinLikeParser to keep backwards compatibility --- bchain/coins/bch/bcashparser.go | 6 +- bchain/coins/bellcoin/bellcoinparser.go | 4 +- bchain/coins/bitcore/bitcoreparser.go | 6 +- bchain/coins/bitzeny/bitzenyparser.go | 4 +- bchain/coins/btc/bitcoinlikeparser.go | 417 ++++++++++++++++ bchain/coins/btc/bitcoinparser.go | 448 +++--------------- bchain/coins/btg/bgoldparser.go | 4 +- bchain/coins/cpuchain/cpuchainparser.go | 4 +- bchain/coins/dash/dashparser.go | 6 +- bchain/coins/dcr/decredparser.go | 10 +- bchain/coins/deeponion/deeponionparser.go | 6 +- bchain/coins/digibyte/digibyteparser.go | 4 +- bchain/coins/divi/diviparser.go | 6 +- bchain/coins/dogecoin/dogecoinparser.go | 4 +- bchain/coins/firo/firoparser.go | 4 +- bchain/coins/flo/floparser.go | 6 +- bchain/coins/fujicoin/fujicoinparser.go | 4 +- bchain/coins/gamecredits/gamecreditsparser.go | 4 +- bchain/coins/grs/grsparser.go | 6 +- bchain/coins/koto/kotoparser.go | 6 +- bchain/coins/liquid/liquidparser.go | 6 +- bchain/coins/litecoin/litecoinparser.go | 4 +- bchain/coins/monacoin/monacoinparser.go | 4 +- .../coins/monetaryunit/monetaryunitparser.go | 6 +- bchain/coins/myriad/myriadparser.go | 4 +- bchain/coins/namecoin/namecoinparser.go | 4 +- bchain/coins/nuls/nulsparser.go | 4 +- .../omotenashicoin/omotenashicoinparser.go | 6 +- bchain/coins/pivx/pivxparser.go | 6 +- bchain/coins/polis/polisparser.go | 4 +- bchain/coins/qtum/qtumparser.go | 4 +- bchain/coins/ravencoin/ravencoinparser.go | 6 +- bchain/coins/ritocoin/ritocoinparser.go | 4 +- bchain/coins/snowgem/snowgemparser.go | 6 +- bchain/coins/trezarcoin/trezarcoinparser.go | 6 +- bchain/coins/unobtanium/unobtaniumparser.go | 4 +- bchain/coins/vertcoin/vertcoinparser.go | 4 +- bchain/coins/viacoin/viacoinparser.go | 4 +- bchain/coins/vipstarcoin/vipstarcoinparser.go | 4 +- bchain/coins/zec/zcashparser.go | 6 +- 40 files changed, 578 insertions(+), 477 deletions(-) create mode 100644 bchain/coins/btc/bitcoinlikeparser.go diff --git a/bchain/coins/bch/bcashparser.go b/bchain/coins/bch/bcashparser.go index b8744ee4..f63f27fc 100644 --- a/bchain/coins/bch/bcashparser.go +++ b/bchain/coins/bch/bcashparser.go @@ -53,7 +53,7 @@ func init() { // BCashParser handle type BCashParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser AddressFormat AddressFormat } @@ -71,8 +71,8 @@ func NewBCashParser(params *chaincfg.Params, c *btc.Configuration) (*BCashParser return nil, fmt.Errorf("Unknown address format: %s", c.AddressFormat) } p := &BCashParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - AddressFormat: format, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + AddressFormat: format, } p.OutputScriptToAddressesFunc = p.outputScriptToAddresses return p, nil diff --git a/bchain/coins/bellcoin/bellcoinparser.go b/bchain/coins/bellcoin/bellcoinparser.go index 617d4dff..c4d5b1c6 100644 --- a/bchain/coins/bellcoin/bellcoinparser.go +++ b/bchain/coins/bellcoin/bellcoinparser.go @@ -34,12 +34,12 @@ func init() { // BellcoinParser handle type BellcoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewBellcoinParser returns new BellcoinParser instance func NewBellcoinParser(params *chaincfg.Params, c *btc.Configuration) *BellcoinParser { - return &BellcoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &BellcoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Bellcoin network, diff --git a/bchain/coins/bitcore/bitcoreparser.go b/bchain/coins/bitcore/bitcoreparser.go index 8dff4d27..2cdaa906 100644 --- a/bchain/coins/bitcore/bitcoreparser.go +++ b/bchain/coins/bitcore/bitcoreparser.go @@ -39,15 +39,15 @@ func init() { // BitcoreParser handle type BitcoreParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewBitcoreParser returns new BitcoreParser instance func NewBitcoreParser(params *chaincfg.Params, c *btc.Configuration) *BitcoreParser { return &BitcoreParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/bitzeny/bitzenyparser.go b/bchain/coins/bitzeny/bitzenyparser.go index 55327d04..82ae2d0e 100644 --- a/bchain/coins/bitzeny/bitzenyparser.go +++ b/bchain/coins/bitzeny/bitzenyparser.go @@ -35,12 +35,12 @@ func init() { // BitZenyParser handle type BitZenyParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewBitZenyParser returns new BitZenyParser instance func NewBitZenyParser(params *chaincfg.Params, c *btc.Configuration) *BitZenyParser { - return &BitZenyParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &BitZenyParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main BitZeny network, diff --git a/bchain/coins/btc/bitcoinlikeparser.go b/bchain/coins/btc/bitcoinlikeparser.go new file mode 100644 index 00000000..3143ead6 --- /dev/null +++ b/bchain/coins/btc/bitcoinlikeparser.go @@ -0,0 +1,417 @@ +package btc + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "math/big" + "strconv" + "unicode/utf8" + + vlq "github.com/bsm/go-vlq" + "github.com/juju/errors" + "github.com/martinboehm/btcd/blockchain" + "github.com/martinboehm/btcd/wire" + "github.com/martinboehm/btcutil" + "github.com/martinboehm/btcutil/chaincfg" + "github.com/martinboehm/btcutil/hdkeychain" + "github.com/martinboehm/btcutil/txscript" + "github.com/trezor/blockbook/bchain" +) + +// OutputScriptToAddressesFunc converts ScriptPubKey to bitcoin addresses +type OutputScriptToAddressesFunc func(script []byte) ([]string, bool, error) + +// BitcoinLikeParser handle +type BitcoinLikeParser struct { + *bchain.BaseParser + Params *chaincfg.Params + OutputScriptToAddressesFunc OutputScriptToAddressesFunc + XPubMagic uint32 + XPubMagicSegwitP2sh uint32 + XPubMagicSegwitNative uint32 + Slip44 uint32 + minimumCoinbaseConfirmations int +} + +// NewBitcoinLikeParser returns new BitcoinLikeParser instance +func NewBitcoinLikeParser(params *chaincfg.Params, c *Configuration) *BitcoinLikeParser { + p := &BitcoinLikeParser{ + BaseParser: &bchain.BaseParser{ + BlockAddressesToKeep: c.BlockAddressesToKeep, + AmountDecimalPoint: 8, + }, + Params: params, + XPubMagic: c.XPubMagic, + XPubMagicSegwitP2sh: c.XPubMagicSegwitP2sh, + XPubMagicSegwitNative: c.XPubMagicSegwitNative, + Slip44: c.Slip44, + minimumCoinbaseConfirmations: c.MinimumCoinbaseConfirmations, + } + p.OutputScriptToAddressesFunc = p.outputScriptToAddresses + return p +} + +// GetAddrDescFromVout returns internal address representation (descriptor) of given transaction output +func (p *BitcoinLikeParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressDescriptor, error) { + ad, err := hex.DecodeString(output.ScriptPubKey.Hex) + if err != nil { + return ad, err + } + // convert possible P2PK script to P2PKH + // so that all transactions by given public key are indexed together + return txscript.ConvertP2PKtoP2PKH(p.Params.Base58CksumHasher, ad) +} + +// GetAddrDescFromAddress returns internal address representation (descriptor) of given address +func (p *BitcoinLikeParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) { + return p.addressToOutputScript(address) +} + +// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable +func (p *BitcoinLikeParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) { + return p.OutputScriptToAddressesFunc(addrDesc) +} + +// GetScriptFromAddrDesc returns output script for given address descriptor +func (p *BitcoinLikeParser) GetScriptFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]byte, error) { + return addrDesc, nil +} + +// IsAddrDescIndexable returns true if AddressDescriptor should be added to index +// empty or OP_RETURN scripts are not indexed +func (p *BitcoinLikeParser) IsAddrDescIndexable(addrDesc bchain.AddressDescriptor) bool { + if len(addrDesc) == 0 || addrDesc[0] == txscript.OP_RETURN { + return false + } + return true +} + +// addressToOutputScript converts bitcoin address to ScriptPubKey +func (p *BitcoinLikeParser) addressToOutputScript(address string) ([]byte, error) { + da, err := btcutil.DecodeAddress(address, p.Params) + if err != nil { + return nil, err + } + script, err := txscript.PayToAddrScript(da) + if err != nil { + return nil, err + } + return script, nil +} + +// TryParseOPReturn tries to process OP_RETURN script and return its string representation +func (p *BitcoinLikeParser) TryParseOPReturn(script []byte) string { + if len(script) > 1 && script[0] == txscript.OP_RETURN { + // trying 2 variants of OP_RETURN data + // 1) OP_RETURN OP_PUSHDATA1 + // 2) OP_RETURN + // 3) OP_RETURN OP_PUSHDATA2 + var data []byte + var l int + if script[1] == txscript.OP_PUSHDATA1 && len(script) > 2 { + l = int(script[2]) + data = script[3:] + if l != len(data) { + l = int(script[1]) + data = script[2:] + } + } else if script[1] == txscript.OP_PUSHDATA2 && len(script) > 3 { + l = int(script[2]) + int(script[3])<<8 + data = script[4:] + } else { + l = int(script[1]) + data = script[2:] + } + if l == len(data) { + var ed string + + ed = p.tryParseOmni(data) + if ed != "" { + return ed + } + + if utf8.Valid(data) { + ed = "(" + string(data) + ")" + } else { + ed = hex.EncodeToString(data) + } + return "OP_RETURN " + ed + } + } + return "" +} + +var omniCurrencyMap = map[uint32]string{ + 1: "Omni", + 2: "Test Omni", + 31: "TetherUS", +} + +// tryParseOmni tries to extract Omni simple send transaction from script +func (p *BitcoinLikeParser) tryParseOmni(data []byte) string { + + // currently only simple send transaction version 0 is supported, see + // https://github.com/OmniLayer/spec#transfer-coins-simple-send + if len(data) != 20 || data[0] != 'o' { + return "" + } + // omni (4) (2) (2) + omniHeader := []byte{'o', 'm', 'n', 'i', 0, 0, 0, 0} + if !bytes.Equal(data[0:8], omniHeader) { + return "" + } + + currencyID := binary.BigEndian.Uint32(data[8:12]) + currency, ok := omniCurrencyMap[currencyID] + if !ok { + return "" + } + amount := new(big.Int) + amount.SetBytes(data[12:]) + amountStr := p.AmountToDecimalString(amount) + + ed := "OMNI Simple Send: " + amountStr + " " + currency + " (#" + strconv.Itoa(int(currencyID)) + ")" + return ed +} + +// outputScriptToAddresses converts ScriptPubKey to addresses with a flag that the addresses are searchable +func (p *BitcoinLikeParser) outputScriptToAddresses(script []byte) ([]string, bool, error) { + sc, addresses, _, err := txscript.ExtractPkScriptAddrs(script, p.Params) + if err != nil { + return nil, false, err + } + rv := make([]string, len(addresses)) + for i, a := range addresses { + rv[i] = a.EncodeAddress() + } + var s bool + if sc == txscript.PubKeyHashTy || sc == txscript.WitnessV0PubKeyHashTy || sc == txscript.ScriptHashTy || sc == txscript.WitnessV0ScriptHashTy { + s = true + } else if len(rv) == 0 { + or := p.TryParseOPReturn(script) + if or != "" { + rv = []string{or} + } + } + return rv, s, nil +} + +// TxFromMsgTx converts bitcoin wire Tx to bchain.Tx +func (p *BitcoinLikeParser) TxFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.Tx { + vin := make([]bchain.Vin, len(t.TxIn)) + for i, in := range t.TxIn { + if blockchain.IsCoinBaseTx(t) { + vin[i] = bchain.Vin{ + Coinbase: hex.EncodeToString(in.SignatureScript), + Sequence: in.Sequence, + } + break + } + s := bchain.ScriptSig{ + Hex: hex.EncodeToString(in.SignatureScript), + // missing: Asm, + } + vin[i] = bchain.Vin{ + Txid: in.PreviousOutPoint.Hash.String(), + Vout: in.PreviousOutPoint.Index, + Sequence: in.Sequence, + ScriptSig: s, + } + } + vout := make([]bchain.Vout, len(t.TxOut)) + for i, out := range t.TxOut { + addrs := []string{} + if parseAddresses { + addrs, _, _ = p.OutputScriptToAddressesFunc(out.PkScript) + } + s := bchain.ScriptPubKey{ + Hex: hex.EncodeToString(out.PkScript), + Addresses: addrs, + // missing: Asm, + // missing: Type, + } + var vs big.Int + vs.SetInt64(out.Value) + vout[i] = bchain.Vout{ + ValueSat: vs, + N: uint32(i), + ScriptPubKey: s, + } + } + tx := bchain.Tx{ + Txid: t.TxHash().String(), + Version: t.Version, + LockTime: t.LockTime, + Vin: vin, + Vout: vout, + // skip: BlockHash, + // skip: Confirmations, + // skip: Time, + // skip: Blocktime, + } + return tx +} + +// ParseTx parses byte array containing transaction and returns Tx struct +func (p *BitcoinLikeParser) ParseTx(b []byte) (*bchain.Tx, error) { + t := wire.MsgTx{} + r := bytes.NewReader(b) + if err := t.Deserialize(r); err != nil { + return nil, err + } + tx := p.TxFromMsgTx(&t, true) + tx.Hex = hex.EncodeToString(b) + return &tx, nil +} + +// ParseBlock parses raw block to our Block struct +func (p *BitcoinLikeParser) ParseBlock(b []byte) (*bchain.Block, error) { + w := wire.MsgBlock{} + r := bytes.NewReader(b) + + if err := w.Deserialize(r); err != nil { + return nil, err + } + + txs := make([]bchain.Tx, len(w.Transactions)) + for ti, t := range w.Transactions { + txs[ti] = p.TxFromMsgTx(t, false) + } + + return &bchain.Block{ + BlockHeader: bchain.BlockHeader{ + Size: len(b), + Time: w.Header.Timestamp.Unix(), + }, + Txs: txs, + }, nil +} + +// PackTx packs transaction to byte array +func (p *BitcoinLikeParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) { + buf := make([]byte, 4+vlq.MaxLen64+len(tx.Hex)/2) + binary.BigEndian.PutUint32(buf[0:4], height) + vl := vlq.PutInt(buf[4:4+vlq.MaxLen64], blockTime) + hl, err := hex.Decode(buf[4+vl:], []byte(tx.Hex)) + return buf[0 : 4+vl+hl], err +} + +// UnpackTx unpacks transaction from byte array +func (p *BitcoinLikeParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { + height := binary.BigEndian.Uint32(buf) + bt, l := vlq.Int(buf[4:]) + tx, err := p.ParseTx(buf[4+l:]) + if err != nil { + return nil, 0, err + } + tx.Blocktime = bt + + return tx, height, nil +} + +// MinimumCoinbaseConfirmations returns minimum number of confirmations a coinbase transaction must have before it can be spent +func (p *BitcoinLikeParser) MinimumCoinbaseConfirmations() int { + return p.minimumCoinbaseConfirmations +} + +func (p *BitcoinLikeParser) addrDescFromExtKey(extKey *hdkeychain.ExtendedKey) (bchain.AddressDescriptor, error) { + var a btcutil.Address + var err error + if extKey.Version() == p.XPubMagicSegwitP2sh { + // redeemScript <20-byte-pubKeyHash> + pubKeyHash := btcutil.Hash160(extKey.PubKeyBytes()) + redeemScript := make([]byte, len(pubKeyHash)+2) + redeemScript[0] = 0 + redeemScript[1] = byte(len(pubKeyHash)) + copy(redeemScript[2:], pubKeyHash) + hash := btcutil.Hash160(redeemScript) + a, err = btcutil.NewAddressScriptHashFromHash(hash, p.Params) + } else if extKey.Version() == p.XPubMagicSegwitNative { + a, err = btcutil.NewAddressWitnessPubKeyHash(btcutil.Hash160(extKey.PubKeyBytes()), p.Params) + } else { + // default to P2PKH address + a, err = extKey.Address(p.Params) + } + if err != nil { + return nil, err + } + return txscript.PayToAddrScript(a) +} + +// DeriveAddressDescriptors derives address descriptors from given xpub for listed indexes +func (p *BitcoinLikeParser) DeriveAddressDescriptors(xpub string, change uint32, indexes []uint32) ([]bchain.AddressDescriptor, error) { + extKey, err := hdkeychain.NewKeyFromString(xpub, p.Params.Base58CksumHasher) + if err != nil { + return nil, err + } + changeExtKey, err := extKey.Child(change) + if err != nil { + return nil, err + } + ad := make([]bchain.AddressDescriptor, len(indexes)) + for i, index := range indexes { + indexExtKey, err := changeExtKey.Child(index) + if err != nil { + return nil, err + } + ad[i], err = p.addrDescFromExtKey(indexExtKey) + if err != nil { + return nil, err + } + } + return ad, nil +} + +// DeriveAddressDescriptorsFromTo derives address descriptors from given xpub for addresses in index range +func (p *BitcoinLikeParser) DeriveAddressDescriptorsFromTo(xpub string, change uint32, fromIndex uint32, toIndex uint32) ([]bchain.AddressDescriptor, error) { + if toIndex <= fromIndex { + return nil, errors.New("toIndex<=fromIndex") + } + extKey, err := hdkeychain.NewKeyFromString(xpub, p.Params.Base58CksumHasher) + if err != nil { + return nil, err + } + changeExtKey, err := extKey.Child(change) + if err != nil { + return nil, err + } + ad := make([]bchain.AddressDescriptor, toIndex-fromIndex) + for index := fromIndex; index < toIndex; index++ { + indexExtKey, err := changeExtKey.Child(index) + if err != nil { + return nil, err + } + ad[index-fromIndex], err = p.addrDescFromExtKey(indexExtKey) + if err != nil { + return nil, err + } + } + return ad, nil +} + +// DerivationBasePath returns base path of xpub +func (p *BitcoinLikeParser) DerivationBasePath(xpub string) (string, error) { + extKey, err := hdkeychain.NewKeyFromString(xpub, p.Params.Base58CksumHasher) + if err != nil { + return "", err + } + var c, bip string + cn := extKey.ChildNum() + if cn >= 0x80000000 { + cn -= 0x80000000 + c = "'" + } + c = strconv.Itoa(int(cn)) + c + if extKey.Depth() != 3 { + return "unknown/" + c, nil + } + if extKey.Version() == p.XPubMagicSegwitP2sh { + bip = "49" + } else if extKey.Version() == p.XPubMagicSegwitNative { + bip = "84" + } else { + bip = "44" + } + return "m/" + bip + "'/" + strconv.Itoa(int(p.Slip44)) + "'/" + c, nil +} diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index f838c484..41fd7a72 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -1,22 +1,13 @@ package btc import ( - "bytes" - "encoding/binary" - "encoding/hex" + "encoding/json" "math/big" - "strconv" - "unicode/utf8" - vlq "github.com/bsm/go-vlq" - "github.com/juju/errors" - "github.com/martinboehm/btcd/blockchain" "github.com/martinboehm/btcd/wire" - "github.com/martinboehm/btcutil" "github.com/martinboehm/btcutil/chaincfg" - "github.com/martinboehm/btcutil/hdkeychain" - "github.com/martinboehm/btcutil/txscript" "github.com/trezor/blockbook/bchain" + "github.com/trezor/blockbook/common" ) // temp params for signet(wait btcd commit) @@ -35,37 +26,16 @@ func init() { SigNetParams.Net = SignetMagic } -// OutputScriptToAddressesFunc converts ScriptPubKey to bitcoin addresses -type OutputScriptToAddressesFunc func(script []byte) ([]string, bool, error) - // BitcoinParser handle type BitcoinParser struct { - *bchain.BaseParser - Params *chaincfg.Params - OutputScriptToAddressesFunc OutputScriptToAddressesFunc - XPubMagic uint32 - XPubMagicSegwitP2sh uint32 - XPubMagicSegwitNative uint32 - Slip44 uint32 - minimumCoinbaseConfirmations int + *BitcoinLikeParser } // NewBitcoinParser returns new BitcoinParser instance func NewBitcoinParser(params *chaincfg.Params, c *Configuration) *BitcoinParser { - p := &BitcoinParser{ - BaseParser: &bchain.BaseParser{ - BlockAddressesToKeep: c.BlockAddressesToKeep, - AmountDecimalPoint: 8, - }, - Params: params, - XPubMagic: c.XPubMagic, - XPubMagicSegwitP2sh: c.XPubMagicSegwitP2sh, - XPubMagicSegwitNative: c.XPubMagicSegwitNative, - Slip44: c.Slip44, - minimumCoinbaseConfirmations: c.MinimumCoinbaseConfirmations, + return &BitcoinParser{ + BitcoinLikeParser: NewBitcoinLikeParser(params, c), } - p.OutputScriptToAddressesFunc = p.outputScriptToAddresses - return p } // GetChainParams contains network parameters for the main Bitcoin network, @@ -86,366 +56,80 @@ func GetChainParams(chain string) *chaincfg.Params { return &chaincfg.MainNetParams } -// GetAddrDescFromVout returns internal address representation (descriptor) of given transaction output -func (p *BitcoinParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressDescriptor, error) { - ad, err := hex.DecodeString(output.ScriptPubKey.Hex) - if err != nil { - return ad, err - } - // convert possible P2PK script to P2PKH - // so that all transactions by given public key are indexed together - return txscript.ConvertP2PKtoP2PKH(p.Params.Base58CksumHasher, ad) +// ScriptPubKey contains data about output script +type ScriptPubKey struct { + // Asm string `json:"asm"` + Hex string `json:"hex,omitempty"` + // Type string `json:"type"` + Addresses []string `json:"addresses"` // removed from Bitcoind 22.0.0 + Address string `json:"address"` // used in Bitcoind 22.0.0 } -// GetAddrDescFromAddress returns internal address representation (descriptor) of given address -func (p *BitcoinParser) GetAddrDescFromAddress(address string) (bchain.AddressDescriptor, error) { - return p.addressToOutputScript(address) +// Vout contains data about tx output +type Vout struct { + ValueSat big.Int + JsonValue common.JSONNumber `json:"value"` + N uint32 `json:"n"` + ScriptPubKey ScriptPubKey `json:"scriptPubKey"` } -// GetAddressesFromAddrDesc returns addresses for given address descriptor with flag if the addresses are searchable -func (p *BitcoinParser) GetAddressesFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]string, bool, error) { - return p.OutputScriptToAddressesFunc(addrDesc) +// Tx is blockchain transaction +// unnecessary fields are commented out to avoid overhead +type Tx struct { + Hex string `json:"hex"` + Txid string `json:"txid"` + Version int32 `json:"version"` + LockTime uint32 `json:"locktime"` + Vin []bchain.Vin `json:"vin"` + Vout []Vout `json:"vout"` + BlockHeight uint32 `json:"blockHeight,omitempty"` + // BlockHash string `json:"blockhash,omitempty"` + Confirmations uint32 `json:"confirmations,omitempty"` + Time int64 `json:"time,omitempty"` + Blocktime int64 `json:"blocktime,omitempty"` + CoinSpecificData interface{} `json:"-"` } -// GetScriptFromAddrDesc returns output script for given address descriptor -func (p *BitcoinParser) GetScriptFromAddrDesc(addrDesc bchain.AddressDescriptor) ([]byte, error) { - return addrDesc, nil -} - -// IsAddrDescIndexable returns true if AddressDescriptor should be added to index -// empty or OP_RETURN scripts are not indexed -func (p *BitcoinParser) IsAddrDescIndexable(addrDesc bchain.AddressDescriptor) bool { - if len(addrDesc) == 0 || addrDesc[0] == txscript.OP_RETURN { - return false - } - return true -} - -// addressToOutputScript converts bitcoin address to ScriptPubKey -func (p *BitcoinParser) addressToOutputScript(address string) ([]byte, error) { - da, err := btcutil.DecodeAddress(address, p.Params) +// ParseTxFromJson parses JSON message containing transaction and returns Tx struct +// Bitcoind version 22.0.0 removed ScriptPubKey.Addresses from the API and replaced it by a single Address +func (p *BitcoinParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) { + var bitcoinTx Tx + var tx bchain.Tx + err := json.Unmarshal(msg, &bitcoinTx) if err != nil { return nil, err } - script, err := txscript.PayToAddrScript(da) - if err != nil { - return nil, err - } - return script, nil -} -// TryParseOPReturn tries to process OP_RETURN script and return its string representation -func (p *BitcoinParser) TryParseOPReturn(script []byte) string { - if len(script) > 1 && script[0] == txscript.OP_RETURN { - // trying 2 variants of OP_RETURN data - // 1) OP_RETURN OP_PUSHDATA1 - // 2) OP_RETURN - // 3) OP_RETURN OP_PUSHDATA2 - var data []byte - var l int - if script[1] == txscript.OP_PUSHDATA1 && len(script) > 2 { - l = int(script[2]) - data = script[3:] - if l != len(data) { - l = int(script[1]) - data = script[2:] - } - } else if script[1] == txscript.OP_PUSHDATA2 && len(script) > 3 { - l = int(script[2]) + int(script[3])<<8 - data = script[4:] + // it is necessary to copy bitcoinTx to Tx to make it compatible + tx.Hex = bitcoinTx.Hex + tx.Txid = bitcoinTx.Txid + tx.Version = bitcoinTx.Version + tx.LockTime = bitcoinTx.LockTime + tx.Vin = bitcoinTx.Vin + tx.BlockHeight = bitcoinTx.BlockHeight + tx.Confirmations = bitcoinTx.Confirmations + tx.Time = bitcoinTx.Time + tx.Blocktime = bitcoinTx.Blocktime + tx.CoinSpecificData = bitcoinTx.CoinSpecificData + tx.Vout = make([]bchain.Vout, len(bitcoinTx.Vout)) + + for i := range bitcoinTx.Vout { + bitcoinVout := &bitcoinTx.Vout[i] + vout := &tx.Vout[i] + // convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal + vout.ValueSat, err = p.AmountToBigInt(bitcoinVout.JsonValue) + if err != nil { + return nil, err + } + vout.N = bitcoinVout.N + vout.ScriptPubKey.Hex = bitcoinVout.ScriptPubKey.Hex + // convert single Address to Addresses if Addresses are empty + if len(bitcoinVout.ScriptPubKey.Addresses) == 0 { + vout.ScriptPubKey.Addresses = []string{bitcoinVout.ScriptPubKey.Address} } else { - l = int(script[1]) - data = script[2:] - } - if l == len(data) { - var ed string - - ed = p.tryParseOmni(data) - if ed != "" { - return ed - } - - if utf8.Valid(data) { - ed = "(" + string(data) + ")" - } else { - ed = hex.EncodeToString(data) - } - return "OP_RETURN " + ed + vout.ScriptPubKey.Addresses = bitcoinVout.ScriptPubKey.Addresses } } - return "" -} -var omniCurrencyMap = map[uint32]string{ - 1: "Omni", - 2: "Test Omni", - 31: "TetherUS", -} - -// tryParseOmni tries to extract Omni simple send transaction from script -func (p *BitcoinParser) tryParseOmni(data []byte) string { - - // currently only simple send transaction version 0 is supported, see - // https://github.com/OmniLayer/spec#transfer-coins-simple-send - if len(data) != 20 || data[0] != 'o' { - return "" - } - // omni (4) (2) (2) - omniHeader := []byte{'o', 'm', 'n', 'i', 0, 0, 0, 0} - if bytes.Compare(data[0:8], omniHeader) != 0 { - return "" - } - - currencyID := binary.BigEndian.Uint32(data[8:12]) - currency, ok := omniCurrencyMap[currencyID] - if !ok { - return "" - } - amount := new(big.Int) - amount.SetBytes(data[12:]) - amountStr := p.AmountToDecimalString(amount) - - ed := "OMNI Simple Send: " + amountStr + " " + currency + " (#" + strconv.Itoa(int(currencyID)) + ")" - return ed -} - -// outputScriptToAddresses converts ScriptPubKey to addresses with a flag that the addresses are searchable -func (p *BitcoinParser) outputScriptToAddresses(script []byte) ([]string, bool, error) { - sc, addresses, _, err := txscript.ExtractPkScriptAddrs(script, p.Params) - if err != nil { - return nil, false, err - } - rv := make([]string, len(addresses)) - for i, a := range addresses { - rv[i] = a.EncodeAddress() - } - var s bool - if sc == txscript.PubKeyHashTy || sc == txscript.WitnessV0PubKeyHashTy || sc == txscript.ScriptHashTy || sc == txscript.WitnessV0ScriptHashTy { - s = true - } else if len(rv) == 0 { - or := p.TryParseOPReturn(script) - if or != "" { - rv = []string{or} - } - } - return rv, s, nil -} - -// TxFromMsgTx converts bitcoin wire Tx to bchain.Tx -func (p *BitcoinParser) TxFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.Tx { - vin := make([]bchain.Vin, len(t.TxIn)) - for i, in := range t.TxIn { - if blockchain.IsCoinBaseTx(t) { - vin[i] = bchain.Vin{ - Coinbase: hex.EncodeToString(in.SignatureScript), - Sequence: in.Sequence, - } - break - } - s := bchain.ScriptSig{ - Hex: hex.EncodeToString(in.SignatureScript), - // missing: Asm, - } - vin[i] = bchain.Vin{ - Txid: in.PreviousOutPoint.Hash.String(), - Vout: in.PreviousOutPoint.Index, - Sequence: in.Sequence, - ScriptSig: s, - } - } - vout := make([]bchain.Vout, len(t.TxOut)) - for i, out := range t.TxOut { - addrs := []string{} - if parseAddresses { - addrs, _, _ = p.OutputScriptToAddressesFunc(out.PkScript) - } - s := bchain.ScriptPubKey{ - Hex: hex.EncodeToString(out.PkScript), - Addresses: addrs, - // missing: Asm, - // missing: Type, - } - var vs big.Int - vs.SetInt64(out.Value) - vout[i] = bchain.Vout{ - ValueSat: vs, - N: uint32(i), - ScriptPubKey: s, - } - } - tx := bchain.Tx{ - Txid: t.TxHash().String(), - Version: t.Version, - LockTime: t.LockTime, - Vin: vin, - Vout: vout, - // skip: BlockHash, - // skip: Confirmations, - // skip: Time, - // skip: Blocktime, - } - return tx -} - -// ParseTx parses byte array containing transaction and returns Tx struct -func (p *BitcoinParser) ParseTx(b []byte) (*bchain.Tx, error) { - t := wire.MsgTx{} - r := bytes.NewReader(b) - if err := t.Deserialize(r); err != nil { - return nil, err - } - tx := p.TxFromMsgTx(&t, true) - tx.Hex = hex.EncodeToString(b) return &tx, nil } - -// ParseBlock parses raw block to our Block struct -func (p *BitcoinParser) ParseBlock(b []byte) (*bchain.Block, error) { - w := wire.MsgBlock{} - r := bytes.NewReader(b) - - if err := w.Deserialize(r); err != nil { - return nil, err - } - - txs := make([]bchain.Tx, len(w.Transactions)) - for ti, t := range w.Transactions { - txs[ti] = p.TxFromMsgTx(t, false) - } - - return &bchain.Block{ - BlockHeader: bchain.BlockHeader{ - Size: len(b), - Time: w.Header.Timestamp.Unix(), - }, - Txs: txs, - }, nil -} - -// PackTx packs transaction to byte array -func (p *BitcoinParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) { - buf := make([]byte, 4+vlq.MaxLen64+len(tx.Hex)/2) - binary.BigEndian.PutUint32(buf[0:4], height) - vl := vlq.PutInt(buf[4:4+vlq.MaxLen64], blockTime) - hl, err := hex.Decode(buf[4+vl:], []byte(tx.Hex)) - return buf[0 : 4+vl+hl], err -} - -// UnpackTx unpacks transaction from byte array -func (p *BitcoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { - height := binary.BigEndian.Uint32(buf) - bt, l := vlq.Int(buf[4:]) - tx, err := p.ParseTx(buf[4+l:]) - if err != nil { - return nil, 0, err - } - tx.Blocktime = bt - - return tx, height, nil -} - -// MinimumCoinbaseConfirmations returns minimum number of confirmations a coinbase transaction must have before it can be spent -func (p *BitcoinParser) MinimumCoinbaseConfirmations() int { - return p.minimumCoinbaseConfirmations -} - -func (p *BitcoinParser) addrDescFromExtKey(extKey *hdkeychain.ExtendedKey) (bchain.AddressDescriptor, error) { - var a btcutil.Address - var err error - if extKey.Version() == p.XPubMagicSegwitP2sh { - // redeemScript <20-byte-pubKeyHash> - pubKeyHash := btcutil.Hash160(extKey.PubKeyBytes()) - redeemScript := make([]byte, len(pubKeyHash)+2) - redeemScript[0] = 0 - redeemScript[1] = byte(len(pubKeyHash)) - copy(redeemScript[2:], pubKeyHash) - hash := btcutil.Hash160(redeemScript) - a, err = btcutil.NewAddressScriptHashFromHash(hash, p.Params) - } else if extKey.Version() == p.XPubMagicSegwitNative { - a, err = btcutil.NewAddressWitnessPubKeyHash(btcutil.Hash160(extKey.PubKeyBytes()), p.Params) - } else { - // default to P2PKH address - a, err = extKey.Address(p.Params) - } - if err != nil { - return nil, err - } - return txscript.PayToAddrScript(a) -} - -// DeriveAddressDescriptors derives address descriptors from given xpub for listed indexes -func (p *BitcoinParser) DeriveAddressDescriptors(xpub string, change uint32, indexes []uint32) ([]bchain.AddressDescriptor, error) { - extKey, err := hdkeychain.NewKeyFromString(xpub, p.Params.Base58CksumHasher) - if err != nil { - return nil, err - } - changeExtKey, err := extKey.Child(change) - if err != nil { - return nil, err - } - ad := make([]bchain.AddressDescriptor, len(indexes)) - for i, index := range indexes { - indexExtKey, err := changeExtKey.Child(index) - if err != nil { - return nil, err - } - ad[i], err = p.addrDescFromExtKey(indexExtKey) - if err != nil { - return nil, err - } - } - return ad, nil -} - -// DeriveAddressDescriptorsFromTo derives address descriptors from given xpub for addresses in index range -func (p *BitcoinParser) DeriveAddressDescriptorsFromTo(xpub string, change uint32, fromIndex uint32, toIndex uint32) ([]bchain.AddressDescriptor, error) { - if toIndex <= fromIndex { - return nil, errors.New("toIndex<=fromIndex") - } - extKey, err := hdkeychain.NewKeyFromString(xpub, p.Params.Base58CksumHasher) - if err != nil { - return nil, err - } - changeExtKey, err := extKey.Child(change) - if err != nil { - return nil, err - } - ad := make([]bchain.AddressDescriptor, toIndex-fromIndex) - for index := fromIndex; index < toIndex; index++ { - indexExtKey, err := changeExtKey.Child(index) - if err != nil { - return nil, err - } - ad[index-fromIndex], err = p.addrDescFromExtKey(indexExtKey) - if err != nil { - return nil, err - } - } - return ad, nil -} - -// DerivationBasePath returns base path of xpub -func (p *BitcoinParser) DerivationBasePath(xpub string) (string, error) { - extKey, err := hdkeychain.NewKeyFromString(xpub, p.Params.Base58CksumHasher) - if err != nil { - return "", err - } - var c, bip string - cn := extKey.ChildNum() - if cn >= 0x80000000 { - cn -= 0x80000000 - c = "'" - } - c = strconv.Itoa(int(cn)) + c - if extKey.Depth() != 3 { - return "unknown/" + c, nil - } - if extKey.Version() == p.XPubMagicSegwitP2sh { - bip = "49" - } else if extKey.Version() == p.XPubMagicSegwitNative { - bip = "84" - } else { - bip = "44" - } - return "m/" + bip + "'/" + strconv.Itoa(int(p.Slip44)) + "'/" + c, nil -} diff --git a/bchain/coins/btg/bgoldparser.go b/bchain/coins/btg/bgoldparser.go index 101e4a82..2e33380d 100644 --- a/bchain/coins/btg/bgoldparser.go +++ b/bchain/coins/btg/bgoldparser.go @@ -47,12 +47,12 @@ func init() { // BGoldParser handle type BGoldParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewBGoldParser returns new BGoldParser instance func NewBGoldParser(params *chaincfg.Params, c *btc.Configuration) *BGoldParser { - return &BGoldParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &BGoldParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Bitcoin Cash network, diff --git a/bchain/coins/cpuchain/cpuchainparser.go b/bchain/coins/cpuchain/cpuchainparser.go index 62542f63..fdc767ec 100644 --- a/bchain/coins/cpuchain/cpuchainparser.go +++ b/bchain/coins/cpuchain/cpuchainparser.go @@ -34,12 +34,12 @@ func init() { // CPUchainParser handle type CPUchainParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewCPUchainParser returns new CPUchainParser instance func NewCPUchainParser(params *chaincfg.Params, c *btc.Configuration) *CPUchainParser { - return &CPUchainParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &CPUchainParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main CPUchain network, diff --git a/bchain/coins/dash/dashparser.go b/bchain/coins/dash/dashparser.go index b345d4c6..d98e26a5 100644 --- a/bchain/coins/dash/dashparser.go +++ b/bchain/coins/dash/dashparser.go @@ -50,15 +50,15 @@ func init() { // DashParser handle type DashParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewDashParser returns new DashParser instance func NewDashParser(params *chaincfg.Params, c *btc.Configuration) *DashParser { return &DashParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/dcr/decredparser.go b/bchain/coins/dcr/decredparser.go index 22361a92..9868266c 100644 --- a/bchain/coins/dcr/decredparser.go +++ b/bchain/coins/dcr/decredparser.go @@ -52,7 +52,7 @@ func init() { // DecredParser handle type DecredParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseParser *bchain.BaseParser netConfig *cfg.Params } @@ -60,11 +60,11 @@ type DecredParser struct { // NewDecredParser returns new DecredParser instance func NewDecredParser(params *chaincfg.Params, c *btc.Configuration) *DecredParser { d := &DecredParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseParser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseParser: &bchain.BaseParser{}, } - switch d.BitcoinParser.Params.Name { + switch d.BitcoinLikeParser.Params.Name { case "testnet3": d.netConfig = cfg.TestNet3Params() default: @@ -213,7 +213,7 @@ func (p *DecredParser) GetAddrDescFromVout(output *bchain.Vout) (bchain.AddressD } if scriptClass.String() == "nulldata" { - if parsedOPReturn := p.BitcoinParser.TryParseOPReturn(script); parsedOPReturn != "" { + if parsedOPReturn := p.BitcoinLikeParser.TryParseOPReturn(script); parsedOPReturn != "" { return []byte(parsedOPReturn), nil } } diff --git a/bchain/coins/deeponion/deeponionparser.go b/bchain/coins/deeponion/deeponionparser.go index 67d85eda..ed95fd20 100644 --- a/bchain/coins/deeponion/deeponionparser.go +++ b/bchain/coins/deeponion/deeponionparser.go @@ -27,15 +27,15 @@ func init() { // DeepOnionParser handle type DeepOnionParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewDeepOnionParser returns new DeepOnionParser instance func NewDeepOnionParser(params *chaincfg.Params, c *btc.Configuration) *DeepOnionParser { return &DeepOnionParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/digibyte/digibyteparser.go b/bchain/coins/digibyte/digibyteparser.go index 776dd5ab..421f2b19 100644 --- a/bchain/coins/digibyte/digibyteparser.go +++ b/bchain/coins/digibyte/digibyteparser.go @@ -34,12 +34,12 @@ func init() { // DigiByteParser handle type DigiByteParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewDigiByteParser returns new DigiByteParser instance func NewDigiByteParser(params *chaincfg.Params, c *btc.Configuration) *DigiByteParser { - return &DigiByteParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &DigiByteParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main DigiByte network diff --git a/bchain/coins/divi/diviparser.go b/bchain/coins/divi/diviparser.go index 8c7aa55c..02b461e0 100755 --- a/bchain/coins/divi/diviparser.go +++ b/bchain/coins/divi/diviparser.go @@ -37,7 +37,7 @@ func init() { // DivicoinParser handle type DivicoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser BitcoinOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc } @@ -45,8 +45,8 @@ type DivicoinParser struct { // NewDiviParser returns new DivicoinParser instance func NewDiviParser(params *chaincfg.Params, c *btc.Configuration) *DivicoinParser { p := &DivicoinParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } p.BitcoinOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc p.OutputScriptToAddressesFunc = p.outputScriptToAddresses diff --git a/bchain/coins/dogecoin/dogecoinparser.go b/bchain/coins/dogecoin/dogecoinparser.go index ed4a59e7..d38de058 100644 --- a/bchain/coins/dogecoin/dogecoinparser.go +++ b/bchain/coins/dogecoin/dogecoinparser.go @@ -36,12 +36,12 @@ func init() { // DogecoinParser handle type DogecoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewDogecoinParser returns new DogecoinParser instance func NewDogecoinParser(params *chaincfg.Params, c *btc.Configuration) *DogecoinParser { - return &DogecoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &DogecoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Dogecoin network, diff --git a/bchain/coins/firo/firoparser.go b/bchain/coins/firo/firoparser.go index db12eb97..a05ce50a 100644 --- a/bchain/coins/firo/firoparser.go +++ b/bchain/coins/firo/firoparser.go @@ -65,13 +65,13 @@ func init() { // FiroParser handle type FiroParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewFiroParser returns new FiroParser instance func NewFiroParser(params *chaincfg.Params, c *btc.Configuration) *FiroParser { return &FiroParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), } } diff --git a/bchain/coins/flo/floparser.go b/bchain/coins/flo/floparser.go index d1ab9265..46d098bf 100644 --- a/bchain/coins/flo/floparser.go +++ b/bchain/coins/flo/floparser.go @@ -36,15 +36,15 @@ func init() { // FloParser handle type FloParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewFloParser returns new FloParser instance func NewFloParser(params *chaincfg.Params, c *btc.Configuration) *FloParser { return &FloParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/fujicoin/fujicoinparser.go b/bchain/coins/fujicoin/fujicoinparser.go index 21325543..0c3e23b9 100644 --- a/bchain/coins/fujicoin/fujicoinparser.go +++ b/bchain/coins/fujicoin/fujicoinparser.go @@ -38,12 +38,12 @@ func init() { // FujicoinParser handle type FujicoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewFujicoinParser returns new FujicoinParser instance func NewFujicoinParser(params *chaincfg.Params, c *btc.Configuration) *FujicoinParser { - return &FujicoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &FujicoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Fujicoin network, diff --git a/bchain/coins/gamecredits/gamecreditsparser.go b/bchain/coins/gamecredits/gamecreditsparser.go index c126b464..b209e874 100644 --- a/bchain/coins/gamecredits/gamecreditsparser.go +++ b/bchain/coins/gamecredits/gamecreditsparser.go @@ -35,12 +35,12 @@ func init() { // GameCreditsParser handle type GameCreditsParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewGameCreditsParser returns new GameCreditsParser instance func NewGameCreditsParser(params *chaincfg.Params, c *btc.Configuration) *GameCreditsParser { - return &GameCreditsParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &GameCreditsParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main GameCredits network, diff --git a/bchain/coins/grs/grsparser.go b/bchain/coins/grs/grsparser.go index f59b70b9..a0bc51bd 100644 --- a/bchain/coins/grs/grsparser.go +++ b/bchain/coins/grs/grsparser.go @@ -42,15 +42,15 @@ func init() { // GroestlcoinParser handle type GroestlcoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewGroestlcoinParser returns new GroestlcoinParser instance func NewGroestlcoinParser(params *chaincfg.Params, c *btc.Configuration) *GroestlcoinParser { return &GroestlcoinParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/koto/kotoparser.go b/bchain/coins/koto/kotoparser.go index 06bc4b2f..7f3c1c5f 100644 --- a/bchain/coins/koto/kotoparser.go +++ b/bchain/coins/koto/kotoparser.go @@ -44,15 +44,15 @@ func init() { // KotoParser handle type KotoParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewKotoParser returns new KotoParser instance func NewKotoParser(params *chaincfg.Params, c *btc.Configuration) *KotoParser { return &KotoParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/liquid/liquidparser.go b/bchain/coins/liquid/liquidparser.go index 8032fee1..fe05712a 100644 --- a/bchain/coins/liquid/liquidparser.go +++ b/bchain/coins/liquid/liquidparser.go @@ -32,7 +32,7 @@ func init() { // LiquidParser handle type LiquidParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser origOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc } @@ -40,8 +40,8 @@ type LiquidParser struct { // NewLiquidParser returns new LiquidParser instance func NewLiquidParser(params *chaincfg.Params, c *btc.Configuration) *LiquidParser { p := &LiquidParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } p.origOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc p.OutputScriptToAddressesFunc = p.outputScriptToAddresses diff --git a/bchain/coins/litecoin/litecoinparser.go b/bchain/coins/litecoin/litecoinparser.go index 3ca9d8f0..1158c1ee 100644 --- a/bchain/coins/litecoin/litecoinparser.go +++ b/bchain/coins/litecoin/litecoinparser.go @@ -35,12 +35,12 @@ func init() { // LitecoinParser handle type LitecoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewLitecoinParser returns new LitecoinParser instance func NewLitecoinParser(params *chaincfg.Params, c *btc.Configuration) *LitecoinParser { - return &LitecoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &LitecoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Litecoin network, diff --git a/bchain/coins/monacoin/monacoinparser.go b/bchain/coins/monacoin/monacoinparser.go index 4e30964e..ee6e7e77 100644 --- a/bchain/coins/monacoin/monacoinparser.go +++ b/bchain/coins/monacoin/monacoinparser.go @@ -34,12 +34,12 @@ func init() { // MonacoinParser handle type MonacoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewMonacoinParser returns new MonacoinParser instance func NewMonacoinParser(params *chaincfg.Params, c *btc.Configuration) *MonacoinParser { - return &MonacoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &MonacoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Monacoin network, diff --git a/bchain/coins/monetaryunit/monetaryunitparser.go b/bchain/coins/monetaryunit/monetaryunitparser.go index 25514a21..045eba03 100644 --- a/bchain/coins/monetaryunit/monetaryunitparser.go +++ b/bchain/coins/monetaryunit/monetaryunitparser.go @@ -43,7 +43,7 @@ func init() { // MonetaryUnitParser handle type MonetaryUnitParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser BitcoinOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc } @@ -51,8 +51,8 @@ type MonetaryUnitParser struct { // NewMonetaryUnitParser returns new MonetaryUnitParser instance func NewMonetaryUnitParser(params *chaincfg.Params, c *btc.Configuration) *MonetaryUnitParser { p := &MonetaryUnitParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } p.BitcoinOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc p.OutputScriptToAddressesFunc = p.outputScriptToAddresses diff --git a/bchain/coins/myriad/myriadparser.go b/bchain/coins/myriad/myriadparser.go index d4aec0d4..9cc50593 100644 --- a/bchain/coins/myriad/myriadparser.go +++ b/bchain/coins/myriad/myriadparser.go @@ -35,12 +35,12 @@ func init() { // MyriadParser handle type MyriadParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewMyriadParser returns new MyriadParser instance func NewMyriadParser(params *chaincfg.Params, c *btc.Configuration) *MyriadParser { - return &MyriadParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &MyriadParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Myriad network diff --git a/bchain/coins/namecoin/namecoinparser.go b/bchain/coins/namecoin/namecoinparser.go index 7daccebb..9ec24c08 100644 --- a/bchain/coins/namecoin/namecoinparser.go +++ b/bchain/coins/namecoin/namecoinparser.go @@ -29,12 +29,12 @@ func init() { // NamecoinParser handle type NamecoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewNamecoinParser returns new NamecoinParser instance func NewNamecoinParser(params *chaincfg.Params, c *btc.Configuration) *NamecoinParser { - return &NamecoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &NamecoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Namecoin network, diff --git a/bchain/coins/nuls/nulsparser.go b/bchain/coins/nuls/nulsparser.go index 278dc3f9..2ea1ab90 100644 --- a/bchain/coins/nuls/nulsparser.go +++ b/bchain/coins/nuls/nulsparser.go @@ -59,12 +59,12 @@ func init() { // NulsParser handle type NulsParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewNulsParser returns new NulsParser instance func NewNulsParser(params *chaincfg.Params, c *btc.Configuration) *NulsParser { - return &NulsParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &NulsParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Gincoin network, diff --git a/bchain/coins/omotenashicoin/omotenashicoinparser.go b/bchain/coins/omotenashicoin/omotenashicoinparser.go index c2e4481f..dd179fab 100644 --- a/bchain/coins/omotenashicoin/omotenashicoinparser.go +++ b/bchain/coins/omotenashicoin/omotenashicoinparser.go @@ -50,7 +50,7 @@ func init() { // OmotenashiCoinParser handle type OmotenashiCoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser BitcoinOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc } @@ -58,8 +58,8 @@ type OmotenashiCoinParser struct { // NewOmotenashiCoinParser returns new OmotenashiCoinParser instance func NewOmotenashiCoinParser(params *chaincfg.Params, c *btc.Configuration) *OmotenashiCoinParser { p := &OmotenashiCoinParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } p.BitcoinOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc p.OutputScriptToAddressesFunc = p.outputScriptToAddresses diff --git a/bchain/coins/pivx/pivxparser.go b/bchain/coins/pivx/pivxparser.go index d5c7aeb2..4dc92943 100644 --- a/bchain/coins/pivx/pivxparser.go +++ b/bchain/coins/pivx/pivxparser.go @@ -50,7 +50,7 @@ func init() { // PivXParser handle type PivXParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser BitcoinOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc } @@ -58,8 +58,8 @@ type PivXParser struct { // NewPivXParser returns new PivXParser instance func NewPivXParser(params *chaincfg.Params, c *btc.Configuration) *PivXParser { p := &PivXParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } p.BitcoinOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc p.OutputScriptToAddressesFunc = p.outputScriptToAddresses diff --git a/bchain/coins/polis/polisparser.go b/bchain/coins/polis/polisparser.go index 5fa742bc..e004d990 100644 --- a/bchain/coins/polis/polisparser.go +++ b/bchain/coins/polis/polisparser.go @@ -45,12 +45,12 @@ func init() { // PolisParser handle type PolisParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewPolisParser returns new PolisParser instance func NewPolisParser(params *chaincfg.Params, c *btc.Configuration) *PolisParser { - return &PolisParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &PolisParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Polis network, diff --git a/bchain/coins/qtum/qtumparser.go b/bchain/coins/qtum/qtumparser.go index e43b7aba..d6f24965 100644 --- a/bchain/coins/qtum/qtumparser.go +++ b/bchain/coins/qtum/qtumparser.go @@ -40,13 +40,13 @@ func init() { // QtumParser handle type QtumParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewQtumParser returns new DashParser instance func NewQtumParser(params *chaincfg.Params, c *btc.Configuration) *QtumParser { return &QtumParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), } } diff --git a/bchain/coins/ravencoin/ravencoinparser.go b/bchain/coins/ravencoin/ravencoinparser.go index 3ad956bd..72efd703 100644 --- a/bchain/coins/ravencoin/ravencoinparser.go +++ b/bchain/coins/ravencoin/ravencoinparser.go @@ -33,15 +33,15 @@ func init() { // RavencoinParser handle type RavencoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewRavencoinParser returns new RavencoinParser instance func NewRavencoinParser(params *chaincfg.Params, c *btc.Configuration) *RavencoinParser { return &RavencoinParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/ritocoin/ritocoinparser.go b/bchain/coins/ritocoin/ritocoinparser.go index 483eb1d6..de134b6e 100644 --- a/bchain/coins/ritocoin/ritocoinparser.go +++ b/bchain/coins/ritocoin/ritocoinparser.go @@ -36,12 +36,12 @@ func init() { // RitocoinParser handle type RitocoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewRitocoinParser returns new RitocoinParser instance func NewRitocoinParser(params *chaincfg.Params, c *btc.Configuration) *RitocoinParser { - return &RitocoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &RitocoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters diff --git a/bchain/coins/snowgem/snowgemparser.go b/bchain/coins/snowgem/snowgemparser.go index 7897d58d..64534d1f 100644 --- a/bchain/coins/snowgem/snowgemparser.go +++ b/bchain/coins/snowgem/snowgemparser.go @@ -49,15 +49,15 @@ func init() { // SnowGemParser handle type SnowGemParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewSnowGemParser returns new SnowGemParser instance func NewSnowGemParser(params *chaincfg.Params, c *btc.Configuration) *SnowGemParser { return &SnowGemParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/trezarcoin/trezarcoinparser.go b/bchain/coins/trezarcoin/trezarcoinparser.go index f4595769..f5f18a87 100644 --- a/bchain/coins/trezarcoin/trezarcoinparser.go +++ b/bchain/coins/trezarcoin/trezarcoinparser.go @@ -26,15 +26,15 @@ func init() { // TrezarcoinParser handle type TrezarcoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewTrezarcoinParser returns new TrezarcoinParser instance func NewTrezarcoinParser(params *chaincfg.Params, c *btc.Configuration) *TrezarcoinParser { return &TrezarcoinParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } } diff --git a/bchain/coins/unobtanium/unobtaniumparser.go b/bchain/coins/unobtanium/unobtaniumparser.go index 7f06b843..3e803ff8 100644 --- a/bchain/coins/unobtanium/unobtaniumparser.go +++ b/bchain/coins/unobtanium/unobtaniumparser.go @@ -31,12 +31,12 @@ func init() { // UnobtaniumParser handle type UnobtaniumParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewUnobtaniumParser returns new UnobtaniumParser instance func NewUnobtaniumParser(params *chaincfg.Params, c *btc.Configuration) *UnobtaniumParser { - return &UnobtaniumParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &UnobtaniumParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams returns network parameters diff --git a/bchain/coins/vertcoin/vertcoinparser.go b/bchain/coins/vertcoin/vertcoinparser.go index 2037a5f0..35d6f830 100644 --- a/bchain/coins/vertcoin/vertcoinparser.go +++ b/bchain/coins/vertcoin/vertcoinparser.go @@ -35,12 +35,12 @@ func init() { // VertcoinParser handle type VertcoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewVertcoinParser returns new VertcoinParser instance func NewVertcoinParser(params *chaincfg.Params, c *btc.Configuration) *VertcoinParser { - return &VertcoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &VertcoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main Vertcoin network, diff --git a/bchain/coins/viacoin/viacoinparser.go b/bchain/coins/viacoin/viacoinparser.go index 4cb0922c..369d45de 100644 --- a/bchain/coins/viacoin/viacoinparser.go +++ b/bchain/coins/viacoin/viacoinparser.go @@ -42,12 +42,12 @@ func init() { // ViacoinParser handle type ViacoinParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewViacoinParser returns new VertcoinParser instance func NewViacoinParser(params *chaincfg.Params, c *btc.Configuration) *ViacoinParser { - return &ViacoinParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &ViacoinParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams returns network parameters diff --git a/bchain/coins/vipstarcoin/vipstarcoinparser.go b/bchain/coins/vipstarcoin/vipstarcoinparser.go index d89513e7..005cab8f 100644 --- a/bchain/coins/vipstarcoin/vipstarcoinparser.go +++ b/bchain/coins/vipstarcoin/vipstarcoinparser.go @@ -40,12 +40,12 @@ func init() { // VIPSTARCOINParser handle type VIPSTARCOINParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser } // NewVIPSTARCOINParser returns new VIPSTARCOINParser instance func NewVIPSTARCOINParser(params *chaincfg.Params, c *btc.Configuration) *VIPSTARCOINParser { - return &VIPSTARCOINParser{BitcoinParser: btc.NewBitcoinParser(params, c)} + return &VIPSTARCOINParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)} } // GetChainParams contains network parameters for the main VIPSTARCOIN network, diff --git a/bchain/coins/zec/zcashparser.go b/bchain/coins/zec/zcashparser.go index 10313646..ed5cf5ec 100644 --- a/bchain/coins/zec/zcashparser.go +++ b/bchain/coins/zec/zcashparser.go @@ -48,15 +48,15 @@ func init() { // ZCashParser handle type ZCashParser struct { - *btc.BitcoinParser + *btc.BitcoinLikeParser baseparser *bchain.BaseParser } // NewZCashParser returns new ZCashParser instance func NewZCashParser(params *chaincfg.Params, c *btc.Configuration) *ZCashParser { return &ZCashParser{ - BitcoinParser: btc.NewBitcoinParser(params, c), - baseparser: &bchain.BaseParser{}, + BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), + baseparser: &bchain.BaseParser{}, } }