Build your first Dapps app

Tram Ho

This tutorial will help you build your first dapp – an owner tracking system in a pet salon! Translated from Truffle’s tutorial .

This tutorial requires:

  • Understand the basics of Ethereum Smart Contract. You can briefly learn about two topics in this article or on google.
  • Little basics of HTML and JavaScript.

That’s just that, you can tell through Solidity code and the dapp is okay, we will go to find out what steps a dapp project has, this tutorial will accompany you from AZ .

In this tutorial we will learn:

  1. Setting up the development environment.
  2. Create a Truffle project using the Truffle Box.
  3. Smart contract programming.
  4. Complie and Migrate smart contract.
  5. Test smart contract.
  6. Create a user interface to interact with smart contracts.
  7. Interacting with the dapp through the browser.


Pet store owner Pete Scandlon wants to use Ethereum to manage pet adoption. The situation is that the store has 16 children, complete data. During the POC (experimental) phase, Pete wants a dapp that associates the Ethereum address with the adopted pet .

Website is well structured and designed, our job is to write smart contracts and front-end logic to use .

Setting up the development environment

Node.js v8 + LTS and npm


You can learn in other tutorials to install them.

After the installation is complete, we type this command in the terminal to install Truffle.

To check if Truffle has been installed with no problem, you can type truffle version in terminal. If you see an error, check if the npm module has been added to your path.

And we will also use Ganache , a personal blockchain used to deploy smart contracts, develop applications and run tests on Ethereum.

To download Ganache, visit and select Download .

Note: If you are developing in a non-graphical environment, you can use Truffle Develop , the personal blockchain available in Truffle, instead of Ganache . You will have to change some settings — like the port on which the blockchain runs — to comply with this tutorial.

Create a Truffle project using the Truffle Box

  1. Create a directory in the directory of your choice and then go inside.

  1. Create a special Truffle Box just for this tutorial called pet-shop , it creates your own project structure and UI code, because in this tutorial we don’t need to pay much attention to them. into expertise. The command is as follows:

Note: The Truffle can be initiated in a variety of ways. A common initialization command is truffle init , which gives you an empty Truffle project, with no code contract available in it. For more details please learn more at Creating a Project .

Directory structure

The default Truffle structure includes:

  • contracts/ : Contains a solidity source file of the smart contract. A fairly important contract here is called Migrations.sol , which will be discussed later.
  • migrations/ : Truffle uses a migration system to handle the implementation of smart contracts. Migration is a special smart contract to track changes.
  • test/ : contains the tests in JavaScript or Solidity.
  • truffle-config.js : Truffle configuration file.

Truffle Box pet-shop has other files and folders, but let it go, focus on expertise.

Write smart contracts

Here is the expertise here, we will write the smart contract for the back-end logic and storage.

  1. Create a new file called Adoption.sol in contracts/
  2. The file contents are as follows:

➡️ Analysis:

  • The minimum required version of Solidity stays on the first line of the contract: pragma solidity ^0.5.0; . pragma means ” this is for the compiler “, and the exponential symbol (^) means ” this version or higher
  • At the end of each command is a semicolon, required buộc.

Set of variables

Solidity is a static variable language, that is, data types such as strings, integers or arrays must be declared clearly, not as messy as JavaScript. Solidity has a special type called address . Address is the Etherum address, stored as a 20-byte value. Every account and smart contract on the Ethereum blockchain has an address that can send and receive Ether using this address.

  1. Declare the variable on the next line of the contract Adoption {


  • We defined an adopters variable. This is an array containing values ​​of the same data type and of a fixed or variable length. In this case, the data type is address and the length is 16 .
  • And the word public . The public variable is automatically given the get method, but in the case of the array this keyword is required and only returns a value in the array based on the index passed. In a little bit we will write a function that returns the array for use in the UI.

The first function: Adopt a pet

Let the user be able to request adoption.

  1. Add the following function to the contract after we have declared the above variable.


  • The function is declared with the function keyword, followed by the function name. In Solidity, the parameters passed and the results returned must be explicitly declared. In the above example, the function is named adopt , the parameter passed and the result is uint (a non-negative integer).
  • We checked to make sure the petId did not get overflowed from the array adopters . Arrays in Solidity start from 0, so the ID value must be in the range 0 through 15. We use require() to make sure the ID is in the above paragraph.
  • If the above condition is met then we will give the pet owner address with this ID equal to the address of the caller to this function ( msg.sender ).
  • Finally, we return the petId for confirmation.

The second function: Lists the owners

As mentioned above, the get array function returns only one value from the given index. Our UI needs to update the owner / owner status of all beasts, but calling 16 APIs right away sounds a bit stinging 😢. So, the next step is to write a function that returns the entire array.

  1. Add the getAdopters() function to the contract, right after the adopt() function we just added above


  • Since adopters was declared, we just need to return it. Remember to specify that the return data type (in this case the adopters data type) is address[16] memory . memory indicates the location where the variable’s data is stored.
  • The view keyword in the function indicates that this function does not modify the state of the contract. You can find more here .

Compile and Migrate contracts

Now that we have written the smart contract, save them, the next step is to Compile and migrate it. I didn’t translate these two words because it sounds weird.


Solidity is a compiled language, that is, we need to compile Solidity into bytecode for the Ethereum Virtual Machine (EVM) to execute. Like the translation of Solidity that he wrote for the EVM guy, he understands.

  1. In the terminal, make sure you are at root containing the dapp, type the command:

Note: If you are using Win that matter when you run this command, try reading through here watching .

The result should look like this:


Now that we have compiled the contracts, it’s time to move them to the blockchain!

A migration is a deployment script that changes the contract state of an application, passing it from one state to the next. The first time you migrate, you may just deploy the new code, but it may be the migrate of the data or the replacement of a whole new contract after a while.

Note: Read more about migration at the Truffle documentation .

You should see an existing JavaScript file in the migrations/ : 1_initial_migration.js . It will deploy the Migrations.sol contract to observe the movements of the following contracts, ensuring that we do not migrate the contract again in the future.

Now we will create a migration script.

  1. Create a file named 2_deploy_contracts.js **** in migrations/ .
  2. Add the following code in the file 2_deploy_contracts.js .

  1. We will then move the contract to the blockchain, but in this tutorial we will use Ganahe , an Ethereum-developed personal blockchain that we can use to deploy contracts, develop applications, and run tests. If you haven’t already, download Ganache and start the application. It will create a blockchain that runs locally on port 7545.

Note: Read more about Ganache at the Truffle Documentation .

Ganache opened for the first time

Open the app and leave it alone, we haven’t touched it for a while.

  1. Back in the terminal, move the contract onto the blockchain.

After a while running, the result will be something like this:

As above, you can see the migrations are executed in order, with some information related to it. (Your migration information will be a little different.)

  1. In Ganache, notice that the state of the blockchain has changed. Blockchain now shows current block, used to be 0 , now it is 4 . Plus, the first account that initially had 100 ether, is now lost due to transaction fees after moving the contract to the blockchain. Now you understand why we have to use personal blockchain, because if we go on the real blockchain, all mistakes must be paid in ether. We will talk about transaction fees later.

Ganache after migrate

Congratulations on coding the first smart contract and deploying it on a local blockchain. Now it’s time to play with it to see if it works as I thought it would.

Test smart contract using JavaScript

Truffle is quite flexible with test run, test we can write in JS and Solidity. In this tutorial, we will write tests in JS using the Chai and Mocha libraries. Briefly explaining this test, you can look at the code for more thought.

  1. Create a new file testAdoption.test.js in **test/** .
  2. Add the following content to the testAdoption.test.js file:

We start writing contracts by importing:

  • Adoption : The contract we want to test. We start our testing by importing the Adoption contract thanks to artifacts.require .

Note : When writing this test, the callback function accepts the accounts parameter. This will give you a list of all the accounts that are on the network when using this test.

Then, we use before to provide the initial setup of:

  • Adopt a pet with id 8 and for the first of any network accounts.
  • This function then checks whether petId:8 is properly adopted by accounts[0] .

Test the adopt function

To test the adopt function, remember that it will return the adopter **** if it succeeds. We must ensure that the adopter of the given petId is returned and compares with the expectedAdopter in the adopt function.

  1. Add the following function in the testAdoption.test.js file, below the before code.

This analysis:

  • We call the contract method named adopters to see the host address of the pet with petId 8.
  • Trfffle imports Chai for the user so we can use the assert function. We passed the actual adopter value, expected value expectedAdopter and an error message (which will be printed to the console if the test fails) into the assert.equal() function.

Test the function that lists the owner

Since the array only returns one value with the index passed, we have to create a function that takes the entire array.

  1. Add the function below the function just added earlier in the testAdoption.test.js file.

Since adopters is an array of adopters address whose index is the corresponding petId, we compare the address with index 8 with the address we hope is correct.

Test run

  1. Back in the terminal, run the test:

  1. If the test passes, you will see a console screen similar to this:

Create a user interface for interacting with smart contracts

Now that we have created the smart contract, deployed it into the personal blockchain, tested and confirmed that we can interact with it through the console, now we create the UI so that Pete (owner) has something that can be used for the zoo. his darling.

Truffle Box pet-shop already has code for the front-end, located in **src/** .

Front-end does not use build systems such as webpack, grunt, … for easy access. The app structure is also available, now we are going to play a game of filling in the blanks the functions only Ethereum has. As a result, you can use this knowledge to apply it to your own front-end.

Web library3

  1. Open /src/js/app.js in the IDE.
  2. View file. Notice that there is a global App object used to manage our application, load the pet data in init() and then call initWeb() . JavaScript web3 library that interacts with the Ethereum blockchain. It can read user accounts, send transactions, interact with smart contracts and much more.
  3. Delete comment in initWeb3 and replace it with:


  • First, we check whether the user is using a genuine dapp browser or has installed MetaMask , an extension that “injects” the ethereum provider into the object window . If so, we use it to create the web3 object, but we also need to request public access to the account using ethereum.enable() .
  • If the ethereum object ethereum not exist then we check the web instance. If it exists then it means we are using an old dapp browser (like Mist or an old version of MetaMask). If this is the case, we obtain and use its provider to create our web3 object.
  • If we do not see the web3 instance, we create web3 based on our local provider. (It’s okay to fall back like this during development, but it’s not safe and suitable for production.)

Create an instance of the contract

Now that we can interact with Ethereum via web3, we need to create an instance of the contract so that web3 knows where and how the contract is used. Truffle has a library for handling this called @truffle/contract . It keeps the contract information in sync with the migration, so you don’t need to manually change the deployment address of the contract.

  1. Still in /src/js/app.js , delete the comment in initContract and replace it with the following line:


  • First we get the artifact file for the contract. Artifact is information about the contract such as its address and ABI. An ABI (Application Binary Interface) is a JavaScript object that defines how to interact with a contract, including variables, functions, and their parameters.
  • There are artifacts in the callback function, we pass them to TruffleContract() . It will create an instance of the contract for us to interact.
  • For instance the contract was created, we set its web3 provider by value App.web3Provider have just saved just now when setting web3.
  • Then we call the app’s markAdopted() function in case a pet has been adopted. We wrap it in a separate function because we still need to update the interface every time we change data data.

Get a list of adopted pets and update their skins

  1. Still in /src/js/app.js , delete the comment in markAdopted and replace it with the following line:


  • We access the Adoption contract, and then call getAdopters() .
  • We declare the external adoptionInstance variable so that we can use it after we first assign a value.
  • After calling getAdopters() , we browse the whole array, checking if any pet has the owner address. Since the array contains the address data type, Ethereum assigns them the default value of 16 empty addresses. That’s why we check for an empty address string, not null or false.
  • When we see that the petId has the corresponding owner address, we will disable the button adopting it and turn it into a button that says “Success”, so that the user can send feedback.
  • The error will be printed on the console screen.

Handle the adopt () function to adopt a pet

  1. Still at /src/js/app.js , delete the comment in handleAdopt and replace it with the following line:


  • We use web3 to get the user’s account. In the callback after checking for errors, we will choose the first account.
  • From there, as we did just now, storing the instance of the contract into the adoptionInstance variable. This time, however, we will have to send a transaction instead of a call. The transaction requires a “from” address and an associated fee. This fee is paid in ether, known as gas. The gas fee is the fee paid for calculating or storing data in a contract. We send the transaction by running the adopt() function with the pet’s ID and an object containing the account address we just saved earlier in the account variable.
  • The result of sending a transaction is a transaction object. If there are no errors, we continue to call markAdopted() to synchronize the interface with the new data.

Interacting with the dapp in the browser

Now get ready to use our dapp!

Install and configure MetaMask

The easiest way to interact with the dapp is through MetaMask , an extension for both Chrome, FireFox, and Microsoft Edge browsers.

  1. Install MetaMask suitable for your browser via the link above.
  2. When the installation is completed, a tab opens in the browser showing the following:

Welcome to MetaMask

  1. After clicking Get started , you will see the first MetaMask screen. Select Import Wallet .

  1. Next you can see the screen asking for anonymous rating. Agree or decline.

  1. In the Wallet Seed box, enter mnemonic displayed in Ganache.

Do not use this mnemonic on the mainnet. You send ETH to an account that creates this mnemonic like throwing money off a cliff.

Enter your password (it’s up to you) and select OK.

  1. If all steps are fine, MetaMask will display the following screen. Select All Done .

  1. We need to connect MetaMask to blockchain created by Ganache. Select the menu that shows “Main Network” and choose Custom RPC .

  1. In the new box, enter “New Network”, , 1337 as follows and select Save .

Once created, the new network will be automatically selected.

  1. Click the X button in the top right corner to close the window and return to the Account window.

Each account created by Ganache is given 100 ether. You will see that the first account is a bit less than before because before deploying and testing the contract we spend a small amount of gas.

Configuration is now complete.

Install and configure lite-server

Now we can start up a local web server and use the dapp. We use lite-server library to serve static files. It comes with the Truffle Box pet-shop , but just leave it there and take a look at how it works already.

  1. Open bs-config.json in the root directory of the project to see the content:

It tells the lite-server what file to put in our base directory. We have added the ./src directory of the website file and ./build/contracts of the contracts.

We also add the dev command to scripts in the package.json file in the root directory. scripts allow us to assign console commands to an npm command. In this case we only assign a simple command, but more detailed configuration is possible. scripts will look like this:

It tells npm that we should execute the lite-server when we run the npm run dev command from the console.

Use dapp

  1. Start the local web server:

The dev server will run and automatically open a new browser window containing your dapp.

Pete’s pet shop

  1. A MetaMask pop-up will appear asking you to confirm the Pete Pet Shop connecting to your MetaMask wallet. Without confirmation, you won’t be able to interact with the dapp. Select Connect .

MetaMask requires confirmation

  1. To use a dapp, select the Adopt button on the pet you like.
  2. You will automatically be notified of a transaction confirmation using MetaMask. Select Submit to confirm the transaction.

For example a pet adoption transaction

  1. You will see that the button next to the adopted pet changes to Success and is deactivated, just as I calculated, because the pet is now owned.


Successful adoption

Note : If the button does not change to “Success” automatically, try reloading the app.

And in MetaMAsk, you will see the transaction listed:

Transaction MetaMask

You will also see the same transaction listed in Ganache under the “Transactions” section.

Okay that’s it! You have made a big step towards becoming a full-fledged dapp developer. Do not be too confused if there are parts of the tutorial you are still confused about, this is an overview tutorial on the development of a dapp, you will know what knowledge you need to supplement.

And if you still want to make dapp able to publicly show off to your friends, have users, look forward to the upcoming tutorials that I translate.


Share the news now

Source : Viblo