How to build a Web App using Blockchain — Part 1

Christophe Verdot
10 min readApr 19, 2020

--

When i started to develop a Web application using Waves Protocol, i was a bit lost, Blockchain was new to me and it was hard to find examples from a Front End Web Developer point of view. In this serie, we will develop a complete Web App from scratch. (see the end project running here: https://covtest.sign-web.app/)

PART 1
a) Define the project
b) Why use Blockchain?
c) Initiate the project

PART 2
d) Create the HTML for your INDEX views
e) Create a GetData and Settings Classes
f) Create the Index javascript logics

PART 3
g) Create the HTML for your ADMIN views
h) Create the Admin javascript logic
i) Integrate Waves Signer

PART 4
j) Create the Smart Contract
k) Deploy the Smart Contract
l) Conclustion

In this article series i want to show you that despite the possible complexity of the overall Blockchain technology, developping a web application using Blockchain is still quite accessible for a front end web developer.
Of course it helps to understand in details every aspects of Blockchain (blocks, transactions, asymetric keypair etc.) but it is not necessary needed to start building.

Simply imagine things like this:
Webapp > API > Middleware > Database

Thats it, Webapp is your regular web interface, API will be offered and accessible via the public Node (you could have your own node later eventually), the Smart Contract will act as a middleware and the data storage of the blockchain will be your database.

If you know how to use an API and install libraries, then all you needs to learn is RIDE (Waves programming language) and it’s really easy, especially in most projects, the Smart Contract often only represent a small piece of the work, everything else will be what you know already eg. the HTML / CSS, Routing, API calls etc.

A) DEFINE THE PROJECT

To get a concrete example, we will build a simple web application tracking COVID19 Data for any entity eg. University, Hospital, City etc.
Keeping track of the COVID cases will be a necessity for upcoming months untill it disappear completely so it will be a good example for this tutorial.

You can find the working Webapp here:
TESTNET: https://covtest.sign-web.app/
MAINNET: https://cov-stats.sign-web.app/

The main idea is to have a web app that display a front page with all the tracking data like chart, filters, table etc.

And a backoffice to administrate these data

The webapp will use a dApp (Smart Contract) on Waves Blockchain to validate and store these data.

The webapp will also use Waves Signer library to allow any Waves account to sign transactions.

When you use a Blockchain, you needs what we call transactions, these transactions carry your data and are sent to the nodes through the node API and then are included in blocks, these blocks are linked together one after the other and it is what make the Blockchain, a chain of blocks. Smart Contract verify the validity of these transactions.

There is no fee in our project aside of the regular transaction fee going to the miners and that are needed to process any transaction on Blockchain.

The web app will offer two options for anyone to have their own tracking page:

  • You can simply use the main entry point:
    https://covtest.sign-web.app/ (for TESTNET)
    and click “EDIT PAGE” button, here you will connect with your Waves account and start adding data. Your page will then be accessible with your data only at https://covtest.sign-web.app/{your_waves_address}
  • You clone the repository from Github and install your own version on your server, you will edit settings.js with your owner address (Waves account used to add data) and the dApp account. dApp account can be ether the public dApp address 3N5NLAqd9w7sNuUnjfWq7mzW3bherD6uZmn (for TESTNET) or your own dApp address (you will then deploy the smart contract on it).

Any entity can then host its own web app or use the public one and display their official Waves address + link to this tracking page into their official website.

Having this link and address on official website of the entity you know then that the data are officials.

B) WHY USE BLOCKCHAIN?

Why would we choose to use blockchain for this? There is several reasons and you should always ask yourself “why blockchain” before starting, blockchain is NOT the answer to everything, it is slower than centralized database, data are public and immutable and it involve transaction fees.

  • We want give opportunity to anyone to see the data in real time and track any possible changes in a totally transparent manner
  • We won’t have to develop a GET API or a secured Login/Account system, both will be available by default with Waves Signer / Waves Account and the Blockchain Node API
  • We want give opportunity to anyone with a Waves account to start its own tracking page easily
  • We want these data public, immutable and decentralized for future reference
  • With all the above, an entity using the dApp cannot modify any data to claim different results later or shut them down in weeks, months or years

C) START A NEW PROJECT

To get the code of the step 1 click here.
To get the code of the full web app click here.

Keep in mind that this project is open source and available for anyone to use but the main goal when i built it was education.

I limitate the use of libraries/tools like Typescript, Sass, Waves Transactions, Surfboard as well as framework like React or Vue (i prefer work in Vanilla JS in general anyway).
I also limitate the code splitting in several files or anything that would over complexify the structure because the goal is to keep it accessible to any front end developer level as well as helping understand as much as possible what really happends.
I heavily commented the code on that purpose.
This project can most certainly be improved.

In this tutorial, i’m going to build the webapp using the following technology and libraries:

For the webapp :

  • VSCODE as ide
  • NodeJS and ExpressJS for the routing & architecture
  • Webpack & Babel to allow us working with es6
  • Nodemon to simplify the process
  • HTML / CSS and Bootstrap for the views
  • Vanila javascript for the programming logics
  • Waves Signer for the signature of transactions
  • Jquery, DataTables and CanvasJs for data display and graph
  • Sanitize-html to sanitize the data we receive from data storage

Lets start!

Let’s first install all the needed libraries, of course i assume that you already have nodejs and npm installed here, if not please follow these steps

Create a new empty folder and do a right click in it “open with Code”, this will open the VSCODE editor.

From there, in VSCODE, open a terminal and type the following to install Express JS:

npm install express -g

Now, we will initiate the new project with:

express --view=ejs .

We are simply telling express to create a new project using EJS as view engine, the . mean we create it at the root of the folder we are currently in.

You should now have the following files and folders structure as well as a ready to use app.js file:

To install dependencies just use the following command:

npm install

We now needs to install Webpack and Babel that will allow us to work in es6:

npm install webpack

In your packages.json, modify the scripts section as follow:

"scripts": {
"start": "node ./bin/www",
"build": "webpack -p",
"watch": "webpack --watch"
}

We have 3 scripts here, “start” is the regular npm start that lunch our webapp, “build” will use webpack to compile our es6 javascript into es5 bundle and “watch” will watch any change and compile without the needs to lunch a build command manually each time.

Now, we will install babel:

npm install -D babel-loader @babel/core @babel/preset-env babel-polyfill

Now, create a file named webpack.config.js at the root of your project and add the following:

As you can see in the entry section of this file, we will needs to create a ./src folder with two files, main.js that will be the javascript code for our index page and admin.js that will be the javascript code for the admin page, the admin page is where anyone will be able to connect with a Waves account and manage data related to this account.

In the output section, the compiled code (from EcmaScript 6 to EcmaScript 5) will be renamed as bundle-[name].js and save in the public/javascripts folder, all your front end assets will be in this ./public folder, meaning:

./src/main.js will compile as ./public/javascripts/bundle-main.js
./src/admin.js
will compile as ./public/javascripts/bundle-admin.js

Please create a ./src folder then in this folder, create 2 files, main.js and admin.js, leave it empty for now.
./” represent the root of your project, don’t include it in the folder name :)

You will also notice in this webpack.config.js file the use of babel loader, for this, we will also have to create another file at the root of our project and call it .babelrc don’t forget the . at the begining.

In this .babelrc files, simply add the following:

{
"presets": ["@babel/preset-env"]
}

We also needs a couple more libraries to avoid runtime errors on async/await:

npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime

Update your .babelrc as follow:

{
"sourceType": "unambiguous",
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-transform-runtime"]
}

You can now simply write in the console:

npm run watch

On first run it will ask you the following:

Do you want to install ‘webpack-cli’ (yes/no)

Just type “yes”

You should see the following, which mean everything is working as expected and the files are compiling:

Open a second terminal (you want keep the webpack watch terminal running) and we will install another important library to simplify our development, type:

npm install -g nodemon

Then just type the following in terminal to run nodemon:

nodemon

Nodemon is a very convenient tools that will restart your server after every changes in any file. We have now 2 terminals running, one with webpack watching your files and one with nodemon restarting the server everytime a file change.

Now your files structure and packages.json architecture should look like this:

Lets now create our routes, route will define what happens when we call a certain url. By default, we have 2 routes in ./routes, index and users.

The index is as follow:

We dont needs users route but an admin route, lets rename the ./routes/users.js file as ./routes/admin.js then change the content as follow:

Im not going to explain everything when it come to nodejs / Express or even the regular javascript i’m going to write later, it is out of the scope and would take too long but remember you always can ask questions in comments section and there is plenty of tutorials already on these matter.

Now go back into your app.js and change your routes related code as follow:

We change line 7 as:

var indexRouter = require("./routes/index");

line 8 as:

var adminRouter = require("./routes/admin");

line 22 and 23 become

app.use("/", indexRouter);
app.use("/admin", adminRouter);

And added at line 24 the following:

app.use("/*", indexRouter);

In short:

  • If we call webapp_url/ or webapp_url/* it will use the index Router (./routes/index.js) which will render the index view (./views/index.ejs)
  • If we call webapp_url/admin it will use the admin Router (./routes/admin.js) which will render the admin view (./views/admin.ejs)

webapp_url/* where * represent anything (anything else than admin since a route is defined for admin) and we will use it as * = waves address, a parameter we will needs to display data for any waves account.

So then we needs to also adjust our views.

Open the ./views/index.ejs and change the content with:

Simply duplicate ./views/index.ejs for now and rename it as admin.ejs, in this new file replace “index” by “admin” in the texte.

Notice that we added the following right before the </html> of the ./views/index.ejs file:

<script src="javascripts/bundle-main.js"></script>

Change it into ./views/admin.ejs for the admin view file:

<script src="javascripts/bundle-admin.js"></script>

If everything is working as expected, you can now access your webapp at localhost:3000

If you want adjust the config and change the port for example, go to the ./bin/www file

Test that everything is compiling as expected, for that, go to ./src/main.js and type:

console.log(“Index Rock!”)

Save the change and go back to your webapp, localhost:3000, click right then “inspect”, go to console tab and you should see there “Index Rocks:”.

Try the same with ./src/admin.js and type:

console.log(“Admin Rock!”)

Save it and go to localhost:3000/admin, check the console!

If both message are showing, then you Rock too! You completed the first step on how to create a Webapp using Waves Blockchain Protocol and have your architecture ready.

The STEP 1 code:
https://github.com/christopheSeeka/covstats-tuto/tree/step1

The complete web app code:
https://github.com/christopheSeeka/cov-stats

The webapp example on TESTNET:
https://covtest.sign-web.app/

The webapp on MAINNET:
https://cov-stats.sign-web.app/

In the upcoming STEP 2, we will work on the html and javascript logics of the index page, stay tuned!

--

--

Christophe Verdot

Web Developer - Waves Platform France Tech Ambassador— Waves Platform Lead for Philippines - Signature Chain founder and Lead Developer / signature-chain.com