core-lightning/lightningd/test/run-funding_tx.c
Rusty Russell ccff3ac437 lightningd/funding_tx: fill in scriptsigs for p2sh UTXOs.
This is a bit tricky: for our signing code, we don't want scriptsigs,
but to calculate the txid, we need them.  For most transactions in lightning,
they're pure segwit so it doesn't matter, but funding transactions can
have P2SH-wrapped P2WPKH inputs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-03-07 11:31:55 +10:30

136 lines
4.4 KiB
C

#include <bitcoin/base58.h>
#include <bitcoin/privkey.h>
#include <bitcoin/pubkey.h>
#include <ccan/str/hex/hex.h>
#include <inttypes.h>
#include <stdio.h>
#include <type_to_string.h>
#include <utils.h>
#define SUPERVERBOSE printf
#include "../funding_tx.c"
#undef SUPERVERBOSE
#include "../key_derive.c"
#if 0
static struct sha256 sha256_from_hex(const char *hex)
{
struct sha256 sha256;
if (strstarts(hex, "0x"))
hex += 2;
if (!hex_decode(hex, strlen(hex), &sha256, sizeof(sha256)))
abort();
return sha256;
}
static struct privkey privkey_from_hex(const char *hex)
{
struct privkey pk;
size_t len;
if (strstarts(hex, "0x"))
hex += 2;
len = strlen(hex);
if (len == 66 && strends(hex, "01"))
len -= 2;
if (!hex_decode(hex, len, &pk, sizeof(pk)))
abort();
return pk;
}
#endif
int main(void)
{
tal_t *tmpctx = tal_tmpctx(NULL);
struct bitcoin_tx *input, *funding;
u64 fee;
struct pubkey local_funding_pubkey, remote_funding_pubkey;
struct privkey input_privkey;
struct pubkey inputkey;
bool testnet;
struct utxo utxo;
const struct utxo **utxomap = tal_arr(tmpctx, const struct utxo *, 1);
u64 funding_satoshis;
u32 funding_outnum;
u8 *subscript;
secp256k1_ecdsa_signature sig;
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN);
/* BOLT #3:
*
* Block 1 coinbase transaction: 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000
*/
input = bitcoin_tx_from_hex(tmpctx,
"01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000",
strlen("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000"));
assert(input);
/* BOLT #3:
* Block 1 coinbase privkey: 6bd078650fcee8444e4e09825227b801a1ca928debb750eb36e6d56124bb20e80101
* # privkey in base58: cRCH7YNcarfvaiY1GWUKQrRGmoezvfAiqHtdRvxe16shzbd7LDMz
*/
if (!key_from_base58("cRCH7YNcarfvaiY1GWUKQrRGmoezvfAiqHtdRvxe16shzbd7LDMz", strlen("cRCH7YNcarfvaiY1GWUKQrRGmoezvfAiqHtdRvxe16shzbd7LDMz"),
&testnet, &input_privkey, &inputkey))
abort();
assert(testnet);
printf("* Block 1 coinbase privkey: %s01\n",
type_to_string(tmpctx, struct privkey, &input_privkey));
/* BOLT #3:
*
* The funding transaction is paid to the following keys:
*
* local_funding_pubkey: 023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb
* remote_funding_pubkey: 030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1
*/
if (!pubkey_from_hexstr("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb",
strlen("023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb"),
&local_funding_pubkey))
abort();
if (!pubkey_from_hexstr("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1",
strlen("030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c1"),
&remote_funding_pubkey))
abort();
bitcoin_txid(input, &utxo.txid);
utxo.outnum = 0;
utxo.amount = 5000000000;
utxo.is_p2sh = false;
funding_satoshis = 10000000;
fee = 13920;
printf("input[0] txid: %s\n",
tal_hexstr(tmpctx, &utxo.txid, sizeof(utxo.txid)));
printf("input[0] input: %u\n", utxo.outnum);
printf("input[0] satoshis: %"PRIu64"\n", utxo.amount);
printf("funding satoshis: %"PRIu64"\n", funding_satoshis);
utxomap[0] = &utxo;
funding = funding_tx(tmpctx, &funding_outnum, utxomap,
funding_satoshis,
&local_funding_pubkey,
&remote_funding_pubkey,
utxo.amount - fee - funding_satoshis,
&inputkey, NULL);
printf("# fee: %"PRIu64"\n", fee);
printf("change satoshis: %"PRIu64"\n",
funding->output[!funding_outnum].amount);
printf("funding output: %u\n", funding_outnum);
subscript = scriptpubkey_p2pkh(funding, &inputkey);
sign_tx_input(funding, 0, subscript, NULL, &input_privkey, &inputkey,
&sig);
funding->input[0].script = bitcoin_redeem_p2pkh(funding, &inputkey,
&sig);
printf("funding tx: %s\n",
tal_hex(tmpctx, linearize_tx(tmpctx, funding)));
/* No memory leaks please */
secp256k1_context_destroy(secp256k1_ctx);
tal_free(tmpctx);
return 0;
}