Coder Social home page Coder Social logo

zkbitcoin's Introduction

zkBitcoin

Use zero-knowledge applications (zkapps) on Bitcoin! (Currently only on testnet.)

image

How does it work? Write your zkapp in circom and deploy it on Bitcoin by sending a transaction to our multi-party wallet run by a committee of nodes.

To use a zkapp, provide a correct proof of execution using snarkjs to our multi-party wallet which will trigger a threshold signature, eventually allowing funds to move out of the zkapp.

Check the whitepaper here.

Installation

Jump straight to usage if you want to see some examples, but make sure to read this section otherwise things won't work!

Circom/snarkjs

We build on top of the well-known circom/snarkjs stack.

Bitcoin wallet

On top that, you'll need your own Bitcoin node/wallet. This application will perform queries to your node/wallet in order to fund your zkapp transactions.

All the following commands expects the following environment variables to be set so that it can communicate with your node/wallet:

export RPC_WALLET="walletname"
export RPC_ADDRESS="http://127.0.01:18331"
export RPC_AUTH="username:password"

zkbtc: the zkBitcoin CLI

To install zkbtc, run the following command:

cargo install --git https://github.com/sigma0-xyz/zkbitcoin.git

Usage

There are two types of zkapps: stateless and stateful.

Stateless zkapps

A stateless zkapp is single-use, and the bitcoin it locks can be redeemed by anyone who can provide a proof of correct execution. An example of a stateless zkapp is in examples/circuit/stateless.circom (which releases funds to anyone who can find the preimage of a hash function). A stateless zkapp must always contains one public input that authenticates the transaction that spends it:

// circom code
template Main() {
    signal input truncated_txid;
    // TRUNCATED...
}
component main{public [truncated_txid]} = Main();

The zkapp doesn't have to do anything with the truncated_txid field (although it can if it wants to).

You can deploy a stateless zkapp with the following command:

$ zkbtc deploy-zkapp --circom-circuit-path examples/circuit/stateless.circom --satoshi-amount 1000

This will lock 1,000 satoshis in the zkapp and return the transaction ID of the transaction that deployed the zkapp. A stateless zkapp can be referenced by that transaction ID.

Bob can then unlock the funds from the stateless zkapp with the following command:

$ zkbtc use-zkapp --txid "e793bdd8dfdd9912d971790a5f385ad3f1215dce97e25dbefe5449faba632836" --circom-circuit-path examples/circuit/stateless.circom --proof-inputs '{"preimage":["1"]}' --recipient-address "tb1q6nkpv2j9lxrm6h3w4skrny3thswgdcca8cx9k6"

Stateful zkapps

A stateful zkapp is a zkapp that has a state, and which state can be updated without consuming the zkapp.

An example of a stateful zkapp is in examples/circuit/stateful.circom. A stateful zkapp must always contains a number of additional public inputs, allowing an execution to authenticate the zkapp state transition, as well as the amounts being withdrawn and deposited:

// circom code
template Main() {
    signal output new_state;
    signal input prev_state;
    signal input truncated_txid; // this should not affect output
    signal input amount_out;
    signal input amount_in;
    // TRUNCATED...
}
component main{public [prev_state, truncated_txid, amount_out, amount_in]} = Main();

You can deploy a stateful zkapp with the following command:

$ zkbtc deploy-zkapp --circom-circuit-path examples/circuit/stateful.circom --initial-state "1" --satoshi-amount 1000     

You can use a stateful zkapps with the following command:

$ zkbtc use-zkapp --circom-circuit-path examples/circuit/stateful.circom --proof-inputs '{"amount_in":["1000"], "amount_out":["1000"]}' --recipient-address "tb1q6vjawwska63qxf77rrm5uwqev0ma8as8d0mkrt" --txid "76763d6130ee460ede2739e0f38ea4d61cc940b00af5eab83e5afb0fcc837b91"

specifying the following inputs:

  • amount_out: amount being withdrawn
  • amount_in: amount being deposited

Other inputs will be automatically filled in (for example, it will use the zkapp's state as prev_state input).

Run an MPC node with Docker

If you're using the DigitalOcean Docker droplet (or any Linux server protected with UFW), you need to open the port first:

sudo ufw allow 8891
  1. Fetch the image:
docker pull imikushin/zkbitcoin
  1. Create the zkBitcoin node container (creates the keys Docker volume if you don't already have it):
docker create --restart=always -v keys:/keys --name zkbtc-node -p 8891:8891 imikushin/zkbitcoin \
  zkbtc start-committee-node \
  --key-path=/keys/key.json --publickey-package-path=/keys/publickey-package.json \
  --address=0.0.0.0:8891
  1. Create the keys (./key.json, ./publickey-package.json) and copy them into the keys volume:
docker cp ./key.json zkbtc-node:/keys/key.json
docker cp ./publickey-package.json zkbtc-node:/keys/publickey-package.json
  1. Start the node:
docker start zkbtc-node

You should now see the container show up in the printout from running the docker ps -a shell command:

CONTAINER ID   IMAGE                 COMMAND                  CREATED             STATUS          PORTS                    NAMES
b3d2e7c028ce   imikushin/zkbitcoin   "zkbtc start-committ…"   About an hour ago   Up 55 minutes   0.0.0.0:8891->8891/tcp   zkbtc-node

Follow its logs with docker logs -f zkbtc-node:

[2024-01-20T22:28:35Z INFO  zkbtc] - zkbitcoin_address: tb1p5sfstsnt9akcqf9zkm6ulke8ujwakjd8kdk5krws2th4ds238meqq4awtv
[2024-01-20T22:28:35Z INFO  zkbtc] - zkbitcoin_fund_address: tb1pv7auuumlqm9kehlep4y83xcthyma5yvprvlx39k7xvveh48976sq7e6sr5
[2024-01-20T22:28:35Z INFO  zkbitcoin::committee::node] - starting node for identifier Identifier("0000000000000000000000000000000000000000000000000000000000000001") at address http://0.0.0.0:8891

The node is now running in the background and listening on port 8891, and you can verify if that's the case (from your local machine):

nc -zv ${SERVER_IP} 8891

Updating the MPC node software

docker pull imikushin/zkbitcoin
docker rm -f zkbtc-node

Now re-run steps 2 and 4 from above: create the container and then start it (the keys volume is re-used).

Tell me more

You can read more about zkBitcoin in our whitepaper, our documentation, and about advanced usage in our developer documentation.

zkbitcoin's People

Contributors

mimoo avatar imikushin avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.