Add Function Descriptors
You can use the Schema Tool to access, and initiate smart contract functions seamlessly using function descriptors. These descriptors allow you to access optional Params and Results maps through strict compile-time checked interfaces.
Function Descriptors Overview
Function descriptors are structures that:
- Offer access to the optional Params and Results maps.
- Allow synchronous or asynchronous initiation of functions through
call()
orpost()
requests.
The Schema Tool in Action
The Schema Tool performs the following tasks:
1. Generate Specific Descriptors:
- For each function (
func
) and view. - The outcome: Structs granting access to Params or Results maps, wherever specified.
2. Create the ScFuncs
Interface:
- Facilitate the creation and initialization of each function descriptor.
- Incorporate a member function for every func or view to craft their respective function descriptor properly.
- Go
- Rust
- Typescript
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
}
use wasmlib::*;
use crate::*;
pub struct DivideCall {
pub func: ScFunc,
}
pub struct InitCall {
pub func: ScInitFunc,
pub params: MutableInitParams,
}
pub struct MemberCall {
pub func: ScFunc,
pub params: MutableMemberParams,
}
pub struct SetOwnerCall {
pub func: ScFunc,
pub params: MutableSetOwnerParams,
}
pub struct GetFactorCall {
pub func: ScView,
pub params: MutableGetFactorParams,
pub results: ImmutableGetFactorResults,
}
pub struct GetOwnerCall {
pub func: ScView,
pub results: ImmutableGetOwnerResults,
}
pub struct ScFuncs {
}
impl ScFuncs {
// divide tokens over members
pub fn divide(_ctx: &dyn ScFuncCallContext) -> DivideCall {
DivideCall {
func: ScFunc::new(HSC_NAME, HFUNC_DIVIDE),
}
}
pub fn init(_ctx: &dyn ScFuncCallContext) -> InitCall {
let mut f = InitCall {
func: ScInitFunc::new(HSC_NAME, HFUNC_INIT),
params: MutableInitParams { proxy: Proxy::nil() },
};
ScInitFunc::link_params(&mut f.params.proxy, &f.func);
f
}
pub fn member(_ctx: &dyn ScFuncCallContext) -> MemberCall {
let mut f = MemberCall {
func: ScFunc::new(HSC_NAME, HFUNC_MEMBER),
params: MutableMemberParams { proxy: Proxy::nil() },
};
ScFunc::link_params(&mut f.params.proxy, &f.func);
f
}
pub fn set_owner(_ctx: &dyn ScFuncCallContext) -> SetOwnerCall {
let mut f = SetOwnerCall {
func: ScFunc::new(HSC_NAME, HFUNC_SET_OWNER),
params: MutableSetOwnerParams { proxy: Proxy::nil() },
};
ScFunc::link_params(&mut f.params.proxy, &f.func);
f
}
pub fn get_factor(_ctx: &dyn ScViewCallContext) -> GetFactorCall {
let mut f = GetFactorCall {
func: ScView::new(HSC_NAME, HVIEW_GET_FACTOR),
params: MutableGetFactorParams { proxy: Proxy::nil() },
results: ImmutableGetFactorResults { proxy: Proxy::nil() },
};
ScView::link_params(&mut f.params.proxy, &f.func);
ScView::link_results(&mut f.results.proxy, &f.func);
f
}
pub fn get_owner(_ctx: &dyn ScViewCallContext) -> GetOwnerCall {
let mut f = GetOwnerCall {
func: ScView::new(HSC_NAME, HVIEW_GET_OWNER),
results: ImmutableGetOwnerResults { proxy: Proxy::nil() },
};
ScView::link_results(&mut f.results.proxy, &f.func);
f
}
}
import * as wasmlib from 'wasmlib';
import * as sc from './index';
export class DivideCall {
func: wasmlib.ScFunc;
public constructor(ctx: wasmlib.ScFuncCallContext) {
this.func = new wasmlib.ScFunc(ctx, sc.HScName, sc.HFuncDivide);
}
}
export class DivideContext {
state: sc.MutableDividendState = new sc.MutableDividendState(
wasmlib.ScState.proxy(),
);
}
export class InitCall {
func: wasmlib.ScInitFunc;
params: sc.MutableInitParams = new sc.MutableInitParams(
wasmlib.ScView.nilProxy,
);
public constructor(ctx: wasmlib.ScFuncCallContext) {
this.func = new wasmlib.ScInitFunc(ctx, sc.HScName, sc.HFuncInit);
}
}
export class InitContext {
params: sc.ImmutableInitParams = new sc.ImmutableInitParams(
wasmlib.paramsProxy(),
);
state: sc.MutableDividendState = new sc.MutableDividendState(
wasmlib.ScState.proxy(),
);
}
export class MemberCall {
func: wasmlib.ScFunc;
params: sc.MutableMemberParams = new sc.MutableMemberParams(
wasmlib.ScView.nilProxy,
);
public constructor(ctx: wasmlib.ScFuncCallContext) {
this.func = new wasmlib.ScFunc(ctx, sc.HScName, sc.HFuncMember);
}
}
export class MemberContext {
params: sc.ImmutableMemberParams = new sc.ImmutableMemberParams(
wasmlib.paramsProxy(),
);
state: sc.MutableDividendState = new sc.MutableDividendState(
wasmlib.ScState.proxy(),
);
}
export class SetOwnerCall {
func: wasmlib.ScFunc;
params: sc.MutableSetOwnerParams = new sc.MutableSetOwnerParams(
wasmlib.ScView.nilProxy,
);
public constructor(ctx: wasmlib.ScFuncCallContext) {
this.func = new wasmlib.ScFunc(ctx, sc.HScName, sc.HFuncSetOwner);
}
}
export class SetOwnerContext {
params: sc.ImmutableSetOwnerParams = new sc.ImmutableSetOwnerParams(
wasmlib.paramsProxy(),
);
state: sc.MutableDividendState = new sc.MutableDividendState(
wasmlib.ScState.proxy(),
);
}
export class GetFactorCall {
func: wasmlib.ScView;
params: sc.MutableGetFactorParams = new sc.MutableGetFactorParams(
wasmlib.ScView.nilProxy,
);
results: sc.ImmutableGetFactorResults = new sc.ImmutableGetFactorResults(
wasmlib.ScView.nilProxy,
);
public constructor(ctx: wasmlib.ScViewCallContext) {
this.func = new wasmlib.ScView(ctx, sc.HScName, sc.HViewGetFactor);
}
}
export class GetFactorContext {
params: sc.ImmutableGetFactorParams = new sc.ImmutableGetFactorParams(
wasmlib.paramsProxy(),
);
results: sc.MutableGetFactorResults = new sc.MutableGetFactorResults(
wasmlib.ScView.nilProxy,
);
state: sc.ImmutableDividendState = new sc.ImmutableDividendState(
wasmlib.ScState.proxy(),
);
}
export class GetOwnerCall {
func: wasmlib.ScView;
results: sc.ImmutableGetOwnerResults = new sc.ImmutableGetOwnerResults(
wasmlib.ScView.nilProxy,
);
public constructor(ctx: wasmlib.ScViewCallContext) {
this.func = new wasmlib.ScView(ctx, sc.HScName, sc.HViewGetOwner);
}
}
export class GetOwnerContext {
results: sc.MutableGetOwnerResults = new sc.MutableGetOwnerResults(
wasmlib.ScView.nilProxy,
);
state: sc.ImmutableDividendState = new sc.ImmutableDividendState(
wasmlib.ScState.proxy(),
);
}
export class ScFuncs {
// divide tokens over members
static divide(ctx: wasmlib.ScFuncCallContext): DivideCall {
return new DivideCall(ctx);
}
static init(ctx: wasmlib.ScFuncCallContext): InitCall {
const f = new InitCall(ctx);
f.params = new sc.MutableInitParams(wasmlib.newCallParamsProxy(f.func));
return f;
}
static member(ctx: wasmlib.ScFuncCallContext): MemberCall {
const f = new MemberCall(ctx);
f.params = new sc.MutableMemberParams(wasmlib.newCallParamsProxy(f.func));
return f;
}
static setOwner(ctx: wasmlib.ScFuncCallContext): SetOwnerCall {
const f = new SetOwnerCall(ctx);
f.params = new sc.MutableSetOwnerParams(wasmlib.newCallParamsProxy(f.func));
return f;
}
static getFactor(ctx: wasmlib.ScViewCallContext): GetFactorCall {
const f = new GetFactorCall(ctx);
f.params = new sc.MutableGetFactorParams(
wasmlib.newCallParamsProxy(f.func),
);
f.results = new sc.ImmutableGetFactorResults(
wasmlib.newCallResultsProxy(f.func),
);
return f;
}
static getOwner(ctx: wasmlib.ScViewCallContext): GetOwnerCall {
const f = new GetOwnerCall(ctx);
f.results = new sc.ImmutableGetOwnerResults(
wasmlib.newCallResultsProxy(f.func),
);
return f;
}
}
dividend
Example - Generated Code
In the dividend
example in contract.xx
, specific structs for Funcs and Views are created.
Here's how they operate:
Access
- Via the
func
member within each struct. - The
func
member type: EitherScFunc
orScView
, contingent on whether it’s a function or a view.
Utilization
- The
func
member is used to initiate function calls in various ways.