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 }