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", diff --git a/pages/developers/intelligent-contracts/quick-start.mdx b/pages/developers/intelligent-contracts/quick-start.mdx new file mode 100644 index 00000000..8adcec00 --- /dev/null +++ b/pages/developers/intelligent-contracts/quick-start.mdx @@ -0,0 +1,256 @@ +import { Callout, Steps, Tabs } from 'nextra/components' + +# Quick Start + +Deploy your first Intelligent Contract in about 10 minutes. + +--- + +## 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 + + + + **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-lint` (from the `genvm-linter` package) — 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 — call an LLM to decide on-chain: + +```python +# { "Depends": "py-genlayer:1jb45aa8ynh2a9c9xn3b7qqh8sm5q93hwfp7jqmwsfhh8jpz09h6" } + +from genlayer import * +import json + +class SentimentChecker(gl.Contract): + last_result: str + + def __init__(self): + self.last_result = "" + + @gl.public.write + 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 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" + ) + return json.dumps(result, sort_keys=True) + + raw = gl.eq_principle.strict_eq(run) + self.last_result = json.loads(raw)["sentiment"] + + @gl.public.view + def get_result(self) -> str: + return self.last_result +``` + + + 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. 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) + + + +--- + +## 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 + +**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 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" /> {/*