Explorar el Código

example/smart-contract: Nullifier lookup in state.

Luther Blissett hace 3 años
padre
commit
ada09adde8

+ 5 - 7
example/smart-contract/Cargo.toml

@@ -9,18 +9,16 @@ edition = "2021"
 crate-type = ["cdylib", "rlib"]
 
 [dependencies]
-borsh = "0.9.3"
-drk-sdk = { path = "../../src/sdk" }
+darkfi-sdk = { path = "../../src/sdk" }
 darkfi = { path = "../../", features = ["serial"]}
-
-[dependencies.pasta_curves]
-git = "https://github.com/darkrenaissance/pasta_curves"
-branch = "serialization-support"
-features = ["borsh"]
+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

+ 15 - 13
example/smart-contract/src/lib.rs

@@ -1,29 +1,22 @@
-use borsh::{BorshDeserialize, BorshSerialize};
-use drk_sdk::{
+use darkfi::serial::{deserialize, SerialDecodable, SerialEncodable};
+use darkfi_sdk::{
+    crypto::Nullifier,
     entrypoint,
     error::{ContractError, ContractResult},
     msg,
+    state::nullifier_exists,
 };
 use pasta_curves::pallas;
 
-use darkfi::serial::{deserialize, SerialDecodable, SerialEncodable};
-
-#[derive(BorshSerialize, BorshDeserialize)]
-pub struct Args {
-    pub a: pallas::Base,
-    pub b: pallas::Base,
-}
-
 #[derive(SerialEncodable, SerialDecodable)]
-pub struct Foo {
+pub struct Args {
     pub a: u64,
     pub b: u64,
 }
 
 entrypoint!(process_instruction);
 fn process_instruction(ix: &[u8]) -> ContractResult {
-    //let args = Args::try_from_slice(ix)?;
-    let args: Foo = deserialize(ix)?;
+    let args: Args = deserialize(ix)?;
 
     if args.a < args.b {
         return Err(ContractError::Custom(69))
@@ -34,5 +27,14 @@ fn process_instruction(ix: &[u8]) -> ContractResult {
     msg!("Hello from the VM runtime!");
     msg!("Sum: {:?}", sum);
 
+    let nf = Nullifier::from(pallas::Base::from(0x10));
+    msg!("Contract nf: {:?}", nf);
+
+    if nullifier_exists(&nf)? {
+        msg!("Nullifier exists");
+    } else {
+        msg!("Nullifier doesn't exist");
+    }
+
     Ok(())
 }

+ 46 - 12
example/smart-contract/tests/runtime.rs

@@ -1,32 +1,66 @@
-use borsh::BorshSerialize;
+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},
+    node::{MemoryState, State},
     runtime::{util::serialize_payload, vm_runtime::Runtime},
     serial::serialize,
     Result,
 };
-use pasta_curves::pallas;
 
-use smart_contract::{Args, Foo};
+use smart_contract::Args;
 
 #[test]
 fn run_contract() -> Result<()> {
+    let mut logcfg = simplelog::ConfigBuilder::new();
+    logcfg.add_filter_ignore("sled".to_string());
     simplelog::TermLogger::init(
         simplelog::LevelFilter::Debug,
-        simplelog::Config::default(),
+        logcfg.build(),
         simplelog::TerminalMode::Mixed,
         simplelog::ColorChoice::Auto,
     )?;
 
-    let wasm_bytes = std::fs::read("smart_contract.wasm")?;
-    let mut runtime = Runtime::new(&wasm_bytes)?;
+    // ============================================================
+    // Build a ledger state so the runtime has something to work on
+    // ============================================================
+    let sled_db = sled::Config::new().temporary(true).open()?;
+    let blockchain =
+        Blockchain::new(&sled_db, *TESTNET_GENESIS_TIMESTAMP, *TESTNET_GENESIS_HASH_BYTES)?;
 
-    let _args = Args { a: pallas::Base::from(777), b: pallas::Base::from(666) };
-    let _payload = _args.try_to_vec()?;
+    let merkle_tree = BridgeTree::<MerkleNode, 32>::new(100);
 
-    let args = Foo { a: 777, b: 666 };
-    let payload = serialize(&args);
+    let state_machine = State {
+        tree: merkle_tree,
+        merkle_roots: blockchain.merkle_roots,
+        nullifiers: blockchain.nullifiers,
+        cashier_pubkeys: vec![],
+        faucet_pubkeys: vec![],
+        mint_vk: Lazy::new(),
+        burn_vk: Lazy::new(),
+    };
 
-    let input = serialize_payload(&payload);
+    // We check if this nullifier is in the set from 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 mut runtime = Runtime::new(&wasm_bytes, MemoryState::new(state_machine))?;
+
+    // ===========================================================
+    // Build some kind of payload for the wasm entrypoint function
+    // ===========================================================
+    let args = Args { a: 777, b: 666 };
+    let payload = serialize(&args);
 
-    runtime.run(&input)
+    // ============================================================
+    // Serialize the payload into the runtime format and execute it
+    // ============================================================
+    runtime.run(&serialize_payload(&payload))
 }