github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/litecoin/litecoinparser.go (about) 1 package litecoin 2 3 import ( 4 "encoding/json" 5 6 "github.com/golang/glog" 7 "github.com/martinboehm/btcd/wire" 8 "github.com/martinboehm/btcutil/chaincfg" 9 "github.com/trezor/blockbook/bchain" 10 "github.com/trezor/blockbook/bchain/coins/btc" 11 ) 12 13 // magic numbers 14 const ( 15 MainnetMagic wire.BitcoinNet = 0xdbb6c0fb 16 TestnetMagic wire.BitcoinNet = 0xf1c8d2fd 17 RegtestMagic wire.BitcoinNet = 0xdab5bffa 18 ) 19 20 // chain parameters 21 var ( 22 MainNetParams chaincfg.Params 23 TestNetParams chaincfg.Params 24 ) 25 26 func init() { 27 MainNetParams = chaincfg.MainNetParams 28 MainNetParams.Net = MainnetMagic 29 MainNetParams.PubKeyHashAddrID = []byte{48} 30 MainNetParams.ScriptHashAddrID = []byte{50} 31 MainNetParams.Bech32HRPSegwit = "ltc" 32 33 TestNetParams = chaincfg.TestNet3Params 34 TestNetParams.Net = TestnetMagic 35 TestNetParams.PubKeyHashAddrID = []byte{111} 36 TestNetParams.ScriptHashAddrID = []byte{58} 37 TestNetParams.Bech32HRPSegwit = "tltc" 38 } 39 40 // LitecoinParser handle 41 type LitecoinParser struct { 42 *btc.BitcoinLikeParser 43 baseparser *bchain.BaseParser 44 } 45 46 // NewLitecoinParser returns new LitecoinParser instance 47 func NewLitecoinParser(params *chaincfg.Params, c *btc.Configuration) *LitecoinParser { 48 p := &LitecoinParser{ 49 BitcoinLikeParser: btc.NewBitcoinLikeParser(params, c), 50 baseparser: &bchain.BaseParser{}, 51 } 52 p.VSizeSupport = true 53 return p 54 } 55 56 // GetChainParams contains network parameters for the main Litecoin network, 57 // and the test Litecoin network 58 func GetChainParams(chain string) *chaincfg.Params { 59 // register bitcoin parameters in addition to litecoin parameters 60 // litecoin has dual standard of addresses and we want to be able to 61 // parse both standards 62 if !chaincfg.IsRegistered(&chaincfg.MainNetParams) { 63 chaincfg.RegisterBitcoinParams() 64 } 65 if !chaincfg.IsRegistered(&MainNetParams) { 66 err := chaincfg.Register(&MainNetParams) 67 if err == nil { 68 err = chaincfg.Register(&TestNetParams) 69 } 70 if err != nil { 71 panic(err) 72 } 73 } 74 switch chain { 75 case "test": 76 return &TestNetParams 77 default: 78 return &MainNetParams 79 } 80 } 81 82 // fallbackTx is used to handle situation when Litecoin mainnet returns 83 // for certain transactions Version 4294967295 instead of -1, which causes json unmarshal error 84 type fallbackTx struct { 85 Hex string `json:"hex"` 86 Txid string `json:"txid"` 87 Version uint32 `json:"version"` 88 LockTime uint32 `json:"locktime"` 89 Vin []bchain.Vin `json:"vin"` 90 Vout []bchain.Vout `json:"vout"` 91 BlockHeight uint32 `json:"blockHeight,omitempty"` 92 // BlockHash string `json:"blockhash,omitempty"` 93 Confirmations uint32 `json:"confirmations,omitempty"` 94 Time int64 `json:"time,omitempty"` 95 Blocktime int64 `json:"blocktime,omitempty"` 96 } 97 98 // ParseTxFromJson parses JSON message containing transaction and returns Tx struct 99 func (p *LitecoinParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) { 100 var tx bchain.Tx 101 err := json.Unmarshal(msg, &tx) 102 if err != nil { 103 var fTx fallbackTx 104 fErr := json.Unmarshal(msg, &fTx) 105 // log warning with Txid possibly parsed using fallbackTx 106 glog.Warningf("ParseTxFromJson txid %s to bchain.Tx error %v, using fallback method", fTx.Txid, err) 107 if fErr != nil { 108 return nil, fErr 109 } 110 tx.Hex = fTx.Hex 111 tx.Txid = fTx.Txid 112 tx.Version = int32(fTx.Version) 113 tx.LockTime = fTx.LockTime 114 tx.Vin = fTx.Vin 115 tx.Vout = fTx.Vout 116 tx.BlockHeight = fTx.BlockHeight 117 tx.Confirmations = fTx.Confirmations 118 tx.Time = fTx.Time 119 tx.Blocktime = fTx.Blocktime 120 } 121 122 for i := range tx.Vout { 123 vout := &tx.Vout[i] 124 // convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal 125 vout.ValueSat, err = p.AmountToBigInt(vout.JsonValue) 126 if err != nil { 127 return nil, err 128 } 129 vout.JsonValue = "" 130 } 131 132 return &tx, nil 133 } 134 135 // PackTx packs transaction to byte array using protobuf 136 func (p *LitecoinParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) { 137 return p.baseparser.PackTx(tx, height, blockTime) 138 } 139 140 // UnpackTx unpacks transaction from protobuf byte array 141 func (p *LitecoinParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { 142 return p.baseparser.UnpackTx(buf) 143 }