Build a DApp using Ethereum and Angular 6

WalkingTree Technologies
Coinmonks
8 min readMay 28, 2018

--

DApp is a web application that will interact with smart contracts deployed on the blockchain. In this article, I will walk you through the steps for creating your first DApp using Angular and Ethereum. The integration process should be similar for the other UI frameworks like Ext JS and React.js. This article is the part of the series of articles on DApps for enabling you to write a most effective distributed applications.

Discover and review best Ethereum development tools

Prerequisite

Ensure that the following is already installed and working on your machine:

  • npm
  • truffle
  • ganache
  • node
  • ng
  • solidity (solc)

Also, this article assumes that you do have some understanding of Angular application development. Also, while this article assumes that you may not have much idea about solidity, however, the solidity smart contract piece is very small and it should not overwhelm you.

Creating A Smart Contract

In this article, we will use the Ethereum Development tool, Truffle, for creating and managing the smart contract. We will be creating a very simple payment contract, which will do the following:

  • it will allow the user to transfer fund from his/her account to an account on the network
  • it will allow the user to query his/her balance

Create an empty project directory and use the truffle init command to create a bare Truffle project with no smart contracts included in it.

$ truffle init

Downloading…

Unpacking…

Setting up…

Unbox successful. Sweet!

Commands:

Compile: truffle compile

Migrate: truffle migrate

Test contracts: truffle test

Above steps result in a project created with the following file structure and the bare minimum content:

You may like to note the following:

  • Migrations are Javascript files that help you deploy contracts to the Ethereum network. These files are responsible for staging your deployment tasks, and they’re written under the assumption that your deployment needs will change over time. As your project evolves, you’ll create new migration scripts to further this evolution on the blockchain.
  • 1_initial_migration.js is the sequenced migration file and during the migration, all these migrations get executed in the given sequence
  • truffle.js allows you to configure project details, specifically the networks on which the project will be deployed.
  • the truffle-config.js is sometimes used on the windows machine
  • prefer using the power shell and hence delete the truffle-config.js from your project
  • in the test directory, you shall be creating test automation suits

Add Payment Contract

Add a payment contract by adding the Payment.sol file in the contract folder of your project.

pragma solidity ^0.4.17;contract Payment {address transferFrom;address transferTo;uint paymentAmount;constructor() public {transferFrom = msg.sender;}event TransferFund(address _transferTo, address _transferFrom, uint amount);function transferFund(address _transferTo) public payable returns (bool){transferTo = _transferTo;transferTo.transfer(msg.value);emit TransferFund(transferTo, transferFrom, msg.value);return true;}function getBalanceOfCurrentAccount() public payable returns (uint) {return transferFrom.balance;}}

Note

  • The transferFund function must be marked payable to ensure that any ether passed to this function get accepted
  • The TransferFund event allows logging of the event and the interested javascript client can watch for this event and take desired actions

Configure Deployment Network

Assuming that you have Ganache up and running on your machine, configure your truffle.js with the following details:

module.exports = {networks : {ganache : {host : ‘localhost’,port : 7545, // By default Ganache runs on this port.network_id : “*” // network_id for ganache is 5777. However, by keeping * as value you can run this node on any network}}};

Run the contract deployment command, as shown below:

$ truffle migrate — compile-all — reset — network ganache

Compiling ./contracts/Migrations.sol…

Compiling ./contracts/Payment.sol…

Writing artifacts to ./build/contracts

Using network ‘ganache’.

Running migration: 1_initial_migration.js

Replacing Migrations…

… 0x8f8e457f2584b9d6a90d17a02f4547a56127e20d4f10cc32f951a86dc5db4e5b

Migrations: 0xf8988a2e0d1c41ddef64374441f4169342105df5

Saving successful migration to network…

… 0xbccbd28c27eb973be48c47656f50f7a0cc696f8ce93e47efab28af09b216c970

Saving artifacts…

Running migration: 2_deploy_contracts.js

Replacing Payment…

… 0x99f9eabc15a3688c78689e084d521e5dbe7dc4531b2084464d332fec4f2c7b14

Payment: 0x028b63d210d8228e33c21bce8d87007fe7848e8d

Saving successful migration to network…

… 0xb217f30cf4fb40b837f5340c565aacfc80dbcc9e75e9ed42fd5be3b51ffe10c2

Saving artifacts…

Verifying your contract in the Truffle Console

Open truffle console and perform a transfer between two accounts. Also, check balances of these accounts before and after the transfer.

Aloks-MacBook-Pro-2:payment alokranjan$ truffle console — network ganache

truffle(ganache)> Payment.deployed().then(function(instance){app = instance;})

undefined

truffle(ganache)> web3.fromWei(web3.eth.getBalance(web3.eth.accounts[0]), “ether”).toNumber()

89.92725709999996

truffle(ganache)> web3.fromWei(web3.eth.getBalance(web3.eth.accounts[2]), “ether”).toNumber()

99.97754

truffle(ganache)> app.transferFund(web3.eth.accounts[2], {from:web3.eth.accounts[0], value:web3.toWei(“6.5”, “ether”)})

{ tx: ‘0xe3fa87474e52ab989e32714de74dd874bb46395bf98d8b1ca8e4061c346ffa06’,

receipt:

{ transactionHash: ‘0xe3fa87474e52ab989e32714de74dd874bb46395bf98d8b1ca8e4061c346ffa06’,

transactionIndex: 0,

blockHash: ‘0x8d85859241e2dd69a7d10ec7d38248e7cb32f7669bd3fa47029183c51b9d3422’,

blockNumber: 44,

gasUsed: 50943,

cumulativeGasUsed: 50943,

contractAddress: null,

logs: [],

status: ‘0x01’,

logsBloom: ‘0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000’ },

logs: [] }

truffle(ganache)> web3.fromWei(web3.eth.getBalance(web3.eth.accounts[0]), “ether”).toNumber()

83.42216279999995

truffle(ganache)> web3.fromWei(web3.eth.getBalance(web3.eth.accounts[2]), “ether”).toNumber()

106.47754

When you check Ganache, you will see the following transaction corresponding to the above transfer:

Creating an Angular App

Follow the instruction on the below URL and create the initial default App: https://angular.io/tutorial/toh-pt0

Use the ng new command to create a fund transfer app and use ng serve to start the application:

Follow us on :
https://www.facebook.com/walkingtreetech/
https://www.linkedin.com/company/walking-tree-Technologies
https://twitter.com/walkingtreetech
https://www.youtube.com/channel/UCH5y9upqT2M7uWwgRWjCWBg

ng new transfercd transfer/ng serve — open

Check out the code from the repository https://github.com/abhilashahyd/ethdapp/tree/master in a separate folder and review the codes in the following files:

Copy the contents in such a way that your DApp resemble the following screen:

Linking with the Ethereum Network

web3.js

web3.js is a collection of libraries which allow you to interact with a local or remote ethereum node, using an HTTP or IPC connection.

Installing web3.js

$ cd transfer/$ npm install web3@0.20.5

The latest version of the web3 may not be compatible with Angular 6. Hence, if you face any challenge then try installing a stable version of web3.

Truffle Contract

The truffle-contract provides contract abstraction. The contract abstractions are wrapper code that makes interaction with your contract easy.

Install truffle-contract and generate service using the following commands:

$ npm install truffle-contract$ ng generate service ethcontractCREATE src/app/ethcontract.service.spec.ts (404 bytes)CREATE src/app/ethcontract.service.ts (140 bytes)

Push all the code responsible for interaction with the network or contract into the ethcontract service. For this demo application, we will need the following

  • constructor for primarily initializing the web3Provider
  • getAccountInfo — to retrieve the account address (which is responsible for paying the gas and transferring the ether) and the balance of that account
  • transferEther — for making the actual transferFund contract call

The content of the service file would look as shown below:

import { Injectable } from ‘@angular/core’;import * as Web3 from ‘web3’;import * as TruffleContract from ‘truffle-contract’;declare let require: any;declare let window: any;let tokenAbi = require(‘../../../build/contracts/Payment.json’);@Injectable({providedIn: ‘root’})export class EthcontractService {private web3Provider: null,private contracts: {},constructor() {if (typeof window.web3 !== ‘undefined’) {this.web3Provider = window.web3.currentProvider;} else {this.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:7545');}window.web3 = new Web3(this.web3Provider);}getAccountInfo() {return new Promise((resolve, reject) => {window.web3.eth.getCoinbase(function(err, account) {if(err === null) {web3.eth.getBalance(account, function(err, balance) {if(err === null) {return resolve({fromAccount: account, balance:web3.fromWei(balance, “ether”)});} else {return reject(“error!”);}});}});});}transferEther(_transferFrom,_transferTo,_amount,_remarks) {let that = this;return new Promise((resolve, reject) => {let paymentContract = TruffleContract(tokenAbi);paymentContract.setProvider(that.web3Provider);paymentContract.deployed().then(function(instance) {return instance.transferFund(_transferTo,{from:_transferFrom,value:web3.toWei(_amount, “ether”)});}).then(function(status) {if(status) {return resolve({status:true});}}).catch(function(error){console.log(error);return reject(“Error in transferEther service call”);});});}}

Import the EthcontractService in app.component.ts. Implement initAndDisplayAccount method and transferEther event handler.

The code should look like the one as shown below:

import { Component } from ‘@angular/core’;import { EthcontractService } from ‘./ethcontract.service’;@Component({selector: ‘app-root’,templateUrl: ‘./app.component.html’,styleUrls: [‘./app.component.css’]})export class AppComponent implements ngOnInit {title = ‘your first DApp in Angular’;accounts:any;transferFrom = ‘0x0’;balance =’0 ETH’;transferTo=’’;amount=0;remarks=’’;constructor( private ethcontractService: EthcontractService ){this.initAndDisplayAccount();}initAndDisplayAccount = () => {let that = this;this.ethcontractService.getAccountInfo().then(function(acctInfo){that.transferFrom = acctInfo.fromAccount;that.balance = acctInfo.balance;}).catch(function(error){console.log(error);});};transferEther(event){let that = this;this.ethcontractService.transferEther(this.transferFrom,this.transferTo,this.amount,this.remarks).then(function(){that.initAndDisplayAccount();}).catch(function(error){console.log(error);that.initAndDisplayAccount();});}}

Add EthcontractService as providers in app.module.ts. The code should look like the one shown below:

import { BrowserModule } from ‘@angular/platform-browser’;import { NgModule } from ‘@angular/core’;import { FormsModule } from ‘@angular/forms’;import { AppComponent } from ‘./app.component’;import { EthcontractService } from ‘./ethcontract.service’;@NgModule({declarations: [AppComponent],imports: [BrowserModule,FormsModule],providers: [EthcontractService],bootstrap: [AppComponent]})export class AppModule { }

Ideally, this should be enough and when you launch the application, you shall get something like this:

Note that the address is the address of the first account in the Ganache, which gets used as coinbase. When the app gets initialized, the balance of the From account is also retrieved. After you transfer some ether, the balance of the coinbase account decreases by the equivalent amount as shown in below screen:

The transaction can be verified by checking the transaction lists in the ganache interface:

The following screen shows the changes in the balance of two accounts:

Congratulations! You just developed and verified a distributed app built using Ethereum and Angular. I hope this encourages you to build your own apps.

Hi We are Conducting a free Webinar on MICROSERVICES OPERATIONAL MANAGEMENT on Dec 5th 2018 9:00 PM (IST)

Register for Webinar : https://walkingtree.tech/webinar-registration/

In this article, I have used Ganache, a personal Ethereum blockchain, to test the application. By default, in Ganache, the blocks in the blockchain is getting created and mined as soon as the transaction is getting created and hence you were abstracted from the complexity of mining the transactions. This article doesn’t talk about various aspects involved in eventually taking your DApps to the public network. In next few articles, I will guide you in that direction.

Source: https://walkingtree.tech/dapps-using-ethereum-angular/

Join Coinmonks Telegram Channel and Youtube Channel get daily Crypto News

Also, Read

--

--

WalkingTree Technologies
Coinmonks

WalkingTree is an IT software and service provider recognized for its passion for technology.