Step by step to teach you to develop and deploy your first de-centralized application (Dapp)-Pet Shop

Source: Internet
Author: User
Tags install node


Today we are going to write a complete de-centric (blockchain) application (Dapps), this article can be combined with the writing of smart contracts to see.




Write in front


Before reading this article, you should know something about Ethereum and smart contracts, and if you don't know it, it's recommended that you look at Ethereum first.
Besides, you'd better get some knowledge of HTML and JavaScript.



This article through the example teaches everybody to develop the central application, the application effect



From this article, you can learn to:


    • Building an intelligent contract development environment
    • Create a truffle project
    • Write a smart contract
    • Compiling and deploying smart contracts to blockchain
    • How to interact with WEB3 and smart contracts
    • Use of Metamask
Project background


Pete has a pet shop with 16 pets, and he wants to develop a hub-and-go app that lets people adopt pets.
In truffle box, the code for the Pet-shop site section has been provided, and we only need to write the contract and the interactive part.


Environment construction
    1. Install node
    2. Install Truffle:npm install -g truffle
    3. Installing ganache

The ganache (or ganache CLI) has replaced the TESTRPC.

Create a project
    1. Set up the project directory and enter
      > mkdir pet-shop-tutorial> cd pet-shop-tutorial
    2. Create a project using truffle unbox
      > truffle unbox pet-shopDownloading...Unpacking...Setting up...Unbox successful. Sweet!


Commands:



Compile:truffle Compile
Migrate:truffle Migrate
Test contracts:truffle Test
Run Dev server:npm Run dev


This step needs to wait for a while

> You can also use truffle init to create a completely new project.

## Project directory structure

`contracts /` folder of smart contracts, all smart contract files are placed here, which contains an important contract Migrations.sol (more on this later)
`migrations /` is used to handle deployment (migration) of smart contracts. Migration is an extra special contract to save contract changes.
`test /` smart contract test case folder
`truffle.js /` configuration file

Other codes can be ignored for the time being

## Writing smart contracts
Smart contracts are responsible for the background logic and storage of distributed applications. Smart contracts are written in solidity and can be read
[solidity series article] (https://learnblockchain.cn/categories/ethereum/Solidity/)

In the contracts directory, add the contract file Adoption.sol
`` `js
pragma solidity ^ 0.4.17;

contract Adoption {

  address [16] public adopters; // save the address of the adopter

    // Adopt a pet
  function adopt (uint petId) public returns (uint) {
    require (petId> = 0 && petId <= 15); // make sure the id is within the length of the array

    adopters [petId] = msg.sender; // Save and call this address
    return petId;
  }

  // return to adopter
  function getAdopters () public view returns (address [16]) {
    return adopters;
  }

}
Compiling and deploying smart contracts


The truffle integrates a developer console that can be used to generate a development chain for testing and deploying smart contracts.


Compile


Solidity is a compiled language and requires that the readable solidity code be compiled into an EVM bytecode to run.
Dapp the root directory pet-shop-tutorial,


> truffle compile


Output


Compiling ./contracts/Adoption.sol...Writing artifacts to ./build/contracts
Deployment


Once compiled, it can be deployed to the blockchain.
There is already a 1_initial_migration.js deployment script under the Migrations folder to deploy the Migrations.sol contract.
Migrations.sol is used to ensure that the same contract is not deployed.



Now let's create a deployment script of our own2_deploy_contracts.js


var Adoption = artifacts.require("Adoption");

module.exports = function(deployer) {
  deployer.deploy(Adoption);
};


Before you perform the deployment, you need to ensure that a blockchain is running and you can use
Ganache to open a private chain for development testing, the default is to run a development chain on port 7545.
This is the case when ganache is started:



Next, execute the deployment command:


> truffle  migrate


After execution, there is a similar output,


Using network ‘develop‘.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x3076b7dac65afc44ec51508bf6f2b6894f833f0f9560ecad2d6d41ed98a4679f
  Migrations: 0x8cdaf0cd259887258bc13a92c0a6da92698644c0
Saving successful migration to network...
  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying Adoption...
  ... 0x2c6ab4471c225b5473f2079ee42ca1356007e51d5bb57eb80bfeb406acc35cd4
  Adoption: 0x345ca3e014aaf5dca488057592ee47305d9b3e10
Saving successful migration to network...
  ... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
Saving artifacts...


In the open ganache you can see changes in the blockchain state, which now produces 4 blocks.

This means that the smart contract has been deployed.


Test


Now let's test the smart contract, the test case can be written in JavaScript or solidity, where solidity is used.



testcreate a new one in the directoryTestAdoption.sol, write a test contract


pragma solidity ^ 0.4.17;

import "truffle / Assert.sol"; // Assertion introduced
import "truffle / DeployedAddresses.sol"; // used to get the addresses of the tested contracts
import "../contracts/Adoption.sol"; // contract tested

contract TestAdoption {
  Adoption adoption = Adoption (DeployedAddresses.Adoption ());

  // adoption test case
  function testUserCanAdoptPet () public {
    uint returnedId = adoption.adopt (8);

    uint expected = 8;
    Assert.equal (returnedId, expected, "Adoption of pet ID 8 should be recorded.");
  }

  // pet owner test case
  function testGetAdopterAddressByPetId () public {
    // The address of the expected adopter is the address of this contract, because the transaction is initiated by the test contract,
    address expected = this;
    address adopter = adoption.adopters (8);
    Assert.equal (adopter, expected, "Owner of pet ID 8 should be recorded.");
  }

    // test all adopters
  function testGetAdopterAddressByPetIdInArray () public {
  // the address of the adopter is the address of this contract
    address expected = this;
    address [16] memory adopters = adoption.getAdopters ();
    Assert.equal (adopters [8], expected, "Owner of pet ID 8 should be recorded.");
  }
}


Assert.sol and Deployedaddresses.sol are provided by the truffle framework and do not provide a truffle directory under the test directory.



Add adopt test Cases to the Testadoption contract


Run test Cases


In the terminal, perform the


truffle test


If the test passes, the terminal outputs:


Using network ‘develop‘.

Compiling ./contracts/Adoption.sol...
Compiling ./test/TestAdoption.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...

  TestAdoption
    ? testUserCanAdoptPet (62ms)
    ? testGetAdopterAddressByPetId (53ms)
    ? testGetAdopterAddressByPetIdInArray (73ms)

  3 passing (554ms)
Create user interface and smart contract interactions


We have written and deployed and tested our contracts, and then we write the UI for the contract so that the contracts can actually be used.



In truffle boxpet-shop, the front-end code for the app is included, and the code is in thesrc/folder.



Open in Editorsrc/js/app.js
You can see the app object used to manage the entire app, and the init function loads the pet information and initializes the WEB3.
WEB3 is a library that implements communication with the Ethereum node, and we use WEB3 to interact with the contract.


Initialize WEB3


Next, let's edit app.js to modify the INITWEB3 ():
Delete the comment and modify it to:


initWeb3: function() {
    // Is there an injected web3 instance?
    if (typeof web3 !== ‘undefined‘) {
      App.web3Provider = web3.currentProvider;
    } else {
      // If no injected web3 instance is detected, fall back to Ganache
      App.web3Provider = new Web3.providers.HttpProvider(‘http://localhost:7545‘);
    }
    web3 = new Web3(App.web3Provider);

    return App.initContract();
  }


The code takes precedence over the WEB3 instance provided by mist or metamask, and if not, creates one from the local environment.


Instantiate a contract


Using Truffle-contract will help us save the contract deployment information, we do not need to manually modify the contract address, modify the Initcontract () code as follows:


initContract: function () {
   // Load Adoption.json, save the ABI (Interface Description) information of Adoption and the deployed network (address) information. It generates ABI when compiling the contract, and adds network information when deploying
   $ .getJSON (‘Adoption.json’, function (data) {
     // Create an interactive TruffleContract contract instance with Adoption.json data.
     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 ();
}
Handling adoptions


Modify the markadopted () code:


markAdopted: function (adopters, account) {
     var adoptionInstance;

     App.contracts.Adoption.deployed (). Then (function (instance) {
       adoptionInstance = instance;

       // Call the contract's getAdopters (), read the information with call without consuming gas
       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);
     });
   }


Modify the Handleadopt () code:


handleAdopt: function (event) {
     event.preventDefault ();

     var petId = parseInt ($ (event.target) .data (‘id‘));

     var adoptionInstance;

     // Get user account
     web3.eth.getAccounts (function (error, accounts) {
       if (error) {
         console.log (error);
       }

       var account = accounts [0];

       App.contracts.Adoption.deployed (). Then (function (instance) {
         adoptionInstance = instance;

         // Send a transaction to adopt a pet
         return adoptionInstance.adopt (petId, (from: account));
       }). then (function (result) {
         return App.markAdopted ();
       }). catch (function (err) {
         console.log (err.message);
       });
     });
   } 
Run the installation metamask in the browser


Metamask is a plug-in form of the Ethereum light client, the development process using Metamask and our Dapp to interact is a good choice, through this link installation, after installation, the browser toolbar will display a small Fox icon.


Configure Wallets


After accepting the privacy statement, the following page appears:



Here we create a good wallet for us by restoring a ganache as our development test wallet. Click Import Existing DENin the page to enter the mnemonic words ganache display.


candy maple cake sugar pudding cream honey rich smooth crumble sweet treat


Then you want the password, click OK.


Connecting the block chain network of development zone


The default connection is the Ethereum main network (upper left corner display), select Custom RPC, add a network:http://127.0.0.1:7545, after the point is returned, the following is displayed:

This is shown in the upper left corner as Private Network, the account is the default first account in ganache.



As of this metamask installation, the configuration is complete.


Installing and configuring Lite-server


Next requires a local Web server to provide access to the service, truffle box pet-shop provides a lite-server that can be used directly, and we'll see how it works.
Bs-config.json indicates the working directory of the Lite-server.


{  "server": {    "baseDir": ["./src", "./build/contracts"]  }}


./SRC is the Web site file directory
./build/contracts is the contract output directory



At the same time, the dev command is added to the scripts of the Package.json file:


"scripts": {  "dev": "lite-server",  "test": "echo \"Error: no test specified\" && exit 1"},


When running NPM run Dev, the Lite-server is started


Start the service
> npm run dev


will automatically open the browser to display our Dapp, such as the first picture of this article.
Now adoption has been pet look, when we click adopt , Metamask will prompt us to confirm the transaction,






After clicking on the submit confirmation, you can see that the pet was adopted successfully.



In Metamask, you can also see a list of transactions:



Well, congratulations, you've become a solid step towards becoming a hub-and-go application developer.


Reference documents
    • Truffle Handbook


In-depth blockchain-the system learns blockchain to create the best blockchain technology blog.



Step by step to teach you to develop and deploy your first de-centralized application (Dapp)-Pet Shop


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.