Learn various features of NEAR & blockchain by building software for an imaginary city, Raenville (pronounced "rainville") (it's "near" backwards).
Target audiences:
- All web developers: anyone from the "web2 developer" audience should find this non-intimidating. By the end should feel like they know both "why would I use a blockchain?" and "how do I build a real-world app with NEAR?"
- Blockchain developers: by the end of the course, a "web3 developer" will know what makes NEAR unique.
The basic project: a walk-through that has you build simplified software that could be used to power a city government. This example was chosen for a few reasons:
- It makes a natural fit for many of blockchain's greatest hits: Non-Fungible Tokens for real estate deeds, Fungible Tokens for local currencies, and DAOs for legislation.
- Showing how these patterns could be used in a real-world context increases the chance of giving non-blockchain developers an "a-ha!" moment about how blockchain could give them superpowers.
- It's somewhat ambitious, teaching blockchain newbies to think big about what blockchain could do for them.
- It's natural to implement as a multi-contract app, to demonstrate good patterns for working with such projects.
- It's fun!
The main interaction with the tutorial will avoid writing custom code. Instead, learners will interact with the already-created web app, look at code, and run some commands with near-cli. However, for people who want to dig in more, "going further" sections are sprinkled throughout. These can involve more error-prone custom coding and can also be quite tangential to the main narrative. If an intermediate web2 developer skips all the "going further" sections, they should be able to complete the entire tutorial in 15-60min.
-
Prerequisites: command line familiarity. If running locally rather than Gitpod, must have Node & Yarn installed.
-
Clone this repo
-
Run
yarn start
. Behind the scenes, this will:- deploy contract with
dev-deploy
- add
dev-*
address to.env
- run
parcel serve
- auto-opens browser to app
- deploy contract with
-
Webpage is split into two parts, "user" part and "developer" part.
Explains:
- what just happened (see
2
above) - how the project is structured
- where the source code of this specific content is
Prompts user to log in with NEAR.
(Doing this should already give people their first a-ha moment: how easy it is to add auth to their app with NEAR. Ideally, the NEAR login process will be simplified, so that even if the web2 crowd drops out after this, they'll still be inspired to reach for NEAR instead of some OAuth solution the next time they want to quickly add authentication to an app.)
- what just happened (see
-
After logging in, content changes.
Remains mostly unchanged and minimal, maybe says "Welcome, account-name.testnet"
Explains:
- Look at that, identity as a primitive! With blockchains, the web finally has identity baked into the protocol.
- More about NEAR Wallet
- near-api-js
- NEAR's awesome account system
Then it prompts developer to use near-cli to:
near login
- use near-cli to create subaccount and deploy contract to it, update
.env
with new contract address. This shows off NEAR's nifty account name system. - call the contract's
set_mayor
function to set self as mayor (to demonstrate common errors/gotchas, initially instructs them to callset_mayor
with poorly-formed JSON). This shows off NEAR-specific feature allowing contracts to accepts JSON as input.
-
After setting the mayor and refreshing the page, the page now:
Shows a special "Howdy, Mayor!" message
- intro to smart contracts & rust-sdk-rs; where to open the contract to see the
set_mayor
function - going further: modify
set_mayor
to store Mayor's name, install rustup & target wasm-unknown-unknown (if running locally instead of in Gitpod), compile updated contract, deploy, call updatedset_mayor
function with near-cli, update frontend to show name
Then, to set up the next step:
- Has learner create new subaccount & deploy NFT contract to it, then update
.env
with new contract address (might require restartingyarn start
process)
- intro to smart contracts & rust-sdk-rs; where to open the contract to see the
-
NFTs: Mayor can now get started on the first major upgrade to the city's digital infrastructure: replacing paper deeds and filing cabinets with NFTs and distributed ledgers!
- Has the mayor add a couple properties to get it started (jokes that they might want to hire some interns to finish this data-entry step)
Other details we may want to explain briefly, with links to read more:
- All entered properties are initially owned by Mayor
- TBD plan to verify people's identities/accounts prior to transfering these NFTs to them
- Ability to comply with local laws & current real-estate transferrence process by doing something like requiring on-chain transactions to be signed by a title company
- Benefits of using NFTs for this process
- Privacy considerations when having all property ownership on a public blockchain – this is in theory similar to the public nature of real estate ownership in the United States
- Introduces nomicon & NFT standard
- Points out what simple programs these are, and that they get their whole power through 1. being deployed to a blockchain and 2. being a standard
- Says where to open the Non-Fungible Token contract code
- Introduces
near-contract-standards
library
Then, to set up the next step:
- Has learner create new subaccount & deploy FT contract to it and update
.env
with new contract address (might require restartingyarn start
process)
-
FTs: New feature unlocked! The page now shows a "Register to vote, earn $RAEN" button
- Explains that RAEN tokens are the city's new local currency, to be minted solely when people register to vote via the new website, and which are already being accepted at many local establishments
- Has mayor register to vote
- requires selecting one of the addresses entered as an NFT
- shows RAEN balance afterward
- Says where to open the Fungible Token contract, highlights & explains the cross-contract call from main contract's
register_voter
function to FT contract'stransfer
- Discusses Sybil-resistance challenges around real-world identity verification, especially given the 1000-RAEN incentive to cheat
- going further: use Testnet version of Ref Finance to provide liquidity for the RAEN/nUSD pair and swap one to the other
Then, to set up the next step:
- Has learner create new subaccount & deploy DAO contract to it and update
.env
with new contract address (might require restartingyarn start
process)
-
DAOs: All registered voters see a new feature: "Make a proposal" – DAO functionality for the city
- Any voter can make proposals, but exact voting mechanics (who is allowed to vote on proposals, how much their votes count, when voting happens) can be decided by the city and can be modified via further proposals over time.
- Anyone making proposals can optionally attach RAEN, which will be released to the city treasury only if the proposal is ratified. This allows proposers to "put their money where their mouth is", putting real money on the line to show that they are serious about getting this proposal passed, as well as allow them to help fund their proposed project.
- The "optional RAEN attachment" feature shows off two NEAR-specific features:
- Function Call keys don't need to sign every transaction (user can make proposal with familiar web2 experience), but attaching a deposit requires signing via NEAR Wallet.
transfer_call
functionality of FTs: if attaching RAEN, the initial contract call goes to the FT contract'stransfer_call
function, which then makes a cross-contract call to the DAO contract.
- Mention ability for contract owner to mint self unlimited RAEN or change votes due to existence of Full Access keys (another NEAR-specific feature), and how a real-world contract would want to remove all Full Access keys and pay for a rigorous security audit if maintainers want to avoid hacks & bad press.
- Mention that even with all Full Access removed, the contract could still be updated via a DAO vote.
-
Going further: Introduction to project's near-sandbox tests, showing that all current functionality has passing tests, but there are failing tests for not-yet-developed features. Self-guided exercise from here: implement new features, make the tests pass! Some feature ideas:
- Rather than just "the Mayor and everyone else", contract also has other roles: city council, block captain, building coordinator
- These different roles get different voting power on proposals, which is not represented with FTs or NFTs because they're not meant to be sellable assets
- Only Mayor and City Council members should be able to change someone else's role
- Get rid of
set_mayor
in favor of more generalset_role
- Allow voters to comment on Proposals and optionally attach more RAEN to go toward the proposed project/improvement
- Implement different governance systems: direct democracy, representative democray, liquid democracy, sortition
- Implement different voting systems