write-contract
Write production-quality GenLayer intelligent contracts. Always pins concrete GenVM runner version hashes and never uses local-only test/latest runner aliases. Covers equivalence principles, storage rules, LLM resilience, and cross-contract interaction.
git clone --depth 1 https://github.com/internet-court/internet-court-skill /tmp/write-contract && cp -r /tmp/write-contract/vendored/genlayer/write-contract ~/.claude/skills/write-contractSKILL.md
# Write Intelligent Contract
Guidance for writing GenLayer intelligent contracts that pass consensus, handle errors correctly, and survive production.
## Critical: Pin the Runner Version
All GenLayer networks reject `py-genlayer:test`, `py-genlayer:latest`, and
unversioned runner aliases. Every generated contract MUST start with a pinned
runner dependency header.
```python
# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" }
```
`test` and `latest` are local-development aliases for GenLayer runtime
developers. They may work only in a specially configured local Studio
environment with a GenLayer developer environment variable, but they do not work
on GenLayer networks and must not appear in generated user contracts.
Before returning any contract code, verify:
- The first line is a pinned `Depends` runner version hash.
- There is no `py-genlayer:test`.
- There is no `py-genlayer:latest`.
- There is no unversioned `py-genlayer`.
Always lint with `genvm-lint check` after writing or modifying a contract.
## When to Use GenLayer
Before writing code, decide whether the feature actually needs GenLayer consensus. Recent builder feedback shows many projects start by treating GenLayer as a generic AI backend; push them toward a clear on-chain consensus role.
Use GenLayer when the contract must coordinate or settle around a subjective, external, or AI-mediated judgment that multiple validators should verify independently:
- Dispute resolution where evidence must be evaluated and the result affects escrow, payouts, reputation, or access.
- Prediction/oracle-style markets where the contract needs an independently validated outcome from external evidence.
- Compliance, moderation, or scoring workflows where the final decision must be reproducible enough for validator agreement but cannot be reduced to a simple deterministic API call.
- Autonomous agents that need transparent settlement, appeals, and auditable state transitions rather than a private off-chain decision.
Prefer a normal backend, frontend, or off-chain LLM workflow when:
- The frontend already computes the final answer and GenLayer would only rubber-stamp it.
- The contract only stores user-provided data with no validator-verifiable judgment.
- A deterministic smart contract, REST API, or database job can perform the work without AI consensus.
- The data-fetching/prompting step is not tied to an on-chain state transition, escrow, payout, or appealable decision.
For every contract, write down the boundary before implementation:
- **Frontend/backend owns:** UI, user auth, indexing, non-authoritative previews, cached market data, and convenience analytics.
- **GenLayer contract owns:** the minimum state transition that needs consensus, the evidence inputs, the validator comparison rule, the final settlement effect, and any appeal/rotation path.
- **External sources own:** raw facts or documents; do not treat them as trusted unless validators can re-fetch, normalize, and compare them.
If the boundary is unclear, create a one-page architecture note before coding: user action -> evidence source -> nondeterministic call -> equivalence principle -> state update -> user-visible settlement.
## Contract Skeleton
```python
# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" }
from genlayer import *
class MyContract(gl.Contract):
# Storage fields — typed, persisted on-chain
owner: Address
items: TreeMap[str, Item]
item_order: DynArray[str]
def __init__(self, param: str):
self.owner = gl.message.sender_account
@gl.public.view
def get_item(self, item_id: str) -> dict:
return {"id": item_id, "value": self.items[item_id].value}
@gl.public.write
def set_item(self, item_id: str, value: str) -> None:
if gl.message.sender_account != self.owner:
raise gl.UserError("Only owner")
self.items[item_id] = Item(value=value)
self.item_order.append(item_id)
```
## Runner Dependencies
The first line of a contract declares the GenVM Python runner. Always pin a
specific runner version hash. All GenLayer networks reject `test`, `latest`, and
unversioned runner aliases in generated contracts.
### Single-file Python contracts
```python
# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" }
```
### Multi-file Python contract packages
Use `py-genlayer-multi` when the contract is packaged across multiple files.
```python
# { "Depends": "py-genlayer-multi:06zyvrlivjga0d5jlpdbprksc0pa6jmllxvp8s20hq1l512vh5yk" }
```
### Contracts using embeddings or semantic search
Add `py-lib-genlayer-embeddings` before the main Python runner with a `Seq`
block.
```python
# {
# "Seq": [
# { "Depends": "py-lib-genlayer-embeddings:0bmbm3cyfwxsyh454z53vxqjf47wz2q7smcqp1q4g4a6k2kidnyk" },
# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" }
# ]
# }
```
## Equivalence Principle — Which One to Use
This is the most critical decision. Pick wrong and consensus will fail or be trivially exploitable.
### Decision Tree
```
Can validators reproduce the exact same normalized output?
├── YES → strict_eq
│ Exact match. Use when outputs are deterministic or can be
│ canonicalized (e.g., JSON with sort_keys=True).
│ Examples: blockchain RPC, stable REST APIs.
│
└── NO → Write a custom validator function (run_nondet_unsafe)
Default: produce independent evidence. Usually rerun the same task
and compare decision fields, derived status, scores, or other stable
outputs with explicit tolerances. Only skip the second answer when the
validator can judge the leader output against source data and criteria.
```
GenLayer also provides `prompt_comparative` and `prompt_non_comparative` as convenience wrappers, but most contracts outgrow them quickly. Start with a custom validator function for full flexibilityEntry point for Internet Court — the trust layer for agent-to-agent commerce. Use whenever an agent needs to transact with another agent or a paid service, or a user mentions agent payments, paid APIs (HTTP 402/x402), wallet custody or trust concerns, spending mandates, delegated permissions (ERC-7710/7715), escrow, agent identity or reputation (ERC-8004), negotiation between agents (A2A), agent jobs (ERC-8183), machine payments (MPP, AP2), supervision of agent behavior, revocation, verification, or dispute resolution (GenLayer) — even if they never say "Internet Court". Routes to the vendored protocol skills and connector skills in this package.
Connect GenLayer Intelligent Contract decisions to ERC-7710-style delegated authority. Use when an agent needs to design the interface, message schema, relayer/bridge path, EVM revocation controller, constraint updates, proof/finality assumptions, and failure handling that turn a GenLayer agent-performance review into ERC-7710 revocation or policy changes.
Internet Court adapter for GenLayer Intelligent Contract supervision. Use to specify agent-performance rubrics, evidence schemas, decision outputs, and ERC-7710 connector expectations, while delegating actual GenLayer contract writing, linting, testing, deployment, and CLI interaction to the official GenLayer skills at https://skills.genlayer.com/.
Design and implement demos combining x402 HTTP payments with ERC-7710 smart contract delegations and ERC-7715 wallet permission requests for subscriptions, bounded agent budgets, recurring spend, pay-per-use APIs, and agentic commerce.
0G Compute Network guide for decentralized AI inference, fine-tuning, and GPU services. Covers chatbots, image generation, speech-to-text, SDK integration (0g-serving-broker), processResponse API, broker.inference methods, CLI commands (0g-compute-cli), and account management. Use this skill for any 0G compute, 0G AI, or decentralized GPU question.
Use this skill when the user asks to list, create, inspect, update, disable, re-enable, or revoke AltLLM Portal API keys for external agents or applications. Do NOT use for wallet login, billing history, or payment links.
Use this skill when the user asks to log in or out with a wallet session, fetch a wallet sign-in challenge, verify an externally signed challenge, or troubleshoot AltLLM Portal wallet login for the local altllm CLI. Do NOT use for API key management, billing history, or payment links.
Use this skill when the user asks to inspect AltLLM Portal balance, redeem a promo code, review billing transactions, or view usage analytics by period, model, or API key using the local altllm CLI. Do NOT use for API key lifecycle management or payment-link execution.