#include #include #include #include #include #include #include #include #include #include #include "../amount.c" #define SUPERVERBOSE printf #include "../funding_tx.c" #undef SUPERVERBOSE #include "../key_derive.c" #include "../type_to_string.c" #include "../permute_tx.c" #include "../utxo.c" /* AUTOGENERATED MOCKS START */ /* Generated stub for fromwire_amount_sat */ struct amount_sat fromwire_amount_sat(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_amount_sat called!\n"); abort(); } /* Generated stub for fromwire_bitcoin_txid */ void fromwire_bitcoin_txid(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct bitcoin_txid *txid UNNEEDED) { fprintf(stderr, "fromwire_bitcoin_txid called!\n"); abort(); } /* Generated stub for fromwire_bool */ bool fromwire_bool(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_bool called!\n"); abort(); } /* Generated stub for fromwire_node_id */ void fromwire_node_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct node_id *id UNNEEDED) { fprintf(stderr, "fromwire_node_id called!\n"); abort(); } /* Generated stub for fromwire_pubkey */ void fromwire_pubkey(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct pubkey *pubkey UNNEEDED) { fprintf(stderr, "fromwire_pubkey called!\n"); abort(); } /* Generated stub for fromwire_u32 */ u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u32 called!\n"); abort(); } /* Generated stub for fromwire_u64 */ u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) { fprintf(stderr, "fromwire_u64 called!\n"); abort(); } /* Generated stub for towire_amount_sat */ void towire_amount_sat(u8 **pptr UNNEEDED, const struct amount_sat sat UNNEEDED) { fprintf(stderr, "towire_amount_sat called!\n"); abort(); } /* Generated stub for towire_bitcoin_txid */ void towire_bitcoin_txid(u8 **pptr UNNEEDED, const struct bitcoin_txid *txid UNNEEDED) { fprintf(stderr, "towire_bitcoin_txid called!\n"); abort(); } /* Generated stub for towire_bool */ void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED) { fprintf(stderr, "towire_bool called!\n"); abort(); } /* Generated stub for towire_node_id */ void towire_node_id(u8 **pptr UNNEEDED, const struct node_id *id UNNEEDED) { fprintf(stderr, "towire_node_id called!\n"); abort(); } /* Generated stub for towire_pubkey */ void towire_pubkey(u8 **pptr UNNEEDED, const struct pubkey *pubkey UNNEEDED) { fprintf(stderr, "towire_pubkey called!\n"); abort(); } /* Generated stub for towire_u32 */ void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED) { fprintf(stderr, "towire_u32 called!\n"); abort(); } /* Generated stub for towire_u64 */ void towire_u64(u8 **pptr UNNEEDED, u64 v UNNEEDED) { fprintf(stderr, "towire_u64 called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #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) { setup_locale(); struct bitcoin_tx *input, *funding; struct amount_sat fee, change; struct pubkey local_funding_pubkey, remote_funding_pubkey; struct privkey input_privkey; struct pubkey inputkey; bool testnet; struct utxo utxo; const struct utxo **utxomap; struct amount_sat funding_sat; u16 funding_outnum; u8 *subscript, *script; struct bitcoin_signature sig; struct bitcoin_address addr; struct amount_sat tmpamt; secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); setup_tmpctx(); /* BOLT #3: * * Block 1 coinbase transaction: 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000 */ input = bitcoin_tx_from_hex(tmpctx, "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000", strlen("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0100f2052a010000001976a9143ca33c2e4446f4a305f23c80df8ad1afdcf652f988ac00000000")); assert(input); /* BOLT #3: * Block 1 coinbase privkey: 6bd078650fcee8444e4e09825227b801a1ca928debb750eb36e6d56124bb20e801 * # privkey in base58: cRCH7YNcarfvaiY1GWUKQrRGmoezvfAiqHtdRvxe16shzbd7LDMz */ if (!key_from_base58("cRCH7YNcarfvaiY1GWUKQrRGmoezvfAiqHtdRvxe16shzbd7LDMz", strlen("cRCH7YNcarfvaiY1GWUKQrRGmoezvfAiqHtdRvxe16shzbd7LDMz"), &testnet, &input_privkey, &inputkey)) abort(); assert(testnet); printf("* Block 1 coinbase privkey: %s\n", type_to_string(tmpctx, struct privkey, &input_privkey)); /* BOLT #3: * * The funding transaction is paid to the following pubkeys: * * 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 = AMOUNT_SAT(5000000000); utxo.is_p2sh = false; utxo.close_info = NULL; funding_sat = AMOUNT_SAT(10000000); fee = AMOUNT_SAT(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: %s\n", type_to_string(tmpctx, struct amount_sat, &utxo.amount)); printf("funding: %s\n", type_to_string(tmpctx, struct amount_sat, &funding_sat)); utxomap = tal_arr(tmpctx, const struct utxo *, 1); utxomap[0] = &utxo; if (!amount_sat_sub(&change, utxo.amount, funding_sat) || !amount_sat_sub(&change, change, fee)) abort(); funding = funding_tx(tmpctx, &funding_outnum, utxomap, funding_sat, &local_funding_pubkey, &remote_funding_pubkey, change, &inputkey, NULL); printf("# fee: %s\n", type_to_string(tmpctx, struct amount_sat, &fee)); tmpamt = bitcoin_tx_output_get_amount(funding, !funding_outnum); printf("change: %s\n", type_to_string(tmpctx, struct amount_sat, &tmpamt)); printf("funding output: %u\n", funding_outnum); pubkey_to_hash160(&inputkey, &addr.addr); subscript = scriptpubkey_p2pkh(funding, &addr); sign_tx_input(funding, 0, subscript, NULL, &input_privkey, &inputkey, SIGHASH_ALL, &sig); script = bitcoin_redeem_p2pkh(funding, &inputkey, &sig); bitcoin_tx_input_set_script(funding, 0, script); 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; }