An Intro To Near Dapp Development With Rust, WASM, Parcel and React -Part 1.

Panasthetik
Coinmonks
Published in
11 min readMar 9, 2022

--

This article will introduce existing Web3 developers to the Near Protocol with a simple, functional, start-to-finish example in three parts.

The entire code repository for Part 1 and Part 2 of this tutorial can be found here.

If you’re coming from Ethereum or even Solana, one of the things that makes Near different as of now (March 2022) is that there aren’t a lot of very recent tutorials for developing a basic, fully-functional application with an upgradeable template — front-end, back-end, and unit tests.

In addition, I think the fact that the protocol’s contracts are written in either Rust or AssemblyScript (then compiled to WASM) tends to discourage would-be developers from jumping right in.

Lastly — both the Near blockchain and the underlying token have, in my opinion been under-represented overall in various news articles and coverage as well as developer tutorials like this one.

I hope to help alleviate these issues with this article, making the Near Protocol more accessible to new creators and also helping to on-board potential users with some of the many things that make Near an awesome, fun, fast, inspiring blockchain with enormous potential. So let’s get started!

The Basics.

First, this tutorial assumes a few things straight away to make our intro to Near easier:

  1. You have already developed initially on Ethereum, an EVM or a layer-2 chain, or on Solana or similar, and have experience with dev tools like Truffle, Hardhat, Anchor or Foundry.
  2. You’re running either Linux or MacOS and have Rust installed, including the latest stable version, the Cargo package manager, and the Rust extension/analyzer for VSCode (We will use VSCode for this article).
  3. Node.js should be installed 14.19.0–17.1.0, and your NPM is at least version 8.3.0+
  4. You are familiar with smart contract deployment, gas fees, wallet accounts, transaction explorers, etc. — fundamental blockchain primitives.
  5. Lastly — although basic Rust is helpful and React experience is great, you don’t have to know either one at an expert level to understand this example and how everything interacts.

Setting Up Our Near Testnet Wallet.

The first thing we will look at is creating a wallet/account on the Near Testnet and getting some test Near tokens to deploy on the network. You can go here to learn how to do that, as it is very similar to other wallets (MetaMask, SolFlare):

An interesting difference with Near already, which can make it more user-friendly, is that Near account addresses appear as human-readable text (ex: “myaccount.testnet” for testing, or “myaccount.near” for mainnet). As long as your suggested name isn’t already taken you can get creative with these account names. Also, no need to reserve a separate ENS-like name (.ETH) or .SOL like on Solana — with Near you have this capability right out the box and your deployed contracts can be mapped directly to your chosen addresses!!

When we actually deploy smart contracts on-chain, we will choose sub-account names as a best practice to contain the contract address, like the following:

contract.myaccount.testnet (for testing)

contract.myaccount.near (for mainnet)

One thing to note about Near is that a smart contract can only be deployed one per sub-address, which keeps things organized and can be upgraded (we will see how to upgrade or replace contracts later in this series).

Once we have our Near test account created we should have a sample Near test token balance to start with, which will help us with the next step.

Setting Up Our Environment.

The best way to start organizing our dev environment is to install the Near CLI as follows using NPM:

With that installed correctly, you should be able to verify in your terminal the current version as:

Next, using Near CLI we will log into the Near Testnet with the following:

When we run this, a browser screen should pop up indicating a login request at “rpc.testnet.near.org”, which should (if you opened your near account correctly) ask that you approve the login transaction.

Once approved, you will see a screen indicating that your login was successful and that you can now close the browser window and return to VSCode terminal. In the terminal, there is a clear message that you are logged into Near CLI using the stated .testnet address:

Great! So we have a Near wallet account (myaccount.testnet) along with the CLI installed, we’ve already logged into the Near testnet, and we’re now ready to start a new project in VSCode which will contain our project directories.

NOTE: Although there is already an NPX package to create a Near boilerplate containing Rust or AssemblyScript starter kits (with React), I have simplified this process quite a bit in this tutorial by eliminating JavaScript testing methods and avoiding Node dependencies such as Webpack, Babel, Jest, Nodemon, ShellJS and a few others. I think in some cases these don’t always work together right out of the box, and we can avoid time diagnosing JS/NPM errors and instead focus on our Near deployment.

For our Near smart contract, we will create this project from scratch and write the unit tests in Rust. We will use the latest Parcel and React exclusively for the front-end later on in Part 3. I hope this approach will make things slightly easier for the new Near developer as a result!

So in your VSCode terminal, we will start with making a new directory as follows:

Within this main directory, let’s make a folder called “contract” which will contain our Rust code and build files like so:

Inside this ‘contract’ directory, we will need to do two things — initialize a new Rust project using Cargo, and write a few useful scripts for building and testing our Rust code before we compile to WASM.

Inside ‘contract’, enter the following:

As we can see, this creates an empty Rust project and provides us with what we need directory-wise to start writing our smart contract. The “src” folder contains the Rust files, while the “cargo.toml” will specify some requirements and dependencies for our project.

Before we proceed with our Rust code, there is one important thing we will need to add to our Rust configuration to be able to compile our contracts correctly, which is the WASM target for deployment. Enter the following in the terminal:

Once we do this, and our directory is ready for Rust, let’s create some simple shell scripts we will need to perform simple build and testing terminal operations within this “contract” directory. We will create the following scripts:

build.sh

build.bat

test.sh

After these scripts are created, our “contract” directory should look like this:

We won’t worry about the cargo.lock file for now, but we will want to edit the cargo.toml file with the following:

Once we have this directory structure set up, let’s create one final directory in our “contracts” folder:

Our final “contract” directory structure is:

Now our Rust environment is set up and we’re ready to write our smart contract for Near!

Starting our Near smart contract

Let’s examine the “src” directory within our main “contracts” folder.

Inside, there is a starter Rust file named “lib.rs” — open this file in VSCode and let’s briefly look at it:

All this does at the moment is run a simple test function, and if we now run our “test.sh” script (from our “contract” folder root), the file is quickly compiled and tested with the result in the terminal as:

Now we want take our “lib.rs” file and completely overwrite it with the following code below:

Some thoughts and explanation on our ‘Event’ contract.

Now, this is quite a lot of code, and since this isn’t a Rust tutorial primarily, I will leave it to the developer to research what every import, struct and function does in this file.

One important point concerning Rust macros and the Near SDK — just like Solana, Elrond and other Rust-based blockchains, the SDK handles a substantial amount of abstraction (which means it “wraps” and greatly abbreviates your code). If we were to type all of what the code above does in low-level Rust, we would have many more lines of code to write, and it would be much more intimidating for onboarding.

To briefly sum up what our smart contract is doing, this project creates a simple app for listing proposed events with Title, Description and a suggested Budget. These events can be created by anyone signed into the app using their Near wallet, and then anyone signed into the app can also Vote on the proposed events listed.

We will work though some of the details as we create our frontend, as well as suggest improvements to the underlying functionality when we deploy.

But first, let’s add two more Rust files to our project so that we have the necessary crates and models (constants/utility functions) to supplement our main application file.

First, we will create a file called “utils.rs” and save it with the following:

Next, we create a file “models.rs” and save the following in it as well:

Our ‘models.rs’ file contains some important structs (mainly the ‘Event’ struct and its implementation block) to import into our main “lib.rs” file. These can be added to later on depending on other things we might want to feature in our overall contract (such as calendar, progress, treasury or members directory structs for example).

The “utils.rs” file is designed to contain some core variables, constants and functions for various unit conversions. Like “models.rs” this file can also be adapted later on as new functionality is introduced. Right now this file just holds two generic functions to aid Promise and serialization.

After finishing these three files, all of them are in the “src” directory and ready for a preliminary “build” to see if our project compiles and is ready for testing and deployment.

Building the smart contract in Cargo and making sure it compiles.

In the root of “contract”, run the “build.sh” script as follows (this approach will defer between Mac and Linux — in Linux you don’t need “bash” before the terminal command, on Mac you proceed like below) :

After a brief waiting period for Cargo to download crates, install all Rust dependencies, compile and assemble everything, we should have a few new things in our “contract” directory.

First, you’ll notice a newly-created “target” folder. This is the standard Rust build folder provided with the Cargo package manager, and it makes output file organization easy and straightforward. Inside this “target” folder are preliminary builds (binaries) of our Rust application, and one of these builds is in a special “wasm32-unknown-unknown” folder.

For now, we can disregard these files in “target” because what we want for the Near Blockchain is the WASM file we specifically copied (automated using our “build.bat” script) to our other build directory — the one called “res”.

Inside “res”, we see one file “near_starter_dapp.wasm” and this is the file we will need to eventually deploy on Near. We actually copied this from “target” for convenience, so we don’t have to dig several levels deep through our target/build directories to find this file every time we make a change and re-compile.

A quick note on error messaging in Rust: you may have done a preliminary build (which shows completed) and yet you still see numerous warnings in the terminal (accented in yellow). Don’t worry, we still compiled our contract successfully! If there were any “red” warnings you would see more serious errors and the project would not compile until addressed. For now, this is totally fine:

As we move forward with our projects with a recent, stable version of Rust, the Cargo package manager and rustc compiler will work hard to tell you what optimized, current and correct code is. Some of the warnings will be related to versions of the Near SDK we specify in “cargo.toml”, while others have to do with slightly older syntax or Rust versioning itself.

Next steps for our tutorial, and end of Part 1.

Without going into too much more technical detail for this example — we have used some methods/macros from Near SDK version 3, while others (for the tests in our next chapter) will use a new, improved “VMContext” builder (a test simulation environment macro) from the Near SDK version 4 which is still currently under development. For our case overall as indicated in “cargo.toml”, we can keep the SDK version as “4.0.0-pre.4” for this entire tutorial and not have to downgrade to the earlier version used in most tutorials out there.

Speaking of testing, why not write a few unit tests right now in Rust that we can run before our final WASM build so we know it does what is required?

Fortunately, writing our tests in Rust is very easy, and of course we already have our test script (test.sh) ready on our “contract” root once unit tests are added to our our main contract file (lib.rs). Also, for numerous reasons it’s preferable to write our tests in the native language we use to write our contracts (in our case, Rust) so we can learn from Cargo and the compiler early on whether our code runs correctly, or we need to tweak it before we compile it down to our “release” file in WASM for contract deployment.

In the next part of this tutorial, we will write some Rust unit tests, run them against our smart contract, create a deployment sub-account in Near-CLI, deploy our contract to Near Testnet, and actually be able to interact with it in the console before we proceed to our React front-end integration in Part Three.

I hope you enjoyed the first part of this three-part series introducing the Near Protocol to new developers like you!

Thanks for reading, and see you next time… — Panasthetik.

Resources:

--

--

Panasthetik
Coinmonks

Web3 Developer and Researcher — Blockchain, Generative Art, Decentralized Identity.