๐Ÿฅ• Create a multisig with taproot and spend from it using BDK ๐Ÿฅ•

Overview

Multisig & carrots

This repository contains all the code to build a taproot multisig with your friends, and to spend from it. It's been used first to do the BDK workshop in the Azores Unconference, where we created this transaction: https://blockstream.info/testnet/tx/d40c55286933dfc2debb6b34832070401db33f53c78143bfb48717b79d237bdf?expand. You can find a transcript of the experiment here: https://twitter.com/michaelfolkson/status/1573644913224425473?s=20&t=NXMkPwrfZRvrUdPb5pBA2g

You can use this same code to re-create this workshop at some conference. You can use it to organize a Taproot night with your friends. You can use it by yourself to learn how BDK works. You can use it however you want. :)

The details

The experiment is composed of various participants, which will hold private keys and sign the transaction, and one coordinator, whose job is to, well, coordinate: creating the descriptor, creating the transaction, merging the signatures together and broadcasting the transaction.

At each step, I suggest commenting the whole file, and then uncommenting it, line by line, while you read it. If some parts are not clear, you are encouraged to add dbg!() and println!() statements, and run the code to see what happens. Don't be scared of experimenting :)

Some data needs to be exchanged between the coordinator and the participants (public keys, descriptor, PSBTs). In the real experiment we chose to use telegram, as it works well on desktop, but there are some obvious privacy concerns. Find a messaging app that works for you, or, if you're a real hacker, build a web page for submitting the data.

This article will give you a brief introduction to Taproot descriptors: https://bitcoinops.org/en/preparing-for-taproot/#taproot-descriptors

In this example, we put a dummy key in the key spend path (spending with just a key is too easy for us ๐Ÿ˜ ), and two different policies in the script spend path:

  1. You can spend immediately if at least half of the participants sign
  2. You can spend after 100 with a recovery key - just in case too many participants lose their keys :)

The steps

The experiment is composed of 5 steps:

  1. Participants generate private keys, and share the public ones
  2. Coordinator generates the descriptor
  3. Coordinator sends money to the descriptor, then creates a PSBT for spending
  4. Participants sign the PSBT
  5. Coordinator merges the signatures together and broadcasts

Step 1: generating the keys (everyone)

This will create a WIF key, print the public one to stdout, and write the private one to key.txt. Make sure not to delete key.txt!

Run with:

cargo run --bin generate_keys

Step 2: generating the descriptor (coordinator only)

Only the coordinator needs to run this step. After gathering all the participants' public keys, insert them in the "keys" vector. The descriptor will be printed to stdout. Send it to the group, as you'll need it for the next steps.

Run with:

cargo run --bin generate_descriptor

Step 3: creating a transaction spending the funds (coordinator only)

Only the coordinator needs to run this step. You should NOT run this file all at once - instead, uncomment Step 1 and 2, insert the descriptor obtained in step 2 where indicated, run the file and send some testnet coins to the address displayed. Only then uncomment the rest. The code will print a PSBT - send it to the group, you'll need it for the next step

Run with:

cargo run --bin create_psbt

Step 4: signing the transaction

In this step everyone will sign the PSBT obtained in step 3. Make sure that you still have the key.txt file, remove the TODOs and insert your descriptor and your PSBT instead. The file will print to stdout the signed PSBT - send it to the coordinator.

Run with:

cargo run --bin sign_transaction

Step 5: merging the signatures together, broadcasting (coordinator only)

Last step! The coordinator will gather everyone's transactions, insert them in the file, which will combine them all together and try to finalize and extract a bitcoin transaction. If all goes well, the transaction will be extracted and broadcasted ๐ŸŽ‰

cargo run --bin combine_psbts

Going further

If you're up for a challenge, try to:

  1. Use BIP32 keys instead of WIF keys
  2. Spend using the recovery path (you need to wait 100 blocks first!)
  3. Sync and broadcast the transaction using a different backend, such as Electrum or Bitcoin Core (we use esplora both in create_psbt and combine_psbts)
  4. Spend using the key spend path (hint: you need to change the descriptor a bit, or find a way to break secp256k1)
You might also like...
Nym provides strong network-level privacy against sophisticated end-to-end attackers, and anonymous transactions using blinded, re-randomizable, decentralized credentials.

The Nym Privacy Platform The platform is composed of multiple Rust crates. Top-level executable binary crates include: nym-mixnode - shuffles Sphinx p

An open source desktop wallet for nano and banano with end-to-end encrypted, on chain messaging using the dagchat protocol.
An open source desktop wallet for nano and banano with end-to-end encrypted, on chain messaging using the dagchat protocol.

An open source wallet with end-to-end encrypted, on chain messaging for nano and banano using the dagchat protocol.

Galleries of NFTs using Solana and Rust for contracts

About this Package created to simplify the process of parsing NFTs on Solana. It consists of: Package basic things like fetch all NFTs for specific wa

Thaler's Proofs, Args, and ZK Implemented in Rust using arkworks
Thaler's Proofs, Args, and ZK Implemented in Rust using arkworks

rthaler โ€ข Dr. Thaler's book Proofs, Args, and ZK implemented in rust using the arkworks cryptographic rust toolset. Various Zero Knowledge Protocols a

Silent monero miner using xmrig and has 0% donation.

Note If this reprository is useful to you in in any shape or form please give it a star. Educational purposes only Don't use this project maliciously.

A black-box raw calldata decoder using only calldata to guess types and parse parameters.
A black-box raw calldata decoder using only calldata to guess types and parse parameters.

Calldata Decoder A black-box raw calldata decoder using only calldata. Based off the topics discussed in DeGatchi's article, Reverse The EVM: Raw Call

๐ŸนBranch and bound solution using Rust to calculate an optimal cocktail ingredient list of arbitrary length ๐Ÿธ

Calculating an Optimal Cocktail Ingredient List Tom Explains the Problem You have 100 different ingredients You have 20 cocktails, each of which use 2

DAPOL+ Proof of Liabilities using Bulletproofs and Sparse Merkle trees

DAPOL+ implementation Implementation of the DAPOL+ protocol introduced in the "Generalized Proof of Liabilities" by Yan Ji and Konstantinos Chalkias A

CosmWasm-Examples is a collection of example contracts and applications built using the CosmWasm framework

CosmWasm-Examples is a collection of example contracts and applications built using the CosmWasm framework. CosmWasm is a secure and efficient smart contract platform designed specifically for the Cosmos ecosystem.

Comments
  • Policy paths

    Policy paths

    Hey, I tried to switch policy paths in your code and in modified code written by me (without taproot) and found out that changes have no effect whatsoever on finalization or signing.

    I am talking about this line

    https://github.com/danielabrozzoni/multisigs_and_carrots/blob/cb7bbd4ce044aca846c930087dc865bf04582af8/src/create_psbt.rs#L40

    may be you have some ideas @danielabrozzoni why it happens?

    opened by evd0kim 0
Owner
Daniela Brozzoni
Daniela Brozzoni
A quick create wizard to create and modify opinionated kustomize deployments.

kqc ?? โ˜ธ๏ธ A quick create wizard to create and modify opinionated kustomize deployments. This tool should help to quickly create and build up kustomize

Daniel Jankowski 8 May 20, 2023
Zei is a library that provide tools to create and verify public transaction with confidential data.

#Zei: Findora's Cryptographic Library Zei is a library that provide tools to create and verify public transaction with confidential data. Support: Bas

Findora Foundation 0 Oct 23, 2022
Starknet Stack let's you easily create new Cairo Starknet chains with their own sequencers, provers and verifiers

Starknet Stack flowchart LR A("Client") ==>|"Starknet Transactions"| subGraph0["Sequencer"] subGraph0 -.->|"Blocks with txs"| 300319["Watcher prover

Lambdaclass 7 Jul 11, 2023
Create your personal token with rust smart contracts

Solana Rust Token ?? This application written Rust using Anchor โš“

Ritesh 6 Nov 22, 2022
MevWallet is a smart contract wallet that allows the user to capture MEV from Searchers, or create MEV on purpose.

MevWallet MevWallet is a smart contract wallet that allows the user to capture MEV from Searchers, or create MEV on purpose. This repo contains the so

Blunt Instruments 94 Jan 26, 2023
A simple and secure rust command-line tool to protect your text by encrypting and decrypting it using the robust AES-256 algorithm.

Secret Keeper A simple and secure command-line tool to protect your text by encrypting and decrypting it using the robust AES-256 algorithm. Built wit

Kunal Bagaria 9 May 11, 2023
Ethereum (and Ethereum like) indexer using P2P message to fetch blocks and transactions

Ethereum P2P indexer This project is an indexer for Ethereum and Ethereum forks. It takes advantage of the ETH (Ethereum Wire Protocol) to fetch block

null 5 Nov 10, 2023
shavee is a Program to automatically decrypt and mount ZFS datasets using Yubikey HMAC as 2FA or any USB drive with support for PAM to auto mount home directories.

shavee is a simple program to decrypt and mount encrypted ZFS user home directories at login using Yubikey HMAC or a Simple USB drive as 2FA written in rust.

Ashutosh Verma 38 Dec 24, 2022
A prototype project integrating jni rust into Kotlin and using protobuf to make them work together

KotlinRustProto a prototype project integrating jni rust into Kotlin and using protobuf to make them work together How to start add a RPC call in Droi

woo 11 Sep 5, 2022
Port path module (and tests) of nodejs to rust using the same algorithms.

rusty_nodejs_path Port path module (and tests) of nodejs to rust using the same algorithms. crates.io Documents Progress posix path.basename(path[, ex

Yunfei He 10 Sep 25, 2022