How to build your first Ðapp through web3.js
Ðapp is the abbreviated form of decentralized application, whose backend code is running on p2p(peer-to-peer) network. In this article, we focus on the Ðapp run on Ethereum network (if you want to know more about ethereum, you can read the previous post). A Ðapp consists of two part:
Frontend provides a user interface
Backend executes the computation and storage.
There are several methods to deploy Ðapp/smart contract. You can learned how to deploy smart contracts to the private network through truffle in the previous post. You will learn how to use web3.js to deploy a Ðapp and build a user interface for the Ðapp in this article.
- Install MetaMask
Metamask allows developers to run Ethereum ÐApps in your browser without running a full Ethereum node. It includes a secure identity vault, providing a user interface for managing your identities on different sites and signing blockchain transactions.
However, it is only supported on google chrome. Download.
2. Install Meteor
Meteor is a full-stack JavaScript environment that helps developers to build the web application. It allows developers to develop in one language, JavaScript, in all environments: application server, web browser, and mobile device. You can download it in your command line (on Linux or on OSX):
$curl https://install.meteor.com/ | sh
But meteor is just an environment that provides an easy way to manipulate the frontend and backend. If you are much familiar with other environments like jQuery, AngularJS, and etc., they are also good tools for building you Ðapp.
3. Build you Ðapp
$meteor create dappDemo
$cd dappDemo
$meteor
Then, go to localhost:3000. You can see a default demo of meteor. You can check whether the web3.js has been installed in your meteor by opening your browser’s console and type
web3.eth.accounts
If the web3.js has not been installed, you can add the package by yourself
$meteor add ethereum:web3
After build your Ðapp, your dappDemo folder should look like
Before making the user interface, we have to build the smart contract at first. In this article, we construct the basic smart contract which receives the Ether from the sender and transfers to the receiver. it is very simple but it helps us to know the structure of the ethereum contract. We can program the contract through truffle or the online compiler remix. The solidity code
pragma solidity ^0.4.0;contract payontime{
address public remitter;
address private remittee;
uint value;/*Only owner can use these function*/
modifier onlyOwner(){
if(msg.sender != remitter) throw;
_;
}/*Initialize the owner*/
function payontime(address receiver) payable{ value = msg.value;
remittee = receiver;
remittee.transfer(value);
}/*Get the remittee*/
function getRemitee() public onlyOwner returns(address){
return remittee;
}
}
pragma solidity ^0.4.0
declares the compiler version not earlier than 0.4.0 and not working in 0.5.o (this second condition is added by using ^
). payontime
is the contract name. And there are several kinds of basic data types in solidity.
address
:160-bit values, not allow arithmetic operation
uint/int
: Unsigned and signed integers of various sizes
uint8
: The unsigned integer with the size of 8 bits. Additionally, uint
is alias for uint256.
boolean
: true
, false
byte/bytes32
: Fixed-size byte arrays
bytes
: Dynamically-sized byte array
string
: Dynamically-sized character array
modifier onlyOwner()
restricts only the owner of the contract can use the function. modifier
can be used to easily change the behavior of functions. We can see how it use in function getRemittee
.
You can set parameters for each function, just like our main function payontime
. Because it is for transferring the ether in the payontime
function, we have to add payable on the header of the function to tell the compiler the function is used for paying.
Note: I use transfer
here to send the money to the remittee because it will be reverted and the current contract will stop with an exception when that execution runs out of gas or fails in any way. However, if we use send
it would only return false when execution fails. Therefore, designers have to check the return value of send
to make sure the contract work well. Unfortunately, transfer
function only supports the version after 4.0.10. Truffle does not support 4.0.10 right now. So if you want to use the function, you have to use other compilers.
After finishing our smart contract code, we need the bytecode and the ABI. There is an easy way to get them through remix. Next, make a file named Payontime.json
to save the interface.
Modify the demo code in the client/main.html and client/main.js
<head>
<title>Send Ether</title>
</head>
<body>
<h1>Send Ether</h1>
{{> sendEther}}</body><template name="sendEther">
<div><label for="amount">Amount:</label><input type="text" id="amount" placeholder="unit:eth"/></div>
<div><label for="receiver">To Address:</label><input type="text" id="receiver"/></div>
<div><button id="send">Send Ether</button></div><br>
<div>Remittee has {{startBalance}} eth before executing the contract</div>
<div>Remittee has {{endBalance}} eth after executing the contract</div>
</template>
Then we would have the basic user interface of our Ðapp.
After accomplishing the UI, we have to modify the client/main.js
to make the Ðapp executable.
import { Template } from ‘meteor/templating’;
import { ReactiveVar } from ‘meteor/reactive-var’;
import payontime_artifacts from ‘./lib/Payontime.json’;
import ‘./main.html’;var payontime = web3.eth.contract(payontime_artifacts);
var bytecode = “your_bytecode”;Template.sendEther.onCreated(
function helloOnCreated() {
this.start_balance = new ReactiveVar(0);
this.end_balance = new ReactiveVar(0);
}
);Template.sendEther.helpers({
startBalance(){
return Template.instance().start_balance.get();
},
endBalance(){
return Template.instance().end_balance.get();
},
});Template.sendEther.events({
‘click #send’(event, instance) {
let sender = web3.eth.accounts[0];
let receiver = $(‘#receiver’).val();
let eth_amount = $(‘#amount’).val();
let amount = web3.toWei(eth_amount, “ether”);web3.eth.getBalance(receiver, function(error,result){
if(!error){
console.log(“Before transfer: “ + result);
instance.start_balance.set(web3.fromWei(result, “ether”));
}else{
console.log(error);
}
});//deploy new contract, the callback function will execute twice
var newContract = payontime.new(receiver,{data:bytecode, from:sender, value:amount},function(err,result){
if(!err){
console.log(newContract);
if(!result.address) {
console.log(result.transactionHash); // The hash of the transaction, which deploys the contract
// check address on the second call (contract deployed)
} else {
var addr = result.address;
console.log(addr);
web3.eth.getBalance(receiver, function(error,result){
if(!error){
console.log(“After transfer: “ + result);
instance.end_balance.set(web3.fromWei(result, “ether”));
}else{
console.log(error);
}
});
}
}else{
console.log(err);
}
});
}
});
payontime.new()
is to deploy the smart contract to the network. In the contract main function payontime(address receiver)
, it requires a parameter, receiver. Therefore we have to pass the parameter when we deploy the Ðapp; meanwhile, we assign where is the contract from and how much the remitter want to send to the contract.
After deploying the contract, we will receive callback twice. At the first time, it returns a 64-length string, which is the transaction hash. You can use those to keep track of a transaction in progress. There is a website Etherscan helping the user to track their transaction. After that, it returns the address of the smart contract in the network. When you want to call the contract next time, the address tells the compiler which contract you wanna use because there are several similar contracts in the network.
The Ðapp works well when the balance of the remittee increased after we send Ether.
The article shows the basic application of Ðapp. However, Ðapps can do more than sending money, they can be utilized in organization transparency, supply chain, healthcare and etc.
You can download the source code here.