github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/btg/bgoldparser.go (about) 1 package btg 2 3 import ( 4 "blockbook/bchain" 5 "blockbook/bchain/coins/btc" 6 "blockbook/bchain/coins/utils" 7 "bytes" 8 "encoding/binary" 9 "io" 10 11 "github.com/martinboehm/btcd/chaincfg/chainhash" 12 "github.com/martinboehm/btcd/wire" 13 "github.com/martinboehm/btcutil/chaincfg" 14 ) 15 16 const ( 17 // MainnetMagic is mainnet network constant 18 MainnetMagic wire.BitcoinNet = 0x446d47e1 19 // TestnetMagic is testnet network constant 20 TestnetMagic wire.BitcoinNet = 0x456e48e2 21 ) 22 23 var ( 24 // MainNetParams are parser parameters for mainnet 25 MainNetParams chaincfg.Params 26 // TestNetParams are parser parameters for testnet 27 TestNetParams chaincfg.Params 28 ) 29 30 func init() { 31 MainNetParams = chaincfg.MainNetParams 32 MainNetParams.Net = MainnetMagic 33 34 // Address encoding magics 35 MainNetParams.PubKeyHashAddrID = []byte{38} // base58 prefix: G 36 MainNetParams.ScriptHashAddrID = []byte{23} // base58 prefix: A 37 38 TestNetParams = chaincfg.TestNet3Params 39 TestNetParams.Net = TestnetMagic 40 41 // Human-readable part for Bech32 encoded segwit addresses, as defined in 42 // BIP 173. 43 // see https://github.com/satoshilabs/slips/blob/master/slip-0173.md 44 MainNetParams.Bech32HRPSegwit = "btg" 45 TestNetParams.Bech32HRPSegwit = "tbtg" 46 } 47 48 // BGoldParser handle 49 type BGoldParser struct { 50 *btc.BitcoinParser 51 } 52 53 // NewBGoldParser returns new BGoldParser instance 54 func NewBGoldParser(params *chaincfg.Params, c *btc.Configuration) *BGoldParser { 55 return &BGoldParser{BitcoinParser: btc.NewBitcoinParser(params, c)} 56 } 57 58 // GetChainParams contains network parameters for the main Bitcoin Cash network, 59 // the regression test Bitcoin Cash network, the test Bitcoin Cash network and 60 // the simulation test Bitcoin Cash network, in this order 61 func GetChainParams(chain string) *chaincfg.Params { 62 if !chaincfg.IsRegistered(&MainNetParams) { 63 err := chaincfg.Register(&MainNetParams) 64 if err == nil { 65 err = chaincfg.Register(&TestNetParams) 66 } 67 if err != nil { 68 panic(err) 69 } 70 } 71 switch chain { 72 case "test": 73 return &TestNetParams 74 case "regtest": 75 return &chaincfg.RegressionNetParams 76 default: 77 return &MainNetParams 78 } 79 } 80 81 // headerFixedLength is the length of fixed fields of a block (i.e. without solution) 82 // see https://github.com/BTCGPU/BTCGPU/wiki/Technical-Spec#block-header 83 const headerFixedLength = 44 + (chainhash.HashSize * 3) 84 const timestampOffset = 100 85 const timestampLength = 4 86 87 // ParseBlock parses raw block to our Block struct 88 func (p *BGoldParser) ParseBlock(b []byte) (*bchain.Block, error) { 89 r := bytes.NewReader(b) 90 time, err := getTimestampAndSkipHeader(r, 0) 91 if err != nil { 92 return nil, err 93 } 94 95 w := wire.MsgBlock{} 96 err = utils.DecodeTransactions(r, 0, wire.WitnessEncoding, &w) 97 if err != nil { 98 return nil, err 99 } 100 101 txs := make([]bchain.Tx, len(w.Transactions)) 102 for ti, t := range w.Transactions { 103 txs[ti] = p.TxFromMsgTx(t, false) 104 } 105 106 return &bchain.Block{ 107 BlockHeader: bchain.BlockHeader{ 108 Size: len(b), 109 Time: time, 110 }, 111 Txs: txs, 112 }, nil 113 } 114 115 func getTimestampAndSkipHeader(r io.ReadSeeker, pver uint32) (int64, error) { 116 _, err := r.Seek(timestampOffset, io.SeekStart) 117 if err != nil { 118 return 0, err 119 } 120 121 buf := make([]byte, timestampLength) 122 if _, err = io.ReadFull(r, buf); err != nil { 123 return 0, err 124 } 125 time := binary.LittleEndian.Uint32(buf) 126 127 _, err = r.Seek(headerFixedLength-timestampOffset-timestampLength, io.SeekCurrent) 128 if err != nil { 129 return 0, err 130 } 131 132 size, err := wire.ReadVarInt(r, pver) 133 if err != nil { 134 return 0, err 135 } 136 137 _, err = r.Seek(int64(size), io.SeekCurrent) 138 if err != nil { 139 return 0, err 140 } 141 142 return int64(time), nil 143 }