From d053181b0b52f483520d6fc2d07700104de8467d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 24 Jul 2015 16:00:10 +0930 Subject: [PATCH] script: add standard routines for secret-or-timedelay outputs. Signed-off-by: Rusty Russell --- bitcoin/script.c | 49 +++++++++++++++++++++++++++++++++----- bitcoin/script.h | 16 +++++++++---- test-cli/create-steal-tx.c | 5 +++- 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/bitcoin/script.c b/bitcoin/script.c index 27ac373e8..1555334b0 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -236,7 +236,44 @@ bool is_p2sh(const u8 *script, size_t script_len) return false; return true; } - + +/* A common script pattern: A can have it with secret, or B can have + * it after delay. */ +u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx, + const struct pubkey *delayed_key, + u32 locktime, + const struct pubkey *key_if_secret_known, + const struct sha256 *hash_of_secret) +{ + struct ripemd160 ripemd; + le32 locktime_le = cpu_to_le32(locktime); + u8 *script = tal_arr(ctx, u8, 0); + + ripemd160(&ripemd, hash_of_secret->u.u8, sizeof(hash_of_secret->u)); + + /* If the secret is supplied.... */ + add_op(&script, OP_HASH160); + add_push_bytes(&script, ripemd.u.u8, sizeof(ripemd.u.u8)); + add_op(&script, OP_EQUAL); + add_op(&script, OP_IF); + + /* They can collect the funds. */ + add_push_key(&script, key_if_secret_known); + + add_op(&script, OP_ELSE); + + /* Other can collect after a delay. */ + add_push_bytes(&script, &locktime_le, sizeof(locktime_le)); + add_op(&script, OP_CHECKSEQUENCEVERIFY); + add_op(&script, OP_DROP); + add_push_key(&script, delayed_key); + + add_op(&script, OP_ENDIF); + add_op(&script, OP_CHECKSIG); + + return script; +} + /* One of: * mysig and relative locktime passed, OR * theirsig and hash preimage. */ @@ -277,17 +314,17 @@ u8 *bitcoin_redeem_revocable(const tal_t *ctx, return script; } -u8 *scriptsig_p2sh_revoke(const tal_t *ctx, - const struct sha256 *preimage, +u8 *scriptsig_p2sh_secret(const tal_t *ctx, + const void *secret, size_t secret_len, const struct bitcoin_signature *sig, - const u8 *revocable_redeem, + const u8 *redeemscript, size_t redeem_len) { u8 *script = tal_arr(ctx, u8, 0); add_push_sig(&script, sig); - add_push_bytes(&script, preimage, sizeof(*preimage)); - add_push_bytes(&script, revocable_redeem, redeem_len); + add_push_bytes(&script, secret, secret_len); + add_push_bytes(&script, redeemscript, redeem_len); return script; } diff --git a/bitcoin/script.h b/bitcoin/script.h index 4407bc2a3..4513f322f 100644 --- a/bitcoin/script.h +++ b/bitcoin/script.h @@ -32,6 +32,14 @@ u8 *bitcoin_redeem_revocable(const tal_t *ctx, const struct pubkey *theirkey, const struct sha256 *revocation_hash); +/* A common script pattern: A can have it with secret, or B can have + * it after delay. */ +u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx, + const struct pubkey *delayed_key, + u32 locktime, + const struct pubkey *key_if_secret_known, + const struct sha256 *hash_of_secret); + /* Create an output script using p2sh for this redeem script. */ u8 *scriptpubkey_p2sh(const tal_t *ctx, const u8 *redeemscript); @@ -47,11 +55,11 @@ u8 *scriptsig_p2sh_2of2(const tal_t *ctx, const struct pubkey *key1, const struct pubkey *key2); -/* Create an input script to solve by revokehash */ -u8 *scriptsig_p2sh_revoke(const tal_t *ctx, - const struct sha256 *preimage, +/* Create an input script to solve by secret */ +u8 *scriptsig_p2sh_secret(const tal_t *ctx, + const void *secret, size_t secret_len, const struct bitcoin_signature *sig, - const u8 *revocable_redeem, + const u8 *redeemscript, size_t redeem_len); /* Create an input script which pushes sigs then redeem script. */ diff --git a/test-cli/create-steal-tx.c b/test-cli/create-steal-tx.c index 304d0be64..7c634439b 100644 --- a/test-cli/create-steal-tx.c +++ b/test-cli/create-steal-tx.c @@ -115,7 +115,10 @@ int main(int argc, char *argv[]) &privkey, &pubkey1, &sig.sig)) errx(1, "Could not sign tx"); sig.stype = SIGHASH_ALL; - tx->input[0].script = scriptsig_p2sh_revoke(tx, &revoke_preimage, &sig, + tx->input[0].script = scriptsig_p2sh_secret(tx, + &revoke_preimage, + sizeof(revoke_preimage), + &sig, redeemscript, tal_count(redeemscript)); tx->input[0].script_length = tal_count(tx->input[0].script);