Skip to content

Commit

Permalink
add zkcard wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
simonjiao committed Apr 21, 2023
1 parent e92ec7b commit c2faae6
Show file tree
Hide file tree
Showing 12 changed files with 799 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"src/components/finutils",
"src/components/abciapp",
"src/components/config",
"src/components/zkcards_wasm",
"src/components/wasm",
"src/components/wallet_mobile",
"src/components/contracts/baseapp",
Expand Down
69 changes: 69 additions & 0 deletions src/components/zkcards_wasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[package]
name = "zkcards-wasm"
version = "0.1.0"
authors = ["[email protected]"]
build = "build.rs"
edition = "2021"

description = ""
repository = ""
license = ""

# wasm-opt has a segfaulting issue. Disabling for now
[package.metadata.wasm-pack.profile.release]
wasm-opt = false

[dependencies]
base64 = "0.12"
hex = "0.4.2"
js-sys = "0.3.27"
rand_chacha = "0.2"
rand_core = { version = "0.5", default-features = false, features = ["alloc"] }
rand = { version = "0.7", features = ["wasm-bindgen"] }
serde = { version = "1.0.124", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = { version = "=0.2.84", features = ["serde-serialize"] }

ring = "0.16.19"
aes-gcm = "0.9.0"
bech32 = "0.7.2"

# Must enable the "js"-feature,
# OR the compiling will fail.
getrandom = { version = "0.2", features = ["js"] }

zei = { git = "https://github.com/FindoraNetwork/zei", branch = "stable-main" }

ark-ff = "0.3.0"
ark-std = { version = "0.3.0", features = ["std"] }
ark-serialize = { version = "0.3.0", features = ["derive"] }
proof-essentials = { git = "https://github.com/FindoraNetwork/proof-toolbox.git", branch = "findora" }
starknet-curve = { git = "https://github.com/FindoraNetwork/proof-toolbox.git", branch = "findora" }
barnett = { git = "https://github.com/simonjiao/mental-poker.git", branch = "develop", package = "barnett-smart-card-protocol" }

[lib]
crate-type = ["cdylib", "rlib"]
path = "src/wasm.rs"

[dependencies.web-sys]
version = "0.3.4"
features = [
'Headers',
'Request',
'RequestInit',
'RequestMode',
'Response',
'Window',
'console',
]

[build-dependencies]
serde = "1.0.124"
serde_json = "1.0.41"
vergen = "=3.1.0"
wasm-bindgen = { version = "=0.2.84", features = ["serde-serialize"] }

[dev-dependencies]
# Must enable the "js"-feature,
# OR the compiling will fail.
getrandom = { version = "0.2", features = ["js"] }
11 changes: 11 additions & 0 deletions src/components/zkcards_wasm/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use vergen::{generate_cargo_keys, ConstantsFlags};

fn main() {
let mut flags = ConstantsFlags::all();
// Tell vergen to use the semver from cargo and not `git describe`
flags.set(ConstantsFlags::SEMVER, false);
flags.set(ConstantsFlags::SEMVER_FROM_CARGO_PKG, true);

// Generate the 'cargo:' key output
generate_cargo_keys(flags).expect("Unable to generate the cargo keys!");
}
3 changes: 3 additions & 0 deletions src/components/zkcards_wasm/conf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["plugins/markdown"]
}
71 changes: 71 additions & 0 deletions src/components/zkcards_wasm/demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Call 'wasm-pack build --target nodejs' to build from this directory for this command to work
const wasm = require('./pkg/wasm.js');
const axios = require('axios');
const HOST = "localhost";
const SUBMISSION_PORT = "8669";
const QUERY_PORT= "8668";

// Create some keypairs
let kp_alice = wasm.new_keypair();
let kp_bob = wasm.new_keypair();
let kp_charlie = wasm.new_keypair();
let kp_auditor = wasm.new_keypair();

console.log(wasm.public_key_to_base64(kp_bob.get_pk()));

// And a separate tracking key for the auditor
let tracking_kp_auditor = wasm.generate_elgamal_keys();

// Alice will define an asset
let token_code = wasm.random_asset_type();
let memo = "test memo";
let definition_transaction = wasm.WasmTransactionBuilder.new().add_operation_create_asset(kp_alice, memo, token_code).transaction();

let route = 'http://' + HOST + ':' + SUBMISSION_PORT;
let ledger = 'http://' + HOST + ':' + QUERY_PORT;

axios.post(route + '/submit_transaction', JSON.parse(definition_transaction))
.then(function(response) {
console.log("Successfully defined asset.");
})
.catch(function(e) {
console.log("Error defining asset. Perhaps the asset has already been created?");
console.log(e);
});

// At this point, transaction would be submitted to the ledger
// Once the definition transaction succeeds, Alice can issue and transfer 1000 units to herself
// Sometimes, it is necessary to have a handle on the issuance output for complicated operations like issuances + transfers.
// Here is an example:

// Manually construct issuance output
let conf_amount = false;
let conf_type = false;
let blind_asset_record = wasm.create_blind_asset_record(1000n, token_code, kp_alice.get_pk(), conf_amount, conf_type);

// Construct transfer operation first
let transfer_op = wasm.WasmTransferOperationBuilder.new()
.add_input(wasm.create_relative_txo_ref(0n),
wasm.open_blind_asset_record(blind_asset_record, kp_alice),
1000n)
.add_output(1000n, kp_bob.get_pk(), token_code)
.create(wasm.standard_transfer_type())
.sign(kp_alice)
.transaction();

// Txn with issuance and transfer operation
let issue_and_transfer_txn = wasm.WasmTransactionBuilder.new()
.add_operation_issue_asset(kp_alice, token_code, 1n, blind_asset_record)
.add_operation(transfer_op)
.transaction();

axios.post(route + '/submit_transaction', JSON.parse(issue_and_transfer_txn))
.then(function(response) {
console.log("Issued and transferred asset.");

})
.catch(function(_) {
console.log("Error issuing and transferring asset");
});


28 changes: 28 additions & 0 deletions src/components/zkcards_wasm/input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"wasm-funcs": [
{ "name": "create_asset",
"result": "Result<String, JsValue>",
"args": [ [ "key_pair", "KeyPair" ],
[ "token_code", "String" ],
[ "updatable", "bool" ],
[ "traceable", "bool" ]
]
},
{ "name": "issue_asset",
"result": "Result<String, JsValue>",
"args": [ [ "key_pair", "KeyPair" ],
[ "token_code", "String" ],
[ "seq_num", "u64" ],
[ "amount", "u64" ]
]
},
{ "name": "transfer_asset",
"result": "Result<String, JsValue>",
"args": [ [ "key_pair", "KeyPair" ],
[ "txo_sid", "u64" ],
[ "amount", "u64" ],
[ "blind_asset_record_str", "String" ]
]
}
]
}
15 changes: 15 additions & 0 deletions src/components/zkcards_wasm/src/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//!
//! Interface for issuing transactions that can be compiled to Wasm.
//!
//! Allows web clients to issue transactions from a browser contexts.
//!
//! For now, forwards transactions to a ledger hosted locally.
//!
//! To compile wasm package, run wasm-pack build in the wasm directory.
//!
#![allow(warnings)]
#![deny(missing_docs)]
#![allow(clippy::needless_borrow)]

mod zkcards;
38 changes: 38 additions & 0 deletions src/components/zkcards_wasm/src/zkcards/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use barnett::error::CardProtocolError;
use proof_essentials::error::CryptoError;
use std::fmt::{Display, Formatter};

pub type Result<U> = std::result::Result<U, GameErrors>;

#[derive(Debug, PartialEq)]
pub enum GameErrors {
InvalidParameters,
CardNotFound,
InvalidCard,
NotReady,
AllShuffled,
ProtocolError(CardProtocolError),
CryptoError(CryptoError),
NotEnoughRevealedTokens(u32),
}

impl Display for GameErrors {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::InvalidParameters => write!(f, "Invalid config parameters"),
Self::CardNotFound => write!(f, "No such card in hand"),
Self::InvalidCard => write!(f, "Invalid card"),
Self::NotReady => write!(f, "Game not Ready"),
Self::AllShuffled => write!(f, "All players have been shuffled"),
Self::ProtocolError(e) => write!(f, "Protocol Error: {}", e.to_string()),
Self::CryptoError(e) => write!(f, "Crypto Error: {}", e.to_string()),
Self::NotEnoughRevealedTokens(_) => write!(f, "No enough revealed tokens"),
}
}
}

impl From<CardProtocolError> for GameErrors {
fn from(value: CardProtocolError) -> Self {
Self::ProtocolError(value)
}
}
Loading

0 comments on commit c2faae6

Please sign in to comment.