github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/btc/bitcoinparser.go (about) 1 package btc 2 3 import ( 4 "encoding/json" 5 "math/big" 6 7 "github.com/martinboehm/btcutil/chaincfg" 8 "github.com/trezor/blockbook/bchain" 9 "github.com/trezor/blockbook/common" 10 ) 11 12 // BitcoinParser handle 13 type BitcoinParser struct { 14 *BitcoinLikeParser 15 } 16 17 // NewBitcoinParser returns new BitcoinParser instance 18 func NewBitcoinParser(params *chaincfg.Params, c *Configuration) *BitcoinParser { 19 p := &BitcoinParser{ 20 BitcoinLikeParser: NewBitcoinLikeParser(params, c), 21 } 22 p.VSizeSupport = true 23 return p 24 } 25 26 // GetChainParams contains network parameters for the main Bitcoin network, 27 // the regression test Bitcoin network, the test Bitcoin network and 28 // the simulation test Bitcoin network, in this order 29 func GetChainParams(chain string) *chaincfg.Params { 30 if !chaincfg.IsRegistered(&chaincfg.MainNetParams) { 31 chaincfg.RegisterBitcoinParams() 32 } 33 switch chain { 34 case "test": 35 return &chaincfg.TestNet3Params 36 case "regtest": 37 return &chaincfg.RegressionNetParams 38 case "signet": 39 return &chaincfg.SigNetParams 40 } 41 return &chaincfg.MainNetParams 42 } 43 44 // ScriptPubKey contains data about output script 45 type ScriptPubKey struct { 46 // Asm string `json:"asm"` 47 Hex string `json:"hex,omitempty"` 48 // Type string `json:"type"` 49 Addresses []string `json:"addresses"` // removed from Bitcoind 22.0.0 50 Address string `json:"address"` // used in Bitcoind 22.0.0 51 } 52 53 // Vout contains data about tx output 54 type Vout struct { 55 ValueSat big.Int 56 JsonValue common.JSONNumber `json:"value"` 57 N uint32 `json:"n"` 58 ScriptPubKey ScriptPubKey `json:"scriptPubKey"` 59 } 60 61 // Tx is blockchain transaction 62 // unnecessary fields are commented out to avoid overhead 63 type Tx struct { 64 Hex string `json:"hex"` 65 Txid string `json:"txid"` 66 Version int32 `json:"version"` 67 LockTime uint32 `json:"locktime"` 68 VSize int64 `json:"vsize,omitempty"` 69 Vin []bchain.Vin `json:"vin"` 70 Vout []Vout `json:"vout"` 71 BlockHeight uint32 `json:"blockHeight,omitempty"` 72 // BlockHash string `json:"blockhash,omitempty"` 73 Confirmations uint32 `json:"confirmations,omitempty"` 74 Time int64 `json:"time,omitempty"` 75 Blocktime int64 `json:"blocktime,omitempty"` 76 CoinSpecificData interface{} `json:"-"` 77 } 78 79 // ParseTxFromJson parses JSON message containing transaction and returns Tx struct 80 // Bitcoind version 22.0.0 removed ScriptPubKey.Addresses from the API and replaced it by a single Address 81 func (p *BitcoinParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) { 82 var bitcoinTx Tx 83 var tx bchain.Tx 84 err := json.Unmarshal(msg, &bitcoinTx) 85 if err != nil { 86 return nil, err 87 } 88 89 // it is necessary to copy bitcoinTx to Tx to make it compatible 90 tx.Hex = bitcoinTx.Hex 91 tx.Txid = bitcoinTx.Txid 92 tx.Version = bitcoinTx.Version 93 tx.LockTime = bitcoinTx.LockTime 94 tx.VSize = bitcoinTx.VSize 95 tx.Vin = bitcoinTx.Vin 96 tx.BlockHeight = bitcoinTx.BlockHeight 97 tx.Confirmations = bitcoinTx.Confirmations 98 tx.Time = bitcoinTx.Time 99 tx.Blocktime = bitcoinTx.Blocktime 100 tx.CoinSpecificData = bitcoinTx.CoinSpecificData 101 tx.Vout = make([]bchain.Vout, len(bitcoinTx.Vout)) 102 103 for i := range bitcoinTx.Vout { 104 bitcoinVout := &bitcoinTx.Vout[i] 105 vout := &tx.Vout[i] 106 // convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal 107 vout.ValueSat, err = p.AmountToBigInt(bitcoinVout.JsonValue) 108 if err != nil { 109 return nil, err 110 } 111 vout.N = bitcoinVout.N 112 vout.ScriptPubKey.Hex = bitcoinVout.ScriptPubKey.Hex 113 // convert single Address to Addresses if Addresses are empty 114 if len(bitcoinVout.ScriptPubKey.Addresses) == 0 { 115 vout.ScriptPubKey.Addresses = []string{bitcoinVout.ScriptPubKey.Address} 116 } else { 117 vout.ScriptPubKey.Addresses = bitcoinVout.ScriptPubKey.Addresses 118 } 119 } 120 121 return &tx, nil 122 }