WarpScript Contracts
WarpScript is WarpCoin's declarative, no-code smart-contract model. Users compose agreements from typed parameters and when/then clauses in a visual studio (no Solidity, no CLI); the compiler turns the design into a deterministic, content-addressed artifact that WarpVM executes on-chain. A deployed contract custodies real WARP, and the chain moves those funds by re-running WarpVM during block processing — with no contract private key. See On-chain execution (WarpVM) below.
A defining property: the compiler is byte-compatible across implementations.
The Go node compiler and the WarpWallet TypeScript compiler produce the identical
contract id and W… contract address for the same spec — verified by a
cross-language golden test.
The contract model
A ContractSpec (schema warpscript/v1) is:
{
"schema": "warpscript/v1",
"name": "Milestone Escrow",
"description": "Two-party escrow with arbiter fallback.",
"author": "W…", // creator's address
"network": "earth", // earth | luna | mars | interplanetary
"params": [ Param, … ],
"clauses": [ Clause, … ],
"createdAt": 1718360000000
}
Param — a typed input:
{ "key": "amount", "label": "Amount (flux)", "type": "amount", "value": "", "required": true }
type ∈ address | tag | amount | duration | number | text | date | boolean.
Clause — a when/then rule:
{
"id": "release",
"name": "Release to seller",
"trigger": { "type": "on_approval", "ref": "buyer" },
"conditions": [ { "type": "any_approved", "ref": "buyer,arbiter" } ],
"actions": [ { "type": "release", "to": "seller", "amount": "amount" } ]
}
Building blocks (palette)
| Triggers | Conditions | Actions |
|---|---|---|
manual |
always |
transfer |
on_fund |
signed_by |
release |
on_approval |
all_approved / any_approved |
refund |
on_deadline |
amount_at_least |
split |
on_oracle |
before / after |
lock |
on_light_time |
light_time_elapsed |
notify |
The on_light_time trigger and light_time_elapsed condition make
inter-planetary contracts possible: settlement that waits for the round-trip
light delay to the destination world to elapse before finalizing. The on_oracle
trigger fires from a signed oracle feed — both are supplied to WarpVM as
deterministic, on-chain inputs (see below).
Determinism & contract addresses
The compiler is fully deterministic. The content hash is taken over a canonical JSON serialization — object keys sorted recursively, compact, no HTML escaping — so the same spec always hashes the same way, in any language:
contractId = hex( sha256d( canonicalJSON(spec) ) )
contractAddress = Base58Check( 0x49 || sha256d(canonicalJSON)[0:20] )
The contract address reuses the account address scheme (version byte 0x49), so
contract addresses are indistinguishable in form from account addresses and begin
with W. Identical specs ⇒ identical addresses across the web app and the node.
Compiler output
Compile(spec) returns:
contractId— hex content hash.contractAddress— deterministicW…address.warpscript— a human-readable source rendering of the spec.bytecode— the machine artifact WarpVM loads and executes (params, clauses).warnings— static-analysis findings (missing required values, unknown param references, clauses with no actions, …).
Example rendered WarpScript:
contract "Milestone Escrow" {
network earth
author W…
param buyer: address required
param seller: address required
param amount: amount required
clause "Release to seller" {
on on_approval(buyer)
when any_approved(buyer,arbiter)
do release(amount to seller)
}
}
Templates
The studio ships starter templates that build a complete spec for you:
| Template | Category | What it does |
|---|---|---|
| Milestone Escrow | Commerce | Buyer funds; release on approval, else refund after a deadline. |
| Time-Locked Vesting | Treasury | Lock WARP for a beneficiary until a release date. |
| Multisig Treasury | Treasury | Pay out only on a quorum of signer approvals. |
| Interplanetary Delayed Transfer | Interplanetary | Finalize only after the round-trip light delay elapses. |
| Subscription | Commerce | Recurring per-period payout to a merchant. |
API
| Endpoint | Method | Purpose |
|---|---|---|
POST /contract/compile |
POST | { spec } → compiled artifact (no deploy; live preview) |
POST /contract/deploy |
POST | { spec } → stored, content-addressed contract + warnings |
GET /contract/get?id=<contractId> |
GET | fetch a deployed contract |
GET /contract/list?author=<addr> |
GET | list deployed contracts (optionally by author) |
GET /contract/templates |
GET | the template catalog |
GET /contract/palette |
GET | available triggers, conditions, and actions |
On-chain execution (WarpVM)
WarpVM is WarpCoin's contract engine, and it runs as consensus. A contract's compiled artifact becomes consensus state, it custodies real WARP, and the chain settles it by re-running WarpVM during block processing — overflow-safe, gas-bounded, and fully deterministic (time comes from the block timestamp, never a wall clock). There is no contract private key; the chain itself moves the funds.
Contract interactions ride on ordinary signed transactions via a ContractOp
field — the transaction's own signature authorizes the operation:
| Op | Consensus effect |
|---|---|
deploy |
compile the spec, register it, create VM state |
fund |
debit the sender; add to the contract's custodied balance; fire on_fund; record the funding time |
approve |
record the sender's approval and re-evaluate |
invoke |
fire manual / time-based clauses |
oracle |
record a signed oracle feed and fire the matching on_oracle clauses |
Deterministic trigger feeds. on_oracle fires when the address named by the
clause's referenced param submits a signed oracle op — the signature is the
authorization, so no oracle key lives on-chain. on_light_time /
light_time_elapsed fire once the round-trip light delay to the destination world
(computed from the block clock) has elapsed since funding. Both are pure functions
of consensus state, so every node derives identical settlement.
Mempool pre-simulation. A contract-op transaction that would fail execution is rejected before it is gossiped or mined, so a failing op can never invalidate the block that includes it.
Money is conserved exactly: the sum of account balances plus contract custody
equals the issued supply. Clients submit these as transactions (POST /tx) and
read on-chain state with GET /chain/contract?id=; the CLI wraps both:
warpcoin contract deploy --template milestone-escrow \
--params "buyer=W..,seller=W..,amount=5000,deadline=9000000000"
warpcoin contract fund --id <contractId> --amount 5000 # flux
warpcoin contract approve --id <contractId> # releases on-chain
warpcoin contract oracle --id <contractId> --ref <param> # fire a signed feed
warpcoin contract show --id <contractId> # on-chain state