Build a DApp using Ethereum and Angular 6
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.
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
- Copy Trading | Crypto Tax Software
- Grid Trading | Crypto Hardware Wallet
- Crypto Telegram Signals | Crypto Trading Bot
- Best Crypto Exchange | Best Crypto Exchange in India
- Best Crypto APIs for Developers
- Best Crypto Lending Platform
- An ultimate guide to Leveraged Token