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.
Writing a module
Section titled “Writing a module”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 NDSRRegister 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.
Host API
Section titled “Host API”| 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.
Build, inspect, run
Section titled “Build, inspect, run”hivec build ./examples/math_module # → dist/math_module.hbchivec inspect dist/math_module.hbchivec functions dist/math_module.hbchivec run dist/math_module.hbc multiply '{"a":7,"b":6}'
# state persists between runs; flags go before the filehivec 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.callhivec 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.
Examples in the SDK
Section titled “Examples in the SDK”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.