1. Available Recordings
- youtube.com/watch?v=K0Bkc0rsW8U
- crowdcast.io/e/hacktherainbow/13
- crowdcast.io/e/hacktherainbow/7
Workshop Preparation
Please complete the following steps before the workshop starts:
- [5 min] Install Node.js locally
- [2 min] Install NEAR CLI locally
- [3 min] Create a TestNet account on NEAR Protocol
If you have time, feel free to complete the following steps as well:
- Read about a few of the key concepts of the NEAR platform:
- Accounts
- Transactions
- Storage Staking
- Deploy the Fungible Token sample application (Gitpod or locally)
NEAR 102
An introductory workshop
for Ethereum developers
near.org
3. NEAR is cheaper, faster and easier to use
Development
- Contracts are written using AssemblyScript or Rust and compiled to Wasm
- 1 million JavaScript / TypeScript developers can learn AssemblyScript quickly and easily
- Rust toolchain and community support speeds development of complex contracts
- Unique account system makes reasoning about complex contract orchestration simple
Production
- Optimizations built into the protocol
- Gas fees (not just cost of gas) are 10x - 100x lower than those of Ethereum
- Contract accounts earn part of tx fees, reducing total cost of ownership for developers
- Automatic account redistribution among shards maximizes throughput
- 1 second block time and 3 second finality
4. Several examples and starters
near.dev
- several full stack examples in
Rust and AssemblyScript
- many have well commented
code to guide your exploration
- best effort at canonical use of
the platform frontend and
contract implementations
5. github.com / near / create-near-app
npx create-near-app banana
- generate a NEAR-compatible
frontend & contract in 1 command
- frontend: React, plain JS, others?
- contract: Rust, AssemblyScript
Ethereum ⇔ NEAR Cookbook
bit.ly / near-102-recipes
Get started in minutes
6. account - Ethereum supports two types of accounts with a single private key for EOAs
- NEAR supports one account type with an unlimited number of scoped keys
state - Ethereum state is replicated across all nodes of a single threaded machine
- NEAR state is isolated to one "home" shard per account in a "multithreaded" env
transaction - Ethereum supports transfer, contract deployment and function call transactions
- NEAR supports 8 composable Actions which determine transaction behavior
gas - Ethereum gas price is determined by network load and profit-motive
- NEAR gas price is algorithmically controlled to limit shard congestion at 50%
block - Ethereum blocks are produced using PoW consensus at a rate of one per 15s
- NEAR blocks are produced using PoS consensus at a rate of one per second
Same-same … but different primitives
7. Ethereum NEAR
standards ERC20 / ERC721 NEP141 / NEP171
transaction results Etherscan either view transaction in NEAR Explorer or use
near tx-status <tx_hash>
special data types address accounts are String type and
validation is available in Rust with
env::is_valid_account_id
mapping Collections ( Rust & AssemblyScript )
payable methods payable #[payable] ( Rust decorator )
event model Events polling EXPERIMENTAL_changes RPC method
running a node ganache nearup ( repo )
Same-same … but different features
8. NEAR
Deployment typically follows these steps:
1. Compile contract bytecode
2. Compose transaction using DeployContract
with attached bytecode (and optionally
CreateAccount, AddKey, Transfer as well)
3. Sign and send transaction to deploy contract
4. Receive transaction outcome
5. … redeploy to same account with FullAccess
private key or remove for trustless operation
step 2 can be decomposed into multiple Txs
Same-same … but different
Ethereum
Deployment typically follows these steps:
1. Compile contract bytecode
2. Compose transaction by attaching
bytecode (and initial value for contract)
3. Sign and send transaction to a special
address which creates new account and
deploys contract
4. Receive new contract address (or calculate
it yourself)
deployment
9. Same-same … but different
Ethereum Transactions NEAR Transactions
origin (signer, pk)
destination (receiver)
uniqueness (nonce)
handled elsewhere
recency (block_hash)
origin (v,r,s)
destination (recipient)
uniqueness (nonce)
cost control (gas price & limit)
transactions
12. Mapping concepts
NEAR supports 8 composable primitive Actions
- CreateAccount to make a new account (for a person, contract, refrigerator, etc)
- DeleteAccount to delete an account (and transfer balance to a beneficiary account)
- AddKey to add a key to an account (either FullAccess or FunctionCall access)
- DeleteKey to delete an existing key from an account
- Transfer to move tokens from one account to another
- Stake to express interest in becoming a validator at the next available opportunity
- DeployContract to deploy a contract
- FunctionCall to invoke a method on a contract (including budget for compute and storage)
transactions
13. Mapping concepts
Ethereum
Custom Language → Custom VM
Pros
- Designed for blockchain
- May allow for formal verification
Cons
- Niche language
NEAR
AssemblyScript / Rust → Wasm VM
Pros
- Existing tooling and community
- General purpose
- Turing complete
Cons
- Not originally designed for blockchain
- No formal verification
runtime
14. Rust
Pros
- Mature, battle-hardened compiler
- Thriving ecosystem
- Real world use cases
- near-sdk-rs makes life easy
Cons
- Steeper learning curve
AssemblyScript
Pros
- Easier for prototyping
- Trivial for JS and TS devs to learn
- Smaller binaries in Wasm
- Binaries are easier to read / debug
Cons
- Current compiler is not stable
- Immature ecosystem
NEAR contract languages development
15. In some ways … different asynchronous calls
B A
C D
16. In some ways … different asynchronous calls
B A
C D
17. In some ways … same no surprise here
External “promise” calls which are used to invoke methods on multiple contracts using the
standard Promise interface
This example was taken from MDN (just assume the functions wrap near-api-js)
A
18. In some ways … same no surprise here
External “batch” calls are used to chain a series of Actions together to be executed on some
target account
B
19. In some ways … different asynchronous calls
Internal “batch” calls which are used to chain a series of Actions together to be executed on
some target account (including being applied to the current contract)
C
20. In some ways … different asynchronous calls
Internal “promise” calls which are used to invoke methods on other contracts (or recursively
on the current contract)
D
30. Rainbow Bridge: NEAR Ethereum
- Decide to send 10 RAIN
- Authorize TokenLocker as escrow for ERC20
token on Ethereum (approve)
- Approve TokenLocker transaction which
locks the tokens on Ethereum (lockToken)
- Tokens are locked (emit Locked event)
- Wait 25 blocks for confirmation
- Attach small deposit to offset the cost of
storing newly minted nRAIN on NEAR
- Receive nRAIN tokens on NEAR
35. create-near-app
To start building on NEAR run the following* in your terminal:
npx create-near-app --help
* you must have Node.js installed to run npx
41. step #5 … n
- discover
- where do we setup a connection to NEAR?
hint: search the code for keyStore
- where do we login to the NEAR Wallet?
hint: search the code for requestSignIn
- which lines of code wire up the contract to our JS context?
hint: search the code for viewMethods or changeMethods
- control
- try to reverse the greeting string before writing on chain
hint 1: search for storage.set … AssemblyScript supports common Array and String functions
hint 2: message.split('').reverse().join('')
create-near-app
43. NEAR exposes two development interfaces
dApp UX development
- Use near-api-js to connect to
NEAR, manage accounts, call
contract methods and more
- Use JSON-RPC API to
communicate with NEAR from
any context (other than JS / TS)
- Manage devops with NEAR Shell
dApp Contract Development
- Use near-sdk-as to build
contracts using AssemblyScript
- Use near-sdk-rs to build
contracts using Rust
- Compose deployed contracts
using cross-contract calls
44. NEAR exposes two development interfaces
dApp UX development
- Use near-api-js to connect to
NEAR, manage accounts, call
contract methods and more
- Use JSON-RPC API to
communicate with NEAR from
any context (other than JS / TS)
- Manage devops with NEAR Shell
dApp Contract Development
- Use near-sdk-as to build
contracts using AssemblyScript
- Use near-sdk-rs to build
contracts using Rust
- Compose deployed contracts
using cross-contract calls
45. NEAR exposes two development interfaces
dApp UX development
- Use near-api-js to connect to
NEAR, manage accounts, call
contract methods and more
- Use JSON-RPC API to
communicate with NEAR from
any context (other than JS / TS)
- Manage devops with NEAR Shell
dApp Contract Development
- Use near-sdk-as to build
contracts using AssemblyScript
- Use near-sdk-rs to build
contracts using Rust
- Compose deployed contracts
using cross-contract calls
46. NEAR exposes two development interfaces
dApp UX development
- Use near-api-js to connect to
NEAR, manage accounts, call
contract methods and more
- Use JSON-RPC API to
communicate with NEAR from
any context (other than JS / TS)
- Manage devops with NEAR Shell
dApp Contract Development
- Use near-sdk-as to build
contracts using AssemblyScript
- Use near-sdk-rs to build
contracts using Rust
- Compose deployed contracts
using cross-contract calls
47. Structure of the Sample Application
Runtime Layer
state storage
virtual
machine
code
load
apply
result
read write
Your dApp
send
receive
Blockchain Layer
RPC Interface
- P2P network
- Consensus
- Block Storage
near-api-js
contracts
near-sdk-as
near-sdk-rs
deploy
49. Lifecycle of a transaction
Runtime Layer
state storage
virtual
machine
code
load
apply
result
read write
Your dApp
send
receive
Blockchain Layer
RPC Interface
- P2P network
- Consensus
- Block Storage
near-api-js
contracts
near-sdk-as
near-sdk-rs
1
2 3 4
5
6
7
deploy
50. Account ≈ Contract + State
Runtime Layer
state storage
virtual
machine
code
load
read write
51. Account ≈ Contract + State
Runtime Layer
virtual
machine
code
load
metadata
result
read write
data
apply
state storage
52. Runtime Layer
result
apply
Account ≈ Contract + State
virtual
machine
code
load
read write
key value
STATE your contract code
message “hello world”
counter 3
prefix::identifier value at collection key
prefix::len PersistentVector length
prefix::last PersistentDeque last item
state storage
56. “To enable WebAssembly to be read and edited by
humans, there is a textual representation of the wasm
binary format. This is an intermediate form designed to be
exposed in text editors, browser developer tools, etc.”
-- Understanding WebAssembly text format
Although we will not spend time on this topic, this format
has proven consistently readable (especially with
AssemblyScript) if only to sanity check that exported
contract functions are visible and near-sdk-as runtime
components are being called in the right places.
The output is always a .wasm file
59. - there are 2 main folders in the project:
- assembly contains the smart contract and tests
- src contains the application’s UX and tests
- there is another folder to be aware of:
- neardev contains contract account details
- this is for development only, your local credentials
will be in ~/.near-credentials
Guest Book Filesystem
60. Guest Book
Contract Data Model : assembly/model.ts
- PostedMessage is a serializable class with three
attributes:
- premium to flag messages with attached
NEAR tokens
- sender to track the signer of the guest
book message
- text to hold the guest book message
- messages is a collection of guest book messages
stored as a PersistentVector of
PostedMessage objects
note: @nearBindgen marks the class as serializable
Contract
61. Contract Behavior : assembly/main.ts
- MESSAGE_LIMIT is used to avoid unbounded calls
(ie. potentially expensive) to retrieve guest book
messages from storage
- two public functions are exposed on the contract:
- addMessage(text: string): void
- getMessages(): PostedMessage[]
Guest Book Contract
62. Guest Book
Network Connection : src/config.js
- data and endpoints required to connect to the
NEAR network
- connection information is included for MainNet,
TestNet and BetaNet as well as the default
LocalNet configuration
Frontend
63. Guest Book Frontend
Configuration : src/index.js
- configure connection to NEAR network
- configure contract interface by injecting
wallet connection and wiring up both
contract methods
- contract is a proxy object for JSON RPC
API calls with methods attached
- contract methods are attached to the
object as either view or change type and
return a Promise
64. Guest Book
Authentication : src/App.js
- NEAR Wallet is used for authentication
- near-api-js exposes two related methods
- wallet.requestSignIn()
- wallet.signOut()
note: useCallback() is a React Hook
Frontend
65. CRUD : src/App.js
- add a message and, once complete, get a list of
all messages (up to MESSAGE_LIMIT)
- contract.addMessage accepts parameters as
a JSON object and returns nothing
- two other parameters are optional
- gas (a “boatload”) to override client defaults
- attached value (in NEAR tokens)
Guest Book Frontend
66. Monitoring the application ...
http post https://rpc.testnet.near.org
jsonrpc=2.0 id=dontcare
method=query params:='{
"request_type": "view_state",
"finality": "final",
"account_id": "test",
"prefix_base64": "U1RBVEU="
}’
And, using the watch command and some
JSON formatting with jq, automatically
refresh a convenient view while we use
the Guestbook example. Here’s how.
Also see here for our JSON RPC API docs
https://docs.near.org/docs/interaction/rpc
Guest Book Demo: Monitoring
68. -
Ethereum supports two types of accounts
1. Externally Owned Accounts (EOA)
a. identified by last 20 bytes of the keccak-256 hash of a public key
b. controlled by a private key of the same public-private key pair
c. can sign and send transactions to other EOAs or contract accounts
2. Contract Accounts
a. controlled by contract code, no keys involved
b. can only send transactions in response to being triggered
c. are of two subtypes
i. Simple
ii. Multisig
From Ethereum to NEAR accounts
69. -
From Ethereum to NEAR
NEAR supports one type of account
- human readable name (like having ENS baked into the protocol *)
- may represent a user, contract or both
- are controlled by an unlimited number of keys
- two types
- FullAccess: can do anything with the account, including send tokens and delete account
- FunctionCall: can only call contract functions which may be limited in scope and budget
* NEAR accounts follow a human friendly DNS naming pattern with similar scoping rules for
ownership and control. For example user.testnet controls app1.user.testnet and
app2.user.testnet.
accounts
70. -
Ethereum
- nonce
- balance
- storageRoot
- codeHash*
* codeHash may be either:
- hash of an empty string (EOAs)
- hash of the code of the contract
NEAR
- balance
- locked balance (for staking)
- code of the contract **
- storage (key-value store for contract data)
- access keys *** (FullAccess, FunctionCall)
- postponed ActionReceipts (ie. “todo”)
- received DataReceipts (ie. “done”)
** code_hash is similar to Ethereum
*** each access key tracks its own nonce
note that receipts are used to manage
cross-contract calls
From Ethereum to NEAR accounts
72. - managing NEAR primitives:
- key stores
- accounts
- contracts
- wallets
- connection providers (RPC)
- generating key pairs locally
- creating transactions locally
- signing transactions locally
- sending transactions to the network
near-api-js
Library designed to connect to the NEAR platform from any JavaScript
execution context (server-side or client-side JS)