How GenLayer Smart Contracts Access the Internet: The `gl.nondet.web` API Explained
GenLayer contracts access the internet through the gl.nondet.web API, a non-deterministic primitive that fetches live web content (HTML, text, screenshots) and requires equivalence-principle validation before results can be used on-chain.
GenLayer enables intelligent contracts to retrieve real-world data directly from the web—a capability that distinguishes its architecture from traditional blockchain platforms. This functionality is implemented in the genlayerlabs/genlayer-project-boilerplate repository and centers on a family of nondeterministic web-access methods that must be paired with consensus mechanisms.
Understanding Non-Deterministic Web Access
Traditional smart contracts are deterministic: given the same inputs, all validators must produce identical outputs. Web access breaks this assumption because network latency, content changes, or server responses may vary across validator nodes.
GenLayer solves this through two-stage execution:
- Fetch external data using
gl.nondet.webmethods - Validate results using equivalence-principle functions like
gl.eq_principle.strict_eq
This pattern ensures validators reach consensus on the same interpretation of web content before state changes are finalized.
The gl.nondet.web API Methods
The gl.nondet.web module provides four primary methods for internet access:
gl.nondet.web.get(url, headers={})— Performs an HTTP GET request and returns aResponseobjectgl.nondet.web.post(url, body, headers={})— Performs an HTTP POST request with a request bodygl.nondet.web.render(url, mode="text")— Retrieves rendered page content as plain textgl.nondet.web.render(url, mode="html")— Retrieves raw HTML sourcegl.nondet.web.render(url, mode="screenshot")— Captures a screenshot image of the page
All methods return data that must be processed through an equivalence principle before on-chain use.
Complete Web Access Pattern: Fetch, Prompt, Validate
The contracts/football_bets.py file demonstrates the full implementation pattern for how GenLayer contracts access the internet. This contract resolves football bets by scraping live match results from BBC Sport.
Step 1: Compose the Target URL
match_resolution_url = (
"https://www.bbc.com/sport/football/scores-fixtures/" + game_date
) # → line 62
Step 2: Fetch Page Content with gl.nondet.web.render
web_data = gl.nondet.web.render(resolution_url, mode="text") # → line 31
The mode="text" parameter returns a clean, parseable text representation of the page rather than raw HTML.
Step 3: Extract Structured Data via LLM
task = f"""
Extract the match result for:
Team 1: {team1}
Team 2: {team2}
Web content:
{web_data}
Respond in JSON:
{{
"score": str,
"winner": int
}}
"""
result = gl.nondet.exec_prompt(task, response_format="json") # → line 51
Step 4: Validate with Equivalence Principle
result_json = json.loads(gl.eq_principle.strict_eq(get_match_result)) # → line 54
The strict_eq wrapper ensures all validators agree on the identical JSON string before the result is accepted.
Full Working Example: FootballBets Contract
def _check_match(self, resolution_url: str, team1: str, team2: str) -> dict:
# 1️⃣ Pull the page content
web_data = gl.nondet.web.render(resolution_url, mode="text") # line 31
# 2️⃣ Build a prompt that asks the LLM to parse the score/winner
task = f"""
Extract the match result for:
Team 1: {team1}
Team 2: {team2}
Web content:
{web_data}
Respond in JSON:
{{
"score": str,
"winner": int
}}
"""
# 3️⃣ Ask the LLM and enforce a JSON response
result = gl.nondet.exec_prompt(task, response_format="json") # line 51
# 4️⃣ Verify the nondeterministic output
result_json = json.loads(gl.eq_principle.strict_eq(lambda: json.dumps(result, sort_keys=True))) # line 54
return result_json
Alternative Patterns for Internet Access
Direct GET Request for API Data
@gl.public.view
def fetch_price(self, ticker: str) -> str:
url = f"https://api.example.com/price?ticker={ticker}"
resp = gl.nondet.web.get(url) # ← HTTP GET
# Validate response content
price = gl.eq_principle.strict_eq(lambda: resp.body)
return price
Screenshot Verification
@gl.public.view
def get_page_snapshot(self, url: str) -> bytes:
img = gl.nondet.web.render(url, mode="screenshot")
# Validators confirm the image hash matches
img_hash = gl.eq_principle.strict_eq(lambda: hashlib.sha256(img).hexdigest())
return img
Key Source Files in the Repository
| File | Purpose | Key Lines |
|---|---|---|
contracts/football_bets.py |
Web rendering, LLM prompting, equivalence-principle validation | 31-34 (web fetch), 51-54 (LLM & validation) |
contracts/__init__.py |
Contract module registration | — |
tests/direct/test_views.py |
Mock web calls in direct-mode tests | — |
config/genlayer_config.py |
Network endpoint configuration | — |
Summary
- GenLayer smart contracts access the internet through
gl.nondet.web, a non-deterministic API that supports GET, POST, and rendered content retrieval - All web calls require equivalence-principle validation (
gl.eq_principle.strict_eqor similar) to achieve validator consensus - Three render modes are available:
"text"for clean extraction,"html"for raw markup, and"screenshot"for visual verification - The
FootballBetscontract incontracts/football_bets.pydemonstrates the complete pattern: URL construction,gl.nondet.web.render, LLM processing withgl.nondet.exec_prompt, and strict equality validation
Frequently Asked Questions
What makes gl.nondet.web "non-deterministic"?
The gl.nondet.web methods are non-deterministic because web servers may return different responses to different validators—due to timing, caching, geo-location, or dynamic content. Unlike deterministic operations that produce identical outputs on every node, these calls require equivalence-principle validation so validators can agree on a single canonical result before updating on-chain state.
Can GenLayer contracts access any website?
Yes, gl.nondet.web.get and gl.nondet.web.render can target any public URL. However, the equivalence principle may fail for highly dynamic or personalized content. For reliable consensus, contracts should target stable, public sources or use mode="text" to reduce noise from JavaScript-rendered variations.
What happens if validators disagree on web content?
If validators produce different outputs from a gl.nondet.web call, the equivalence-principle function (e.g., gl.eq_principle.strict_eq) detects the mismatch and halts execution. The transaction does not finalize until a sufficient majority agrees on the same result, preserving network consensus.
How do you test contracts that use internet access?
The tests/direct/test_views.py file demonstrates mocking web calls in direct-mode tests. Developers can simulate gl.nondet.web responses without making actual network requests, enabling deterministic test behavior while preserving the production code structure.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →