第二十六課 如何從零開始搭建一個Truffle框架的DAPP應用1,摘要2, 需求描述3,操作步驟4,總結

1,摘要

第六課 技術小白如何開發一個DAPP區塊鏈應用(以寵物商店爲例)介紹瞭如何獲取寵物商店的TRUFLLE框架代碼,並完成部署的過程。 但是這個是已經成熟的代碼框架,一般用戶要開發自己的一能用。那如何借用寵物商店成熟框架完成自有DAPP的搭建呢?我們以tiny熊老師的一個姓名/年齡智能合約用例來呈現方法。

2, 需求描述

我們要實現一個用戶姓名和年紀的輸入和呈現頁面,能更新智能合約上的用戶名和年齡。重新輸入用戶名和年紀,點擊按鈕可更新智能合約的這2個變量信息。

3,操作步驟

3.1 創建目錄,下載框架

首先創建好目錄,下載寵物商店的代碼框架。

duncanwang@ubuntu:~/work$ mkdir name-age
duncanwang@ubuntu:~/work$ cd name-age
duncanwang@ubuntu:~/work/name-age$ truffle unbox pet-shop
Downloading...
Unpacking...
Setting up...
Unbox successful. Sweet!

Commands:

  Compile:        truffle compile
  Migrate:        truffle migrate
  Test contracts: truffle test
  Run dev server: npm run dev
duncanwang@ubuntu:~/work/name-age$ 

3.2 創建智能合約代碼

新建一個InfoContract.sol智能合約文件,並把它更新到./contracts目錄下。

pragma solidity ^0.4.24;

contract InfoContract {
    string name;
    uint age;

    event Instructor(string name, uint age);

    function setInfo(string _name, uint _age) public {
        name = _name;
        age = _age;
        emit Instructor(name, age);
    }

    function getInfo() public view returns(string, uint) {
        return (name, age);
    }
}

3.3 增加合約相關的部署和測試代碼

1) 增加合約部署測試 文件2_info_contract.js到./migrations目錄,代碼如下,表示contract InfoContract合約部署。

var MyContract = artifacts.require("./InfoContract.sol");

module.exports = function(deployer) {
  // deployment steps
  deployer.deploy(MyContract);
};

2) 增加測試文件

pragma solidity ^0.4.24;

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/InfoContract.sol";

contract TestInfoContract {
   InfoContract info = InfoContract(DeployedAddresses.InfoContract());
   string name;
   uint age;

   function testInfo() {
     info.setInfo("ABC", 10);

     (name, age) = info.getInfo();

     Assert.equal(name, "ABC", "設置名字出錯");
     Assert.equal(age, 10, "設置年齡出錯");
   }
}
  1. 修改配置文件 因爲默認ganache-cli的端口爲8545,所以需要修改truffle.js的端口號由7545 變爲8545。
module.exports = {
  // See <http://truffleframework.com/docs/advanced/configuration>
  // for more about customizing your Truffle configuration!
  networks: {
    development: {
      host: "127.0.0.1",
      port: 8545,
      network_id: "*" // Match any network id
    }
  }
};

否則測試時會有找不到客戶端提示。

duncanwang@ubuntu:~/work/name-age$ truffle test
Could not connect to your Ethereum client. Please check that your Ethereum client:
    - is running
    - is accepting RPC connections (i.e., "--rpc" option is used in geth)
    - is accessible over the network
    - is properly configured in your Truffle configuration file (truffle.js)

3.4 驗收測試智能合約

1)參考寵物商店的文章代碼,在一個窗口啓動一個ganache-cli 錢包。

duncanwang@ubuntu:~/work/name-age$ cd ..
duncanwang@ubuntu:~/work$ ganache-cli >>trace.log

2)編譯智能合約 然後啓動另外一個窗口命令行,輸入一下命令。

duncanwang@ubuntu:~/work/name-age$ truffle compile
Compiling ./contracts/InfoContract.sol...
Compiling ./contracts/Migrations.sol...
Writing artifacts to ./build/contracts

智能合約驗收命令。

測試成功的提示說明:

duncanwang@ubuntu:~/work/name-age$ truffle test
Using network 'development'.

Compiling ./contracts/InfoContract.sol...
Compiling ./test/TestInfoContract.sol...
Compiling truffle/Assert.sol...
Compiling truffle/DeployedAddresses.sol...

Compilation warnings encountered:

/home/duncanwang/work/name-age/test/TestInfoContract.sol:12:4: Warning: No visibility specified. Defaulting to "public". 
   function testInfo() {
   ^ (Relevant source part starts here and spans across multiple lines).



  TestInfoContract
    ✓ testInfo (838ms)


  1 passing (5s)

3.5 完成前端頁面

完成以下2個文件的修改更新和上傳。 1) index.html 把寵物商店的index.html的代碼刪除,替換爲本文需要的框架代碼。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>First Truffle DApp Demo</title>
    <link rel="stylesheet" type="text/css" href="main.css">

</head>
<body>
    <div class="container">
        <h1> First Truffle DApp Demo</h1>

        <h2 id="info"></h2>
        <img id="loader" src="https://loading.io/spinners/double-ring/lg.double-ring-spinner.gif">

        <label for="name" class="col-lg-2 control-label">姓名:</label>
        <input id="name" type="text">

        <label for="name" class="col-lg-2 control-label">年齡:</label>
        <input id="age" type="text">

        <button id="button">更新</button>

    </div>

    <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
    <script src="js/web3.min.js"></script>
    <script src="js/truffle-contract.js"></script>
    <script src="js/app.js"></script>

2) app.js 然後修改app.js的代碼,完成智能合約的執行和調用作用。

App = {
  web3Provider: null,
  contracts: {},

  init: function() {
    return App.initWeb3();
  },

/*加載web3*/
  initWeb3: function() {
    if (typeof web3 !== 'undefined') {
         App.web3Provider = web3.currentProvider
         web3 = new Web3(App.web3Provider);
     } else {
         App.web3Provider = new Web3.providers.HttpProvider("http://localhost:9545")
         web3 = new Web3(App.web3Provider);
     }

     return App.initContract();
  },

/*初始化合約,獲取合約,不需要使用at()的方式;
  顯示合約的姓名和年齡信息*/
  initContract: function() {

    $.getJSON('InfoContract.json', function(data){
      App.contracts.InfoContract = TruffleContract(data);
      App.contracts.InfoContract.setProvider(App.web3Provider);

      App.getInfo();
      App.watchChanged();
    });

    App.bindEvents();

  },

  getInfo: function() {
    App.contracts.InfoContract.deployed().then(function(instance) {
      return instance.getInfo.call();
    }).then(function(result) {
      $("#loader").hide();
      $("#info").html(result[0]+' ('+result[1]+' years old)');
      console.log(result);
    }).catch(function(err) {
      console.error(err);
    });
  },

/*點擊按鈕更新姓名和年齡,則需要更新到智能合約上*/
  bindEvents: function() {
    $("#button").click(function() {
        $("#loader").show();

        App.contracts.InfoContract.deployed().then(function(instance) {
          return instance.setInfo($("#name").val(), $("#age").val(), {gas: 500000});
        }).then(function(result) {
          return App.getInfo();
        } ).catch(function(err) {
          console.error(err);
        });
      });
  },

  watchChanged: function() {
    App.contracts.InfoContract.deployed().then(function(instance) {
      var infoEvent = instance.Instructor();
      return infoEvent.watch(function(err, result) {
        $("#loader").hide();
        $("#info").html(result.args.name +' ('+ result.args.age +' years old)');
      });
    });
  }

  }



$(function(){
  $(window).load(function() {
      App.init();
  });
});

3.6 測試驗收前端和合約交互代碼

1) 部署合約 合約部署成功。

duncanwang@ubuntu:~/work/name-age$ truffle migrate
Using network 'development'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x5b3cd41a7fa7c58361172ac797412469a10edfbe721d8d81988f19282c9cb6e4
  Migrations: 0x92b6ecd23aa98fad36926c12ec701f9aaa0933f4
Saving successful migration to network...
  ... 0x826fcd5b72b48435bf4f9941305727e52b0b7290631ba7b39f642027b1ee6947
Saving artifacts...
Running migration: 2_info_contract.js
  Deploying InfoContract...
  ... 0x9943dd7b90207bd9fd1e85524d1d0227f18a92269d73f5a2141cb71c22dda1e9
  InfoContract: 0x191391c710e1b632e40b4f2267dbc0f3bdb2bed4
Saving successful migration to network...
  ... 0x7e11f6e32585524e338e73439e4026c7c766625e5d23d56a4c90f8a11e5001ed
Saving artifacts...

2)啓動lite-server 參考第六課 技術小白如何開發一個DAPP區塊鏈應用(以寵物商店爲例),完成MetaMask和liteServer的安裝。 在新的窗口完成liteServer的啓動。

duncanwang@ubuntu:~/work/name-age$ npm run dev

> [email protected] dev /home/duncanwang/work/name-age
> lite-server

** browser-sync config **
{ injectChanges: false,
  files: [ './**/*.{html,htm,css,js}' ],
  watchOptions: { ignored: 'node_modules' },
  server: 
   { baseDir: [ './src', './build/contracts' ],
     middleware: [ [Function], [Function] ] } }
[Browsersync] Access URLs:
 --------------------------------------
       Local: http://localhost:3000
    External: http://10.225.18.149:3000
 --------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 --------------------------------------
[Browsersync] Serving files from: ./src
[Browsersync] Serving files from: ./build/contracts
[Browsersync] Watching files...
  1. 打開主頁 輸入lite-server提示的主頁地址:http://10.225.18.149:3000 可以看到頁面輸出信息。

image.png

4)更新姓名和年齡 輸入框輸入姓名和年齡:王登輝,18 ,點擊更新按鈕,會彈出MEATMASK的交易提示,確認交易。

image.png

確認交易後,姓名和年齡信息會更新。

4,總結

本文僅從操作層面講解了如何利用寵物商店的模板樣例,快速重構一個含前端的DAPP頁面。 具體WEB.3J的接口函數及定義,參考文章《第十一課 從寵物商店案例看DAPP架構和WEB3.JS交互接口》。 所有工程的源碼已上傳到知識星球,有需要的同學可加入下載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章