forked from ElementsProject/lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mkfunding.c
144 lines (125 loc) · 5.34 KB
/
mkfunding.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* For example, in the spec tests we use the following keys:
*
* lightning/devtools/mkfunding 16835ac8c154b616baac524163f41fb0c4f82c7b972ad35d4d6f18d854f6856b 1 0.01btc 253 76edf0c303b9e692da9cb491abedef46ca5b81d32f102eb4648461b239cb0f99 0000000000000000000000000000000000000000000000000000000000000010 0000000000000000000000000000000000000000000000000000000000000020
*
* lightning/devtools/mkfunding 16835ac8c154b616baac524163f41fb0c4f82c7b972ad35d4d6f18d854f6856b 0 0.02btc 253 bc2f48a76a6b8815940accaf01981d3b6347a68fbe844f81c50ecbadf27cd179 0000000000000000000000000000000000000000000000000000000000000030 0000000000000000000000000000000000000000000000000000000000000040
*
* lightning/devtools/mkfunding 16835ac8c154b616baac524163f41fb0c4f82c7b972ad35d4d6f18d854f6856b 3 0.03btc 253 16c5027616e940d1e72b4c172557b3b799a93c0582f924441174ea556aadd01c 0000000000000000000000000000000000000000000000000000000000000050 0000000000000000000000000000000000000000000000000000000000000060
*/
#include <bitcoin/address.h>
#include <bitcoin/script.h>
#include <bitcoin/tx.h>
#include <ccan/err/err.h>
#include <ccan/str/hex/hex.h>
#include <common/amount.h>
#include <common/derive_basepoints.h>
#include <common/funding_tx.h>
#include <common/initial_commit_tx.h>
#include <common/keyset.h>
#include <common/status.h>
#include <common/type_to_string.h>
#include <common/utxo.h>
#include <stdio.h>
void status_fmt(enum log_level level, const char *fmt, ...)
{
}
static char *sig_as_hex(const struct bitcoin_signature *sig)
{
u8 compact_sig[64];
secp256k1_ecdsa_signature_serialize_compact(secp256k1_ctx,
compact_sig,
&sig->s);
return tal_hexstr(NULL, compact_sig, sizeof(compact_sig));
}
int main(int argc, char *argv[])
{
struct privkey input_privkey;
struct privkey local_funding_privkey, remote_funding_privkey;
struct pubkey funding_localkey, funding_remotekey, inputkey;
struct amount_sat fee, funding_amount;
unsigned int feerate_per_kw;
int argnum;
struct bitcoin_tx *tx;
u16 outnum;
size_t weight;
struct utxo input;
const struct utxo **utxomap;
struct bitcoin_signature sig;
struct bitcoin_txid txid;
const struct chainparams *chainparams = chainparams_for_network("bitcoin");
u8 **witnesses;
setup_locale();
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY |
SECP256K1_CONTEXT_SIGN);
if (argc != 1 + 7)
errx(1, "Usage: mkfunding <input-txid> <input-txout> <input-amount> <feerate-per-kw> <input-privkey> <local-funding-privkey> <remote-funding-privkey>");
input.is_p2sh = false;
input.close_info = NULL;
argnum = 1;
if (!bitcoin_txid_from_hex(argv[argnum],
strlen(argv[argnum]), &input.txid))
errx(1, "Bad input-txid");
argnum++;
input.outnum = atoi(argv[argnum++]);
if (!parse_amount_sat(&input.amount, argv[argnum], strlen(argv[argnum])))
errx(1, "Bad input-amount");
argnum++;
feerate_per_kw = atoi(argv[argnum++]);
if (!hex_decode(argv[argnum], strlen(argv[argnum]),
&input_privkey, sizeof(input_privkey)))
errx(1, "Parsing input-privkey");
argnum++;
if (!hex_decode(argv[argnum], strlen(argv[argnum]),
&local_funding_privkey, sizeof(local_funding_privkey)))
errx(1, "Parsing local-funding-privkey");
argnum++;
if (!hex_decode(argv[argnum], strlen(argv[argnum]),
&remote_funding_privkey, sizeof(remote_funding_privkey)))
errx(1, "Parsing remote-funding-privkey");
argnum++;
if (!pubkey_from_privkey(&input_privkey, &inputkey)
|| !pubkey_from_privkey(&local_funding_privkey, &funding_localkey)
|| !pubkey_from_privkey(&remote_funding_privkey, &funding_remotekey))
errx(1, "Bad privkeys");
/* nVersion, input count, output count, nLocktime */
weight = 4 * (4 + 1 + 1 + 4);
/* Add segwit fields: marker + flag */
weight += 1 + 1;
/* Single output: Satoshis, script length, p2wsh. */
weight += 4 * (8 + 1 + BITCOIN_SCRIPTPUBKEY_P2WSH_LEN);
/* Single input: txid, index, scriptlen, nSequence */
weight += 4 * (32 + 4 + 1 + 4);
/* Single witness: witness element count, len[0], sig, len[2], key */
weight += 1 + (1 + 73 + 1 + 33);
fee = amount_tx_fee(feerate_per_kw, weight);
if (!amount_sat_sub(&funding_amount, input.amount, fee))
errx(1, "Input %s can't afford fee %s",
type_to_string(NULL, struct amount_sat, &input.amount),
type_to_string(NULL, struct amount_sat, &fee));
/* funding_tx wants a utxo array. */
utxomap = tal_arr(tmpctx, const struct utxo *, 1);
utxomap[0] = &input;
/* No change output, so we don't need a bip32 base. */
tx = funding_tx(NULL, chainparams, &outnum, utxomap, funding_amount,
&funding_localkey, &funding_remotekey,
AMOUNT_SAT(0), NULL, NULL);
/* P2WSH of inputkey */
bitcoin_tx_input_set_script(tx, 0, NULL);
sign_tx_input(tx, 0, NULL, p2wpkh_scriptcode(NULL, &inputkey),
&input_privkey, &inputkey,
SIGHASH_ALL, &sig);
witnesses = bitcoin_witness_p2wpkh(NULL, &sig, &inputkey);
bitcoin_tx_input_set_witness(tx, 0, witnesses);
printf("# funding sig: %s\n", sig_as_hex(&sig));
printf("# funding witnesses: [\n");
for (size_t i = 0; i < tal_count(witnesses); i++)
printf("\t%s\n", tal_hex(NULL, witnesses[i]));
printf("# ]\n");
printf("# funding amount: %s\n",
type_to_string(NULL, struct amount_sat, &funding_amount));
bitcoin_txid(tx, &txid);
printf("# funding txid: %s\n",
type_to_string(NULL, struct bitcoin_txid, &txid));
printf("tx: %s\n", tal_hex(NULL, linearize_tx(NULL, tx)));
return 0;
}