In this guide, you’ll learn all you have to take a web app and convert it into a dApp. This tutorial is perfect for people who have some experience creating Smart Contracts however don’t know how to really apply their knowledge to make something useful with a dapp. So let’s start.

ICOs, Smart Contracts, Mist, Remix, Metamask, geth, web3. You’ve most likely seen it all if you invested a little time attempting to get into the world of Ethereum development.

Some deploy Smart Contracts to a test network, others instruct you to read a yellow paper, while others encourage you to utilize the truffle suite since it’s extraordinary. And you are there, not knowing what precisely to do and how everything cooperates.

This is the 2nd part of the blog series which contains following chapters.

Develop a Smart contract in solidity and deploy it in one of the test networks Automate the testing and deploying your Smart Contract in a real network( Rinkeby Network ) — ( this post ) Build a front-end web layer to interact with that Smart Contract. Deploy the Smart Contract on your own multi-node Ethereum network

If you haven’t gone through the first part, I recommend you to skim through the Part 1 and start following this post. If you are comfortable with Smart Contract development in Ethereum and solidity, then you can jump into this post.

We are going to use the same Smart Contract that we have developed in the first part. In this post, we are using the Truffle framework to Contract creation , local testing and the deployment. Ultimately the Smart Contracts would get deployed into the Rinkeby test network for real testing.

The Truffle framework contains a great tool set to perform many Ethereum operations but still lots of development going on with it even now. The framework is considered not that stable. So you need to brace for failures when you are working with such a framework.

Setting up the Testing and Deployment Environment

In the previous post, we have used the Remix online IDE to create our Smart Contract and used its own testing environment as well. An online IDE is not going to be enough when you are working in a production grade real application.

Setup the following folder structure in your local machine to continue with. No need to add anything to the files , just leave them blank for the time being.

Image 1 : Folder Structure

I am using Linux as the OS and VS Code as the local IDE. But you can use any OS or any IDE in your liking.

Go to the root of your project folder and execute the npm init command. This would initialize all required file structures and required libraries. Provide default values to all required params.

As the next step we need to configure the compiler. We are going to use the solidity compiler to compile our Smart Contract.

> npm install — save solc

Next, we need to copy and paste our Contract code from Remix to the multiauth.sol file.

Then we need to create our compile.js file as below.

const path = require('path');

const fs = require('fs');

const solc = require('solc');



const sourcePath = path.resolve(__dirname,'contracts','multiauth.sol');



const source = fs.readFileSync(sourcePath,'utf8');



console.log(solc.compile(source,1));

This compiling script reading the source file and compile it using the solc compiler.

Save the compiler.js file and run the compilation command as below.

> node compile.js

If everything goes well, it would give you following output in the console.

Image 2 : Compile output

The compiler outputs many attributes such as bytecode , interface and the opcode. If you remember the previous post , I have mentioned that the solidity compiler outputs 2 parts where we can utilize, the bytecode and the ABI( Application Binary Interface ). bytecode in the binary that runs on top of the EVM and the interface is what we are using to integrate the Smart Contract with any 3rd party applications.

Testing the Contract

After the compilation , we need to make sure our compiled Contracts are running properly without any glitches. Remember guys , unlike other programs we are compiling and executing day-to day, the Ethereum Contracts are linked with money. So you need to make sure that there are no bugs in your code because you do not want to end up sending some automated transactions to wrong person.

Manual testing is a less effective and tedious task. Hence, we need to automate the testing process so after any change we can quickly test our Smart Contracts with less effort.

We need to set up a local test network and the Ganache ( formally known as TestRPC ) can be used for this purpose. Ganache would provide the same set of services as in Remix’s test EVM. We are going to use the Web3 library ( which is interacting with the contract’s ABI ) to perform our testing. Following diagram illustrates the testing setup.

Image 3 : Bytecode and ABI interface with Ganache

First of all we need to install the Web3 , Ganache and mocha( test framework ) as follows.

> npm install — save mocha

> npm install — save ganache-cli

>npm install — save web3@1.0.0-beta.26

We are installing the Web3 version 1.0 because it is supporting the async/await calls and promises which are useful for our async programming patterns. The previous web3 versions supports only the callbacks for async code.

In Web3 we need to specify a provider which is responsible for the interfacing with any Ethereum network ( Ganache in our case ). The Mocha framework provides all required testing functionalities such as assertions etc.. Change your package.json file as follows to include mocha framework.( just change the scripts->test attribute.

{

"name": "mutiauth",

"version": "1.0.0",

"description": "",

"main": "index.js",

"scripts": {

"test": "mocha"

},

"author": "",

"license": "ISC",

"dependencies": {

"ganache-cli": "^6.1.4",

"mocha": "^5.2.0",

"solc": "^0.4.24",

"web3": "^1.0.0-beta.26"

}

}

Ganache provides few defaults unlocked ( you do not need to worry about private/public keys of these accounts ) to test our Contracts.

Edit the multiauth.test.js file as follows to list all our ganache local test accounts.

Note that we are executing an empty assertion here just to list down our test accounts.

const assert = require('assert');

const ganache = require('ganache-cli');

const Web3 = require('web3');





const provider = ganache.provider();

const web3 = new Web3(provider);



beforeEach( async ()=> {



// Get list of all accounts

web3.eth.getAccounts()

.then(fetchedAccounts => {

console.log(fetchedAccounts);

});



});



describe('MultiAuth',()=>{

it('contract deployment',()=>{});

});

Image 4 : Ganache testaccounts

You can see that it contains 10 test accounts. There accounts are pre-loaded with enough ETH so we can use them to send money and execute other functionalities as well.

Next, we will deploy our Contract to Ganache and test the deployment process. Before changing the test script, we need to do a small alteration into our compile script. Earlier , we just logged the output of the compile command. In order to inject the this output into the test script, we need to do following change.

module.exports = solc.compile(source,1).contracts[‘:MultiAuth’];

Update the test script as follows.

const assert = require('assert');

const ganache = require('ganache-cli');

const Web3 = require('web3');





const provider = ganache.provider();

const web3 = new Web3(provider);



//get output of the compilers

const {interface,bytecode} = require('../compile');

let auth;

let accounts;



beforeEach( async ()=> {



// Get list of all accounts

accounts = await web3.eth.getAccounts();



auth = await new web3.eth.Contract(JSON.parse(interface))

.deploy({data:bytecode, arguments:[[accounts[1],accounts[2]],accounts[3]]})

.send({from:accounts[0], gas: '1000000', value: '2000000000'});



});



describe('MultiAuth',()=>{

it(' Deployment and log ', async ()=>{

console.log(auth);

});



});

In this test script, we are importing the output of the compile.js file and assign the interface and bytecode elements into a constant. Then we are passing the required params into the contract using the ABI( the interface variable). We need to specify the initial gas amount, the account that we are deploying and the initial value of the Smart Contract.

Finally we are logging the output of the deployment process into the console. If everything goes well, you would be able to inspect the result of the deployment in you console.

Its time to script down some real assertions to test our Smart Contracts. We are going to test following items.

1. The Receiver

2. Contract balance

3. Approval Process

4. Receiver’s final balance

Following is the full test script using assertions.

const assert = require('assert');

const ganache = require('ganache-cli');

const Web3 = require('web3');





const provider = ganache.provider();

const web3 = new Web3(provider);



//get output of the compilers

const {interface,bytecode} = require('../compile');

let auth;

let accounts;



beforeEach( async ()=> {



// Get list of all accounts

accounts = await web3.eth.getAccounts();



auth = await new web3.eth.Contract(JSON.parse(interface))

.deploy({data:bytecode, arguments:[[accounts[1],accounts[2]],accounts[3]]})

.send({from:accounts[0], gas: '1000000', value: '20000000000000000000'});



});



describe('MultiAuth',()=>{



it('Testing Receiver ', async ()=>{

assert.equal(await auth.methods.receiver().call(),accounts[3]);

});



it('Testing The Contract balance ', async ()=>{

const bal = await auth.methods.getContractBalance().call();

assert.equal(bal,'20000000000000000000');

});



it('Testing The Approval ', async ()=>{

await auth.methods.approve().send({from:accounts[1]}); // First approver

await auth.methods.approve().send({from:accounts[2]}); // Second approver

});



it('Testing The Receivers balance ', async ()=>{

const accBal = await web3.eth.getBalance(accounts[3]);

assert.ok(accBal >= 120000000000000000000);

});

});

Execute the following to run the tests.

> npm run test

If all of your tests are passed , you will be able to see a message as following.

Image 5: Test results

Deploying the Contract into a real test network

After a successful test, now we need to deploy the Contract into a real network. In this post we are going to deploy the Smart Contract into Rinkeby network.

Unlike our test environment, the Rinkeby network do not have open test accounts. So first of all , we need to setup few sample accounts in the Rinkeby network. You can easily do this using the Metamask tool.

Install the Metamask tool into your browser and you can create many accounts as you like. To get some Ether to test ( in Rinkeby ) you use the Rinkeby Faucet. All you need to do is publish your account address in a social media site.

To deploy our contract into a real network, we have to have an Ethereum node. But configuring it would not be an easy task and it is out of the scope of this blog post as well. Hence , we are going to use the Infura to deploy our Contracts. Once you get registered , you will be given and API key and endpoints to each of the networks. We are going to those API endpoints to deploy our Contracts.

Following is a high level deployment diagram.

Image 6 : Deployment diagram

Next, we need to write our deploy script. First of all you need to install the Truffle wallet provider as follows.

> npm install — save truffle-hdwallet-provider

Following is the deploy.js code.

const HDWalletProvider = require('truffle-hdwallet-provider');

const Web3 = require('web3');

const {interface,bytecode} = require('./compile');



const provider = new HDWalletProvider(

'<your mnemonic>',

'https://rinkeby.infura.io/<your Infura API Endpoint>'



);



const web3 = new Web3(provider);



const deploy = async () => {

const accounts = await web3.eth.getAccounts();



console.log('Deploying to the Network using account : ', accounts[0]);



const result = await new web3.eth.Contract(JSON.parse(interface))

.deploy({data: '0x'+ bytecode, arguments: [['0x61Ee7fA43ff49d4E9CC680E6031F074bd4BF85c7','0xBdAb9d885443A1D381EF4c03600d80FED63ABf46'],'0x9De226640854E3b2408cDFD486663bEaC3C072EC']})

.send({gas: '1000000', from : accounts[0], value: '2000000' });



console.log('Contract Deployed to : ', result.options.address);

};



deploy();

We are using the truffle-hdwallet-provider to configure the Infura API. Note passing in the Meta mask mnemonic and the InfuraAPI to access our accounts. Then we need to specify the correct argument list and other relevant parameters into the deployment script. Please make sure to to provide valid addresses as parameters because we need to execute the Smart Contract using these accounts.

Finally, we are logging the address that we have deployed our Smart Contract because we need to know where our Smart Contract got deployed.

Image 7 : Deployment output

We can use the EtherScan to analyze where and how your Smart Contract gets deployed. It records all the transactions in the Rinkeby network and presents using an easy to use web page.

To analyze the transaction we did, copy the Contract’s deployed address and paste in the search bar.

Image 8 : Deployed Smart contract details

You can see the Contract’s balance, the block number, address who deployed the Contract etc.. So if we do have a web application ready, then we can interact with this Contract. We are going to to that in the next part of this blog series.

But until then, there is a method that we can test this using the Remix. Open up the Remix tool in your browser and go to the Run tab. Change the environment to Injected Web3. Now you can see that the account is set to the account that you have selected in the Metamask tool and the balance is that account’s balance.

Image 9: Remix Account properties

Copy the address of the deployed Contract into the “At Address” section and then you will be able to load the deployed contract into Remix. You can inspect the balance , requester address etc.. using the Remix tool.

Image 10 : Testing in Remix

Execute Contract’s functionalities using Remix

Now select any approver account from the MetaMask tool. Make sure you are in the connect account using the Account dropdown. Try to approve the Contract by using the approve button.

You would get a prompt from the Meta mask wallet and asking your consent to perform the transaction. So this will send some ether to the target address ( Contract’s address ).

Image 11 : Confirm Metamask transaction

Give some time to mine your transaction ( yes , now you are in a real Ethereum network :D ) and analyze approval status using the approvers button in the contract. You can see that first approver approves the Contract.

Image 12 : Smart contract approval status

Go ahead and approve the Contract from all required approvers.

Now, go the receiver’s account and see what had happened there. You will be able to see that the particular account received the Contract’s balance.

Conclusion

During this post, we went through the Smart Contract testing using mocha and the truffle framework. Then we have deployed the Smart Contract into a real test network ( Rinkeby ) and interacted with the deployed Smart Contract using the Remix tool.

Hoping to see you in the next section, Build a web application to interact with this Smart Contract.

You can find the source code files in this git repo.