Skip to content

Go

hivekit-go modules are compiled with TinyGo (-target=wasm-unknown) and packaged as Hive Bytecode (.hbc); the compiled code inside implements the hive-wasm-v1 ABI.

package main
import (
"errors"
hivekit "github.com/necter-network/hivekit-go"
)
type pair struct {
A float64 `json:"a"`
B float64 `json:"b"`
}
func init() {
// Typed: input decoded from JSON, output encoded as JSON, error fails the call.
hivekit.DefineJSON("divide", func(p pair) (map[string]float64, error) {
if p.B == 0 {
return nil, errors.New("division by zero")
}
return map[string]float64{"result": p.A / p.B}, nil
})
// Untyped JSON object in, JSON object out.
hivekit.Define("greet", func(in map[string]any) map[string]any {
name, _ := in["name"].(string)
return map[string]any{"message": "Hello, " + name}
})
// Raw bytes in, raw UTF-8 bytes out.
hivekit.DefineRaw("echo", func(in []byte) ([]byte, error) { return in, nil })
}
func main() {} // required by Go, never called by NDSR

Register functions from init() (or package-level initializers). Names must match [A-Za-z_][A-Za-z0-9_]{0,63}; registering a name twice panics. NDSR never calls _start: the SDK initializes TinyGo’s runtime lazily on the first call, which costs roughly 35–40k gas per call.

Go Host import Notes
StorageGet(key) ([]byte, bool), StorageGetString, StorageGetJSON storage.get absent → false
StorageSet(key, val), StorageSetString, StorageSetJSON storage.set empty value deletes
StorageDel(key) storage.del
Emit(name, data), EmitRaw(name, json) hive.emit canonical-JSON compatible data
Call(addr, fn, input) ([]byte, error), CallJSON(addr, fn, in, &out) hive.call errors are *CallError (CallModuleNotFound −1, CallFunctionNotFound −2, CallFailed −3, CallDepthExceeded −5, CallBadAddress −6)
Hash(data) string crypto.hash Keccak-256 as 0x…
Log(msg), Logf(...) console.log
Abort(msg) hive.abort fails the call; nothing written or emitted is kept

Panics (index out of range, nil map write) trap the call; recover is not available on this target, so return errors instead.

Terminal window
hivec build ./examples/math_module # → dist/math_module.hbc
hivec inspect dist/math_module.hbc
hivec functions dist/math_module.hbc
hivec run dist/math_module.hbc multiply '{"a":7,"b":6}'
# state persists between runs; flags go before the file
hivec run -data-dir ./state dist/price_oracle.hbc submit '{"pair":"ETH/USD","source":"a","price":320012}'
hivec run -data-dir ./state dist/price_oracle.hbc price '{"pair":"ETH/USD"}'
# make another module callable through hive.call
hivec run -module dist/math_module.hbc dist/ledger.hbc record '{"math":"0x<math address>","a":6,"b":7}'

hivec build flags: -o DIR, -name, -version, -description, -tinygo PATH, -gc, -keep-wasm. hivec package module.wasm -name N packages a wasm you built yourself. Without ndsr (or with -local) hivec run falls back to a built-in runner with no gas metering and no receipt, for quick iteration only.

hivekit-go/examples/: math_module (pure), price_oracle (sources submit prices, median in storage), ledger (hive.call into math_module, storage, events, crypto.hash). Built from source with TinyGo 0.42.0 they reproduce the testnet addresses: math_module = 0x5b89b7c4f37ab4cf68f30999424ee32775d5c137d35c066e8ce9ce75563887bb, ledger = 0x8c69b941c33d72a06c7275087adad4602f7f039bf742e0c25802dc0a53a9ce1d.

Testing: Testing modules.