Now let's write a client for our DApp and build it using truffle's default builder. First of all, create files and directories based on the preceding configuration we set: create an app directory and inside it, create an index.html file and two directories called javascripts and styelsheets. Inside the javascripts directory, create a file called index.js and in the stylesheets directory, download and place the CSS file of Bootstrap 4. You can find it at https://v4-alpha.getbootstrap.com/getting-started/download/#bootstrap-css-and-js.
In the index.html file, place this code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6">
<br>
<h2>Send Metacoins</h2>
<hr>
<form id="sendForm">
<div class="form-group">
<label for="fromAddress">Select Account Address</label>
<select class="form-control" id="fromAddress">
</select>
</div>
<div class="form-group">
<label for="amount">How much metacoin do you want to send?
</label>
<input type="text" class="form-control" id="amount">
</div>
<div class="form-group">
<label for="toAddress">Enter the address to which you want to
send matacoins</label>
<input type="text" class="form-control" id="toAddress"
placeholder="Prefixed with 0x">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<div class="col-md-6">
<br>
<h2>Find Balance</h2>
<hr>
<form id="findBalanceForm">
<div class="form-group">
<label for="address">Select Account Address</label>
<select class="form-control" id="address">
</select>
</div>
<button type="submit" class="btn btn-primary">Check
Balance</button>
</form>
</div>
</div>
</div>
<script type="text/javascript" src="/app.js"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6">
<br>
<h2>Send Metacoins</h2>
<hr>
<form id="sendForm">
<div class="form-group">
<label for="fromAddress">Select Account Address</label>
<select class="form-control" id="fromAddress">
</select>
</div>
<div class="form-group">
<label for="amount">How much metacoin you want to send?</label>
<input type="text" class="form-control" id="amount">
</div>
<div class="form-group">
<label for="toAddress">Enter the address to which you want to send matacoins</label>
<input type="text" class="form-control" id="toAddress" placeholder="Prefixed with 0x">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
<div class="col-md-6">
<br>
<h2>Find Balance</h2>
<hr>
<form id="findBalanceForm">
<div class="form-group">
<label for="address">Select Account Address</label>
<select class="form-control" id="address">
</select>
</div>
<button type="submit" class="btn btn-primary">Check Balance</button>
</form>
</div>
</div>
</div>
<script type="text/javascript" src="/app.js"></script>
</body>
</html>
In the preceding code, we are loading the bootstrap.min.css and app.js files. We have two forms: one is to send metacoins to a different account and the other one is to check the metacoins balance of an account. In the first form, the user has to select an account and then enter the amount of metacoin to send and the address that it wants to send to. And in the second form, the user simply has to select the address whose metacoin balance it wants to check.
In the index.js file, place this code:
window.addEventListener("load", function(){
var accounts = web3.eth.accounts;
var html = "";
for(var count = 0; count < accounts.length; count++)
{
html = html + "<option>" + accounts[count] + "</option>";
}
document.getElementById("fromAddress").innerHTML = html;
document.getElementById("address").innerHTML = html;
MetaCoin.detectNetwork();
})
document.getElementById("sendForm").addEventListener("submit", function(e){
e.preventDefault();
MetaCoin.deployed().then(function(instance){
return instance.sendCoin(document.getElementById("toAddress").value, document.getElementById("amount").value, {
from: document.getElementById("fromAddress").options[document.getElementById("fromAddress").selectedIndex].value
});
}).then(function(result){
alert("Transaction mined successfully. Txn Hash: " + result.tx);
}).catch(function(e){
alert("An error occured");
})
})
document.getElementById("findBalanceForm").addEventListener("submit", function(e){
e.preventDefault();
MetaCoin.deployed().then(function(instance){
return instance.getBalance.call(document.getElementById("address").value);
}).then(function(result){
console.log(result);
alert("Balance is: " + result.toString() + " metacoins");
}).catch(function(e){
alert("An error occured");
})
})
Here is how the code works:
- The truffle-default-builder makes artifacts objects available under the __contracts__ global object.
- It also makes available contract abstractions for all the contracts available as global variables with the variable name the same as the contract name.
- It also provides the web3 object by already setting the provider. It also sets the provider for the contract abstractions. It makes the web3 object connect to the network with the name development and if it doesn't exist, then the default value is http://localhost:8545.
- In the preceding code, at first, we wait for the page to load, and once loaded, we retrieve the list of accounts in the connected node and display them in both the forms. And we call the detectNetwork() method of the MetaCoin abstraction as well.
- Then, we have submit event handlers for both the forms. They both do what they are supposed to do and display the result in a popup.
- When the first form is submitted, we get the MetaCoin contract's deployed instance and call the sendCoin method with the correct arguments.
- When the second form is submitted, we retrieve the balance of the selected account by calling the getBalance method in the EVM instead of broadcasting a transaction.
Now go ahead and run the truffle build command, and you will notice that truffle will create index.html, app.js, and bootstrap.min.css files in the build directory and put the client's final deployment code in them.