example/smart-contract: Cleanup

This commit is contained in:
Luther Blissett
2022-10-14 03:13:35 +02:00
parent ecbe5c35c8
commit 12b7419c10
10 changed files with 3736 additions and 41 deletions

View File

@@ -1,3 +1,3 @@
target/*
Cargo.lock
smart_contract.wasm
proof/*.bin
contract.wasm

3650
example/smart-contract/Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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"

View File

@@ -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

View 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.

View File

@@ -0,0 +1,13 @@
# Currently just a dummy contract
constant "SmartContract" {
EcFixedPointBase NULLIFIER_K,
}
contract "SmartContract" {
Base something,
}
circuit "SmartContract" {
constrain_instance(something);
}

View File

@@ -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");

View File

@@ -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);

View File

@@ -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),
}
}

View File

@@ -1,3 +1,5 @@
pub use pasta_curves as pasta;
/// Entrypoint used for the wasm binaries
pub mod entrypoint;