Here you will learn about the steps to build a Dapp on Wethio Blockchain.
You will learn how to:
Set up Truffle
Create a Truffle project
Create a ZYN wallet
Request free coins using Wethio faucet
Write a smart contract
Compile and migrate the smart contract to Wethio
Connect to Metamask to Wethio Testnet
Create a user interface to interact with the smart contract
Advantages of developing Dapp on Wethio
We recommend developers to build Dapps on Wethio because it is 100 times faster than the Ethereum Blockchain, and also cheaper than it. The Wethio Testnet can process 2,000 TPS, that makes it a great choice for developers to build Dapps.
Let’s get started with the Dapp development.
Setup Requirements
Install the following programs to start building your Dapp
Node.js & npm (“Node.js Package Manager”)
Git
Set up Truffle
As Truffle Framework is a great tool for developing Dapps, you can install Truffle and deploy your smart contracts to Wethio.
To do so: npm install -g truffle
Create a Truffle project
At first you need to set up a directory in your choice of development folder and then move inside it
mkdir pet-shop-tutorialcd pet-shop-tutorial
Then you can begin creating the Truffle project in any of the following two ways:
Create a new project from the ground up with no smart contracts included
Use Truffle Boxes that consists of applications and project templates
We will proceed further with a Truffle Box called pet-shop which includes the basic project structure as well as code for the user interface
You can unpack this Truffle Box using the following command:
truffle unbox pet-shop
Create a ZYN Wallet and save your Mnemonic
Create a new ZYN wallet using ZynWallet mobile app for Android or iOS, or from link
a. Select Wethio Testnet from Advanced Settings under Settings
From Settings, select Backup wallet and Continue
Note down the 12-word recovery phrase
You can also create a new Zyn wallet with MetaMask, MyEtherWallet or TrustWallet
Enter a password and create a new wallet
Note down the recovery phrase
For this tutorial, my wallet address is:
0xc9b694877acd4e2e100e095788a591249c38b9c5
My recovery phrase (12-word Mnemonic)
myth ahead spin horn minute tag spirit please gospel infant clog camera
Get ZYN funds
To be used for smart contract deployment or in Dapps
Free ZYN coins are available through Wethio’s testnet Faucet.
The Block Explorer
At WeSight, you can check the balance of a wallet address
Programming the Smart Contract
Let’s begin with writing a smart contract
Create a new file Adoption.sol in the contracts/ directory
Copy the code below
pragma solidity ^0.5.0;contract Adoption {
address[16] public adopters; // Adopting a pet
function adopt(uint petId) public returns (uint) {
// check that petId is in range of our adopters array
require(petId >= 0 && petId <= 15); // add the address who called this function to our adopter array
adopters[petId] = msg.sender; // return the petId provided as a confirmation
return petId;
} // Retrieving the adopters
function getAdopters() public view returns (address[16] memory) {
return adopters;
}
}
Compiling
To make the EVM understand and execute the code, we need to compile it into bytecode. Also as Wethio is EVM-compatible, any contract written in Ethereum can be effortlessly ported to Wethio Ensure that in the terminal you are in the root of the directory that contains the Dapp, so when you type:
truffle compile
You’ll see the below outputs
Compiling ./contracts/Migrations.sol...
Compiling ./contracts/Adoption.sol...
Writing artifacts to ./build/contracts
Migrating Dapps from Ethereum
A migration is basically altering the state of your application’s contracts through a deployment script, i.e. moving from state to another.
After you have compiled the smart contracts, you can now migrate them to Wethio’s blockchain. To do so follow these steps:
Create the migration scripts
Open migrations/ directory
Create a new file named 2_deploy_contracts.js
Add the below code to the file
var Adoption = artifacts.require("Adoption");module.exports = function(deployer) {
deployer.deploy(Adoption);
};
After creating the migration script, you will need to configure the migration network in truffle.js
Before beginning, specify the blockchain where you want to deploy your smart contracts, the address to deploy, the wallet you just created, and gas, gas price etc.
Now follow the steps:
Install Tuffle’s HDWalletProvider - an individual npm package to find and sign transactions for addresses
Open truffle.js file and edit the migration settings
Define networks to migrate Dapp, We’ll proceed with two networks, development and wethio testnet
You can learn more about testnet configuration in the Wethio network section of this documentation.
Before proceeding, we need to have: RPC endpoint, the Chain id and the HD derivation path.
Update the truffle.js file with your own recovery phrase, the 12-word Mnemonic
```text var mnemonic = '';
Now that we done with the migration configuration, you will now be able to be deploy the smart contracts to public blockchains like Wethio
##### Start the migration
1. Have the compiled smart contract ready
2. Start the migration to the Wethio Testnet in the terminal
3. truffle migrate --network wethiotestnet
Once done, you will have the transaction ID and the contract address.
Troubleshooting
What to do when you see the following errors?
Error 1: smart contract creation cost is under allowance
Edit truffle.js and add more gas/gasPrice to deploy
Error 2: insufficient funds for gas * price + value.
Add more funds to your wallet to deploy, go to Faucet and get more tokens
You can check the transaction status of the deployment on WeSight. You can check details of the transaction by searching for the Transaction ID for your new contract.
And it’s done. You’ve successfully deployed your contract to Wethio using Truffle.
#### Testing the smart contract
Write tests in the **test/** directory and execute with truffle test to test your smart contracts.
#### Build a Web3 Frontend to Interact with Smart Contract
Take the smart contract you created and deployed on Wethio blockchain to the public by creating a UI. Through this UI people will be able to use the shop
The **pet-shop** Truffle Box has the code for front-end included in the src/ directory
1. Open **/src/js/app.js** in text editor
2. Analyze the file. The object, load, and the function all are in there. The **global** App object to manage our application, load the data in **init()**, call the function **initWeb3()**. The web3 JavaScript library interacts with the Ethereum blockchain and can retrieve user accounts, send transactions, interact with smart contracts, and do much more
3. Paste the below code
```text
App = {
web3Provider: null,
contracts: {},
init: async function() {
// Load pets.
$.getJSON('../pets.json', function(data) {
var petsRow = $('#petsRow');
var petTemplate = $('#petTemplate');
for (i = 0; i < data.length; i ++) {
petTemplate.find('.panel-title').text(data[i].name);
petTemplate.find('img').attr('src', data[i].picture);
petTemplate.find('.pet-breed').text(data[i].breed);
petTemplate.find('.pet-age').text(data[i].age);
petTemplate.find('.pet-location').text(data[i].location);
petTemplate.find('.btn-adopt').attr('data-id', data[i].id);
petsRow.append(petTemplate.html());
}
});
return await App.initWeb3();
}, initWeb3: async function() {
//----
// Modern dapp browsers...
if (window.ethereum) {
App.web3Provider = window.ethereum;
try {
// Request account access
await window.ethereum.enable();
} catch (error) {
// User denied account access...
console.error("User denied account access")
}
}
// Legacy dapp browsers...
else if (window.web3) {
App.web3Provider = window.web3.currentProvider;
}
// If no injected web3 instance is detected, fall back to Ganache
else {
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
web3 = new Web3(App.web3Provider);
//----
return App.initContract();
}, initContract: function() {
//----
$.getJSON('Adoption.json', function(data) {
// Get the necessary contract artifact file and instantiate it with truffle-contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact); // Set the provider for our contract
App.contracts.Adoption.setProvider(App.web3Provider); // Use our contract to retrieve and mark the adopted pets
return App.markAdopted();
});
//---- return App.bindEvents();
}, bindEvents: function() {
$(document).on('click', '.btn-adopt', App.handleAdopt);
}, markAdopted: function(adopters, account) {
//----
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance; return adoptionInstance.getAdopters.call();
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
if (adopters[i] !== '0x0000000000000000000000000000000000000000') {
$('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);
}
}
}).catch(function(err) {
console.log(err.message);
});
//----
}, handleAdopt: function(event) {
event.preventDefault(); var petId = parseInt($(event.target).data('id')); //----
var adoptionInstance; web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
} var account = accounts[0]; App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance; // Execute adopt as a transaction by sending account
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
return App.markAdopted();
}).catch(function(err) {
console.log(err.message);
});
});
//---
}
};$(function() {
$(window).load(function() {
App.init();
});
});
Here is what the various functions mentioned in the above code do:
initWeb3() - Checks the version of Dapp browsers or MetaMask
initContract() - Retrieves the artifact file for our smart contract. Now, artifacts are the basic information about our contracts such as deployed address and ABI (application binary interface).
markAdopted() - To check if any pets are already adopted from a previous visit
handleAdopt() - To obtain the deployed contract and store the instance in adoptionInstance. When we execute the adopt() function with both the pet’s ID and an object with the account address, we send a transaction instead of a call. Then, we proceed to call our markAdopted() function to sync the UI with our newly stored data