libbolt/README.md

243 lines
11 KiB
Markdown
Raw Permalink Normal View History

2018-02-15 21:00:07 -08:00
# libbolt
2018-04-02 07:48:01 -07:00
2018-07-23 23:40:13 -07:00
A pure-Rust library implementation of BOLT: Blind Off-chain Lightweight Transactions.
2018-04-02 07:48:01 -07:00
2018-08-16 23:00:02 -07:00
BOLT is a system for conducting **privacy-preserving off-chain payments** between pairs of individual parties. BOLT is designed to provide a Layer 2 payment protocol for privacy-preserving cryptocurrencies such as Zcash, by allowing individuals to establish and use payment channels for instantaneous payments that do not require an on-chain transaction.
2018-07-23 23:40:13 -07:00
# WARNING
2018-08-13 21:14:02 -07:00
The libbolt library is a proof of concept implementation that relies on experimental libraries and dependencies at the moment. It is not suitable for production software yet.
2018-07-23 23:40:13 -07:00
# NOTE
Active development of libbolt is ongoing at [Bolt Labs, Inc](https://github.com/boltlabs-inc/libbolt) to instantiate on a cryptocurrency. Will submit pull requests periodically to this repo when new features are complete.
2018-07-23 23:40:13 -07:00
# Dependencies
* secp256k1
2019-10-17 16:13:12 -07:00
* ff
* pairing
2019-10-17 16:13:12 -07:00
* serde
* sha2
2018-07-23 23:40:13 -07:00
2018-08-14 23:04:44 -07:00
Note that the above rust dependencies will be compiled and installed as a result of running the `make` command.
2018-08-14 22:58:16 -07:00
# Rust Nightly Setup
Please keep in mind we are currently working with nightly Rust for now which gives access to the nightly compiler and experimental features.
rustup install nightly
To run a quick test of the nightly toolchain, run the following command:
rustup run nightly rustc --version
Optionally, to make this the default globally, run the following command:
rustup default nightly
We will switch to the stable release channel once libbolt (and dependencies) are ready for production use.
2018-08-14 10:12:28 -07:00
# Build & Install
2018-08-14 05:28:01 -07:00
2019-11-18 20:11:50 -08:00
To build the library in debug, execute tests and basic examples, run `make`
2018-07-23 23:40:13 -07:00
# Tests
2018-08-14 22:58:16 -07:00
To run libbolt unit tests, run `make test`
2018-07-23 23:40:13 -07:00
# Benchmarks
2018-08-14 22:58:16 -07:00
To run libbolt benchmarks, run `make bench`
2018-07-23 23:40:13 -07:00
# Usage
To use the libbolt library, add the `libbolt` crate to your dependency file in `Cargo.toml` as follows:
```toml
[dependencies]
bolt = "0.3.0"
2018-07-23 23:40:13 -07:00
```
Then add an extern declaration at the root of your crate as follows:
```rust
2018-12-18 11:45:04 -08:00
extern crate bolt;
2018-07-23 23:40:13 -07:00
```
# API
The libbolt library provides APIs for two types of payment channels:
2018-07-23 23:40:13 -07:00
2018-08-16 23:00:02 -07:00
* bidirectional payment channels
* third-party payments
2018-07-23 23:40:13 -07:00
## Bidirectional Payment Channels
A bidirectional payment channel enables two parties to exchange arbitrary positive and negative amounts.
### Channel Setup and Key Generation
The first part of setting up bi-directional payment channels involve generating initial setup parameters using curve BLS12-381 with channel state.
2018-12-18 11:45:51 -08:00
use bolt::bidirectional;
// generate the initial channel state
// second argument represents third-party mode
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Channel A -> B"), false);
let mut rng = &mut rand::thread_rng();
// generate fresh public parameters
channel_state.setup(&mut rng);
### Initialization
2019-08-27 23:17:12 -07:00
To initialize state/keys for both parties, call the ``bidirectional::init_merchant()`` and ``bidirectional::init_customer()``:
let b0_merch = 10;
let b0_cust = 100;
2019-08-27 23:17:12 -07:00
// initialize the merchant state and initialize with balance
2019-09-11 08:27:12 -07:00
let (mut channel_token, mut merch_state, mut channel_state) = bidirectional::init_merchant(rng, &mut channel_state, "Bob");
2019-09-16 09:21:00 -07:00
2019-08-27 23:17:12 -07:00
// generate the customer state using the channel token from the merchant
let mut cust_state = bidirectional::init_customer(rng, // rng
&mut channel_token, // channel token
b0_cust, // init customer balance
b0_merch, // init merchant balance
"Alice")); // channel name/purpose
### Establish Protocol
When opening a payment channel, execute the establishment protocol API to escrow funds privately as follows:
2019-08-27 23:17:12 -07:00
// establish the channel by generating initial state commitment proof
let (com, com_proof) = bidirectional::establish_customer_generate_proof(rng, &mut channel_token, &mut cust_state);
// obtain close token for closing out channel
2019-08-27 23:17:12 -07:00
let close_token = bidirectional::establish_merchant_issue_close_token(rng, &channel_state, &com, &com_proof, &merch_state);
// customer verifies that close-token
2019-08-27 23:17:12 -07:00
assert!(cust_state.verify_close_token(&channel_state, &close_token));
// form funding tx and wait for network confirmation
// obtain payment token after confirming funding tx
2019-08-27 23:17:12 -07:00
let pay_token = bidirectional::establish_merchant_issue_pay_token(rng, &channel_state, &com, &merch_state);
// customer
2019-08-27 23:17:12 -07:00
assert!(bidirectional::establish_final(&mut channel_state, &mut cust_state, &pay_token));
// confirm that the channel state is now established
assert!(channel_state.channel_established);
### Pay protocol
To spend on the channel, execute the pay protocol API (can be executed as many times as necessary):
2019-08-27 23:17:12 -07:00
// phase 1 - payment proof and new cust state
let (payment, new_cust_state) = bidirectional::generate_payment_proof(rng, &channel_state, &cust_state, 10);
// phase 1 - merchant verifies the payment proof and returns a close-token
2019-08-27 23:17:12 -07:00
let new_close_token = bidirectional::verify_payment_proof(rng, &channel_state, &payment, &mut merch_state);
2019-08-27 23:17:12 -07:00
// phase 2 - verify the close-token, update cust state and generate a revoke token for previous cust state state
let revoke_token = bidirectional::generate_revoke_token(&channel_state, &mut cust_state, new_cust_state, &new_close_token);
// phase 2 - merchant verifies the revoke token and sends back the pay-token in response
2019-08-27 23:17:12 -07:00
let new_pay_token = bidirectional::verify_revoke_token(&revoke_token, &mut merch_state);
// final - customer verifies the pay token and updates internal state
2019-08-27 23:17:12 -07:00
assert!(cust_state.verify_pay_token(&channel_state, &new_pay_token));
2019-07-31 20:11:02 -07:00
### Channel Closure Algorithms
2018-08-16 23:00:02 -07:00
To close a channel, the customer must execute the `bidirectional::customer_refund()` routine as follows:
2019-09-09 08:08:13 -07:00
let cust_close_msg = bidirectional::customer_close(&channel_state, &cust_state);
2019-08-27 23:17:12 -07:00
If the customer broadcasts an outdated version of his state, then the merchant can dispute this claim by executing the `bidirectional::merchant_retute()` routine as follows:
2019-09-09 08:08:13 -07:00
let merch_close = bidirectional::merchant_close(&channel_state, &channel_token, &cust_close_msg, &merch_state);
2019-07-31 20:11:02 -07:00
## Third-party Payments
2018-08-14 23:04:44 -07:00
2018-08-16 23:00:02 -07:00
The bidirectional payment channels can be used to construct third-party payments in which a party **A** pays a second party **B** through an untrusted intermediary (**I**) to which both **A** and **B** have already established a channel. With BOLT, the intermediary learns nothing about the payment from **A** to **B** and cannot link transactions to individual users.
To enable third-party payment support, initialize each payment channel as follows:
2018-08-16 23:00:02 -07:00
// create the channel state for each channel and indicate third-party support
2019-10-17 15:36:11 -07:00
let mut channel_state = bidirectional::ChannelState::<Bls12>::new(String::from("Third-party Channels"), true);
2018-08-16 23:00:02 -07:00
Moreover, the intermediary can set a channel fee as follows:
2019-10-17 15:36:11 -07:00
channel_state.set_channel_fee(5);
2018-08-16 23:00:02 -07:00
The channel establishment still works as described before and the pay protocol includes an additional step to verify that the payments on both channels cancel out or include a channel fee (if specified).
...
let payment_amount = 20;
2019-10-17 15:36:11 -07:00
// get payment proof on first channel with party A and H
2019-10-17 16:01:32 -07:00
let (sender_payment, new_cust_stateA) = bidirectional::generate_payment_proof(rng, &channel_state,
2019-08-27 23:17:12 -07:00
&cust_stateA,
2018-08-16 23:00:02 -07:00
payment_amount); // bal inc
2019-10-17 15:36:11 -07:00
// get payment proof on second channel with party B and H
let (receiver_payment, new_cust_stateB) = bidirectional::generate_payment_proof(rng, &channel_state,
2019-08-27 23:17:12 -07:00
&cust_stateB,
2019-07-31 20:11:02 -07:00
-payment_amount); // bal dec
2019-10-17 15:36:11 -07:00
// intermediary executes the following on the two payment proofs
// verifies that the payment proof is valid & cancels out and results in hub's fee
let close_token_result = bidirectional::verify_multiple_payment_proofs(rng, &channel_state,
&sender_payment,
&receiver_payment,
&mut merch_state);
2019-10-17 16:01:32 -07:00
// alice gets a close token and bob gets a conditional token which requires alice's revoke token to be valid
2019-10-17 15:36:11 -07:00
let (alice_close_token, bob_cond_close_token) = handle_bolt_result!(close_token_result).unwrap();
2018-08-16 23:00:02 -07:00
2019-10-17 15:36:11 -07:00
// both alice and bob generate a revoke token
let revoke_token_alice = bidirectional::generate_revoke_token(&channel_state,
&mut cust_stateA,
new_cust_stateA,
&alice_close_token);
let revoke_token_bob = bidirectional::generate_revoke_token(&channel_state,
&mut cust_stateB,
new_cust_stateB,
&bob_cond_close_token);
// send both revoke tokens to intermediary and receive pay-tokens (one for sender and another for receiver)
let new_pay_tokens: BoltResult<(cl::Signature<Bls12>,cl::Signature<Bls12>)> = \
bidirectional::verify_multiple_revoke_tokens(&revoke_token_sender,
&revoke_token_receiver,
&mut merch_state);
2018-08-16 23:00:02 -07:00
...
2019-10-17 15:36:11 -07:00
See the `intermediary_payment_basics_works()` unit test in `src/lib.rs` for more details.
2018-08-14 05:28:01 -07:00
# Documentation (TODO)
2018-08-14 05:28:01 -07:00
Build the api documentation by simply running `make doc`. Documentation will be generated in your local `target/doc` directory.
2018-08-14 22:58:16 -07:00
For the libbolt design documentation, see the `docs/bolt_design.pdf` document.
2018-08-14 05:28:01 -07:00
# Contributions
2018-08-14 22:58:16 -07:00
To contribute code improvements, please checkout the repository, make your changes and submit a pull request.
2018-08-14 05:28:01 -07:00
git clone https://github.com/ZcashFoundation/libbolt.git
2018-08-14 05:28:01 -07:00
# TODOs
Here are some TODOs (not in any particular order):
2019-09-09 08:08:13 -07:00
* Add more unit tests for other dispute resolution scenarios and third-party test cases
2018-08-14 05:28:01 -07:00
# License
2018-07-23 23:40:13 -07:00
2018-08-14 05:28:01 -07:00
Licensed under MIT (LICENSE-MIT or http://opensource.org/licenses/MIT)