Scripts.hs (18717B)
1 {-# OPTIONS_HADDOCK prune #-} 2 {-# LANGUAGE BangPatterns #-} 3 {-# LANGUAGE OverloadedStrings #-} 4 5 -- | 6 -- Module: Lightning.Protocol.BOLT3.Scripts 7 -- Copyright: (c) 2025 Jared Tobin 8 -- License: MIT 9 -- Maintainer: Jared Tobin <jared@ppad.tech> 10 -- 11 -- Script templates for BOLT #3 transaction outputs. 12 -- 13 -- Includes witness scripts for: 14 -- 15 -- * Funding output (2-of-2 multisig) 16 -- * to_local output (revocable with CSV delay) 17 -- * to_remote output (P2WPKH or anchored) 18 -- * Anchor outputs 19 -- * Offered HTLC outputs 20 -- * Received HTLC outputs 21 -- * HTLC-timeout/success output (revocable with delay) 22 23 module Lightning.Protocol.BOLT3.Scripts ( 24 -- * Funding output 25 funding_script 26 , funding_witness 27 28 -- * to_local output 29 , to_local_script 30 , to_local_witness_spend 31 , to_local_witness_revoke 32 33 -- * to_remote output 34 , to_remote_script 35 , to_remote_witness 36 37 -- * Anchor outputs 38 , anchor_script 39 , anchor_witness_owner 40 , anchor_witness_anyone 41 42 -- * Offered HTLC output 43 , offered_htlc_script 44 , offered_htlc_witness_preimage 45 , offered_htlc_witness_revoke 46 47 -- * Received HTLC output 48 , received_htlc_script 49 , received_htlc_witness_timeout 50 , received_htlc_witness_revoke 51 52 -- * HTLC-timeout/success output (same as to_local) 53 , htlc_output_script 54 , htlc_output_witness_spend 55 , htlc_output_witness_revoke 56 57 -- * P2WSH helpers 58 , to_p2wsh 59 , witness_script_hash 60 ) where 61 62 import Data.Bits ((.&.), shiftR) 63 import Data.Word (Word8, Word16, Word32) 64 import qualified Data.ByteString as BS 65 import qualified Data.ByteString.Builder as BSB 66 import qualified Data.ByteString.Lazy as BSL 67 import qualified Crypto.Hash.SHA256 as SHA256 68 import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 69 import Lightning.Protocol.BOLT3.Types 70 71 -- opcodes --------------------------------------------------------------------- 72 73 -- | OP_0 / OP_FALSE (0x00) 74 op_0 :: Word8 75 op_0 = 0x00 76 77 -- | OP_PUSHDATA for 1-75 bytes just uses the length as opcode 78 -- For data <=75 bytes, opcode is just the length 79 80 -- | OP_IF (0x63) 81 op_if :: Word8 82 op_if = 0x63 83 84 -- | OP_NOTIF (0x64) 85 op_notif :: Word8 86 op_notif = 0x64 87 88 -- | OP_ELSE (0x67) 89 op_else :: Word8 90 op_else = 0x67 91 92 -- | OP_ENDIF (0x68) 93 op_endif :: Word8 94 op_endif = 0x68 95 96 -- | OP_DROP (0x75) 97 op_drop :: Word8 98 op_drop = 0x75 99 100 -- | OP_DUP (0x76) 101 op_dup :: Word8 102 op_dup = 0x76 103 104 -- | OP_SWAP (0x7c) 105 op_swap :: Word8 106 op_swap = 0x7c 107 108 -- | OP_SIZE (0x82) 109 op_size :: Word8 110 op_size = 0x82 111 112 -- | OP_EQUAL (0x87) 113 op_equal :: Word8 114 op_equal = 0x87 115 116 -- | OP_EQUALVERIFY (0x88) 117 op_equalverify :: Word8 118 op_equalverify = 0x88 119 120 -- | OP_IFDUP (0x73) 121 op_ifdup :: Word8 122 op_ifdup = 0x73 123 124 -- | OP_HASH160 (0xa9) 125 op_hash160 :: Word8 126 op_hash160 = 0xa9 127 128 -- | OP_CHECKSIG (0xac) 129 op_checksig :: Word8 130 op_checksig = 0xac 131 132 -- | OP_CHECKSIGVERIFY (0xad) 133 op_checksigverify :: Word8 134 op_checksigverify = 0xad 135 136 -- | OP_CHECKMULTISIG (0xae) 137 op_checkmultisig :: Word8 138 op_checkmultisig = 0xae 139 140 -- | OP_CHECKLOCKTIMEVERIFY (0xb1) 141 op_checklocktimeverify :: Word8 142 op_checklocktimeverify = 0xb1 143 144 -- | OP_CHECKSEQUENCEVERIFY (0xb2) 145 op_checksequenceverify :: Word8 146 op_checksequenceverify = 0xb2 147 148 -- | OP_1 (0x51) 149 op_1 :: Word8 150 op_1 = 0x51 151 152 -- | OP_2 (0x52) 153 op_2 :: Word8 154 op_2 = 0x52 155 156 -- | OP_16 (0x60) 157 op_16 :: Word8 158 op_16 = 0x60 159 160 -- helpers --------------------------------------------------------------------- 161 162 -- | Push a bytestring onto the stack (handles length encoding). 163 -- 164 -- For data <= 75 bytes, the length itself is the opcode. 165 push_data :: BS.ByteString -> BSB.Builder 166 push_data !bs 167 | len <= 75 = BSB.word8 (fromIntegral len) <> BSB.byteString bs 168 | len <= 255 = BSB.word8 0x4c <> BSB.word8 (fromIntegral len) 169 <> BSB.byteString bs 170 | len <= 65535 = BSB.word8 0x4d <> BSB.word16LE (fromIntegral len) 171 <> BSB.byteString bs 172 | otherwise = BSB.word8 0x4e <> BSB.word32LE (fromIntegral len) 173 <> BSB.byteString bs 174 where 175 !len = BS.length bs 176 {-# INLINE push_data #-} 177 178 -- | Encode a Word16 as minimal script number (for CSV delays). 179 push_csv_delay :: Word16 -> BSB.Builder 180 push_csv_delay !n 181 | n == 0 = BSB.word8 op_0 182 | n <= 16 = BSB.word8 (0x50 + fromIntegral n) 183 | n <= 0x7f = push_data (BS.singleton (fromIntegral n)) 184 | n <= 0x7fff = push_data (BS.pack [lo, hi]) 185 | otherwise = push_data (BS.pack [lo, hi, 0x00]) -- need sign byte 186 where 187 !lo = fromIntegral (n .&. 0xff) 188 !hi = fromIntegral ((n `shiftR` 8) .&. 0xff) 189 {-# INLINE push_csv_delay #-} 190 191 -- | Encode a Word32 as minimal script number (for CLTV). 192 push_cltv :: Word32 -> BSB.Builder 193 push_cltv !n 194 | n == 0 = BSB.word8 op_0 195 | n <= 16 = BSB.word8 (0x50 + fromIntegral n) 196 | otherwise = push_data (encode_scriptnum n) 197 where 198 encode_scriptnum :: Word32 -> BS.ByteString 199 encode_scriptnum 0 = BS.empty 200 encode_scriptnum !v = 201 let -- Build bytes little-endian (LSB first) 202 go :: Word32 -> [Word8] 203 go 0 = [] 204 go !x = fromIntegral (x .&. 0xff) : go (x `shiftR` 8) 205 !bytes = go v 206 -- If MSB has high bit set, need 0x00 suffix for positive numbers 207 !result = case reverse bytes of 208 [] -> bytes 209 (msb:_) | msb .&. 0x80 /= 0 -> bytes ++ [0x00] 210 _ -> bytes 211 in BS.pack result 212 {-# INLINE push_cltv #-} 213 214 -- | Build script from builder. 215 build_script :: BSB.Builder -> Script 216 build_script = Script . BSL.toStrict . BSB.toLazyByteString 217 {-# INLINE build_script #-} 218 219 -- | HASH160 = RIPEMD160(SHA256(x)) 220 hash160 :: BS.ByteString -> BS.ByteString 221 hash160 = RIPEMD160.hash . SHA256.hash 222 {-# INLINE hash160 #-} 223 224 -- P2WSH helpers --------------------------------------------------------------- 225 226 -- | Compute SHA256 hash of a witness script. 227 -- 228 -- >>> witness_script_hash (Script "some_script") 229 -- <32-byte SHA256 hash> 230 witness_script_hash :: Script -> BS.ByteString 231 witness_script_hash (Script !s) = SHA256.hash s 232 {-# INLINE witness_script_hash #-} 233 234 -- | Convert a witness script to P2WSH scriptPubKey. 235 -- 236 -- P2WSH format: OP_0 <32-byte-hash> 237 -- 238 -- >>> to_p2wsh some_witness_script 239 -- Script "\x00\x20<32-byte-hash>" 240 to_p2wsh :: Script -> Script 241 to_p2wsh !script = 242 let !h = witness_script_hash script 243 in build_script (BSB.word8 op_0 <> push_data h) 244 {-# INLINE to_p2wsh #-} 245 246 -- funding output -------------------------------------------------------------- 247 248 -- | Funding output witness script (2-of-2 multisig). 249 -- 250 -- Script: @2 <pubkey1> <pubkey2> 2 OP_CHECKMULTISIG@ 251 -- 252 -- Where pubkey1 is lexicographically lesser. 253 -- 254 -- >>> funding_script pk1 pk2 255 -- Script "R!<pk_lesser>!<pk_greater>R\xae" 256 funding_script :: FundingPubkey -> FundingPubkey -> Script 257 funding_script (FundingPubkey (Pubkey !pk1)) (FundingPubkey (Pubkey !pk2)) = 258 let (!lesser, !greater) = if pk1 <= pk2 then (pk1, pk2) else (pk2, pk1) 259 in build_script $ 260 BSB.word8 op_2 261 <> push_data lesser 262 <> push_data greater 263 <> BSB.word8 op_2 264 <> BSB.word8 op_checkmultisig 265 266 -- | Witness for spending funding output. 267 -- 268 -- Witness: @0 <sig1> <sig2>@ 269 -- 270 -- Signatures ordered to match pubkey order in script. 271 -- 272 -- >>> funding_witness sig1 sig2 273 -- Witness ["", sig1, sig2] 274 funding_witness :: BS.ByteString -> BS.ByteString -> Witness 275 funding_witness !sig1 !sig2 = Witness [BS.empty, sig1, sig2] 276 277 -- to_local output ------------------------------------------------------------- 278 279 -- | to_local witness script (revocable with CSV delay). 280 -- 281 -- Script: 282 -- 283 -- @ 284 -- OP_IF 285 -- <revocationpubkey> 286 -- OP_ELSE 287 -- <to_self_delay> 288 -- OP_CHECKSEQUENCEVERIFY 289 -- OP_DROP 290 -- <local_delayedpubkey> 291 -- OP_ENDIF 292 -- OP_CHECKSIG 293 -- @ 294 -- 295 -- >>> to_local_script revpk delay localpk 296 -- Script "c!<revpk>g<delay>\xb2u!<localpk>h\xac" 297 to_local_script 298 :: RevocationPubkey 299 -> ToSelfDelay 300 -> LocalDelayedPubkey 301 -> Script 302 to_local_script 303 (RevocationPubkey (Pubkey !revpk)) 304 (ToSelfDelay !delay) 305 (LocalDelayedPubkey (Pubkey !localpk)) = 306 build_script $ 307 BSB.word8 op_if 308 <> push_data revpk 309 <> BSB.word8 op_else 310 <> push_csv_delay delay 311 <> BSB.word8 op_checksequenceverify 312 <> BSB.word8 op_drop 313 <> push_data localpk 314 <> BSB.word8 op_endif 315 <> BSB.word8 op_checksig 316 317 -- | Witness for delayed spend of to_local output. 318 -- 319 -- Input nSequence must be set to to_self_delay. 320 -- 321 -- Witness: @<local_delayedsig> <>@ 322 -- 323 -- >>> to_local_witness_spend sig 324 -- Witness [sig, ""] 325 to_local_witness_spend :: BS.ByteString -> Witness 326 to_local_witness_spend !sig = Witness [sig, BS.empty] 327 328 -- | Witness for revocation spend of to_local output. 329 -- 330 -- Witness: @<revocation_sig> 1@ 331 -- 332 -- >>> to_local_witness_revoke sig 333 -- Witness [sig, "\x01"] 334 to_local_witness_revoke :: BS.ByteString -> Witness 335 to_local_witness_revoke !sig = Witness [sig, BS.singleton 0x01] 336 337 -- to_remote output ------------------------------------------------------------ 338 339 -- | to_remote witness script. 340 -- 341 -- With option_anchors: 342 -- 343 -- @ 344 -- <remotepubkey> OP_CHECKSIGVERIFY 1 OP_CHECKSEQUENCEVERIFY 345 -- @ 346 -- 347 -- Without option_anchors: P2WPKH (just the pubkey hash). 348 -- 349 -- >>> to_remote_script pk (ChannelFeatures True) 350 -- Script "!<pk>\xadQ\xb2" 351 to_remote_script :: RemotePubkey -> ChannelFeatures -> Script 352 to_remote_script (RemotePubkey (Pubkey !pk)) !features 353 | has_anchors features = 354 -- Anchors: script with 1-block CSV 355 build_script $ 356 push_data pk 357 <> BSB.word8 op_checksigverify 358 <> BSB.word8 op_1 359 <> BSB.word8 op_checksequenceverify 360 | otherwise = 361 -- No anchors: P2WPKH (OP_0 <20-byte-hash>) 362 let !h = hash160 pk 363 in build_script (BSB.word8 op_0 <> push_data h) 364 365 -- | Witness for spending to_remote output. 366 -- 367 -- With option_anchors (P2WSH), input nSequence must be 1. 368 -- Witness: @<remote_sig>@ (witness script appended by caller) 369 -- 370 -- Without option_anchors (P2WPKH): 371 -- Witness: @<remote_sig> <remotepubkey>@ 372 -- 373 -- >>> to_remote_witness sig pk (ChannelFeatures False) 374 -- Witness [sig, pk] 375 to_remote_witness :: BS.ByteString -> RemotePubkey -> ChannelFeatures -> Witness 376 to_remote_witness !sig (RemotePubkey (Pubkey !pk)) !features 377 | has_anchors features = Witness [sig] 378 | otherwise = Witness [sig, pk] 379 380 -- anchor outputs -------------------------------------------------------------- 381 382 -- | Anchor output witness script. 383 -- 384 -- Script: 385 -- 386 -- @ 387 -- <funding_pubkey> OP_CHECKSIG OP_IFDUP 388 -- OP_NOTIF 389 -- OP_16 OP_CHECKSEQUENCEVERIFY 390 -- OP_ENDIF 391 -- @ 392 -- 393 -- >>> anchor_script fundpk 394 -- Script "!<fundpk>\xac\x73d`\xb2h" 395 anchor_script :: FundingPubkey -> Script 396 anchor_script (FundingPubkey (Pubkey !pk)) = 397 build_script $ 398 push_data pk 399 <> BSB.word8 op_checksig 400 <> BSB.word8 op_ifdup 401 <> BSB.word8 op_notif 402 <> BSB.word8 op_16 403 <> BSB.word8 op_checksequenceverify 404 <> BSB.word8 op_endif 405 406 -- | Witness for owner to spend anchor output. 407 -- 408 -- Witness: @<sig>@ 409 -- 410 -- >>> anchor_witness_owner sig 411 -- Witness [sig] 412 anchor_witness_owner :: BS.ByteString -> Witness 413 anchor_witness_owner !sig = Witness [sig] 414 415 -- | Witness for anyone to sweep anchor output after 16 blocks. 416 -- 417 -- Witness: @<>@ 418 -- 419 -- >>> anchor_witness_anyone 420 -- Witness [""] 421 anchor_witness_anyone :: Witness 422 anchor_witness_anyone = Witness [BS.empty] 423 424 -- offered HTLC output --------------------------------------------------------- 425 426 -- | Offered HTLC witness script. 427 -- 428 -- Without option_anchors: 429 -- 430 -- @ 431 -- OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL 432 -- OP_IF 433 -- OP_CHECKSIG 434 -- OP_ELSE 435 -- <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL 436 -- OP_NOTIF 437 -- OP_DROP 2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG 438 -- OP_ELSE 439 -- OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY 440 -- OP_CHECKSIG 441 -- OP_ENDIF 442 -- OP_ENDIF 443 -- @ 444 -- 445 -- With option_anchors, adds @1 OP_CHECKSEQUENCEVERIFY OP_DROP@ before 446 -- final OP_ENDIF. 447 offered_htlc_script 448 :: RevocationPubkey 449 -> RemoteHtlcPubkey 450 -> LocalHtlcPubkey 451 -> PaymentHash 452 -> ChannelFeatures 453 -> Script 454 offered_htlc_script 455 (RevocationPubkey (Pubkey !revpk)) 456 (RemoteHtlcPubkey (Pubkey !remotepk)) 457 (LocalHtlcPubkey (Pubkey !localpk)) 458 (PaymentHash !ph) 459 !features = 460 let !revpk_hash = hash160 revpk 461 !payment_hash160 = RIPEMD160.hash ph 462 !csv_suffix = if has_anchors features 463 then BSB.word8 op_1 464 <> BSB.word8 op_checksequenceverify 465 <> BSB.word8 op_drop 466 else mempty 467 in build_script $ 468 -- OP_DUP OP_HASH160 <revpk_hash> OP_EQUAL 469 BSB.word8 op_dup 470 <> BSB.word8 op_hash160 471 <> push_data revpk_hash 472 <> BSB.word8 op_equal 473 -- OP_IF OP_CHECKSIG 474 <> BSB.word8 op_if 475 <> BSB.word8 op_checksig 476 -- OP_ELSE 477 <> BSB.word8 op_else 478 -- <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL 479 <> push_data remotepk 480 <> BSB.word8 op_swap 481 <> BSB.word8 op_size 482 <> push_data (BS.singleton 32) 483 <> BSB.word8 op_equal 484 -- OP_NOTIF 485 <> BSB.word8 op_notif 486 -- OP_DROP 2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG 487 <> BSB.word8 op_drop 488 <> BSB.word8 op_2 489 <> BSB.word8 op_swap 490 <> push_data localpk 491 <> BSB.word8 op_2 492 <> BSB.word8 op_checkmultisig 493 -- OP_ELSE 494 <> BSB.word8 op_else 495 -- OP_HASH160 <payment_hash160> OP_EQUALVERIFY OP_CHECKSIG 496 <> BSB.word8 op_hash160 497 <> push_data payment_hash160 498 <> BSB.word8 op_equalverify 499 <> BSB.word8 op_checksig 500 -- OP_ENDIF 501 <> BSB.word8 op_endif 502 -- CSV suffix for anchors 503 <> csv_suffix 504 -- OP_ENDIF 505 <> BSB.word8 op_endif 506 507 -- | Witness for remote node to claim offered HTLC with preimage. 508 -- 509 -- With option_anchors, input nSequence must be 1. 510 -- 511 -- Witness: @<remotehtlcsig> <payment_preimage>@ 512 -- 513 -- >>> offered_htlc_witness_preimage sig preimage 514 -- Witness [sig, preimage] 515 offered_htlc_witness_preimage 516 :: BS.ByteString -> PaymentPreimage -> Witness 517 offered_htlc_witness_preimage !sig (PaymentPreimage !preimage) = 518 Witness [sig, preimage] 519 520 -- | Witness for revocation spend of offered HTLC. 521 -- 522 -- Witness: @<revocation_sig> <revocationpubkey>@ 523 -- 524 -- >>> offered_htlc_witness_revoke sig revpk 525 -- Witness [sig, revpk] 526 offered_htlc_witness_revoke :: BS.ByteString -> Pubkey -> Witness 527 offered_htlc_witness_revoke !sig (Pubkey !revpk) = Witness [sig, revpk] 528 529 -- received HTLC output -------------------------------------------------------- 530 531 -- | Received HTLC witness script. 532 -- 533 -- Without option_anchors: 534 -- 535 -- @ 536 -- OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL 537 -- OP_IF 538 -- OP_CHECKSIG 539 -- OP_ELSE 540 -- <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL 541 -- OP_IF 542 -- OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY 543 -- 2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG 544 -- OP_ELSE 545 -- OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP 546 -- OP_CHECKSIG 547 -- OP_ENDIF 548 -- OP_ENDIF 549 -- @ 550 -- 551 -- With option_anchors, adds @1 OP_CHECKSEQUENCEVERIFY OP_DROP@ before 552 -- final OP_ENDIF. 553 received_htlc_script 554 :: RevocationPubkey 555 -> RemoteHtlcPubkey 556 -> LocalHtlcPubkey 557 -> PaymentHash 558 -> CltvExpiry 559 -> ChannelFeatures 560 -> Script 561 received_htlc_script 562 (RevocationPubkey (Pubkey !revpk)) 563 (RemoteHtlcPubkey (Pubkey !remotepk)) 564 (LocalHtlcPubkey (Pubkey !localpk)) 565 (PaymentHash !ph) 566 (CltvExpiry !expiry) 567 !features = 568 let !revpk_hash = hash160 revpk 569 !payment_hash160 = RIPEMD160.hash ph 570 !csv_suffix = if has_anchors features 571 then BSB.word8 op_1 572 <> BSB.word8 op_checksequenceverify 573 <> BSB.word8 op_drop 574 else mempty 575 in build_script $ 576 -- OP_DUP OP_HASH160 <revpk_hash> OP_EQUAL 577 BSB.word8 op_dup 578 <> BSB.word8 op_hash160 579 <> push_data revpk_hash 580 <> BSB.word8 op_equal 581 -- OP_IF OP_CHECKSIG 582 <> BSB.word8 op_if 583 <> BSB.word8 op_checksig 584 -- OP_ELSE 585 <> BSB.word8 op_else 586 -- <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL 587 <> push_data remotepk 588 <> BSB.word8 op_swap 589 <> BSB.word8 op_size 590 <> push_data (BS.singleton 32) 591 <> BSB.word8 op_equal 592 -- OP_IF 593 <> BSB.word8 op_if 594 -- OP_HASH160 <payment_hash160> OP_EQUALVERIFY 595 <> BSB.word8 op_hash160 596 <> push_data payment_hash160 597 <> BSB.word8 op_equalverify 598 -- 2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG 599 <> BSB.word8 op_2 600 <> BSB.word8 op_swap 601 <> push_data localpk 602 <> BSB.word8 op_2 603 <> BSB.word8 op_checkmultisig 604 -- OP_ELSE 605 <> BSB.word8 op_else 606 -- OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP OP_CHECKSIG 607 <> BSB.word8 op_drop 608 <> push_cltv expiry 609 <> BSB.word8 op_checklocktimeverify 610 <> BSB.word8 op_drop 611 <> BSB.word8 op_checksig 612 -- OP_ENDIF 613 <> BSB.word8 op_endif 614 -- CSV suffix for anchors 615 <> csv_suffix 616 -- OP_ENDIF 617 <> BSB.word8 op_endif 618 619 -- | Witness for remote node to timeout received HTLC. 620 -- 621 -- With option_anchors, input nSequence must be 1. 622 -- 623 -- Witness: @<remotehtlcsig> <>@ 624 -- 625 -- >>> received_htlc_witness_timeout sig 626 -- Witness [sig, ""] 627 received_htlc_witness_timeout :: BS.ByteString -> Witness 628 received_htlc_witness_timeout !sig = Witness [sig, BS.empty] 629 630 -- | Witness for revocation spend of received HTLC. 631 -- 632 -- Witness: @<revocation_sig> <revocationpubkey>@ 633 -- 634 -- >>> received_htlc_witness_revoke sig revpk 635 -- Witness [sig, revpk] 636 received_htlc_witness_revoke :: BS.ByteString -> Pubkey -> Witness 637 received_htlc_witness_revoke !sig (Pubkey !revpk) = Witness [sig, revpk] 638 639 -- HTLC-timeout/success output ------------------------------------------------- 640 641 -- | HTLC output witness script (same structure as to_local). 642 -- 643 -- Used for HTLC-timeout and HTLC-success transaction outputs. 644 -- 645 -- Script: 646 -- 647 -- @ 648 -- OP_IF 649 -- <revocationpubkey> 650 -- OP_ELSE 651 -- <to_self_delay> 652 -- OP_CHECKSEQUENCEVERIFY 653 -- OP_DROP 654 -- <local_delayedpubkey> 655 -- OP_ENDIF 656 -- OP_CHECKSIG 657 -- @ 658 htlc_output_script 659 :: RevocationPubkey 660 -> ToSelfDelay 661 -> LocalDelayedPubkey 662 -> Script 663 htlc_output_script = to_local_script 664 665 -- | Witness for delayed spend of HTLC output. 666 -- 667 -- Input nSequence must be set to to_self_delay. 668 -- 669 -- Witness: @<local_delayedsig> 0@ 670 htlc_output_witness_spend :: BS.ByteString -> Witness 671 htlc_output_witness_spend = to_local_witness_spend 672 673 -- | Witness for revocation spend of HTLC output. 674 -- 675 -- Witness: @<revocationsig> 1@ 676 htlc_output_witness_revoke :: BS.ByteString -> Witness 677 htlc_output_witness_revoke = to_local_witness_revoke