mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
example/smart-contract: Cleanup
This commit is contained in:
4
example/smart-contract/.gitignore
vendored
4
example/smart-contract/.gitignore
vendored
@@ -1,3 +1,3 @@
|
||||
target/*
|
||||
Cargo.lock
|
||||
smart_contract.wasm
|
||||
proof/*.bin
|
||||
contract.wasm
|
||||
|
||||
3650
example/smart-contract/Cargo.lock
generated
Normal file
3650
example/smart-contract/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
[package]
|
||||
name = "smart-contract"
|
||||
version = "0.3.0"
|
||||
authors = ["darkfi <dev@dark.fi>"]
|
||||
license = "AGPL-3.0-only"
|
||||
edition = "2021"
|
||||
|
||||
[workspace]
|
||||
@@ -8,19 +10,15 @@ edition = "2021"
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
darkfi-sdk = { path = "../../src/sdk" }
|
||||
darkfi = { path = "../../", features = ["serial"]}
|
||||
pasta_curves = "0.4.0"
|
||||
|
||||
[dev-dependencies]
|
||||
darkfi = { path = "../../", features = ["wasm-runtime"] }
|
||||
incrementalmerkletree = "0.3.0"
|
||||
lazy-init = "0.5.1"
|
||||
simplelog = "0.12.0"
|
||||
sled = "0.34.7"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
codegen-units = 1
|
||||
overflow-checks = true
|
||||
|
||||
[dependencies]
|
||||
darkfi-sdk = { path = "../../src/sdk" }
|
||||
darkfi = { path = "../../", features = ["serial"] }
|
||||
|
||||
[dev-dependencies]
|
||||
darkfi = { path = "../../", features = ["wasm-runtime"] }
|
||||
simplelog = "0.12.0"
|
||||
|
||||
@@ -1,22 +1,39 @@
|
||||
.POSIX:
|
||||
|
||||
SRC = $(shell find src -type f)
|
||||
WASM_SRC = $(shell find src -type f)
|
||||
PROOF_SRC = $(shell find proof -type f -name '*.zk')
|
||||
|
||||
# Cargo binary
|
||||
CARGO = cargo
|
||||
|
||||
BIN = smart_contract.wasm
|
||||
# zkas binary
|
||||
ZKAS = ../../zkas
|
||||
|
||||
all: $(BIN)
|
||||
# wasm-strip binary (Part of https://github.com/WebAssembly/wabt)
|
||||
WASM_STRIP = wasm-strip
|
||||
|
||||
smart_contract.wasm: $(SRC)
|
||||
# Contract WASM binary
|
||||
WASM_BIN = contract.wasm
|
||||
|
||||
# ZK circuit binaries
|
||||
PROOF_BIN = $(PROOF_SRC:=.bin)
|
||||
|
||||
all: $(PROOF_BIN) $(WASM_BIN)
|
||||
|
||||
strip: $(WASM_BIN)
|
||||
$(WASM_STRIP) $<
|
||||
|
||||
$(WASM_BIN): $(WASM_SRC)
|
||||
$(CARGO) build --release --lib --target wasm32-unknown-unknown
|
||||
cp -f target/wasm32-unknown-unknown/release/$@ $@
|
||||
cp -f target/wasm32-unknown-unknown/release/*.wasm $@
|
||||
|
||||
$(PROOF_BIN): $(PROOF_SRC)
|
||||
$(ZKAS) $(basename $@) -o $@
|
||||
|
||||
test: all
|
||||
$(CARGO) test --release -- --nocapture
|
||||
|
||||
clean:
|
||||
rm -f $(BIN)
|
||||
rm -f $(PROOF_BIN) $(WASM_BIN)
|
||||
|
||||
.PHONY: all test clean
|
||||
|
||||
6
example/smart-contract/README.md
Normal file
6
example/smart-contract/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Smart contract demo and template
|
||||
================================
|
||||
|
||||
This crate is a reference DarkFI smart contract implementation. All
|
||||
repositories implementing contracts should follow the same layout, as
|
||||
this will allow easy deployments using the commandline utilities.
|
||||
13
example/smart-contract/proof/contract.zk
Normal file
13
example/smart-contract/proof/contract.zk
Normal file
@@ -0,0 +1,13 @@
|
||||
# Currently just a dummy contract
|
||||
|
||||
constant "SmartContract" {
|
||||
EcFixedPointBase NULLIFIER_K,
|
||||
}
|
||||
|
||||
contract "SmartContract" {
|
||||
Base something,
|
||||
}
|
||||
|
||||
circuit "SmartContract" {
|
||||
constrain_instance(something);
|
||||
}
|
||||
@@ -4,31 +4,38 @@ use darkfi_sdk::{
|
||||
entrypoint,
|
||||
error::{ContractError, ContractResult},
|
||||
msg,
|
||||
pasta::pallas,
|
||||
state::nullifier_exists,
|
||||
};
|
||||
use pasta_curves::pallas;
|
||||
|
||||
// An example of deserializing the payload into a struct
|
||||
#[derive(SerialEncodable, SerialDecodable)]
|
||||
pub struct Args {
|
||||
pub a: u64,
|
||||
pub b: u64,
|
||||
}
|
||||
|
||||
// This is the main entrypoint function where the payload is fed.
|
||||
// Through here, you can branch out into different functions inside
|
||||
// this library.
|
||||
entrypoint!(process_instruction);
|
||||
fn process_instruction(ix: &[u8]) -> ContractResult {
|
||||
// Deserialize the payload into `Args`.
|
||||
let args: Args = deserialize(ix)?;
|
||||
|
||||
if args.a < args.b {
|
||||
// Returning custom errors
|
||||
return Err(ContractError::Custom(69))
|
||||
}
|
||||
|
||||
let sum = args.a + args.b;
|
||||
|
||||
// Publicly logged messages
|
||||
msg!("Hello from the VM runtime!");
|
||||
msg!("Sum: {:?}", sum);
|
||||
|
||||
// Querying of ledger state available from the VM host
|
||||
let nf = Nullifier::from(pallas::Base::from(0x10));
|
||||
msg!("Contract nf: {:?}", nf);
|
||||
msg!("Contract Nullifier: {:?}", nf);
|
||||
|
||||
if nullifier_exists(&nf)? {
|
||||
msg!("Nullifier exists");
|
||||
|
||||
@@ -1,47 +1,43 @@
|
||||
use incrementalmerkletree::bridgetree::BridgeTree;
|
||||
use lazy_init::Lazy;
|
||||
use pasta_curves::pallas;
|
||||
|
||||
use darkfi::{
|
||||
blockchain::Blockchain,
|
||||
consensus::{TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP},
|
||||
crypto::{merkle_node::MerkleNode, nullifier::Nullifier},
|
||||
crypto::nullifier::Nullifier,
|
||||
node::{MemoryState, State},
|
||||
runtime::{util::serialize_payload, vm_runtime::Runtime},
|
||||
serial::serialize,
|
||||
Result,
|
||||
};
|
||||
use darkfi_sdk::pasta::pallas;
|
||||
|
||||
use smart_contract::Args;
|
||||
|
||||
#[test]
|
||||
fn run_contract() -> Result<()> {
|
||||
let mut logcfg = simplelog::ConfigBuilder::new();
|
||||
logcfg.add_filter_ignore("sled".to_string());
|
||||
// Debug log configuration
|
||||
let mut cfg = simplelog::ConfigBuilder::new();
|
||||
cfg.add_filter_ignore("sled".to_string());
|
||||
simplelog::TermLogger::init(
|
||||
simplelog::LevelFilter::Debug,
|
||||
logcfg.build(),
|
||||
cfg.build(),
|
||||
simplelog::TerminalMode::Mixed,
|
||||
simplelog::ColorChoice::Auto,
|
||||
)?;
|
||||
|
||||
// ============================================================
|
||||
// =============================================================
|
||||
// Build a ledger state so the runtime has something to work on
|
||||
// ============================================================
|
||||
let state_machine = MemoryState::new(State::dummy())?;
|
||||
// =============================================================
|
||||
let state_machine = State::dummy()?;
|
||||
|
||||
// We check if this nullifier is in the set from the contract
|
||||
// Add a nullifier to the nullifier set. (This is checked by the contract)
|
||||
state_machine.nullifiers.insert(&[Nullifier::from(pallas::Base::from(0x10))])?;
|
||||
|
||||
// ================================================================
|
||||
// Load the wasm binary into memory and create an execution runtime
|
||||
// ================================================================
|
||||
let wasm_bytes = std::fs::read("smart_contract.wasm")?;
|
||||
let wasm_bytes = std::fs::read("contract.wasm")?;
|
||||
let mut runtime = Runtime::new(&wasm_bytes, MemoryState::new(state_machine))?;
|
||||
|
||||
// ===========================================================
|
||||
// Build some kind of payload for the wasm entrypoint function
|
||||
// ===========================================================
|
||||
// =============================================
|
||||
// Build some kind of payload to show an example
|
||||
// =============================================
|
||||
let args = Args { a: 777, b: 666 };
|
||||
let payload = serialize(&args);
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ pub enum ContractError {
|
||||
|
||||
#[error("Error checking if nullifier exists")]
|
||||
NullifierExistCheck,
|
||||
|
||||
#[error("Error checking merkle root validity")]
|
||||
ValidMerkleCheck,
|
||||
}
|
||||
|
||||
/// Builtin return values occupy the upper 32 bits
|
||||
@@ -33,6 +36,7 @@ pub const CUSTOM_ZERO: u64 = to_builtin!(1);
|
||||
pub const INTERNAL_ERROR: u64 = to_builtin!(2);
|
||||
pub const IO_ERROR: u64 = to_builtin!(3);
|
||||
pub const NULLIFIER_EXIST_CHECK: u64 = to_builtin!(4);
|
||||
pub const VALID_MERKLE_CHECK: u64 = to_builtin!(5);
|
||||
|
||||
impl From<ContractError> for u64 {
|
||||
fn from(err: ContractError) -> Self {
|
||||
@@ -40,6 +44,7 @@ impl From<ContractError> for u64 {
|
||||
ContractError::Internal => INTERNAL_ERROR,
|
||||
ContractError::IoError(_) => IO_ERROR,
|
||||
ContractError::NullifierExistCheck => NULLIFIER_EXIST_CHECK,
|
||||
ContractError::ValidMerkleCheck => VALID_MERKLE_CHECK,
|
||||
ContractError::Custom(error) => {
|
||||
if error == 0 {
|
||||
CUSTOM_ZERO
|
||||
@@ -58,6 +63,7 @@ impl From<u64> for ContractError {
|
||||
INTERNAL_ERROR => Self::Internal,
|
||||
IO_ERROR => Self::IoError("Unknown".to_string()),
|
||||
NULLIFIER_EXIST_CHECK => Self::NullifierExistCheck,
|
||||
VALID_MERKLE_CHECK => Self::ValidMerkleCheck,
|
||||
_ => Self::Custom(error as u32),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
pub use pasta_curves as pasta;
|
||||
|
||||
/// Entrypoint used for the wasm binaries
|
||||
pub mod entrypoint;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user