eigerco / nebula

A soroban contract library
https://nebula.eiger.co
Apache License 2.0
7 stars 2 forks source link

Investigate the host side functions #27

Closed eloylp closed 1 year ago

eloylp commented 1 year ago

Context

In the Soroban platform, there are 2 environment layers. The guest and the host envs. See the documentation for more information.

The guest part is completelly hosted by a wasm VM. So there could be certain limitations there, depending the kind of implementation we want to contribute to Soroban.

Probably due to the above, most cryptographic functions are in the host side. And we are planning to build some of them.

There is of course an interaction among the guest side and the host side function calls.

Goals

geofmureithi commented 1 year ago

So I have this markdown which I plan to share. It covers this an more!

eloylp commented 1 year ago

Great ! @geofmureithi Looks like you are making progress on this. I will assign it to you so you can take the ownership of this investigation, so other participants needs to sync with you on this via this issue. And yeah , would be great to see that ideas here ! :books:

geofmureithi commented 1 year ago

FYI soroban abstracts communication between host and guest. So this may be out of scope for what we are doing.

geofmureithi commented 1 year ago

Host Contract Communication

The interaction between soroban and the Wasm contracts is facilitated through a mechanism called "host functions" or "imports." They allow the Wasm contracts to interact with the outside world, including accessing external data, sending transactions, and more.

For purposes of simplicity we will have a simple example where the contract is allowed to read data from soroban's storage.

  1. Defining Imports
    (import "env" "read_data" (func $read_data (param i32) (result i32)))
  2. The host environment. We can imagine the soroban environment initialization.
    
    use wasmtime::*;

fn main() -> Result<(), Box> { let engine = Engine::default(); let store = Store::new(&engine); let mut instance = Instance::new(&module)?;

let read_data_func = Func::wrap(&store, |data_ptr: i32| -> i32 {
    // This is just a simplified example.
    let data = read_data_from_storage(data_ptr);
    data
});

// Attach the host function implementation to the contract instance.
instance.insert_func("read_data", read_data_func)?;

// Import contracts

Ok(())

}

3. The contract implementation
```wat
(func (export "my_contract_function") (param i32) (result i32)
  local.get 0                ;; Get the parameter passed to the contract function
  call $read_data            ;; Call the host function
  i32.const 42               ;; An example value
  i32.add                    ;; Add the result to the example value
  return)

This forms the basis of all soroban contract communication. For a list of these host functions, a good place to start is: https://docs.rs/soroban-env-host/latest/soroban_env_host/trait.Env.html