github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/qtum/qtumparser.go (about) 1 package qtum 2 3 import ( 4 "blockbook/bchain" 5 "blockbook/bchain/coins/btc" 6 "blockbook/bchain/coins/utils" 7 "bytes" 8 "encoding/json" 9 "io" 10 11 "github.com/martinboehm/btcd/wire" 12 "github.com/martinboehm/btcutil/chaincfg" 13 ) 14 15 // magic numbers 16 const ( 17 MainnetMagic wire.BitcoinNet = 0xf1cfa6d3 18 TestnetMagic wire.BitcoinNet = 0x0d221506 19 ) 20 21 // chain parameters 22 var ( 23 MainNetParams chaincfg.Params 24 TestNetParams chaincfg.Params 25 ) 26 27 func init() { 28 MainNetParams = chaincfg.MainNetParams 29 MainNetParams.Net = MainnetMagic 30 MainNetParams.PubKeyHashAddrID = []byte{58} 31 MainNetParams.ScriptHashAddrID = []byte{50} 32 MainNetParams.Bech32HRPSegwit = "qc" 33 34 TestNetParams = chaincfg.TestNet3Params 35 TestNetParams.Net = TestnetMagic 36 TestNetParams.PubKeyHashAddrID = []byte{120} 37 TestNetParams.ScriptHashAddrID = []byte{110} 38 TestNetParams.Bech32HRPSegwit = "tq" 39 } 40 41 // QtumParser handle 42 type QtumParser struct { 43 *btc.BitcoinParser 44 } 45 46 // NewQtumParser returns new DashParser instance 47 func NewQtumParser(params *chaincfg.Params, c *btc.Configuration) *QtumParser { 48 return &QtumParser{ 49 BitcoinParser: btc.NewBitcoinParser(params, c), 50 } 51 } 52 53 // GetChainParams contains network parameters for the main Qtum network, 54 // the regression test Qtum network, the test Qtum network and 55 // the simulation test Qtum network, in this order 56 func GetChainParams(chain string) *chaincfg.Params { 57 if !chaincfg.IsRegistered(&MainNetParams) { 58 err := chaincfg.Register(&MainNetParams) 59 if err == nil { 60 err = chaincfg.Register(&TestNetParams) 61 } 62 if err != nil { 63 panic(err) 64 } 65 } 66 switch chain { 67 case "test": 68 return &TestNetParams 69 default: 70 return &MainNetParams 71 } 72 } 73 74 func parseBlockHeader(r io.Reader) (*wire.BlockHeader, error) { 75 h := &wire.BlockHeader{} 76 err := h.Deserialize(r) 77 if err != nil { 78 return nil, err 79 } 80 81 // hash_state_root 32 82 // hash_utxo_root 32 83 // hash_prevout_stake 32 84 // hash_prevout_n 4 85 buf := make([]byte, 100) 86 _, err = io.ReadFull(r, buf) 87 if err != nil { 88 return nil, err 89 } 90 91 sigLength, err := wire.ReadVarInt(r, 0) 92 if err != nil { 93 return nil, err 94 } 95 sigBuf := make([]byte, sigLength) 96 _, err = io.ReadFull(r, sigBuf) 97 if err != nil { 98 return nil, err 99 } 100 101 return h, err 102 } 103 104 func (p *QtumParser) ParseBlock(b []byte) (*bchain.Block, error) { 105 r := bytes.NewReader(b) 106 w := wire.MsgBlock{} 107 108 h, err := parseBlockHeader(r) 109 if err != nil { 110 return nil, err 111 } 112 113 err = utils.DecodeTransactions(r, 0, wire.WitnessEncoding, &w) 114 if err != nil { 115 return nil, err 116 } 117 118 txs := make([]bchain.Tx, len(w.Transactions)) 119 for ti, t := range w.Transactions { 120 txs[ti] = p.TxFromMsgTx(t, false) 121 } 122 123 return &bchain.Block{ 124 BlockHeader: bchain.BlockHeader{ 125 Size: len(b), 126 Time: h.Timestamp.Unix(), 127 }, 128 Txs: txs, 129 }, nil 130 } 131 132 // ParseTxFromJson parses JSON message containing transaction and returns Tx struct 133 func (p *QtumParser) ParseTxFromJson(msg json.RawMessage) (*bchain.Tx, error) { 134 var tx bchain.Tx 135 err := json.Unmarshal(msg, &tx) 136 if err != nil { 137 return nil, err 138 } 139 140 for i := range tx.Vout { 141 vout := &tx.Vout[i] 142 // convert vout.JsonValue to big.Int and clear it, it is only temporary value used for unmarshal 143 vout.ValueSat, err = p.AmountToBigInt(vout.JsonValue) 144 if err != nil { 145 return nil, err 146 } 147 vout.JsonValue = "" 148 149 if vout.ScriptPubKey.Addresses == nil { 150 vout.ScriptPubKey.Addresses = []string{} 151 } 152 } 153 154 return &tx, nil 155 }