コード例 #1
0
struct bitcoin_tx *create_close_tx(secp256k1_context *secpctx,
				   const tal_t *ctx,
				   const struct pubkey *our_final,
				   const struct pubkey *their_final,
				   const struct sha256_double *anchor_txid,
				   unsigned int anchor_index,
				   u64 anchor_satoshis,
				   uint64_t to_us, uint64_t to_them)
{
	struct bitcoin_tx *tx;
	const u8 *redeemscript;

	/* Now create close tx: one input, two outputs. */
	tx = bitcoin_tx(ctx, 1, 2);

	/* Our input spends the anchor tx output. */
	tx->input[0].txid = *anchor_txid;
	tx->input[0].index = anchor_index;
	tx->input[0].input_amount = anchor_satoshis;

	/* One output is to us. */
	tx->output[0].amount = to_us;
	redeemscript = bitcoin_redeem_single(tx, our_final);
	tx->output[0].script = scriptpubkey_p2sh(tx, redeemscript);
	tx->output[0].script_length = tal_count(tx->output[0].script);

	/* Other output is to them. */
	tx->output[1].amount = to_them;
	redeemscript = bitcoin_redeem_single(tx, their_final);
	tx->output[1].script = scriptpubkey_p2sh(tx, redeemscript);
	tx->output[1].script_length = tal_count(tx->output[1].script);

	assert(tx->output[0].amount + tx->output[1].amount
	       <= tx->input[0].input_amount);
	tx->fee = tx->input[0].input_amount
		- (tx->output[0].amount + tx->output[1].amount);

	permute_outputs(tx->output, 2, NULL);
	return tx;
}
コード例 #2
0
ファイル: packets.c プロジェクト: dooglus/lightning
void queue_pkt_close_clearing(struct peer *peer)
{
	u8 *redeemscript;
	CloseClearing *c = tal(peer, CloseClearing);

	close_clearing__init(c);
	redeemscript = bitcoin_redeem_single(c, &peer->us.finalkey);
	peer->closing.our_script = scriptpubkey_p2sh(peer, redeemscript);

	c->scriptpubkey.data = tal_dup_arr(c, u8,
					   peer->closing.our_script,
					   tal_count(peer->closing.our_script),
					   0);
	c->scriptpubkey.len = tal_count(c->scriptpubkey.data);

	queue_pkt(peer, PKT__PKT_CLOSE_CLEARING, c);
}
コード例 #3
0
u32 find_p2sh_out(const struct bitcoin_tx *tx, u8 *redeemscript)
{
	/* This is the scriptPubKey commit tx will have */
	u8 *p2sh = scriptpubkey_p2sh(NULL, redeemscript);
	u32 i;

	for (i = 0; i < tx->output_count; i++) {
		if (tx->output[i].script_length != tal_count(p2sh))
			continue;
		if (memcmp(tx->output[i].script, p2sh, tal_count(p2sh)) == 0)
			break;
	}
	/* FIXME: Return failure! */
	if (i == tx->output_count)
		errx(1, "No matching output in tx");
	tal_free(p2sh);
	return i;
}
コード例 #4
0
int main(int argc, char *argv[])
{
	OpenChannel *o1, *o2;
	struct bitcoin_tx *anchor;
	const tal_t *ctx = tal_arr(NULL, char, 0);
	u64 anchor_fee, amount, total_in, change;
	struct input *in;
	u8 *redeemscript;
	size_t i;
	struct pubkey pubkey1, pubkey2;

	err_set_progname(argv[0]);

	anchor_fee = 10000;
	
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<open-channel-file1> <open-channel-file2> <amount> <changepubkey> <txid>/<outnum>/<satoshis>/<script-in-hex>/<privkey>...\n"
			   "A test program to create an anchor tx on stdout.",
			   "Print this message.");
	opt_register_arg("--anchor-fee=<bits>",
			 opt_set_bits, opt_show_bits, &anchor_fee,
			 "100's of satoshi to pay for anchor");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5 or more arguments");

	o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	if (!proto_to_pubkey(o1->commit_key, &pubkey1))
		errx(1, "Invalid o1 commit_key");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit_key");

	amount = atol(argv[3]);
	if (!amount)
		errx(1, "Invalid total: must be > 0");

	in = tal_arr(ctx, struct input, argc - 5);

	total_in = 0;
	for (i = 0; i < tal_count(in); i++) {
		parse_anchor_input(argv[5+i], &in[i]);
		total_in += in[i].in.input_amount;
	}

	if (total_in < amount + anchor_fee)
		errx(1, "Only %llu satoshi in, and %llu out (+%llu fee)",
		     (unsigned long long)total_in,
		     (unsigned long long)amount,
		     (unsigned long long)anchor_fee);

	change = total_in - (amount + anchor_fee);

	/* If there's change, we have an extra output. */
	anchor = bitcoin_tx(ctx, tal_count(in), change ? 2 : 1);
	anchor->fee = anchor_fee;

	/* Commitment redeems this via 2 of 2 payment. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	/* Set up outputs. */
	anchor->output[0].amount = amount;
	anchor->output[0].script = scriptpubkey_p2sh(anchor, redeemscript);
	anchor->output[0].script_length = tal_count(anchor->output[0].script);

	if (change) {
		struct pubkey change_key;

		if (!pubkey_from_hexstr(argv[4], &change_key))
			errx(1, "Invalid change key %s", argv[3]);

		redeemscript = bitcoin_redeem_single(anchor, &change_key);
		anchor->output[1].amount = change;
		anchor->output[1].script = scriptpubkey_p2sh(anchor,
							     redeemscript);
		anchor->output[1].script_length
			= tal_count(anchor->output[1].script);
	}

	/* Set up inputs (leaving scripts empty for signing) */
	for (i = 0; i < tal_count(in); i++) {
		anchor->input[i].input_amount = in[i].in.input_amount;
		anchor->input[i].txid = in[i].in.txid;
		anchor->input[i].index = in[i].in.index;
	}
	
	/* Now, sign each input. */
	for (i = 0; i < tal_count(in); i++) {
		in[i].sig.stype = SIGHASH_ALL;
		if (!sign_tx_input(ctx, anchor, i, in[i].in.script,
				   in[i].in.script_length,
				   &in[i].privkey, &in[i].pubkey,
				   &in[i].sig.sig))
			errx(1, "Error signing input %zi", i);
	}

	/* Finally, complete inputs using signatures. */
	for (i = 0; i < tal_count(in); i++) {
		if (!is_pay_to_pubkey_hash(in[i].in.script,
					   in[i].in.script_length))
			errx(1, "FIXME: Don't know how to handle input %zi", i);
		anchor->input[i].script
			= scriptsig_pay_to_pubkeyhash(anchor, &in[i].pubkey,
						      &in[i].sig);
		anchor->input[i].script_length
			= tal_count(anchor->input[i].script);
	}

	/* Print it out in hex. */
	if (!bitcoin_tx_write(STDOUT_FILENO, anchor))
		err(1, "Writing out transaction");

	tal_free(ctx);
	return 0;
}
コード例 #5
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *commit, *tx;
	struct bitcoin_signature sig;
	struct privkey privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2, outpubkey;
	u8 *redeemscript;
	struct sha256 rhash;
	size_t p2sh_out;
	u64 fee = 10000;
	u32 locktime;

	err_set_progname(argv[0]);

	/* FIXME: If we've updated channel since, we need the final
	 * revocation hash we sent (either update_accept or update_complete) */
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<commitment-tx> <open-channel-file1> <open-channel-file2> <open-anchor-file> <my-privoutkey> <someaddress> [previous-updates]\n"
			   "Create the transaction to spend our commit transaction",
			   "Print this message.");
	opt_register_arg("--fee=<bits>",
			 opt_set_bits, opt_show_bits, &fee,
			 "100's of satoshi to pay in transaction fee");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5+ arguments");

	commit = bitcoin_tx_from_file(ctx, argv[1]);

	o1 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[4], PKT__PKT_OPEN_ANCHOR)->open_anchor;
	if (!proto_to_rel_locktime(o2->delay, &locktime))
		errx(1, "Invalid locktime in o2");

 	/* We need our private key to spend commit output. */
	if (!key_from_base58(argv[5], strlen(argv[5]), &testnet, &privkey, &pubkey1))
		errx(1, "Invalid private key '%s'", argv[5]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[5]);

	if (!pubkey_from_hexstr(argv[6], &outpubkey))
		errx(1, "Invalid bitcoin pubkey '%s'", argv[6]);

	/* Get pubkeys */
	if (!proto_to_pubkey(o1->final_key, &pubkey2))
		errx(1, "Invalid o1 final pubkey");
	if (!pubkey_eq(&pubkey1, &pubkey2))
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->final_key, &pubkey2))
		errx(1, "Invalid o2 final pubkey");

	/* We use this simply to get final revocation hash. */
	gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 7,
		       NULL, &rhash, NULL, NULL);

	/* Create redeem script */
	redeemscript = bitcoin_redeem_secret_or_delay(ctx, &pubkey1, locktime,
						      &pubkey2, &rhash);

	/* Now, create transaction to spend it. */
	tx = bitcoin_tx(ctx, 1, 1);
	bitcoin_txid(commit, &tx->input[0].txid);
	p2sh_out = find_p2sh_out(commit, redeemscript);
	tx->input[0].index = p2sh_out;
	tx->input[0].input_amount = commit->output[p2sh_out].amount;
	tx->fee = fee;

	tx->input[0].sequence_number = bitcoin_nsequence(locktime);

	if (commit->output[p2sh_out].amount <= fee)
		errx(1, "Amount of %llu won't exceed fee",
		     (unsigned long long)commit->output[p2sh_out].amount);

	tx->output[0].amount = commit->output[p2sh_out].amount - fee;
	tx->output[0].script = scriptpubkey_p2sh(tx,
						 bitcoin_redeem_single(tx, &outpubkey));
	tx->output[0].script_length = tal_count(tx->output[0].script);

	/* Now get signature, to set up input script. */
	if (!sign_tx_input(tx, tx, 0, redeemscript, tal_count(redeemscript),
			   &privkey, &pubkey1, &sig.sig))
		errx(1, "Could not sign tx");
	sig.stype = SIGHASH_ALL;
	tx->input[0].script = scriptsig_p2sh_secret(tx, NULL, 0, &sig,
						    redeemscript,
						    tal_count(redeemscript));
	tx->input[0].script_length = tal_count(tx->input[0].script);

	/* Print it out in hex. */
	if (!bitcoin_tx_write(STDOUT_FILENO, tx))
		err(1, "Writing out transaction");

	tal_free(ctx);
	return 0;
}