-
Notifications
You must be signed in to change notification settings - Fork 15
teos_cli tests with real transactions
This documents defines how to create commitment
and penalty
transactions* in Bitcoin testnet3 to add to the appointment_data.json
that will be used to send an appointment to the eye of satoshi
😄.
We assume that you've already been able to send a dummy appointment (meaning that you've successfully installed teos_cli
and run over the examples).
The first thing you'll need to do is run a testnet3 node. To do so you need to get Bitcoin Core and run it with the testnet flag:
bitcoind -server -daemon -testnet -rpcuser=user -rpcpassword=passwd
It may take a while until the IDB (Initial Block Download) is completed, so go out, take a break and maybe have a nice coffee ☕️, I'll be here waiting.
You can test if your node is already up to date by checking the block height:
bitcoin-cli -testnet -rpcuser=user -rpcpassword=passwd getblockcount
And check if that matches with the latest block in any testnet explorer, such as blockcypher.
Now it's time to create a new address so you can get some sats to your wallet. Run:
bitcoin-cli -testnet -rpcuser=user -rpcpassword=passwd getnewaddress
That will output a new address four you. Now let's go to a faucet and get some coins. This one should do.
You may need to wait a bit till the transaction gets some confirmations.
Now it's time for the fun part. Get this Python script and save it as create_txs.py
or whatever name you like.
from decimal import Decimal, getcontext
from bitcoinrpc.authproxy import AuthServiceProxy
getcontext().prec = 10
def create_commitment_tx(bitcoin_cli, utxo, destination=None, fee=Decimal(1 / pow(10, 5))):
# We will set the recipient to ourselves is destination is None
if destination is None:
destination = utxo.get("address")
commitment_tx_ins = {"txid": utxo.get("txid"), "vout": utxo.get("vout")}
commitment_tx_outs = {destination: utxo.get("amount") - fee}
raw_commitment_tx = bitcoin_cli.createrawtransaction([commitment_tx_ins], commitment_tx_outs)
signed_commitment_tx = bitcoin_cli.signrawtransactionwithwallet(raw_commitment_tx)
if not signed_commitment_tx.get("complete"):
raise ValueError("Couldn't sign transaction. {}".format(signed_commitment_tx))
return signed_commitment_tx.get("hex")
def create_penalty_tx(bitcoin_cli, decoded_commitment_tx, destination=None, fee=Decimal(1 / pow(10, 5))):
# We will set the recipient to ourselves is destination is None
if destination is None:
destination = decoded_commitment_tx.get("vout")[0].get("scriptPubKey").get("addresses")[0]
penalty_tx_ins = {"txid": decoded_commitment_tx.get("txid"), "vout": 0}
penalty_tx_outs = {destination: decoded_commitment_tx.get("vout")[0].get("value") - fee}
orphan_info = {
"txid": decoded_commitment_tx.get("txid"),
"scriptPubKey": decoded_commitment_tx.get("vout")[0].get("scriptPubKey").get("hex"),
"vout": 0,
"amount": decoded_commitment_tx.get("vout")[0].get("value"),
}
raw_penalty_tx = bitcoin_cli.createrawtransaction([penalty_tx_ins], penalty_tx_outs)
signed_penalty_tx = bitcoin_cli.signrawtransactionwithwallet(raw_penalty_tx, [orphan_info])
if not signed_penalty_tx.get("complete"):
raise ValueError("Couldn't sign orphan transaction. {}".format(signed_penalty_tx))
return signed_penalty_tx.get("hex")
def create_txs(rpc_user, rpc_pass, rpc_host, rpc_port):
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (rpc_user, rpc_pass, rpc_host, rpc_port))
utxos = bitcoin_cli.listunspent()
if len(utxos) == 0:
raise ValueError("There're no UTXOs.")
utxo = utxos.pop(0)
while utxo.get("amount") < Decimal(2 / pow(10, 5)):
utxo = utxos.pop(0)
signed_commitment_tx = create_commitment_tx(bitcoin_cli, utxo)
decoded_commitment_tx = bitcoin_cli.decoderawtransaction(signed_commitment_tx)
signed_penalty_tx = create_penalty_tx(bitcoin_cli, decoded_commitment_tx)
return signed_commitment_tx, decoded_commitment_tx.get("txid"), signed_penalty_tx
if __name__ == "__main__":
rpc_user = "user"
rpc_pass = "passwd"
rpc_host = "localhost"
rpc_port = 18332
commitment_tx, commitment_txid, penalty_tx = create_txs(rpc_user, rpc_pass, rpc_host, rpc_port)
print(
"Commitment txid (to be included in the tx_id field of dummy_appointment_data.json): {}".format(commitment_txid)
)
print("Penalty tx (to be included in the tx field of dummy_appointment_data.json): {}".format(penalty_tx))
print("Commitment tx (to be used to trigger a breach): {}".format(commitment_tx))
Now install bitcoinrpc
using pip:
pip install python-bitcoinrpc
And you should be good to go. Run the script and it will create the transaction for you.
python create_txs.py
*Notice that the created transactions are not actual lightning commitment
and penalty
transactions, but a pair or regular parent and child transactions. However, this won't matter for the sake of the test, since once the appointment is added broadcasting the parent will trigger the tower response.