Coinjoin implementation using nostr
-
Input registration:
5 users publish inputs using nostr
import requests
import pexpect
url = "http://127.0.0.1:18332/wallet/W1"
headers = {
'Authorization': 'Basic dXNlcjpwYXNz',
'Content-Type': 'text/plain'
}
def publish():
noscl = pexpect.spawn ('noscl publish "' + input + '"')
noscl.expect ('Seen ')
output = str(noscl.read())
eventid = output.replace('b"','').replace(" on 'wss://nostr-pub.wellorder.net'.","").replace('\\r\\n"','')
noscl.interact()
return eventid
def listunspent():
payload = "{\"jsonrpc\": \"1.0\", \"id\": \"joinstr\", \"method\": \"listunspent\"}"
response = requests.request("POST", url, headers=headers, data=payload)
i =0
for i in range(0,len(response.json()['result'])):
txid = response.json()['result'][i]['txid']
vout = response.json()['result'][i]['vout']
amount = response.json()['result'][i]['amount']
print(txid, ",",vout ,",",amount)
i = i + 1
if __name__=="__main__":
utxo_list = listunspent()
input = input("Enter input for registration (txid,vout): ")
eventid = publish()
print(eventid)
-
Output registration:
5 users share a new address for output.
-
Create and publish tx:
User that registered the last output creates a PSBT with all inputs, outputs using
createpsbt
and publishes it. -
Sign and broadcast tx:
All users verify, sign with
walletprocesspsbt
and publish PSBT. Last user that signs the transaction, combines them withcombinepsbt
, finalize withfinalizepsbt
and broadcast withsendrawtransaction
.
Example of a coinjoin transaction:
Things that could be improved:
-
Relay shares a random number with first input and same number with next 4 inputs registered. Clients will mention this number in the request sent for registering outputs to prove they own one registered input in this round. If more than 5 outputs are registered for a round its cancelled.
-
Use new private key for nostr and a new tor circuit every time soemtihng is published using nostr.
-
Break UTXOs in pool denominations before coinjoin if amount exceeds pool denomination by more than 200 sats.
-
Create an Android app that connects with bitcoin core and makes it easier to do coinjoin.
Checkout Coinshuffle for a sophisticated decentralized coinjoin coordination scheme.
Single denomintion rounds are very blockspace expensive and create non-private change or loss, so consider multi-standard-denominations [low hamming weight numbers are efficient in decomposition].