github.com/cerberus-wallet/blockbook@v0.3.2/bchain/coins/liquid/liquidparser.go (about) 1 package liquid 2 3 import ( 4 "blockbook/bchain" 5 "blockbook/bchain/coins/btc" 6 "strconv" 7 8 vlq "github.com/bsm/go-vlq" 9 "github.com/golang/glog" 10 11 "github.com/martinboehm/btcd/txscript" 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 = 0xdab5bffa 19 ) 20 21 var ( 22 // MainNetParams are parser parameters for mainnet 23 MainNetParams chaincfg.Params 24 ) 25 26 func init() { 27 MainNetParams = chaincfg.MainNetParams 28 MainNetParams.Net = MainnetMagic 29 MainNetParams.PubKeyHashAddrID = []byte{57} 30 MainNetParams.ScriptHashAddrID = []byte{39} 31 // BLINDED_ADDRESS 12 32 } 33 34 // LiquidParser handle 35 type LiquidParser struct { 36 *btc.BitcoinParser 37 baseparser *bchain.BaseParser 38 origOutputScriptToAddressesFunc btc.OutputScriptToAddressesFunc 39 } 40 41 // NewLiquidParser returns new LiquidParser instance 42 func NewLiquidParser(params *chaincfg.Params, c *btc.Configuration) *LiquidParser { 43 p := &LiquidParser{ 44 BitcoinParser: btc.NewBitcoinParser(params, c), 45 baseparser: &bchain.BaseParser{}, 46 } 47 p.origOutputScriptToAddressesFunc = p.OutputScriptToAddressesFunc 48 p.OutputScriptToAddressesFunc = p.outputScriptToAddresses 49 return p 50 } 51 52 // GetChainParams contains network parameters for the main GameCredits network, 53 // and the test GameCredits network 54 func GetChainParams(chain string) *chaincfg.Params { 55 if !chaincfg.IsRegistered(&MainNetParams) { 56 err := chaincfg.Register(&MainNetParams) 57 if err != nil { 58 panic(err) 59 } 60 } 61 switch chain { 62 default: 63 return &MainNetParams 64 } 65 } 66 67 // PackTx packs transaction to byte array using protobuf 68 func (p *LiquidParser) PackTx(tx *bchain.Tx, height uint32, blockTime int64) ([]byte, error) { 69 return p.baseparser.PackTx(tx, height, blockTime) 70 } 71 72 // UnpackTx unpacks transaction from protobuf byte array 73 func (p *LiquidParser) UnpackTx(buf []byte) (*bchain.Tx, uint32, error) { 74 return p.baseparser.UnpackTx(buf) 75 } 76 77 // GetAddrDescForUnknownInput processes inputs that were not found in txAddresses - they are bitcoin transactions 78 // create a special script for the input in the form OP_INVALIDOPCODE <txid> <vout varint> 79 func (p *LiquidParser) GetAddrDescForUnknownInput(tx *bchain.Tx, input int) bchain.AddressDescriptor { 80 var iTxid string 81 s := make([]byte, 0, 40) 82 if len(tx.Vin) > input { 83 iTxid = tx.Vin[input].Txid 84 btxID, err := p.PackTxid(iTxid) 85 if err == nil { 86 buf := make([]byte, vlq.MaxLen64) 87 l := vlq.PutInt(buf, int64(tx.Vin[input].Vout)) 88 s = append(s, txscript.OP_INVALIDOPCODE) 89 s = append(s, btxID...) 90 s = append(s, buf[:l]...) 91 } 92 } 93 glog.Info("tx ", tx.Txid, ", encountered Bitcoin tx ", iTxid) 94 return s 95 } 96 97 // outputScriptToAddresses converts ScriptPubKey to bitcoin addresses 98 func (p *LiquidParser) outputScriptToAddresses(script []byte) ([]string, bool, error) { 99 // minimum length of the special script OP_INVALIDOPCODE <txid> <index varint> is 34 bytes (1 byte opcode, 32 bytes tx, 1 byte vout) 100 if len(script) > 33 && script[0] == txscript.OP_INVALIDOPCODE { 101 txid, _ := p.UnpackTxid(script[1:33]) 102 vout, _ := vlq.Int(script[33:]) 103 return []string{ 104 "Bitcoin tx " + txid + ":" + strconv.Itoa(int(vout)), 105 }, false, nil 106 } 107 return p.origOutputScriptToAddressesFunc(script) 108 }