tlnbase: initial commitment transaction - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit ba997951317ecb3b2274ff8c3ed78468a3265c5d DIR parent 451d52281ab8d3a94479cd79045bf7cd6817ef89 HTML Author: ThomasV <thomasv@electrum.org> Date: Fri, 13 Apr 2018 12:22:47 +0200 lnbase: initial commitment transaction Diffstat: M lib/lnbase.py | 59 ++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 8 deletions(-) --- DIR diff --git a/lib/lnbase.py b/lib/lnbase.py t@@ -29,6 +29,7 @@ from . import transaction from .util import PrintError, bh2u from .wallet import Wallet from .storage import WalletStorage +from .transaction import opcodes, Transaction tcp_socket_timeout = 10 server_response_timeout = 60 t@@ -388,7 +389,25 @@ class Peer(PrintError): keys = get_unused_keys() temp_channel_id = os.urandom(32) funding_pubkey, funding_privkey = next(keys) - msg = gen_msg("open_channel", temporary_channel_id=temp_channel_id, chain_hash=bytes.fromhex(rev_hex(constants.net.GENESIS)), funding_satoshis=20000, max_accepted_htlcs=5, funding_pubkey=funding_pubkey, revocation_basepoint=next(keys)[0], htlc_basepoint=next(keys)[0], payment_basepoint=next(keys)[0], delayed_payment_basepoint=next(keys)[0], first_per_commitment_point=next(keys)[0]) + revocation_pubkey, revocation_privkey = next(keys) + htlc_pubkey, htlc_privkey = next(keys) + payment_pubkey, payment_privkey = next(keys) + delayed_pubkey, delayed_privkey = next(keys) + + funding_satoshis = 20000 + msg = gen_msg( + "open_channel", + temporary_channel_id=temp_channel_id, + chain_hash=bytes.fromhex(rev_hex(constants.net.GENESIS)), + funding_satoshis=funding_satoshis, + max_accepted_htlcs=5, + funding_pubkey=funding_pubkey, + revocation_basepoint=revocation_pubkey, + htlc_basepoint=htlc_pubkey, + payment_basepoint=payment_pubkey, + delayed_payment_basepoint=delayed_pubkey, + first_per_commitment_point=next(keys)[0] + ) self.temporary_channel_id_to_incoming_accept_channel[temp_channel_id] = asyncio.Future() self.send_message(msg) try: t@@ -400,19 +419,43 @@ class Peer(PrintError): redeem_script = transaction.multisig_script(pubkeys, 2) funding_address = bitcoin.redeem_script_to_address('p2wsh', redeem_script) #TODO support passwd, fix fee - funding_output = (bitcoin.TYPE_ADDRESS, funding_address, 20000) - tx = wallet.mktx([funding_output], None, config, 1000) - funding_index = tx.outputs().index(funding_output) - tx.sign({funding_pubkey: (funding_privkey, True)}) - # this is wrong: you need to send the signature of the first commitment tx - sig = bytes.fromhex(tx.inputs()[0]["signatures"][0]) + funding_output = (bitcoin.TYPE_ADDRESS, funding_address, funding_satoshis) + funding_tx = wallet.mktx([funding_output], None, config, 1000) + funding_index = funding_tx.outputs().index(funding_output) + # commitment tx input + c_inputs = [{ + 'type': 'p2wsh', + 'x_pubkeys': pubkeys, + 'signatures':[None, None], + 'num_sig': 2, + 'prevout_n': funding_index, + 'prevout_hash': funding_tx.txid(), + 'value': funding_satoshis, + 'coinbase': False + }] + # commitment tx outputs + local_script = bytes([opcodes.OP_IF]) + revocation_pubkey + bytes([opcodes.OP_ELSE, opcodes.OP_CSV, opcodes.OP_DROP]) + delayed_pubkey + bytes([opcodes.OP_ENDIF, opcodes.OP_CHECKSIG]) + local_address = bitcoin.redeem_script_to_address('p2wsh', bh2u(local_script)) + local_amount = funding_satoshis + remote_address = bitcoin.pubkey_to_address('p2wpkh', bh2u(remote_pubkey)) + remote_amount = 0 + to_local = (bitcoin.TYPE_ADDRESS, local_address, local_amount) + to_remote = (bitcoin.TYPE_ADDRESS, remote_address, remote_amount) + # no htlc for the moment + c_outputs = [to_local, to_remote] + # create commitment tx + c_tx = Transaction.from_io(c_inputs, c_outputs) + c_tx.sign({bh2u(funding_pubkey): (funding_privkey, True)}) + # + self.print_error('ctx inputs', c_tx.inputs()) + sig = bytes.fromhex(c_tx.inputs()[0]["signatures"][0]) self.print_error('sig', len(sig)) sig = bytes(sig[:len(sig)-1]) r, s = sigdecode_der(sig, SECP256k1.generator.order()) sig = sigencode_string_canonize(r, s, SECP256k1.generator.order()) self.print_error('canonical signature', len(sig)) self.temporary_channel_id_to_incoming_funding_signed[temp_channel_id] = asyncio.Future() - self.send_message(gen_msg("funding_created", temporary_channel_id=temp_channel_id, funding_txid=bytes.fromhex(tx.txid()), funding_output_index=funding_index, signature=sig)) + self.send_message(gen_msg("funding_created", temporary_channel_id=temp_channel_id, funding_txid=bytes.fromhex(funding_tx.txid()), funding_output_index=funding_index, signature=sig)) try: funding_signed = await self.temporary_channel_id_to_incoming_funding_signed[temp_channel_id] finally: