blockbook/bchain/coins/vipstarcoin/vipstarcoinparser.go
Martin Boehm eae9b6b613 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
2021-09-21 23:59:20 +02:00

154 lines
3.4 KiB
Go

package vipstarcoin
import (
"bytes"
"encoding/json"
"io"
"github.com/martinboehm/btcd/wire"
"github.com/martinboehm/btcutil/chaincfg"
"github.com/trezor/blockbook/bchain"
"github.com/trezor/blockbook/bchain/coins/btc"
"github.com/trezor/blockbook/bchain/coins/utils"
)
// magic numbers
const (
MainnetMagic wire.BitcoinNet = 0x012ce7b5
TestnetMagic wire.BitcoinNet = 0x1a2b3c4d
)
// chain parameters
var (
MainNetParams chaincfg.Params
TestNetParams chaincfg.Params
)
func init() {
MainNetParams = chaincfg.MainNetParams
MainNetParams.Net = MainnetMagic
MainNetParams.PubKeyHashAddrID = []byte{70}
MainNetParams.ScriptHashAddrID = []byte{50}
MainNetParams.Bech32HRPSegwit = "vips"
TestNetParams = chaincfg.TestNet3Params
TestNetParams.Net = TestnetMagic
TestNetParams.PubKeyHashAddrID = []byte{132}
TestNetParams.ScriptHashAddrID = []byte{110}
TestNetParams.Bech32HRPSegwit = "tvips"
}
// VIPSTARCOINParser handle
type VIPSTARCOINParser struct {
*btc.BitcoinLikeParser
}
// NewVIPSTARCOINParser returns new VIPSTARCOINParser instance
func NewVIPSTARCOINParser(params *chaincfg.Params, c *btc.Configuration) *VIPSTARCOINParser {
return &VIPSTARCOINParser{BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c)}
}
// GetChainParams contains network parameters for the main VIPSTARCOIN network,
// and the test VIPSTARCOIN network
func GetChainParams(chain string) *chaincfg.Params {
if !chaincfg.IsRegistered(&MainNetParams) {
err := chaincfg.Register(&MainNetParams)
if err == nil {
err = chaincfg.Register(&TestNetParams)
}
if err != nil {
panic(err)
}
}
switch chain {
case "test":
return &TestNetParams
default:
return &MainNetParams
}
}
func parseBlockHeader(r io.Reader) (*wire.BlockHeader, error) {
h := &wire.BlockHeader{}
err := h.Deserialize(r)
if err != nil {
return nil, err
}
// hash_state_root 32
// hash_utxo_root 32
// hash_prevout_stake 32
// hash_prevout_n 4
buf := make([]byte, 100)
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, err
}
sigLength, err := wire.ReadVarInt(r, 0)
if err != nil {
return nil, err
}
sigBuf := make([]byte, sigLength)
_, err = io.ReadFull(r, sigBuf)
if err != nil {
return nil, err
}
return h, err
}
// ParseBlock parses block from byte array
func (p *VIPSTARCOINParser) ParseBlock(b []byte) (*bchain.Block, error) {
r := bytes.NewReader(b)
w := wire.MsgBlock{}
h, err := parseBlockHeader(r)
if err != nil {
return nil, err
}
err = utils.DecodeTransactions(r, 0, wire.WitnessEncoding, &w)
if 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: h.Timestamp.Unix(),
},
Txs: txs,
}, nil
}
// ParseTxFromJson parses JSON message containing transaction and returns Tx struct
func (p *VIPSTARCOINParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) {
var tx bchain.Tx
err := json.Unmarshal(msg, &tx)
if err != nil {
return nil, err
}
for i := range tx.Vout {
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(vout.JsonValue)
if err != nil {
return nil, err
}
vout.JsonValue = ""
if vout.ScriptPubKey.Addresses == nil {
vout.ScriptPubKey.Addresses = []string{}
}
}
return &tx, nil
}