github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/lnutil/lnlib.go (about)

     1  package lnutil
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/mit-dci/lit/logging"
     8  
     9  	"github.com/mit-dci/lit/btcutil/txscript"
    10  	"github.com/mit-dci/lit/wire"
    11  )
    12  
    13  // CommitScript is the script for 0.13.1: OP_CHECKSIG turned into OP_CHECSIGVERIFY
    14  func CommitScript(RKey, TKey [33]byte, delay uint16) []byte {
    15  	builder := txscript.NewScriptBuilder()
    16  
    17  	// 1 for penalty / revoked, 0 for timeout
    18  	// 1, so revoked
    19  	builder.AddOp(txscript.OP_IF)
    20  
    21  	// Just push revokable key
    22  	builder.AddData(RKey[:])
    23  
    24  	// 0, so timeout
    25  	builder.AddOp(txscript.OP_ELSE)
    26  
    27  	// CSV delay
    28  	builder.AddInt64(int64(delay))
    29  	// CSV check, fails here if too early
    30  	builder.AddOp(txscript.OP_NOP3) // really OP_CHECKSEQUENCEVERIFY
    31  	// Drop delay value
    32  	builder.AddOp(txscript.OP_DROP)
    33  	// push timeout key
    34  	builder.AddData(TKey[:])
    35  
    36  	builder.AddOp(txscript.OP_ENDIF)
    37  
    38  	// check whatever pubkey is left on the stack
    39  	builder.AddOp(txscript.OP_CHECKSIG)
    40  
    41  	// never any errors we care about here.
    42  	s, _ := builder.Script()
    43  	return s
    44  }
    45  
    46  // FundMultiPre generates the non-p2sh'd multisig script for 2 of 2 pubkeys.
    47  // useful for making transactions spending the fundtx.
    48  // returns a bool which is true if swapping occurs.
    49  func FundTxScript(aPub, bPub [33]byte) ([]byte, bool, error) {
    50  	var swapped bool
    51  	if bytes.Compare(aPub[:], bPub[:]) == -1 { // swap to sort pubkeys if needed
    52  		aPub, bPub = bPub, aPub
    53  		swapped = true
    54  	}
    55  	bldr := txscript.NewScriptBuilder()
    56  	// Require 1 signatures, either key// so from both of the pubkeys
    57  	bldr.AddOp(txscript.OP_2)
    58  	// add both pubkeys (sorted)
    59  	bldr.AddData(aPub[:])
    60  	bldr.AddData(bPub[:])
    61  	// 2 keys total.  In case that wasn't obvious.
    62  	bldr.AddOp(txscript.OP_2)
    63  	// Good ol OP_CHECKMULTISIG.  Don't forget the zero!
    64  	bldr.AddOp(txscript.OP_CHECKMULTISIG)
    65  	// get byte slice
    66  	pre, err := bldr.Script()
    67  	return pre, swapped, err
    68  }
    69  
    70  // FundTxOut creates a TxOut for the funding transaction.
    71  // Give it the two pubkeys and it'll give you the p2sh'd txout.
    72  // You don't have to remember the p2sh preimage, as long as you remember the
    73  // pubkeys involved.
    74  func FundTxOut(pubA, pubB [33]byte, amt int64) (*wire.TxOut, error) {
    75  	if amt < 0 {
    76  		return nil, fmt.Errorf("Can't create FundTx script with negative coins")
    77  	}
    78  	scriptBytes, _, err := FundTxScript(pubA, pubB)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	scriptBytes = P2WSHify(scriptBytes)
    83  
    84  	return wire.NewTxOut(amt, scriptBytes), nil
    85  }
    86  
    87  func ReceiveHTLCScript(revPKH [20]byte, remotePub [33]byte, RHash [32]byte, localPub [33]byte, locktime uint32) []byte {
    88  	logging.Infof("Generating receive HTLC with localPub [%x] and remotePub [%x]", localPub, remotePub)
    89  	b := txscript.NewScriptBuilder()
    90  
    91  	b.AddOp(txscript.OP_DUP)
    92  	b.AddOp(txscript.OP_HASH160)
    93  	b.AddData(revPKH[:])
    94  	b.AddOp(txscript.OP_EQUAL)
    95  	b.AddOp(txscript.OP_IF)
    96  	b.AddOp(txscript.OP_CHECKSIG)
    97  	b.AddOp(txscript.OP_ELSE)
    98  	b.AddData(remotePub[:])
    99  	b.AddOp(txscript.OP_SWAP)
   100  	b.AddOp(txscript.OP_SIZE)
   101  	b.AddInt64(16)
   102  	b.AddOp(txscript.OP_EQUAL)
   103  	b.AddOp(txscript.OP_IF)
   104  	b.AddOp(txscript.OP_SHA256)
   105  	b.AddData(RHash[:])
   106  	b.AddOp(txscript.OP_EQUALVERIFY)
   107  	b.AddInt64(2)
   108  	b.AddOp(txscript.OP_SWAP)
   109  	b.AddData(localPub[:])
   110  	b.AddInt64(2)
   111  	b.AddOp(txscript.OP_CHECKMULTISIG)
   112  	b.AddOp(txscript.OP_ELSE)
   113  	b.AddOp(txscript.OP_DROP)
   114  	b.AddInt64(int64(locktime))
   115  	b.AddOp(txscript.OP_CHECKLOCKTIMEVERIFY)
   116  	b.AddOp(txscript.OP_DROP)
   117  	b.AddOp(txscript.OP_CHECKSIG)
   118  	b.AddOp(txscript.OP_ENDIF)
   119  	b.AddOp(txscript.OP_ENDIF)
   120  
   121  	s, _ := b.Script()
   122  	return s
   123  }
   124  
   125  func OfferHTLCScript(revPKH [20]byte, remotePub [33]byte, RHash [32]byte, localPub [33]byte) []byte {
   126  	logging.Infof("Generating offer HTLC with localPub [%x] and remotePub [%x]", localPub, remotePub)
   127  	b := txscript.NewScriptBuilder()
   128  
   129  	b.AddOp(txscript.OP_DUP)
   130  	b.AddOp(txscript.OP_HASH160)
   131  	b.AddData(revPKH[:])
   132  	b.AddOp(txscript.OP_EQUAL)
   133  	b.AddOp(txscript.OP_IF)
   134  	b.AddOp(txscript.OP_CHECKSIG)
   135  	b.AddOp(txscript.OP_ELSE)
   136  	b.AddData(remotePub[:])
   137  	b.AddOp(txscript.OP_SWAP)
   138  	b.AddOp(txscript.OP_SIZE)
   139  	b.AddInt64(16)
   140  	b.AddOp(txscript.OP_EQUAL)
   141  	b.AddOp(txscript.OP_NOTIF)
   142  	b.AddOp(txscript.OP_DROP)
   143  	b.AddInt64(2)
   144  	b.AddOp(txscript.OP_SWAP)
   145  	b.AddData(localPub[:])
   146  	b.AddInt64(2)
   147  	b.AddOp(txscript.OP_CHECKMULTISIG)
   148  	b.AddOp(txscript.OP_ELSE)
   149  	b.AddOp(txscript.OP_SHA256)
   150  	b.AddData(RHash[:])
   151  	b.AddOp(txscript.OP_EQUALVERIFY)
   152  	b.AddOp(txscript.OP_CHECKSIG)
   153  	b.AddOp(txscript.OP_ENDIF)
   154  	b.AddOp(txscript.OP_ENDIF)
   155  
   156  	s, _ := b.Script()
   157  	return s
   158  }