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
This commit is contained in:
Martin Boehm 2021-09-21 23:54:08 +02:00
parent 93d09014c1
commit eae9b6b613
40 changed files with 578 additions and 477 deletions

View File

@ -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

View File

@ -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,

View File

@ -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{},
}
}

View File

@ -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,

View File

@ -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 <datalen> <data>
// 2) OP_RETURN <datalen> <data>
// 3) OP_RETURN OP_PUSHDATA2 <datalenlow> <datalenhigh> <data>
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) <tx_version> (2) <tx_type> (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 <witness version: OP_0><len pubKeyHash: 20><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
}

View File

@ -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 <datalen> <data>
// 2) OP_RETURN <datalen> <data>
// 3) OP_RETURN OP_PUSHDATA2 <datalenlow> <datalenhigh> <data>
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) <tx_version> (2) <tx_type> (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 <witness version: OP_0><len pubKeyHash: 20><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
}

View File

@ -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,

View File

@ -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,

View File

@ -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{},
}
}

View File

@ -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
}
}

View File

@ -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{},
}
}

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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),
}
}

View File

@ -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{},
}
}

View File

@ -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,

View File

@ -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,

View File

@ -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{},
}
}

View File

@ -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{},
}
}

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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),
}
}

View File

@ -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{},
}
}

View File

@ -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

View File

@ -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{},
}
}

View File

@ -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{},
}
}

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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{},
}
}