simple-token step-by-step alongside the instructor, then prove what you
learned by extending my-token on your own.
How it works. Each chapter has two tracks running in parallel: a
Guided track (copy-paste into
simple-token) and an Exercise track
(build the same thing yourself in my-token). Tests verify your
implementation; reveal solutions inline whenever you get stuck.The two tracks
Guided track — simple-token
Copy-paste alongside the chapter. A stripped-down version of the GEN
token standard. You’ll see every line before you write it.
Exercise track — my-token
Implement the same functionality yourself. Starter and solution tags
in git; tests in
my-token-tests tell you when you’re right.The chapters
| # | Chapter | What it teaches |
|---|---|---|
| — | Environment Setup | Native macOS toolchain (recommended) or devcontainer fallback. |
| — | Project Setup | Clone my-token, init simple-token via gen genie init-contract. |
| 1 | First Build, First Test | Anatomy of a contract — root component, #[deploy], #[installation_request], ABI-driven typed clients, push + deploy + install. |
| 2 | Adding Functionality | The simple-token holder — transfer + receive, storage, and the access modifiers (#[owner], #[private], #[public], #[view]) that make inter-component calls safe. |
| 3 | Everything but the Kitchen Sync | .local (sync, same entity) vs .remote (async, anywhere). The lever for choosing where parallelism lives. |
| 4 | To Panic is Human | Why panic! doesn’t save Alice — atomicity is local, not global. Result::Err + compensation patterns. await vs spawn. |
| 5a | Borrowed Code · Make It Compile | Contract refs, instances, the dependency plumbing. Install simple-token’s holder into your components until it compiles. |
| 5b | Borrowed Code · Make It Run | Default routing, the cross-contract transfer() call, and the test (plus the ContractRefError fix). |
| 6 | Final Exercises | Safe Swap (peer-to-peer with cancel + safety) and a Central Limit Order Book. Build from scratch with everything you learned. |
The shape of a GEN contract
The four access modifiers
| Modifier | Who can call |
|---|---|
#[owner] | Only the entity where the component is installed. |
#[private] | Any component in the same contract. |
#[public] | Anyone. |
#[view] | Anyone, read-only, free. |
Sync vs async, in one rule
.local— sync; only works between components on the same entity; no entity-lock yield..remote— async; works regardless of entity; yields the lock, produces a deferred result.
What you’ll need
- An Apple Silicon Mac (recommended) or any machine with Docker for the devcontainer path.
- Familiarity with Rust at a reading level — async, traits,
Result. - A GitHub account for cloning the workshop repo.
Claim to fame
Mainstream payment processors handle around 30,000 transactions per second at peak. Most L1s top out somewhere between a few thousand and ~100K TPS in the optimistic case, and far less once transactions actually conflict, because their execution model serializes contended writes. The Grid’s design point sits well above that, and the reason is architectural:| Property | Number | Why it matters |
|---|---|---|
| Throughput | 1,000,000 activations/sec (design target) | Parallelism is per-entity, not per-block. Conflicts are bounded to the entity scope you chose — throughput becomes a property of your contract design, not of the chain you happen to be on. |
| Block time | ~10 ms (~500 ms finality) | A write is one round-trip in tens of milliseconds; reads don’t touch the activation pipeline at all. |
| Cost | Low, quoted in stablecoin | No “wait for gas to come down” UX. Per-call economics survive going from one transaction to ten million of them. |
- No singletons. The same contract code can be instantiated many times — each instance gets its own state and execution. Throughput scales with deployments, not against them.
- Compose, don’t replicate. Your swap or vesting contract installs the canonical token contract’s holder onto itself instead of reimplementing it. Your contract participates in deployed state; logic runs where the state lives.
Start here
Environment Setup
Step 1 · Install the toolchain — native macOS binaries (recommended)
or devcontainer.
Project Setup
Step 2 · Clone
my-token and initialize simple-token from the CLI.
