Build a Decentralized Todo App Using Vue.js & Rust (WebAssembly) via Wavelet (v0.1.0)
One of the first tutorials you come across when learning a new programming language is to build a Todo App. While some think it is reinventing the wheel to build one, one can get a grasp of how the framework/libraries work.
Here is the final working product: https://wavelet-todo.surge.sh in case you are in a rush :)
This tutorial adds a bit of twist to the normal Todo App by making it decentralized on the Wavelet blockchain, as a decentralized app (Dapp).
Why, you might ask, do I have to build a Dapp and store data on the blockchain, when I can just store my data with the conventional database?
With this in mind, we can build apps that are resilient and secure on the blockchain. As a developer, one only have to worry about code, and less about infrastructure security hardening.
Well, let’s start to create a decentralized todo list :)
If you are not familiar with Vue, you are most welcome to use other frameworks that suit your workflow or infrastructure (e.g. React, Angular etc.).
Here is the basic scaffold we will build upon:
We will be adding in code to link up this frontend to the backend (via Wavelet smart contracts) in the next section. So don’t move away yet!
Backend (on the Wavelet blockchain!)
Think of the backend for our decentralized todo app compared to the conventional as follows:
Node JS HTTP Server => Rust Smart Contract
Database (MySQL, Postgres, MongoDB etc.) => Wavelet (blockchain)
Getting some PERLs
First things first, in order to deploy and run smart contracts, you will need gas. You can think of gas as the cost for hosting/server rental, where it is calculated according to the machine CPU and memory consumption of your app. (Note: Wavelet’s testnet is live, however, the fees for invoking smart contracts racking up to 250,000 PERLs is in no way representative of how expensive smart contracts will really be when Wavelet is fully decentralized and publicly open)
You can get PERLs from the testnet faucet on Discord: https://discord.gg/dMYfDPM
Preparing to write the contract
You may refer to the steps here for setting up Rust and writing your first Wavelet smart contract.
Writing the contract
As we are writing a Todo Dapp, we have several additional functions implemented compared to the Decentralized Chat app. We would need the following features:
- Removing a Todo
- Toggling the ‘done’ status for each Todo
Here we have the full smart contract written out like the following:
89 lines of code. Small, eh? To explain what’s going on here:
The smart contract exposes four functions that may be called by our frontend: get_todos(), add_todo(content: String), toggle_todo(id: uint32) and remove_todo(id: uint32).
The String param for add_todo(…) is read using the param.read()function when declaring the todo variable. For more details on how inputs are specified into smart contracts, click here.
Todos are stored in a VecDeque (a double-ended queue where you can push items to the front of the queue, or to the end of the queue), which is initialized in init().
Each todo contains a content field.
You call add_todo(…) to place a todo into the logs queue. Empty todo descriptions are not allowed, and todos may at most be 250 characters.
The logs queue has a capacity of at most 20 todo entries. Should the queue be full when a new chat log is to be inserted into the queue, the queue removes the oldest todo using logs.pop_front(). This logic is handled in the prune_old_todos() function.
You may call get_todos() to get a human-friendly readable version of a chatlog. Sender ID’s get printed out as a hex string, and are concatenated with the senders message contents.
Then a log!() macro is used to have the smart contract provide to your frontend all available chat messages from get_todos().
You call toggle_todo(…) to toggle the done boolean variable which indicates whether you can completed the todo.
You can also call remove_todo(…) to remove the todo from the Todo queue.
Let’s now build our smart contract using Rust’s Cargo tool:
❯ cargo build --release --target wasm32-unknown-unknown
… and if everything goes well, in the
target/wasm32-unknown-unknown/release folder, you will see a
That is your smart contract, ready to be deployed on Wavelet’s blockchain.
Deploying the contract
You may refer to the steps here for deploying the contract you just wrote on the Lens platform. You can test out the functions you wrote on the Lens platform first, before integrating it to the frontend. Make sure to replenish your wallet with PERLs after invoking calls!
Linking up the Frontend and Backend via Wavelet JS Client
In this section we will provide you with the glue needed to stitch the frontend and backend together.
Building on top of the scaffold we had in the previous section, we need to make a few changes to the main.js and App.vue files.
Note that in order to make the todos update after they are added/removed/toggled, you need to poll for updates (in Wavelet, that is consensus changes). Add the following inside the load() method:
Up till this point, you have built your very own decentralized Todo Dapp, with an awesome and even awesomer (is there a word like this?) backend! Give yourself a round of applause!
Here how it looks:
Congratulations, you just made your very first, scalable, secure Wavelet Dapp!
There is a lot more to explore, such as a plethora of additional functionalities provided by the Wavelet JS client, alongside an extensive set of documentation for Wavelet located at https://wavelet.perlin.net.
Source code for the full tutorial is available here: https://github.com/johnhorsema/wavelet-todo