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  }