什么996? 有了这个工具咱自愿007...
来源 | 深入浅出区块链
作者 | Tiny 熊
出品 | 区块链大本营(blockchain_camp)
生活中,你常会为自己定一些小目标、列一些小计划,但仔细一想,你又完成了多少呢?说到底是没人监督你,即使你不做也可以耍赖...
那如果有一个链上笔记本呢?写到笔记本上的内容不可更改,你也不能耍赖偷懒,因为它删不掉、擦不去,永远都在那里。
到那时,“什么996啊,我自愿007!”
毕竟立下了那么多 flag,不是吗?
不要被吓到啊,其实,营长只是教你开发一个基于以太坊的 DApp — — 链上笔记本。老铁们,一起来动手实操吧。
注:本文以编写一个链上记事本为例,介绍如何开发一款 DApp,也将介绍如何使用 Truffle 工具把智能合约部署到以太坊正式网络上。
先做个小调查:
好啦,跟着营长一起实战吧!
项目背景及效果
链上记事本让事件永久上链,让事件成为无法修改的历史,从此再无删帖,之前有一个帖子,介绍如何 MetaMask 上链记事,现在我们通过这个 DApp 来完成。
链上记事本有两个功能:
添加一个新记事
查看之前(自己的)记事本
实现效果:
本合约也部署到以太坊官方测试网络 Ropsten,如 Englist first Note 的交易记录可以在EtherScan 查询。
项目准备
创建项目文件夹:noteOnChain,然后在目录下,执行:
truffle unbox pet-shop
使用 Truffle 对项目初始化。Truffle 的 Box,是一套套的开发模板,它会帮助我们安装好相应的依赖,快速的启动应用开发。如果我们项目需要是使用到 JQuery,Bootstrap 库,使用 pet-shop 这个 Box 是不错的选择,官方还提供了 React 、Vue 项目相应的模板。
合约实现
项目初始化会在 noteOnChain 目录下生成 contracts 目录来存放合约文件,在 contracts 目录下添加一个合约文件 NoteContract.sol:
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, 保存着所有地址下所有的记事本。
修改记事本逻辑
如果需要修改笔记功能,可以在合约中加入以下代码:
event ModifyNote(address, uint index);
function modifyNote(address own, uint index, string memory note) public {
notes[own][index] = note;
emit ModifyNote(own, index);
}
如果需要只有自己能修改笔记可以 modifyNote 的第一行加上:
require(own == msg.sender)
合约部署
先为合约添加一个部署脚本:
var Note = artifacts.require("./NoteContract.sol");
module.exports = function(deployer) {
deployer.deploy(Note);
};
truffle 部署的命令是:
truffle migrate
默认情况下,会部署到本地的 Ganache 提供的测试网络,本文介绍下如何通过 Truffle 部署到太坊官方网络,这里以 Ropsten 为例介绍。
Infura 节点服务注册与 HDWalletProvider 安装
大多数人应该都没有部署自己的节点,我们可以使用 Infura 提供的节点服务。
有部分人可能不解 Infura 服务,其实 MetaMask 后面的节点服务就是 Infura。
然后通过 HDWalletProvider 连接到 Infura 节点,并为我们签署交易,通过下面命令安装 HDWalletProvider:
npm install truffle-hdwallet-provider
在使用 Infura 之前,我们需要注册一个访问 Infura 服务的 Token,
注册地址为:https://infura.io/register,注册后创建一个 Project,复制节点 url:
为 truffle 配置一个新网络
修改 truffle.js 加入一个新网络.
首先引入 HDWalletProvider:
var HDWalletProvider = require("truffle-hdwallet-provider");
配置签名的钱包助记词:
var mnemonic = "orange apple banana ... ";
助记词其实不应该明文配置保存,最好配置在一个隐私文件里,并被代码管理工具所忽略。
加入新网络,以 Ropsten 为例:
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。
部署
通过以下命令来选择网络部署:
truffle migrate --network ropsten
此过程大约需要等待半分钟,正常的话会输出像下面的提示:
Running migration: 1_initial_migration.js
Deploying Migrations...
... 0xd79bc3c5a7d338a7f85db9f86febbee738ebdec9494f49bda8f9f4c90b649db7
Migrations: 0x0c6c4fc8831755595eda4b5724a61ff989e2f8b9
Saving successful migration to network...
... 0xc37320561d0004dc149ea42d839375c3fc53752bae5776e4e7543ad16c1b06f0
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying NoteContract...
... 0x7efbb3e4f028aa8834d0078293e0db7ff8aff88e72f33960fc806a618a6ce4d3
NoteContract: 0xda05d7bfa5b6af7feab7bd156e812b4e564ef2b1
Saving successful migration to network...
... 0x6257dd237eb8b120c8038b066e257baee03b9c447c3ba43f843d1856de1fe132
Saving artifacts...
可以用输出的交易 Hash 到 https://ropsten.etherscan.io/ 查询。
前端界面
Truffle Boxs 为项目生成了 html 前端文件 src/index.html,删除原来 Boxs 提供的宠物相关代码,加入一下 html:
<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 的初始化:
// 最新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 初始化合约:
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 用来获取当前账号的所有笔记:
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 来逐条获取笔记:
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 函数把用户输入的笔记存储到智能合约。
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 服务:
npm run dev
在浏览器打开 http://localhost:3000,
浏览器的 MetaMask 也需要连接 Ropsten 网络,确保网络一致。
然后,看看效果吧!!!
原文链接:
https://learnblockchain.cn/2019/03/30/dapp_noteOnChain/
推荐阅读:
裁员25%, 梅西也拯救不了全球第一款区块链手机!
别的公司裁员996, 区块链公司一将难求, 什么样的公司最容易招到开发者?
用一枚比特币环游世界? 他是不是疯了...
强推!十大顶级大数据可视化工具 | 程序员硬核评测
程序员的双肩包,大概能装下整个宇宙!
深入卷积神经网络背后的数学原理 | 技术头条
源码泄露是裁员报复还是程序员反抗 996?
他说:当一个程序员决定告别996,什么都有可能发生!
猛戳"阅读原文"有惊喜哟
老铁在看了吗??
什么996? 有了这个工具咱自愿007...相关推荐
- 为什么程序猿996多猝屎,而企业家007却不会?
原作者公众号:Source Code Labs 查看全文 http://www.taodudu.cc/news/show-3053358.html 相关文章: [转]为什么程序猿996多猝屎,而企业家 ...
- 超给力,一款程序员必备的 996 代码工作量分析工具
公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 程序员是一个创作型的职业,频繁的加班并不能增加产出,而国内 996 的公司文化,真的一言难尽.但是如果你进到一家公 ...
- 致996.ICU,我可以自愿007,但坚决拒绝被强制996!
昨天天github上有一个项目火了,今天一天的star数量超过1w,第二名才781.项目的信息想必大家都知道,996.ICU.项目链接如下:https://github.com/996icu/996. ...
- 韦一之SI等工具使用(007课)
本节主要介绍了SI软件和Hex Editor Neo二进制查看软件. 笔记摘录: ./hello (执行程序) (不用点直接写hello不行吗?) gcc -v 查看gcc的版本,从而验证了gcc编译 ...
- 【转】为什么程序猿996多猝屎,而企业家007却不会?
公号:程序员吴小胖 [转载请务必携带此二维码] </div><link href="https://csdnimg.cn/release/phoenix/mdeditor/ ...
- 原来马云是对的,我有点相信996是福报了
马云最开始说996是福报的时候,我是不屑一顾的.当时,我在本号也发了一篇文章说了一下我的观点:<我可以自愿007,但拒绝被强制996>. 而现在,我越发觉得马云才是对的,有点相信996是福 ...
- 华为狼文化被喷,任正非回应:华为没有996,更没有007!
近日,华为心声社区发布了任正非接受<南华早报>采访纪要,在采访中记者问到有些员工批评了华为的所谓"狼文化",说科技领域有"996"的说法,华为似乎是 ...
- 为啥程序员撕996建筑人不撕007?——晒知乎高赞沙雕回答,和说说工程师文化
轻友们大家好~我是珍妮兔,一只工程效率顾问.我的日常生活是在不同的软件研发团队和大家聊天,给大家分享各种轻松把软件做好的最佳实践.如果你有特别想要解决的问题,不妨加我的个人微信:jenny1652告诉 ...
- 第三十九期:1024特别版:向“程序媛们”致敬!
对女性程序员而言,似乎怎么选择都是错:闯入男性领地,输了,会强化社会对女性的固有刻板印象:赢了,打破了职业性别固化,会导致整个职业收入的下降. 作者:奇点.轻音 "到家得十二点半了,我现在真 ...
最新文章
- match_parent和fill_parent的区别
- Transact_SQL小手册(各种sql语句大集合)
- SaaS业务的价值评估
- nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
- 如何系统搭建现代 Web CI/CD
- RedHat中敲sh-copy-id命令报错:-bash: ssh-copy-id: command not found
- python学习-- django 2.1.7 ajax 请求 进阶版
- 生成主键ID,唯一键id,分布式ID生成器雪花算法代码实现
- Django 高级(其他知识点)
- Visio风格源代码组件库,流程图,矢量图,图形编辑,打印,导入,导出,VC++源代码...
- sql server 存储过程中拼接sql,转义单引号
- CAD2008详细安装教程和激活失败方法
- 三足鼎立 – Mac 输入法横向对比
- Photoshop压缩png图片
- Exchange Server 2016 CU22升级更新
- sl4a库_SL4A客户端Python服务器(SL4A client Python server)
- 金域医学与华为云联合,AI辅助宫颈癌筛查方案获得阶段性突破
- 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)
- 庖丁解牛Transformer原理
- 苹果用计算机知道密码,苹果电脑钥匙串登录密码忘了怎么办