How to build a Web App using Blockchain — Part 3

Christophe Verdot
6 min readApr 19, 2020

--

In the previous article, we built together the html of the index page, our settings and getData classes, our index javascript logics and were able to get an index page displaying data from a Waves Blockchain Data Storage.
If you didn’t read the previous parts,
please start there.

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

G) CREATE THE ADMIN HTML

To get the step 3 code click here.
To get the complete web app code click here.

Now let’s work on the admin page, this page is accessible with the localhost:3000/admin route and display a button “start” which will open Waves Signer popin to let you ether create a new Waves account if you don’t have any yet or choose an existing one.

THE ADMIN VIEW
https://github.com/christopheSeeka/covstats-tuto/blob/step3/views/admin.ejs

Go to the ./views/admin.ejs file and change the content with the following one from this page.

Similarly to the index page, we first include all our needed libraries and css in the <head>.
We have a sort of header (where i could have used a <header> :)) with the title, the description and links to homepage or to waves.exchange. Waves.exchange is where you needs to go get your seed (if you just created an account) or get Waves token to pay transaction fee.

We use here the bootstrap basic accordion element separated in two blocks:

  • Block 1 is where you manage the title and description of the page
  • Block 2 is where you add or edit entries cases

You would see a <div id=”loader”> in the code which will be used as overlay element when we are waiting for data (when we select an existing entry in the “identifiant” <select> for example)

Something to keep in mind, when we add a new entry, the identifiant list wont be available untill the transaction get at least 1 confirmation (no worries, it’s super fast on Waves).

At the bottom we include our javascript logics bundle call, remember?:

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

H) THE ADMIN JAVASCRIPT LOGIC

https://github.com/christopheSeeka/covstats-tuto/blob/step3/src/admin.js

First we needs to add two new libraries here, Waves Signer:

npm install @waves/signer

And the Provider Web:

npm install @waves.exchange/provider-web

These two libraries are required to login with your Waves account and sign every transactions, in the admin page we will use the invokeScript transaction to update infos and to add/update entries.

Now go to ./src/admin.js and replace the content with the content from this page.

We will go quickly over it but only focus on what is related to the dApp calls.

First we import our libraries and classes then to configure Waves Signer we do the following:

Remember, getdata.nodeUrl is getting the nodeURL we entered in our settings.js, we are using a testnet url, for mainnet or stagenet it would be a different url.

Same with the providerUrl used for new Provider(), it also come from our configuration file.

After that we see a resetForm, pretty self explanator, same for displayAlert.

Then we have 4 important listeners:

The “change” event

Listening over the <select id=”identifiant”> element and called every time we choose a differet option in this <select>, here its quite simple, ether we select an existing option and it mean we are updating an entry or we leave it as “New entry” which have the value = 0 and it means we create a new entry.

When we choose an existing entry, this listener will automatically retrieve all the info with our getdata.getDataByKey() method with the proper key as argument and display the data in the different fields.

We could just have retrieve the json entry (you will see that in the next part) but i wanted to show you a different way, getting each separated data from our Node API.

The “login” event

This one is linked to the <button id=”login”> element and is calling the Waves Signer method signer.login() which open the signer popin where you create/choose your account. Once you select an account, the callback will:

  • Get the name/title of the page and display it
  • Get the introduction texte of the page and display it
  • Retrieve all the entry id associated to your address and populate the <select id=”identifiant”> element with it

The Waves Signer login method work as follow:

The “addEntry” event

This is called every time <input id=”addEntry”> is clicked, the callback will define if we add a new entry or update an existing one, based on the <select id=”identifiant”> selection. Then it will create the needed parameters for our invokeScript transaction, which is the transaction type we needs on Waves Blockchain to call our dApp Smart Contract function (that we will create in part 4 of this series).

Here our data object:

dApp is the address of the dApp account with our smart contract attached to it, we pass here the dappAddress that we get from our settings.js file

call.function this is the name of the function we want to call on the Smart Contract/dApp account, here it’s addUpdateCase

call.args is an array of object with all the different data from our form that needs to match the parameters of the dapp function (in exact order) we are calling, note that you needs to define the type (integer, string, boolean or bytearray) aside of the value.

Once our data are ready, we will sign these data and broadcast them to the Blockchain through the Node API.

To sign data with signer you just have to use the following:

Basically, you use the invoke method of Waves Signer (each transaction type have its own method), you call this invoke method with your data object as parameter and then you attach the broadcast() method right after it.

Signing data don’t send them to the blockchain, it only sign the data with your private key (you sign with your Waves account), once you signed, you needs to send these data to the Blockchain, which is what broadcast is doing.

Since its a promise, you simply can add your .then() and .catch() after broadcast() to do your stuff once its sent.

You will see a checkStateChange function too in my code, i wont go over it for now as i don’t want overcomplicate things, in short, its because since we added a new entry, we need to wait it to be confirmed and then update or <select id=”identifiant’> list.

The “accountInfo” event

This one is called when you click on the <input id=”accountInfo”> element, in the first form of our accordion element, to update the title and description, it work exactly like the previous event, meaning it create a data object with data and use the same dApp address.

The call.function here will change, we want call another one, which is “updateInfo” and then the call.args will simply get the title and description data from the form fields.

We sign the data with signer.invoke() method again, we broadcast it and we clear the form once its done.

At the end of the ./src/admin.js file you’ll see a loadResize function, this is juste to adjust the layout on different screens.

You should now be able to go to localhost:3000/admin, click on “start” and login with your account (or create a new one), if you don’t have any testnet waves token, go get some here.

Try to enter a “Page name” and “Introduction” once connected, then click UPDATE INFOS, after that, click on “ADD OR UPDATE ENTRY” to switch tab and fill the form, click on ADD NEW CASE, once its done, you should see your data at localhost:3000/your_waves_address

If you want configure the Web App on your Waves Address, you can change this.userAddress in settings.js with your own address (the one you used to add an entry); then localhost:3000 will directly display your data.

And that’s it for our STEP 3!! Almost done! we have one more step to go!

In STEP 4 we will see the dApp Smart Contract, go over it together, see how to deploy it then we will configure our Web App to use this dApp instead of the current one.

The STEP 3 code:
https://github.com/christopheSeeka/covstats-tuto/tree/step3

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/

--

--

Christophe Verdot

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