​Truffle框架的学习与使用(二)——开发一个链上记事本

有了前一章节使用Truffle框架搭建的一个小Demo后,我们现在来尝试自己写一个小应用;——一个链上Flags记事本

基于Truffle框架,我们只需要关注三部分文件:

  • 智能合约.sol文件(本demo的MyFlag.sol)——智能合约主体

  • web页面页面(index.html, index.js, index.css等)——我们应用的页面展示部分

  • 合约部署文件(3_deploy_myFlag.js)——我们要部署哪一个智能合约

好,我们现在就开始以上面3步的顺序完成我们的小应用吧;


一、智能合约.sol文件——MyFlag.sol

比较简单的一个合约内容,直接贴代码:

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.24;

contract MyFlag {
    struct Topic{
        string title;  //标题
        string content;  //内容
        address owner;  //发布人
        uint ts; //发布时的时间戳
    }

    Topic[] public topics;

    //立Flag
    function postTopic(string memory title, string memory content) public {
        topics.push(Topic(title, content, msg.sender, block.timestamp));
    } 

    //获取Flag的总条数
    function getCount() public view returns(uint) {
        return topics.length;
    }
}

二、web前端页面

1、index.html,很简单的内容,没有任何设计感:

<!DOCTYPE html>
<html>
  <head>
    <title>MyFlag</title>
    <script src="index.js"></script>
  </head>
  <body>
    <h1>展示所有的Flags</h1>
    <div>共<span id="count">0</span>条Flags</div>
    <ol id="topics">
    </ol>
    标题:<input type="text" id="title">
    <br/><br/>
    内容:<textarea name="" id="content" cols="30" rows="10"></textarea>
    <button onclick="App.postTopic()">立新Flag</button>
  </body>
</html>

2、重点,index.js部分:

import Web3 from "web3";
import myFlagArtifact from "../../build/contracts/MyFlag.json";

const App = {
  web3: null,
  account: null,
  meta: null,

  start: async function() {
    const { web3 } = this;

    try {
      // 获取合约部署后的实例
      const networkId = await web3.eth.net.getId();
      const deployedNetwork = myFlagArtifact.networks[networkId];
      this.meta = new web3.eth.Contract(
        myFlagArtifact.abi,
        deployedNetwork.address,
      );

      // 初始化账户信息,取第一个地址账户作为默认账户;
      const accounts = await web3.eth.getAccounts();
      this.account = accounts[0];

      this.getTopics();  //本方法可以初始化页面(刷新页面)
    } catch (error) {
      console.error("Could not connect to contract or chain.");
    }
  },

  //读链上数据(总条数,和每一条数据)
  getTopics: async function() {
    let meta = this.meta;
    const { topics, getCount } = meta.methods;

    const countDiv = document.getElementById("count");
    const topicsDiv = document.getElementById("topics");

    const count = await getCount().call();
    countDiv.innerHTML = count;
    topicsDiv.innerHTML = '';
    for(let i=0; i<count; i++){
      const topic = await topics(i).call();
      const title = topic[0];
      const content = topic[1];
      const owner = topic[2];
      const ts = topic[3];
      topicsDiv.innerHTML += `<li>${title} | ${content} | ${owner} | ${ts}</li>`
    }
  },

  // 向链上写数据,需要消耗gas的;
  postTopic: async function() {
    const title = document.getElementById("title").value;
    const content = document.getElementById("content").value;

    const { postTopic } = this.meta.methods;
    await postTopic(title, content).send({ from: this.account, gas: 1000000 });
    this.getTopics();
  },
};

window.App = App;

//Truffle帮我们自动生成好的,获取Web3,有小狐狸就用小狐狸当前的网络,没有就用我们自己不急部署的8545端口上的区块链网络
window.addEventListener("load", function() {
  if (window.ethereum) {
    // use MetaMask's provider
    App.web3 = new Web3(window.ethereum);
    window.ethereum.enable(); // get permission to access accounts
  } else {
    console.warn(
      "No web3 detected. Falling back to http://127.0.0.1:8545. You should remove this fallback when you deploy live",
    );
    // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
    App.web3 = new Web3(
      new Web3.providers.HttpProvider("http://127.0.0.1:8545"),
    );
  }

  App.start();
});

三、合约部署文件——3_deploy_myFlag.js

const MyFlag = artifacts.require("MyFlag");

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

四、测试

1、使用truffle启动测试环境并编译、部署合约(三步);

truffle develop
truffle(develop)> compile
truffle(develop)> migrate

2、启动我们的web应用:

npm install
npm run dev
...
i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from D:\Study\Blockchain\Truffle\myDapp\app\dist
i 「wdm」: Hash: 0ce8bf089f79211b4b86
Version: webpack 4.41.2
...

3、现在打开 http://localhost:8080/ 页面,就可以看到我们的应用啦

我先立几条Flags:

9.jpg

再立条新的Flag:“第五条Flag”

10.jpg

好啦,由此,我们的第一个Dapp小应用就完成啦。


补充:传统web/app应用和基于区块链的Dapp应用的区别

其实理解起来也很简单:

传统web/app应用 基于区块链+智能合约的Dapp
前端页面 前端页面
后端服务 智能合约
Mysql数据库 区块链

jiguiquan@163.com

文章作者信息...

留下你的评论

*评论支持代码高亮<pre class="prettyprint linenums">代码</pre>

相关推荐