Skip to content

Instantly share code, notes, and snippets.


Adam Gibson AdamISZ

View GitHub Profile
AdamISZ /
Last active Jan 17, 2019
Notes on backout / recovery of coins in coinswap proposal

Explanation of how using Schnorr signatures, we can achieve an atomic swap of the "scriptless script" style.

This is based on Poelstra's ideas as summarised in ; also see the earlier outline in

Note that the details here are just my thoughts, so if you come to this randomly, don't take it as some kind of well established protocol!


We'll use || for concatenation and capitals for elliptic curve points and lower case letters for scalars.

AdamISZ /
Last active May 5, 2021
On chain contracting - privacy enhancing use-cases

On-chain contracting for privacy

(thanks to @fivepiece for significant contributions to these ideas)

"On chain contracting" is of course a very generic term; it applies to multisignature, coinjoin, coinswap or other exotic transactions that involve more than one party in one transaction (coinjoin, multisig) or multiple transactions (swaps with atomic-via-secret).

Here we're going to focus on a broader model that may allow more complex setups, with a focus on how they may apply to gaining privacy, although this model may well be useful in other ways too.

AdamISZ /
Last active Apr 26, 2020
SNICKER - Simple Non-Interactive Coinjoins with Keys for Encryption Reused

Simple Non-Interactive Coinjoins with Keys for Encryption Reused


Use pubkeys available on the blockchain (in scriptSigs/witnesses) to encrypt messages to owners of those pubkeys, these messages containing partially signed coinjoins. Broadcast these encrypted messages; owners scan for their own messages and broadcast as they choose. This is intended to be fully non-interactive so anyone can propose such transactions, and anyone who can decrypt such a message can choose to co-sign and broadcast.

Basic Coinjoin background

Each input to a transaction requires (for the transaction to be valid) a signature by the owner of the private key (using singular deliberately, restricting consideration to p2pkh or segwit equivalent here) over a message which is ~ the transaction. Each of these signatures can be constructed separately, by separate parties if indeed the private key for each input are owned by separate parties. The "normal" coinjoining process thus involves the following steps (for now,

#!/usr/bin/env python2
from __future__ import print_function
"""Simple illustration of 2 stage process:
1. Prepare a single (input, output) pair from some wallet
(the idea is that a utxo splitter service can do this for a client)
2. Take that partial transaction (serialized), and by feeding in
data from an input file gathered from Electrum GUI, add another
input and output (only one input here, should be OK to increase to more inputs),
AdamISZ / electrumx-regtest-setup-notes.txt
Created Dec 25, 2017
Electrum X regtest setup (very rough notes)
View electrumx-regtest-setup-notes.txt
pre-requisite: a Bitcoin Core instance, set up regtest and start running it.
Before starting run, set up a bitcoin conf in say ~/bitcoin.conf and put:
Then, ./bitcoind -regtest -daemon -conf=/home/username/bitcoin.conf
or whatever. Make sure to generate some blocks.
AdamISZ /
Created Jan 15, 2018
Simple BOLT 8 Lightning handshake in Python3
#!/usr/bin/env python
This script implements a handshake with a remote Lightning
Network node; see BOLT8:
, which is the Noise-based transport protocol
for Lightning network nodes.
Specify server, port and remote node pubkey as three command line arguments;
here's an example invocation:
AdamISZ /
Last active Jun 30, 2018
Hybrid swap design, minimising interactivity

Alice has 1 Alice-coin UA on Alice-chain. Bob has 1 BTC UB on Bitcoin. X-rate = 1/1. M() is multisig.

  2. Negotiate keys: A1,A2, A3, B1. Create M(2,2,A1,B1). Alice create txid from UA to M(2,2,A1,B1), give to Bob. Bob pre-sign backout to A2 with nlocktime L1.
  3. Alice gives key A3 as ephem key for BTC side of swap.
  4. A and B do C&C ending with Bob receiving H(k) and E_k(sig on M(2,2,A1,B1)->B2_m) for m distinct cases, and note Alice doesn't know the B2 keys.

(everything else does not require communication)

AdamISZ / test-coinjoin.go
Created Aug 4, 2018
Elementary test of co-signing/coinjoin in lnd
View test-coinjoin.go
// This tests a simple 2 party of coinjoin by first funding a utxo
// for both of Bob and Alice, and then spending both into one
// transaction. The purpose is to test construction and broadcast,
// not sophisticated validation.
func testCospend(r *rpctest.Harness,
alice, bob *lnwallet.LightningWallet, t *testing.T) {
// Start building the coinjoin transaction; we'll append
// inputs and outputs as we build
tx1 := wire.NewMsgTx(2)
AdamISZ /
Created Aug 27, 2018
Derivatives and manipulation?

So, why the current narrative around ETFs, futures and similar is wrong, I believe:

Start with the idea of Darwinian natural selection. People say "evolution is a theory, it isn't proven", now you may think they're stupid because the theory is proven, but the error is much more fundamental: natural selection is not really a theory at all. It's an inevitable logical consequence of a simple set of conditions: basically, reproduction through encoding along with random variation. Natural selection has to happen in this case.

There is a similar story around the famous "Efficient Market Hypothesis". People love to say that this theory is wrong, in fact I get the impression many think they're very smart for realizing that this is