前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >什么996? 有了这个工具咱自愿007...

什么996? 有了这个工具咱自愿007...

作者头像
区块链大本营
发布2019-05-10 15:08:16
6930
发布2019-05-10 15:08:16
举报
文章被收录于专栏:区块链大本营区块链大本营

来源 | 深入浅出区块链

作者 | Tiny 熊

出品 | 区块链大本营(blockchain_camp)

生活中,你常会为自己定一些小目标、列一些小计划,但仔细一想,你又完成了多少呢?说到底是没人监督你,即使你不做也可以耍赖...

那如果有一个链上笔记本呢?写到笔记本上的内容不可更改,你也不能耍赖偷懒,因为它删不掉、擦不去,永远都在那里。

到那时,“什么996啊,我自愿007!”

毕竟立下了那么多 flag,不是吗?

不要被吓到啊,其实,营长只是教你开发一个基于以太坊的 DApp — — 链上笔记本。老铁们,一起来动手实操吧。

注:本文以编写一个链上记事本为例,介绍如何开发一款 DApp,也将介绍如何使用 Truffle 工具把智能合约部署到以太坊正式网络上。

好啦,跟着营长一起实战吧!

项目背景及效果

链上记事本让事件永久上链,让事件成为无法修改的历史,从此再无删帖,之前有一个帖子,介绍如何 MetaMask 上链记事,现在我们通过这个 DApp 来完成。

链上记事本有两个功能:

  • 添加一个新记事
  • 查看之前(自己的)记事本

实现效果:

本合约也部署到以太坊官方测试网络 Ropsten,如 Englist first Note 的交易记录可以在EtherScan 查询。

项目准备

创建项目文件夹:noteOnChain,然后在目录下,执行:

代码语言:javascript
复制
truffle unbox pet-shop

使用 Truffle 对项目初始化。Truffle 的 Box,是一套套的开发模板,它会帮助我们安装好相应的依赖,快速的启动应用开发。如果我们项目需要是使用到 JQuery,Bootstrap 库,使用 pet-shop 这个 Box 是不错的选择,官方还提供了 React 、Vue 项目相应的模板。

合约实现

项目初始化会在 noteOnChain 目录下生成 contracts 目录来存放合约文件,在 contracts 目录下添加一个合约文件 NoteContract.sol:

代码语言:javascript
复制
pragma solidity ^0.5.0;
contract NoteContract {        mapping(address => string [] ) public notes;
    constructor() public {    }
    event NewNote(address, string note);
// 添加记事    function addNote( string memory note) public {        notes[msg.sender].push(note);        emit NewNote(msg.sender, note);    }
    function getNotesLen(address own) public view returns (uint) {        return notes[own].length;    }}

合约关键是状态变量 notes 的定义,这是一个 mapping, 保存着所有地址下所有的记事本。

修改记事本逻辑

如果需要修改笔记功能,可以在合约中加入以下代码:

代码语言:javascript
复制
event ModifyNote(address, uint index);    function modifyNote(address own, uint index, string memory note) public {notes[own][index] = note;emit ModifyNote(own, index);}

如果需要只有自己能修改笔记可以 modifyNote 的第一行加上:

代码语言:javascript
复制
require(own == msg.sender)

合约部署

先为合约添加一个部署脚本:

代码语言:javascript
复制
var Note = artifacts.require("./NoteContract.sol");
module.exports = function(deployer) {  deployer.deploy(Note);};

truffle 部署的命令是:

代码语言:javascript
复制
truffle migrate

默认情况下,会部署到本地的 Ganache 提供的测试网络,本文介绍下如何通过 Truffle 部署到太坊官方网络,这里以 Ropsten 为例介绍。

Infura 节点服务注册与 HDWalletProvider 安装

大多数人应该都没有部署自己的节点,我们可以使用 Infura 提供的节点服务。

有部分人可能不解 Infura 服务,其实 MetaMask 后面的节点服务就是 Infura。

然后通过 HDWalletProvider 连接到 Infura 节点,并为我们签署交易,通过下面命令安装 HDWalletProvider:

代码语言:javascript
复制
npm install truffle-hdwallet-provider

在使用 Infura 之前,我们需要注册一个访问 Infura 服务的 Token,

注册地址为:https://infura.io/register,注册后创建一个 Project,复制节点 url:

为 truffle 配置一个新网络

修改 truffle.js 加入一个新网络.

  • 首先引入 HDWalletProvider:

代码语言:javascript
复制
var HDWalletProvider = require("truffle-hdwallet-provider");
  • 配置签名的钱包助记词:

代码语言:javascript
复制
var mnemonic = "orange apple banana ... ";

助记词其实不应该明文配置保存,最好配置在一个隐私文件里,并被代码管理工具所忽略。

  • 加入新网络,以 Ropsten 为例:

代码语言:javascript
复制
networks: {    ropsten: {      provider: function() {        return new HDWalletProvider(mnemonic, "https://ropsten.infura.io/xxx")      },      network_id: 3,      gas: 7003605,      gasPrice: 100000000000,    }   }

HDWalletProvider 的第一个参数是助记词(确保账号有足够的余额),第二个参数是 上面复制的 Infura 节点服务地址,gas 和 gasPrice 分别配置部署时的 Gas Limit 和 Gas Price。

部署

通过以下命令来选择网络部署:

代码语言:javascript
复制
truffle migrate --network ropsten

此过程大约需要等待半分钟,正常的话会输出像下面的提示:

代码语言:javascript
复制
Running migration: 1_initial_migration.js  Deploying Migrations...  ... 0xd79bc3c5a7d338a7f85db9f86febbee738ebdec9494f49bda8f9f4c90b649db7  Migrations: 0x0c6c4fc8831755595eda4b5724a61ff989e2f8b9Saving successful migration to network...  ... 0xc37320561d0004dc149ea42d839375c3fc53752bae5776e4e7543ad16c1b06f0Saving artifacts...Running migration: 2_deploy_contracts.js  Deploying NoteContract...  ... 0x7efbb3e4f028aa8834d0078293e0db7ff8aff88e72f33960fc806a618a6ce4d3  NoteContract: 0xda05d7bfa5b6af7feab7bd156e812b4e564ef2b1Saving successful migration to network...  ... 0x6257dd237eb8b120c8038b066e257baee03b9c447c3ba43f843d1856de1fe132Saving artifacts...

可以用输出的交易 Hash 到 https://ropsten.etherscan.io/ 查询。

前端界面

Truffle Boxs 为项目生成了 html 前端文件 src/index.html,删除原来 Boxs 提供的宠物相关代码,加入一下 html:

代码语言:javascript
复制
<div class="form-group">  <div class="col-sm-8 col-sm-push-1 ">        <textarea class="form-control" id="new_note" ></textarea>    </div>      <button for="new_note" class="" id="add_new">添加笔记</button>    </div>  <div id="notes" ></div>

以上 html 定义了一个文本框 textarea 用来输入笔记,定义了一个 button 用来提交笔记上链。定义了一个 ID 为 notes 的 div, 用来加载已有笔记。初始内容为空,后通过 web3 读取到合约里笔记后,通过 JQuery 插入。

合约交互

删除原来 Boxs 提供的加载宠物逻辑,逻辑分三个部分:

  • 初始化 web3 及合约
  • 获取笔记填充到前端页面
  • 发布笔记上链

初始化

在 initWeb3 函数中,完成 web3 的初始化:

代码语言:javascript
复制
// 最新dapp 浏览器或MetaMask  if (window.ethereum) {  App.web3Provider = window.ethereum;  try {    // 请求账号授权    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;}else {  App.web3Provider = new Web3.providers.HttpProvider('http://localhost:9545');}web3 = new Web3(App.web3Provider);

完成 initContract 初始化合约:

代码语言:javascript
复制
initContract: function() {    $.getJSON('NoteContract.json', function(data) {      App.contracts.noteContract = TruffleContract(data);      App.contracts.noteContract.setProvider(App.web3Provider);
      App.contracts.noteContract.deployed().then(function(instance) {        App.noteIntance = instance;        return App.getNotes();      });    });    return App.bindEvents();}

获取笔记填充到前端页面

initContract 函数里,noteIntance 保存了部署后的合约实例,getNotes 用来获取当前账号的所有笔记:

代码语言:javascript
复制
getNotes: function() {    App.noteIntance.getNotesLen(App.account).then(function(len) {      App.noteLength = len;      if (len > 0) {        App.loadNote( len - 1);      }     }).catch(function(err) {    });}

目前 solidity 还无法支持返回动态类型的数组,没有办法直接获取到如 string 数组的内容,所有这里采用一个变通的方法,先获取到笔记的长度,然后通过 loadNote 来逐条获取笔记:

代码语言:javascript
复制
loadNote: function(index) {    App.noteIntance.notes(App.account, index).then(function(note) {      $("#notes").append(      '<div > <textarea >'      + note      + '</textarea></div>' ;      if (index -1 >= 0) {        App.loadNote(index - 1);      }    } ).catch(function(err) {    });}

发布笔记上链

使用 JQuery 监听用户点击 add_new 按钮,然后调用合约的 addNote 函数把用户输入的笔记存储到智能合约。

代码语言:javascript
复制
bindEvents: function() {    $("#add_new").on('click', function() {      $("#loader").show();
      App.noteIntance.addNote($("#new_note").val()).then(function(result) {         return App.watchChange();      }).catch(function (err) {        console.log(err.message);      });    });}

运行 DApp

使用以下命令,启动 DApp 服务:

代码语言:javascript
复制
npm run dev

在浏览器打开 http://localhost:3000,

浏览器的 MetaMask 也需要连接 Ropsten 网络,确保网络一致。

然后,看看效果吧!!!

原文链接: https://learnblockchain.cn/2019/03/30/dapp_noteOnChain/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 区块链大本营 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目背景及效果
  • 项目准备
  • 合约实现
    • 修改记事本逻辑
    • 合约部署
      • Infura 节点服务注册与 HDWalletProvider 安装
        • 为 truffle 配置一个新网络
          • 部署
          • 前端界面
          • 合约交互
            • 初始化
              • 获取笔记填充到前端页面
                • 发布笔记上链
                • 运行 DApp
                相关产品与服务
                区块链
                云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档