From 527079f63c4be50dd992a8fe095ebe2bdbb5ce18 Mon Sep 17 00:00:00 2001 From: DhoziL <55169789+dhozil@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:46:08 +0700 Subject: [PATCH 1/6] Create quick-start.mdx --- .../intelligent-contracts/quick-start.mdx | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 pages/developers/intelligent-contracts/quick-start.mdx diff --git a/pages/developers/intelligent-contracts/quick-start.mdx b/pages/developers/intelligent-contracts/quick-start.mdx new file mode 100644 index 00000000..85215b4b --- /dev/null +++ b/pages/developers/intelligent-contracts/quick-start.mdx @@ -0,0 +1,253 @@ +import { Callout, Steps, Tabs } from 'nextra/components' + +# Quick Start + +Deploy your first Intelligent Contract in about 10 minutes. + +--- + +## Before you start: pick your path + + + + **GLSim** — a lightweight simulator that implements the GenLayer JSON-RPC protocol. + Starts in ~1 second, no Docker required. Ideal for getting started quickly. + + You'll need: **Python 3.12+** and **Node.js 18+** + + + **GenLayer Studio (local)** — full GenVM execution with real validator consensus, + transaction inspection, and a visual UI. Use this before deploying to testnet. + + You'll need: **Python 3.12+**, **Node.js 18+**, and **Docker 26+** + + + +Both paths use the same contracts, the same CLI, and the same tests. You can switch at any time. + +--- + + + +### Set up your project + +Clone the official boilerplate — it includes a contract template, testing infrastructure, and a frontend scaffold. + +```bash +git clone https://github.com/genlayerlabs/genlayer-project-boilerplate.git my-project +cd my-project +pip install -r requirements.txt +``` + +This installs two tools: +- `genlayer-test` — testing framework (direct mode, GLSim, integration tests) +- `genvm-linter` — static analysis that catches contract errors before you deploy + +Your project layout: + +``` +contracts/ # Your Intelligent Contracts +tests/ + direct/ # Fast in-memory tests — no server needed + integration/ # Full end-to-end tests against a GenLayer environment +frontend/ # Next.js frontend with GenLayerJS pre-wired +deploy/ # Deployment scripts +gltest.config.yaml # Network and account configuration +``` + +### Start your environment + + + + ```bash + pip install genlayer-test[sim] + glsim --port 4000 --validators 5 + ``` + + GLSim runs the Python runner natively — not inside GenVM — so there can be minor + incompatibilities. Always validate against Studio before deploying to testnet. + + + ```bash + npm install -g genlayer + genlayer init + genlayer up + ``` + + Once running, open [http://localhost:8080](http://localhost:8080) to access the Studio UI. + Your tests and frontend connect to the JSON-RPC API at `http://localhost:4000/api`. + + + +### Write your first contract + +Create `contracts/hello.py`: + +```python +# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" } + +from genlayer import * + +class Hello(gl.Contract): + name: str + + def __init__(self, name: str): + self.name = name + + @gl.public.view + def greet(self) -> str: + return f'Hello, {self.name}!' + + @gl.public.write + def set_name(self, name: str): + self.name = name +``` + +A few things every contract needs: +- **Line 1** — the version comment pins the GenVM version. Required. +- **`gl.Contract`** — marks this class as an Intelligent Contract. +- **`@gl.public.view`** — read-only method, no state change. +- **`@gl.public.write`** — method that modifies on-chain state. +- **Class-level type annotations** — persistent fields must be declared in the class body. Fields set via `self.field = value` outside the class body are not persisted. + + + The GenLayer Studio auto-detects constructor parameters from your contract code and generates a UI for them — no ABI configuration needed. + + +### Lint and test + +Catch issues before deploying: + +```bash +# Static analysis — catches forbidden imports, invalid types, missing decorators +genvm-lint check contracts/hello.py + +# Fast in-memory tests — no server, no Docker +pytest tests/direct/ -v +``` + +A minimal direct-mode test looks like this: + +```python +def test_greet(direct_vm, direct_deploy, direct_alice): + contract = direct_deploy("contracts/hello.py", args=["World"]) + + result = contract.greet() + assert result == "Hello, World!" + + direct_vm.sender = direct_alice + contract.set_name("GenLayer") + assert contract.greet() == "Hello, GenLayer!" +``` + +Available fixtures: `direct_vm`, `direct_deploy`, `direct_alice`, `direct_bob`, `direct_charlie`, `direct_owner`. + +### Deploy and call + + + + 1. Open [http://localhost:8080](http://localhost:8080) (or [studio.genlayer.com](https://studio.genlayer.com) for zero-setup) + 2. Load `contracts/hello.py` + 3. Click **Deploy** — Studio detects the `name` parameter and shows an input field + 4. Call `greet` from the UI to see the output + + You should see `Hello, World!` (or whatever name you passed). That's your first contract running. ✓ + + + ```bash + npm install -g genlayer + + # Deploy — pass constructor args as JSON + genlayer deploy contracts/hello.py --args '["World"]' + # → Contract deployed at 0xabc... + + # Call a view method (instant, no transaction) + genlayer call 0xabc... greet + # → "Hello, World!" + + # Call a write method (creates a transaction) + genlayer write 0xabc... set_name --args '["GenLayer"]' + genlayer call 0xabc... greet + # → "Hello, GenLayer!" + ``` + + + +### Make it intelligent + +Now add what no regular smart contract can do — access the web or call an LLM: + +```python +# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" } + +from genlayer import * +import json + +class PriceFeed(gl.Contract): + last_price: str + + def __init__(self): + self.last_price = "unknown" + + @gl.public.write + def update_price(self, ticker: str) -> None: + # Non-deterministic operations must run inside a function + # passed to gl.eq_principle.* — this is how GenLayer reaches + # consensus across validators that may get slightly different results. + def fetch() -> str: + data = gl.nondet.web.get( + f"https://api.coinbase.com/v2/prices/{ticker}-USD/spot" + ) + parsed = json.loads(data) + return json.dumps({"price": parsed["data"]["amount"]}, sort_keys=True) + + result = gl.eq_principle.strict_eq(fetch) + self.last_price = json.loads(result)["price"] + + @gl.public.view + def get_price(self) -> str: + return self.last_price +``` + + + Always use `json.dumps(..., sort_keys=True)` before returning from a `strict_eq` block. + Without it, validators may produce differently-ordered JSON and fail to reach consensus. + + +The key concept: `gl.eq_principle.strict_eq` tells GenLayer that all validators must +return byte-identical results. Use this when output is constrained (JSON with fixed keys, +booleans). For subjective outputs like summaries or classifications, use `prompt_comparative` instead. + +→ Deep dive: [Equivalence Principle](/developers/intelligent-contracts/equivalence-principle) + + + +--- + +## Zero-setup alternative + +Don't want to install anything yet? Open [studio.genlayer.com](https://studio.genlayer.com) and +load any built-in example. You can write, deploy, and call contracts directly in the browser — +no local setup needed. You can also import any deployed contract by address to interact with it. + +--- + +## What's next? + +**Go deeper on Intelligent Contracts** +- [Equivalence Principle](/developers/intelligent-contracts/equivalence-principle) — how validators reach consensus on non-deterministic outputs +- [Calling LLMs](/developers/intelligent-contracts/features/calling-llms) — `exec_prompt`, response formats, and choosing the right eq principle +- [Web Access](/developers/intelligent-contracts/features/web-access) — `web.get` vs `web.render`, modes, and when to use each +- [Prompt & Data Techniques](/developers/intelligent-contracts/crafting-prompts) — prompt patterns that maximize validator agreement +- [Best Practices & Common Patterns](/developers/intelligent-contracts/security-and-best-practices/best-practices) — access control, storage patterns, common mistakes, upgrade patterns + +**Write proper tests** +- [Testing](/developers/intelligent-contracts/testing) — direct mode, mocking web/LLM calls, integration tests +- [Debugging](/developers/intelligent-contracts/debugging) — reading validator execution logs, tracing failed transactions + +**Connect a frontend** +- [DApp Development Workflow](/developers/decentralized-applications/dapp-development-workflow) — full-stack architecture overview +- [GenLayerJS SDK](/developers/decentralized-applications/genlayer-js) — reading and writing contracts from JavaScript + +**Ship to testnet** +- [Deploying](/developers/intelligent-contracts/deploying) — deployment methods, Testnet Bradbury, network configuration From f3a94bf467ec46733f09dfd2de0fc916002c9f0f Mon Sep 17 00:00:00 2001 From: DhoziL <55169789+dhozil@users.noreply.github.com> Date: Sun, 29 Mar 2026 11:53:45 +0700 Subject: [PATCH 2/6] Update _meta.json --- pages/developers/intelligent-contracts/_meta.json | 1 + 1 file changed, 1 insertion(+) diff --git a/pages/developers/intelligent-contracts/_meta.json b/pages/developers/intelligent-contracts/_meta.json index 65b0d23b..dcb736c3 100644 --- a/pages/developers/intelligent-contracts/_meta.json +++ b/pages/developers/intelligent-contracts/_meta.json @@ -1,4 +1,5 @@ { + "quick-start": "Quick Start", "introduction": "Introduction to Intelligent Contracts", "features": "Feature List", "tooling-setup": "Development Setup", From f4e4ff27f4ce50519e0c2266884bd21d5b8c967f Mon Sep 17 00:00:00 2001 From: DhoziL <55169789+dhozil@users.noreply.github.com> Date: Sun, 29 Mar 2026 12:05:28 +0700 Subject: [PATCH 3/6] Update index.mdx --- pages/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/index.mdx b/pages/index.mdx index 2eeae696..dca7147c 100644 --- a/pages/index.mdx +++ b/pages/index.mdx @@ -40,7 +40,7 @@ Protocols and applications that can **understand, learn, and adapt to real-world arrow title="For Developers" description="Step-by-step guides to building Intelligent Contracts using the Python-based GenLayer SDK." - href="/developers" + href="/developers/intelligent-contracts/quick-start" /> {/* Date: Tue, 31 Mar 2026 04:25:32 +0700 Subject: [PATCH 4/6] Update quick-start.mdx --- .../intelligent-contracts/quick-start.mdx | 61 ++++++++++--------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/pages/developers/intelligent-contracts/quick-start.mdx b/pages/developers/intelligent-contracts/quick-start.mdx index 85215b4b..48041ea2 100644 --- a/pages/developers/intelligent-contracts/quick-start.mdx +++ b/pages/developers/intelligent-contracts/quick-start.mdx @@ -6,7 +6,17 @@ Deploy your first Intelligent Contract in about 10 minutes. --- -## Before you start: pick your path +## Option A: Zero setup — try in the browser + +The fastest path to a running contract is [studio.genlayer.com](https://studio.genlayer.com) — open it, pick a built-in example, and click **Deploy**. No installation needed. You can also import any deployed contract by address to interact with it directly. + +When you're ready to build locally, continue with Option B below. + +--- + +## Option B: Local development + +### Before you start: pick your environment @@ -41,7 +51,7 @@ pip install -r requirements.txt This installs two tools: - `genlayer-test` — testing framework (direct mode, GLSim, integration tests) -- `genvm-linter` — static analysis that catches contract errors before you deploy +- `genvm-lint` (from the `genvm-linter` package) — static analysis that catches contract errors before you deploy Your project layout: @@ -60,7 +70,7 @@ gltest.config.yaml # Network and account configuration ```bash - pip install genlayer-test[sim] + pip install 'genlayer-test[sim]' glsim --port 4000 --validators 5 ``` @@ -175,7 +185,7 @@ Available fixtures: `direct_vm`, `direct_deploy`, `direct_alice`, `direct_bob`, ### Make it intelligent -Now add what no regular smart contract can do — access the web or call an LLM: +Now add what no regular smart contract can do — call an LLM to make a decision on-chain: ```python # { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" } @@ -183,30 +193,32 @@ Now add what no regular smart contract can do — access the web or call an LLM: from genlayer import * import json -class PriceFeed(gl.Contract): - last_price: str +class SentimentChecker(gl.Contract): + last_result: str def __init__(self): - self.last_price = "unknown" + self.last_result = "" @gl.public.write - def update_price(self, ticker: str) -> None: + def analyze(self, text: str) -> None: # Non-deterministic operations must run inside a function # passed to gl.eq_principle.* — this is how GenLayer reaches # consensus across validators that may get slightly different results. - def fetch() -> str: - data = gl.nondet.web.get( - f"https://api.coinbase.com/v2/prices/{ticker}-USD/spot" + def run(): + result = gl.nondet.exec_prompt( + f'Classify the sentiment of this text as POSITIVE, NEGATIVE, or NEUTRAL. ' + f'Text: "{text}". ' + f'Respond ONLY with valid JSON: {{"sentiment": ""}}', + response_format="json" ) - parsed = json.loads(data) - return json.dumps({"price": parsed["data"]["amount"]}, sort_keys=True) + return json.dumps(result, sort_keys=True) - result = gl.eq_principle.strict_eq(fetch) - self.last_price = json.loads(result)["price"] + raw = gl.eq_principle.strict_eq(run) + self.last_result = json.loads(raw)["sentiment"] @gl.public.view - def get_price(self) -> str: - return self.last_price + def get_result(self) -> str: + return self.last_result ``` @@ -214,9 +226,9 @@ class PriceFeed(gl.Contract): Without it, validators may produce differently-ordered JSON and fail to reach consensus. -The key concept: `gl.eq_principle.strict_eq` tells GenLayer that all validators must -return byte-identical results. Use this when output is constrained (JSON with fixed keys, -booleans). For subjective outputs like summaries or classifications, use `prompt_comparative` instead. +The key concept: `gl.eq_principle.strict_eq` tells GenLayer that all validators must return byte-identical results. It works best when output is tightly constrained — like a fixed JSON schema with a small set of possible values. + +For web data access (like fetching live prices), validators may get slightly different values depending on timing. See the [Price Oracle example](/developers/intelligent-contracts/equivalence-principle) in the Equivalence Principle docs for the correct pattern. → Deep dive: [Equivalence Principle](/developers/intelligent-contracts/equivalence-principle) @@ -224,14 +236,6 @@ booleans). For subjective outputs like summaries or classifications, use `prompt --- -## Zero-setup alternative - -Don't want to install anything yet? Open [studio.genlayer.com](https://studio.genlayer.com) and -load any built-in example. You can write, deploy, and call contracts directly in the browser — -no local setup needed. You can also import any deployed contract by address to interact with it. - ---- - ## What's next? **Go deeper on Intelligent Contracts** @@ -239,7 +243,6 @@ no local setup needed. You can also import any deployed contract by address to i - [Calling LLMs](/developers/intelligent-contracts/features/calling-llms) — `exec_prompt`, response formats, and choosing the right eq principle - [Web Access](/developers/intelligent-contracts/features/web-access) — `web.get` vs `web.render`, modes, and when to use each - [Prompt & Data Techniques](/developers/intelligent-contracts/crafting-prompts) — prompt patterns that maximize validator agreement -- [Best Practices & Common Patterns](/developers/intelligent-contracts/security-and-best-practices/best-practices) — access control, storage patterns, common mistakes, upgrade patterns **Write proper tests** - [Testing](/developers/intelligent-contracts/testing) — direct mode, mocking web/LLM calls, integration tests From 0a4d237fba4695442b8877e1fb91e84f55a5c66b Mon Sep 17 00:00:00 2001 From: DhoziL <55169789+dhozil@users.noreply.github.com> Date: Tue, 31 Mar 2026 04:45:36 +0700 Subject: [PATCH 5/6] Update quick-start.mdx --- pages/developers/intelligent-contracts/quick-start.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/developers/intelligent-contracts/quick-start.mdx b/pages/developers/intelligent-contracts/quick-start.mdx index 48041ea2..d3f35d18 100644 --- a/pages/developers/intelligent-contracts/quick-start.mdx +++ b/pages/developers/intelligent-contracts/quick-start.mdx @@ -185,7 +185,7 @@ Available fixtures: `direct_vm`, `direct_deploy`, `direct_alice`, `direct_bob`, ### Make it intelligent -Now add what no regular smart contract can do — call an LLM to make a decision on-chain: +Now add what no regular smart contract can do — call an LLM to decision on-chain: ```python # { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" } From 28ec564d49294d3202abb6683c33f1711404d74d Mon Sep 17 00:00:00 2001 From: DhoziL <55169789+dhozil@users.noreply.github.com> Date: Tue, 31 Mar 2026 12:57:51 +0700 Subject: [PATCH 6/6] Update quick-start.mdx --- pages/developers/intelligent-contracts/quick-start.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/developers/intelligent-contracts/quick-start.mdx b/pages/developers/intelligent-contracts/quick-start.mdx index d3f35d18..8adcec00 100644 --- a/pages/developers/intelligent-contracts/quick-start.mdx +++ b/pages/developers/intelligent-contracts/quick-start.mdx @@ -185,7 +185,7 @@ Available fixtures: `direct_vm`, `direct_deploy`, `direct_alice`, `direct_bob`, ### Make it intelligent -Now add what no regular smart contract can do — call an LLM to decision on-chain: +Now add what no regular smart contract can do — call an LLM to decide on-chain: ```python # { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" }