CHAINOPOLY.PRG

2018-10-08 → 2019-01-05 · 92 commits · solo · PUBLIC

WHAT IT IS.

A Monopoly clone whose state lives on a permissioned chain. I was invited to teach a short course on blockchain use cases in 2018, and there was almost no public material to point students at — so I built a small one. The dApp was a didactic tool: clarity and simplicity over scope, every line of state on the board made legible in three layers the class could compare. The same Monopoly rules live in a Python engine on the server, an Angular client in the browser, and a small set of Solidity contracts that own the ledger.

HOW THE CLASS USED IT.

The first sessions walked through real use cases — a few hours surveying what people were actually doing with the technology in 2018, the rest spent on the patterns I wanted students to be able to recognise in any dApp. The last few sessions were a post-mortem of Chainopoly itself: where the rules live, what the chain actually adds over a regular database, what the chain makes harder, and what the chain would have made unnecessary if the game were simpler. The course deck (SLIDES.PRG) carries the lecture material; this page is about the artifact we kept returning to.

THE STRUCTURE.

  • Server engine (Tornado / Python 3). A JSON-driven game state machine. The engine modules (entities, fungible, nonfungible, game, atomic_swap, eventemitter) are split so the rule for any single concept lives in one place and the same concept can be lifted into the contract layer without rewriting it. The engine speaks plain JSON to the client and to the contract layer; no blockchain types leak into the room where the rules are.

  • Browser client (Angular 6 + Webpack). A board, two seats, a per-round command loop. The client talks to the engine over WebSockets. The w3/ service layer is the seam: when it is wired to mock services, the game runs without a chain attached, which is how the post-mortem sessions showed the difference between a board game and a dApp.

  • On-chain state (Truffle + OpenZeppelin). Five small contracts: Game.sol (the dice and the per-round handoff), ChainopolyCoin.sol (the in-game currency), ChainopolyProperties.sol (the deeds), Property.sol (one deed), and AtomicSwap.sol (the trade that has to succeed as a whole or not at all). The contract layer is deliberately small — the engine is what the class reads; the contracts are what the chain owns.

WHAT I LEARNED.

  • Clarity over scope: the dApp was built so every state transition could be read end to end in a single sitting. A larger feature set would have made the post-mortem sessions longer, not clearer.

  • The chain earns its place when the rule is atomic: a trade either settles or it does not, and the chain's only job is to make that observable. Rent, dice, and movement did not need a chain; the swap did.

  • Engine–client–contract is one rulebook repeated three times. The class got more out of arguing about where each rule belonged than out of any single layer in isolation.

[ DEODORO ] > CODE / chainopoly EJECT → SHELF