gear-foundation/vara-eth-skills · Archived

vara-eth-contract-writer

Write and review Rust Sails contracts for Vara.eth.

First seen May 6, 2026

Installation

$ npx skills add gear-foundation/vara-eth-skills --skill vara-eth-contract-writer

Summary

  • Write and review Rust Sails contracts for Vara.eth.
  • Use when an AI agent is asked to scaffold a new contract with `cargo sails new --eth`, implement or explain `Program` and `Service` structure, add events and exported methods, define payable methods, choose ABI-safe public types, or flag `ethexe` runtime limitations and forbidden patterns in contract design.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from gear-foundation/vara-eth-skills.

npx skills add gear-foundation/vara-eth-skills

Browse all from gear-foundation/vara-eth-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
Default branch master
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,222 B
  • docs SUMMARY.md 393 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Vara.eth Contract Writer

Use this skill when writing, changing, or reviewing a Rust contract for Vara.eth with Sails.

Core Rule

Treat the target as Vara.eth, not generic Vara, generic Gear, or EVM Solidity. Use Sails with the ethexe feature and the Vara.eth artifact workflow.

Keep examples minimal, runnable, and explicit about generated artifacts. When contract behavior intersects with deployment, ABI, RPC, or runtime semantics, verify against ../../references/source-map.md.

Environment

Make sure the environment has:

  • Rust toolchain.
  • wasm32v1-none, installed with rustup target add wasm32v1-none.
  • sails-cli, installed with cargo install sails-cli.

Scaffold new contracts with --eth:

AUTHOR="Gear Technologies"
USERNAME="gear-tech"

cargo sails new counter \
  --author "$AUTHOR" \
  --username "$USERNAME" \
  --eth

cd counter

Treat the generated project as the starting point. Add or revise services, events, and program state inside the generated Rust sources instead of inventing a parallel layout.

Dependencies

Vara.eth contracts must use Sails with the ethexe feature enabled.

Typical dependency block:

[dependencies]
sails-rs = { version = "1.0.0-beta.2", features = ["ethexe"] }
parity-scale-codec = { version = "3", default-features = false }
scale-info = { version = "2", default-features = false }

Keep the sails-rs version compatible with the installed sails-cli and generated project. The examples in this repository use sails-rs = "1.0.0-beta.2".

Use parity-scale-codec and scale-info when public custom types need encoding and type metadata.

Contract Shape

A clear Sails contract usually has:

  • #![no_std].
  • use sails_rs::{cell::RefCell, prelude::*};.
  • A state/data struct that owns service state.
  • An event enum marked with #[event].
  • One or more service structs that borrow shared state through RefCell.
  • #[service] impl blocks with exported methods.
  • A #[program] impl with init and exposed services.

For a small counter, exported methods can be add(value: u32) -> u32, sub(value: u32) -> u32, and value() -> u32, with events such as Added(u32) and Subtracted(u32). Call out underflow or overflow risks when examples mutate integers.

Services And State

Split services by responsibility, not by accident. A useful first split is user actions in one service and admin or config actions in another.

Good patterns:

  • Keep shared contract data in one state struct.
  • Pass &RefCell<State> into each service.
  • Keep exported APIs narrow and domain-specific.
  • Use helper guards such as ensureadmin(...) or ensurenot_paused(...) when several methods need the same check.
  • Use explicit read methods instead of assuming callers can inspect internal state.
  • Emit events for meaningful state transitions that clients need to observe.

Avoid global mutable state except in the smallest teaching examples.

Errors And Results

Use #[export(unwrap_result)] for business errors that callers should see, for example:

  • insufficient deposited balance
  • caller is not admin
  • contract is paused

Use direct panics or expect(...) only for internal failures that should be impossible in normal contract flow.

Payable Methods

For Vara.eth contracts with the ethexe feature enabled, mark a constructor or exported method as payable only when it must receive positive value with the incoming message.

Use:

#[export(payable)]

or combine it with result unwrapping:

#[export(payable, unwrap_result)]

Important points:

  • Do not mark a method payable unless positive incoming value is part of its public API.
  • Do not assume exported methods are payable by default.
  • If value is sent to a non-payable method or constructor in the ethexe path, execution will panic.
  • Do not add a redundant value == 0 guard inside a payable method; #[export(payable)] already means the method is called with value > 0.

Public Types

Separate two concerns:

  • IDL-friendly public types.
  • Solidity-ABI-friendly public types.

For Sails IDL generation, public input and output types should be encodable, introspectable, and simple enough for generated clients.

For Solidity tooling, public types need an additional check: the ABI-facing surface must be compatible with the current ethexe Solidity generation path. Run cargo sails sol --idl-path ... early when Solidity integration is planned.

Known notes for the current path:

  • u8 does not work on the current ethexe Solidity path.
  • i8, Vec<u8>, and String work on the current ethexe Solidity path.
  • For event fields that identify accounts, choose a type that is verified by the current ethexe build and Solidity generation path. In the vault example, [u8; 32] compiled cleanly for account identifiers.
  • If cargo sails sol fails on an IDL whose program declaration looks like program <Name>.opt { ... }, regenerate the IDL with cargo sails idl --program-name <NameWithoutDot>.

Treat these as common ABI friction points until verified:

  • maps such as HashMap or BTreeMap
  • deeply nested enums or tuples
  • heavily generic public signatures
  • internal program-specific types exposed directly in public methods

For Solidity-facing APIs, be explicit about ActorId versus Ethereum address:

  • ActorId is 32 bytes.
  • Ethereum address is 20 bytes.
  • Conversions can require padding or explicit mapping rules.

ethexe Runtime Restrictions

Design around ethexe runtime restrictions from the start.

Do not use:

  • runtime randomness
  • in-program creation of another program
  • msgsendwithgas, msgreplywithgas, or other *withgas helpers or wrappers
  • gas reservation or unreservation flows
  • reservation-based send or reply commit flows
  • signal syscalls
  • plain wait-based blocking behavior
  • delayed wake flows

Flag patterns that imply these forbidden runtime syscalls:

  • random
  • create_program
  • reserve_gas
  • unreserve_gas
  • systemreservegas
  • reply_deposit
  • reservationsendcommit
  • reservationreplycommit
  • signal_from
  • signal_code
  • gr_wait

Favor explicit message-driven state machines, deterministic logic, and externally orchestrated workflows.

Build And Test

Use:

cargo build --release
cargo test --release

Expected artifacts live under target/wasm32-gear/release/:

  • <program>.idl
  • <program>.wasm
  • <program>.opt.wasm

Before saying a contract is ready, confirm the .idl and .opt.wasm files exist.

References

Read ../../references/contract-writing-checklist.md for the final contract review checklist.

Read ../../references/source-map.md when a contract claim depends on deployment, ABI, RPC, CLI, or runtime implementation behavior.