In this tutorial I will show you step-by-step how to create your first front end to interact with a smart contract deployed at RSK testnet, using only Javascript and HTML and connected to a wallet using a web3 provider.
RSK is an open-source platform for Ethereum compatible smart contracts based on the Bitcoin network.
Below is a summary of the steps to be taken to build our front end:
Steps 1 to 4 are explained in detail in the tutorial link below:
As earlier mentioned, to install Metamask and connect to RSK testnet and to connect Remix with RSK Testnet are explained in detail in the tutorial link below:
Node.js and NPM are needed, though both are usually installed at once.
NB: To check if Node.js and NPM is already installed, input the following commands in the terminal:
node --version
npm --version
Go to Node.js if you need to install it.
In this tutorial, we would use VSCode to create and deploy our project.
To use VSCode, download it here .
Verify if your VS code installation was successful by typing the following command into the terminal:
code -v
Create a folder named Register, and start an npm project in the Register folder by typing the following commands below into the terminal:
mkdir Register
cd Register
npm init -y
For example, I will create a folder at this location: C:\RSK\
My project can be located in the folder C:\RSK\Register
Express is a Node.js web application framework that helps to develop web applications. It is a minimalist HTTP server.
To install Express, input the command below into the terminal and press `enter` at your project location:
npm install express --save
More info:
https://www.npmjs.com/package/express
Web3.js helps us to develop websites or clients that interact with the blockchain - writing code that reads and writes data from the blockchain with smart contracts.
The web3.js library is an Ethereum Javascript API which connects using the generic JSON-RPC spec. As RSK's virtual machine implementation is compatible with the Ethereum Virtual Machine (EVM), it is possible to use web3.js to do the communications between the front-end and the RSK testnet.
To install web3.js, input the command below into the terminal and press enter at your project location:
npm install web3 --save
More info:
https://web3js.readthedocs.io/
`package.json` is a file created by npm with some configurations, including the packages which we installed before using the command `npm init -y`.
After the installations, I will open the project folder named Register in VSCode and verify the file package.json. Let's take a look at the dependencies in the file:
You will find the previously installed packages:
"dependencies": {
"express": "^4.17.1",
"web3": "^1.2.6"
}
This is explained in detail in the tutorial:
I will resume it here:
Remix
Go to Remix
Create a smart contract
Create a new file
File name: Register.sol
Copy and paste the smart contract from the following gist, or copy and paste the code below:
pragma solidity 0.5.4;
contract Register {
string private info;
function setInfo(string memory _info) public {
info = _info;
}
function getInfo() public view returns (string memory) {
return info;
}
}
Register.sol
This smart contract has:
In the 3rd button at the left side select Solidity compiler and click in the button Compile Register.sol.
In the left side panel, go to the button Deploy and run transactions.
Under Environment, make sure you have selected the Injected Web3 option, as this tells Remix to use the Web3 provider injected by a browser plugin such as MetaMask or Nifty.
Then click the button `Deploy`.
Ensure that you have tR-BTC in your wallet, as this is needed to pay gas fees when deploying the smart contracts. To do so, please follow this guide: Using remix and metamask with RSK Testnet.
When a smart contract is deployed with Remix, we can see it in the left panel under deploy and run transactions. Click on the copy button at the right side of the smart contract to copy the address of the smart contract. We will need it for use on the front end.
In my example, the contract address is `0xc864D0fef177A69aFa8E302A1b90e450910A4c3E`.
Now let's start building out the front end that will interact with the smart contract. We have only 2 files in the front end:
In the Register folder, create the file index.html
Copy and paste the smart contract from the following gist, or copy and paste the code below:
<!DOCTYPE html>
<html >
<head>
<title>Register information at Blockchain</title>
<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' type='text/css'>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="./node_modules/web3/dist/web3.min.js"></script>
<script src="./index.js"></script>
</head>
<body class="container">
<h1 class="page-header">Register information at Blockchain - RSK network</h1>
<div class="row">
<div>
<h3 class="sub-header">Set information</h3>
<form class="form-inline" role="form">
<div class="form-group">
<table>
<tr>
<td><label for="newInfo">Info:</label> </td>
<td>
<input class="form-control" id="newInfo">
</td>
</tr>
</table>
</div>
<a href="#" onclick="registerSetInfo()" class="btn btn-primary">Set</a>
</form>
</div>
</div>
<div class="row">
<div>
<h3 class="sub-header">Get last information saved</h3>
<form class="form-inline" role="form">
<a href="#" onclick="registerGetInfo()" class="btn btn-primary">Get</a>
<div class="form-group">
<table>
<tr>
<td>Info:</td>
<td>
<label id="lastInfo">
</td>
</tr>
</table>
</div>
</form>
</div>
</div>
</body>
In the Register folder, create the file index.js
Copy and paste the smart contract from the following gist, or copy and paste the code below:
// Source code to interact with smart contract
// web3 provider with fallback for old version
window.addEventListener('load', async () => {
// New web3 provider
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
// ask user for permission
await ethereum.enable();
// user approved permission
} catch (error) {
// user rejected permission
console.log('user rejected permission');
}
}
// Old web3 provider
else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
// no need to ask for permission
}
// No web3 provider
else {
console.log('No web3 provider detected');
}
});
console.log (window.web3.currentProvider)
// contractAddress and abi are setted after contract deploy
var contractAddress = '0xc864D0fef177A69aFa8E302A1b90e450910A4c3E';
var abi = JSON.parse( '[{"constant":true,"inputs":[],"name":"getInfo","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_info","type":"string"}],"name":"setInfo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]' );
//contract instance
contract = new web3.eth.Contract(abi, contractAddress);
// Accounts
var account;
web3.eth.getAccounts(function(err, accounts) {
if (err != null) {
alert("Error retrieving accounts.");
return;
}
if (accounts.length == 0) {
alert("No account found! Make sure the Ethereum client is configured properly.");
return;
}
account = accounts[0];
console.log('Account: ' + account);
web3.eth.defaultAccount = account;
});
//Smart contract functions
function registerSetInfo() {
info = $("#newInfo").val();
contract.methods.setInfo (info).send( {from: account}).then( function(tx) {
console.log("Transaction: ", tx);
});
$("#newInfo").val('');
}
function registerGetInfo() {
contract.methods.getInfo().call().then( function( info ) {
console.log("info: ", info);
document.getElementById('lastInfo').innerHTML = info;
});
}
This part connected to RSK testnet using the wallet injected, in our case, Metamask:
window.addEventListener('load', async () => {
// New web3 provider
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
// ask user for permission
await ethereum.enable();
// user approved permission
} catch (error) {
// user rejected permission
console.log('user rejected permission');
}
}
// Old web3 provider
else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
// no need to ask for permission
}
// No web3 provider
else {
console.log('No web3 provider detected');
}
});
console.log (window.web3.currentProvider)
Did you remember the address of the smart contract that you copied after deploying it?
It will be updated here:
var contractAddress = '0xc864D0fef177A69aFa8E302A1b90e450910A4c3E';
In the Register folder, create the file server.js
var express = require('express');
var app = express();
app.use(express.static(__dirname));
app.listen('3300');
console.log('Running at\nhttp://localhost:3300');
This file configures the express HTML server.
The last step is to execute the express server. Input the command below into the terminal.
node server.js
In your browser, go to:
Click on the Connect button when the Metamask Wallet pops up:
Get
Click on the Get button.
The web3 instance will call the
setInfo()
function on the `register` smart contract instance, with the info that you entered into the text field.We do not have any information stored, because we did not specify an initial value in the smart contract.
Set
Enter any value in the info text field, and click on the Set button.
The web3 instance would call the
setInfo()
function at the smart contract instance register, with the info that you defined.Wait a few seconds for the transaction to be included in a block...
getInfo
(again)Now we have the value “RSK” saved, and we can check it.
Click on the Get button again
And it returned the info “RSK”.
Great! Now we have information stored in our smart contract, and we can retrieve it!
Note
You have successfully built and deployed your first decentralized application (DApp) powered by RSK smart contracts!
You can download the full source code to this tutorial here:
Satisfied with this tutorial? I’d appreciate your feedback and you can share it :)
Check out the RSK developers portal.
We have run a webinar in which we run through this tutorial, in different languages:
|
Ask in RSK chat.
Author: Solange Gueiros
Reviewers: Brendan Graetz and Owanate Amachree