github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/bchain/coins/liquid/liquidparser.go (about)

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