Skip to main content

Function Descriptors

The Schema Tool provides us with an easy way to get access to smart contract functions through function descriptors. These are structures that provide access to the optional Params and Results maps through strict compile-time checked interfaces. They will also allow you to initiate the function by calling it synchronously, or posting a request to run it asynchronously.

The Schema Tool will generate a specific function descriptor for each func and view. It will also generate an interface called ScFuncs, that can be used to create and initialize each function descriptor. Here is the code generated for the dividend example in contract.xx:

package dividend

import "github.com/iotaledger/wasp/packages/wasmvm/wasmlib/go/wasmlib"

type DivideCall struct {
Func *wasmlib.ScFunc
}

type InitCall struct {
Func *wasmlib.ScInitFunc
Params MutableInitParams
}

type MemberCall struct {
Func *wasmlib.ScFunc
Params MutableMemberParams
}

type SetOwnerCall struct {
Func *wasmlib.ScFunc
Params MutableSetOwnerParams
}

type GetFactorCall struct {
Func *wasmlib.ScView
Params MutableGetFactorParams
Results ImmutableGetFactorResults
}

type GetOwnerCall struct {
Func *wasmlib.ScView
Results ImmutableGetOwnerResults
}

type Funcs struct{}

var ScFuncs Funcs

// divide tokens over members
func (sc Funcs) Divide(ctx wasmlib.ScFuncCallContext) *DivideCall {
return &DivideCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncDivide)}
}

func (sc Funcs) Init(ctx wasmlib.ScFuncCallContext) *InitCall {
f := &InitCall{Func: wasmlib.NewScInitFunc(ctx, HScName, HFuncInit)}
f.Params.proxy = wasmlib.NewCallParamsProxy(&f.Func.ScView)
return f
}

func (sc Funcs) Member(ctx wasmlib.ScFuncCallContext) *MemberCall {
f := &MemberCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncMember)}
f.Params.proxy = wasmlib.NewCallParamsProxy(&f.Func.ScView)
return f
}

func (sc Funcs) SetOwner(ctx wasmlib.ScFuncCallContext) *SetOwnerCall {
f := &SetOwnerCall{Func: wasmlib.NewScFunc(ctx, HScName, HFuncSetOwner)}
f.Params.proxy = wasmlib.NewCallParamsProxy(&f.Func.ScView)
return f
}

func (sc Funcs) GetFactor(ctx wasmlib.ScViewCallContext) *GetFactorCall {
f := &GetFactorCall{Func: wasmlib.NewScView(ctx, HScName, HViewGetFactor)}
f.Params.proxy = wasmlib.NewCallParamsProxy(f.Func)
wasmlib.NewCallResultsProxy(f.Func, &f.Results.proxy)
return f
}

func (sc Funcs) GetOwner(ctx wasmlib.ScViewCallContext) *GetOwnerCall {
f := &GetOwnerCall{Func: wasmlib.NewScView(ctx, HScName, HViewGetOwner)}
wasmlib.NewCallResultsProxy(f.Func, &f.Results.proxy)
return f
}

As you can see a struct has been generated for each of the Funcs and Views. The structs only provide access to the Params or Results maps when these are specified for the function. Each struct has a func member that can be used to initiate the function call in certain ways. The func member will be of type ScFunc or ScView, depending on whether the function is a func or a view.

The ScFuncs struct provides a member function for each func or view that will create their respective function descriptor, initialize it properly, and returns it.

In the next section we will look at how to use function descriptors to synchronously call smart contract functions on the same chain.