瀏覽代碼

wasm: add metadata() functionality

x 3 年之前
父節點
當前提交
3aba630188

+ 38 - 1
example/smart-contract/src/lib.rs

@@ -6,8 +6,9 @@ use darkfi_sdk::{
     msg,
     tx::FuncCall,
     util::set_return_data,
+    pasta::pallas
 };
-use darkfi_serial::{deserialize, serialize, SerialDecodable, SerialEncodable};
+use darkfi_serial::{deserialize, serialize, SerialDecodable, SerialEncodable, Encodable};
 
 /// Available functions for this contract.
 /// We identify them with the first byte passed in through the payload.
@@ -85,6 +86,42 @@ fn get_metadata(_cid: ContractId, ix: &[u8]) -> ContractResult {
             let _call_data: FooCallData =
                 deserialize(&func_calls[func_call_index as usize].call_data)?;
 
+            let zk_public_values = vec![
+                (
+                    "DaoProposeInput".to_string(),
+                    vec![
+                        pallas::Base::from(110),
+                        pallas::Base::from(4)
+                    ]
+                ),
+                (
+                    "DaoProposeInput".to_string(),
+                    vec![
+                        pallas::Base::from(7),
+                        pallas::Base::from(4)
+                    ]
+                ),
+                (
+                    "DaoProposeMain".to_string(),
+                    vec![
+                        pallas::Base::from(1),
+                        pallas::Base::from(3),
+                        pallas::Base::from(5),
+                        pallas::Base::from(7)
+                    ]
+                )
+            ];
+
+            let signature_public_keys: Vec<pallas::Point> = vec![
+                //pallas::Point::identity()
+            ];
+
+            let mut metadata = Vec::new();
+            zk_public_values.encode(&mut metadata)?;
+            signature_public_keys.encode(&mut metadata)?;
+            set_return_data(&metadata)?;
+            msg!("metadata returned!");
+
             // Convert call_data to halo2 public inputs
             // Pass this to the env
         }

+ 10 - 1
example/smart-contract/tests/runtime.rs

@@ -16,6 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use std::io::Cursor;
 use darkfi::{
     blockchain::Blockchain,
     consensus::{TESTNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_TIMESTAMP},
@@ -23,7 +24,7 @@ use darkfi::{
     Result,
 };
 use darkfi_sdk::{crypto::ContractId, pasta::pallas, tx::FuncCall};
-use darkfi_serial::{serialize, Encodable, WriteExt};
+use darkfi_serial::{serialize, Decodable, Encodable, WriteExt};
 
 use smart_contract::{FooCallData, Function};
 
@@ -84,5 +85,13 @@ fn run_contract() -> Result<()> {
     // =====================================================
     runtime.apply(&update)?;
 
+    // =====================================================
+    // Verify ZK proofs and signatures
+    // =====================================================
+    let metadata = runtime.metadata(&payload)?;
+    let mut decoder = Cursor::new(&metadata);
+    let zk_public_values: Vec<(String, Vec<pallas::Base>)> = Decodable::decode(&mut decoder)?;
+    let signature_public_keys: Vec<pallas::Point> = Decodable::decode(decoder)?;
+
     Ok(())
 }

+ 1 - 1
src/runtime/import/util.rs

@@ -42,7 +42,7 @@ pub(crate) fn drk_log(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) {
 pub(crate) fn set_return_data(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i32 {
     let env = ctx.data();
     match env.contract_section {
-        ContractSection::Exec => {
+        ContractSection::Exec | ContractSection::Metadata => {
             let memory_view = env.memory_view(&ctx);
 
             let Ok(slice) = ptr.slice(&memory_view, len) else {

+ 8 - 1
src/runtime/vm_runtime.rs

@@ -51,6 +51,8 @@ pub enum ContractSection {
     Exec,
     /// Apply function of a contract
     Update,
+    /// Metadata
+    Metadata,
     /// Placeholder state before any initialization
     Null,
 }
@@ -61,6 +63,7 @@ impl ContractSection {
             Self::Deploy => "__initialize",
             Self::Exec => "__entrypoint",
             Self::Update => "__update",
+            Self::Metadata => "__metadata",
             Self::Null => unreachable!(),
         }
     }
@@ -226,7 +229,7 @@ impl Runtime {
         self.set_memory_page_size(pages_required as u32)?;
         self.copy_to_memory(&payload)?;
 
-        debug!(target: "runtime", "Getting initialize function");
+        debug!(target: "runtime", "Getting {} function", section.name());
         let entrypoint = self.instance.exports.get_function(section.name())?;
 
         debug!(target: "runtime", "Executing wasm");
@@ -307,6 +310,10 @@ impl Runtime {
         Ok(())
     }
 
+    pub fn metadata(&mut self, payload: &[u8]) -> Result<Vec<u8>> {
+        self.call(ContractSection::Metadata, payload)
+    }
+
     fn print_logs(&self) {
         let logs = self.ctx.as_ref(&self.store).logs.borrow();
         for msg in logs.iter() {

+ 1 - 1
src/sdk/src/entrypoint.rs

@@ -60,7 +60,7 @@ macro_rules! define_contract {
             }
         }
         #[no_mangle]
-        pub unsafe extern "C" fn __get_metadata(input: *mut u8) -> u64 {
+        pub unsafe extern "C" fn __metadata(input: *mut u8) -> u64 {
             let (contract_id, instruction_data) = $crate::entrypoint::deserialize(input);
 
             match $metadata_func(contract_id, &instruction_data) {