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