Finschia/cosmwasm

Divide "read only dynamic link" and "read/write dynamic link"

loloicci opened this issue · 3 comments

Other than function name information cannot be used to tell external modules whether the function is read-only or read/write. Now I am considering making a rule to add a prefix declaring whether it is read-only or read/write to each dynamic linked function.

Consider solving #252 not to divide read-only and read/write

The entry point query can be written that sometimes be "read-only" and sometimes be "read-write" as like as dynamic link functions. And in this case, an error is issued when the function tries to write.

This can be confirmed via the following change

diff --git a/contracts/number/src/contract.rs b/contracts/number/src/contract.rs
index d6a76a19..xxxxxxxx 100644
--- a/contracts/number/src/contract.rs
+++ b/contracts/number/src/contract.rs
@@ -64,12 +64,41 @@ fn handle_mul(deps: DepsMut, by: i32) -> Result<Response, ContractError> {
     Ok(Response::default())
 }
 
+/*
 #[entry_point]
 pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result<Binary, ContractError> {
     match msg {
         QueryMsg::Number {} => Ok(to_binary(&query_number(deps)?)?),
     }
 }
+ */
+
+#[cfg(target_arch = "wasm32")]
+mod __wasm_export_query {
+    #[no_mangle]
+    extern "C" fn query(env_ptr: u32, msg_ptr: u32) -> u32 {
+        let _env: Vec<u8> = unsafe { cosmwasm_std::memory::consume_region(env_ptr as *mut cosmwasm_std::memory::Region) };
+        let msg: Vec<u8> = unsafe { cosmwasm_std::memory::consume_region(msg_ptr as *mut cosmwasm_std::memory::Region) };
+
+        let mut deps = cosmwasm_std::make_dependencies();
+
+        let res = if msg.len() > 3 {
+            let nr = super::query_number(deps.as_ref()).unwrap();
+            cosmwasm_std::ContractResult::Ok(
+                super::to_binary(&nr).unwrap()
+            )
+        } else {
+            super::write(deps.as_mut().storage, 42);
+            let msg = "written";
+            cosmwasm_std::ContractResult::Ok(
+                super::to_binary(&msg).unwrap()
+            )
+        };
+
+        let v = cosmwasm_std::to_vec(&res).unwrap();
+        cosmwasm_std::memory::release_buffer(v) as u32
+    }
+}
 
 fn query_number(deps: Deps) -> Result<NumberResponse, ContractError> {
     let value = read(deps.storage)?;