这里写目录标题

  • Truffle
    • Truffle 简介
    • Truffle 的客户端
    • 安装Truffle
    • 创建项目
    • Migration
      • artifacts.require()
      • exports 的函数
      • deployer 对象
      • 更新 migration 文件
    • 更新 truffle 配置文件
    • 创建账户(可用 metamask 上账户转币)
    • 部署
      • 新建 JavaScript 文件 app/scripts/index.js

Truffle

Truffle 简介

truffle unbox webpack 一条命令由于要下载众多需要的模块,大概耗时 10
分钟左右,所以我们先来了解一下 Truffle。

Truffle 是目前最流行的以太坊 DApp 开发框架,(按照官网说法)是一个世
界级的开发环境和测试框架,也是所有使用了 EVM 的区块链的资产管理通道,它基于 JavaScript,致力于让以太坊上的开发变得简单。

Truffle 有以下功能:

 内置的智能合约编译,链接,部署和二进制文件的管理。
 合约自动测试,方便快速开发。
 脚本化的、可扩展的部署与发布框架。
 可部署到任意数量公网或私网的网络环境管理功能
 使用 EthPM 和 NPM 提供的包管理,使用 ERC190 标准。
 与合约直接通信的直接交互控制台(写完合约就可以命令行里验证了)。
 可配的构建流程,支持紧密集成。
 在 Truffle 环境里支持执行外部的脚本。

Truffle 的客户端

我们之后写的智能合约必须要部署到链上进行测试,所以 truffle 构建的
DApp 也必须选择一条链来进行部署。我们可以选择部署到一些公共的测试链比如 Rinkeby 或者 Ropsten 上,缺点是部署和测试时间比较长,而且需要花费一定的时间赚取假代币防止 out of gas。当然,对于 DApp 发布的正规流程,staging(模拟环境)还是应该用测试公链的。

还有一种方式就是部署到私链上,这在开发阶段是通常的选择。Truffle 官方
推荐使用以下两种客户端:
 Ganache
 truffle develop

而 truffle develop 是 truffle 内置的客户端,跟命令行版本的 Ganache 基本
类似。在 truffle 目录下 bash 输入:

>truffle develop

即可开启客户端,和 ganache 一样,它也会给我们自动生成 10 个账户。
唯一要注意的是在 truffle develop 里执行 truffle 命令的时候需要省略前面的
“truffle”,比如“truffle compile”只需要敲“compile”就可以了

安装Truffle

启动 geth,然后我们来安装 truffle。truffle 是一个 dapp 的开发框架,它
可以使得 dapp 的构建和管理非常容易。

你可以像这样使用 npm 安装 truffle: >npm install -g truffle
然后我们创建一个空目录,在下面创建 truffle 项目:

>mkdir simple_voting_by_truffle_dapp
>cd simple_voting_by_truffle_dapp
>npm install -g webpack
>truffle unbox webpack

truffle init: 在当前目录初始化一个新的 truffle 空项目(项目文件只有
truffle-config.js 和 truffle.js;contracts 目录中只有 Migrations.sol;migrations目录中只有 1_initial_migration.js)

truffle unbox: 直接下载一个 truffle box,即一个预先构建好的 truffle 项目;
unbox 的过程相对会长一点,完成之后应该看到这样的提示:


这里的 webpack 就是一个基于 webpack 构建流程的官方项目框架(truffle
box),更多 truffle box 参见 https://truffleframework.com/boxes

创建项目

初始化一个 truffle 项目时,它会创建运行一个完整 dapp 所有必要的文件
和目录。我们直接下载 webpack 这个 truffle box,它里面的目录也是类似的:

>ls
README.md contracts node_modules test
webpack.config.js truffle.js app migrations
package.json
>ls app/
index.html javascripts stylesheets
>ls contracts/
ConvertLib.sol MetaCoin.sol Migrations.sol
>ls migrations/
1_initial_migration.js 2_deploy_contracts.js

 app/ - 你的应用文件运行的默认目录。这里面包括推荐的 javascript 文
件和 css 样式文件目录,但你可以完全决定如何使用这些目录。
 contract/ - Truffle 默认的合约文件存放目录。  migrations/ - 部署脚本文件的存放目录
 test/ - 用来测试应用和合约的测试文件目录
 truffle.js - Truffle 的配置文件
truffle 也会创建一个你可以快速上手的示例应用,你可以放心地删除项目下面 contracts 目录的 ConvertLib.sol和 MetaCoin.sol 文件。

>rm contracts/ConvertLib.sol contracts/MetaCoin.sol

此外,在你的项目目录下查找一个叫做 truffle.js 的配置文件。它里面包含
了一个用于开发网络的配置。将端口号从 7545 改为 8545,因为我们的私链及ganache 默认都会在该端口运行。

Migration

migration 的概念
理解 migrations(迁移)目录的内容非常重要。这些迁移文件用于将合约
部署到区块链上。

之前的项目中通过在 node 控制台中调VotingContract.new 将投票合约部署到区块链上。以后,我们再也不需要这么做了,truffle 将会部署和跟踪所有的部署。

Migrations(迁移)是 JavaScript 文件,这些文件负责暂存我们的部署任务,并且假定部署需求会随着时间推移而改变。随着项目的发展,我们应该创建新的迁移脚本,来改变链上的合约状态。所有运行过的 migration 历史记录,都会通过特殊的迁移合约记录在链上。

第一个迁移 1_initial_migration.js 向区块链部署了一个叫做 Migrations
的合约,并用于存储你已经部署的最新合约。每次你运行 migration 时,truffle 会向区块链查询获取最新已部署好的合约,然后部署尚未部署的任何合约。

然后它会更新 Migrations 合约中的 last_completed_migration 字段指向最新部署的合约。你可以简单地把它当成是一个数据库表,里面有一列
last_completed_migration ,该列总是保持最新状态。

migration 文件的命名有特殊要求:前缀是一个数字(必需),用来标记迁
移是否运行成功;后缀是一个描述词汇,只是单纯为了提高可读性,方便理解。

artifacts.require()

在脚本的开始,我们用 artifacts.require() 方法告诉 truffle 想要进行部署迁
移的合约,这跟 node 里的 require 很类似。不过需要注意,最新的官方文档告诫,应该传入定义的合约名称,而不要给文件名称——因为一个.sol 文件中可能包含了多个 contract。

exports 的函数

migration js 里的 exports 的函数,需要接收一个 deployer 对象作为第一个
参数。这个对象在部署发布的过程中,主要是用来提供清晰的语法支持,同时提供一些通用的合约部署职责,比如保存部署的文件以备稍后使用。

deployer 对象

deployer 对象是用来暂存(stage)部署任务的主要操作接口。
像所有其它在 Truffle 中的代码一样,Truffle 提供了我们自己代码的合约抽
象层(contract abstractions),并且进行了初始化,以方便你可以便利的与以太坊的网络交互。这些抽象接口都是部署流程的一部分。

更新 migration 文件

将 2_deploy_contracts.js 的内容更新为以下信息:

var Voting = artifacts.require("./Voting.sol");
module.exports = function(deployer) {deployer.deploy(Voting, ['Alice', 'Bob', 'Cary'], {gas:
290000});
};

从上面可以看出,部署者希望第一个参数为合约名,跟在构造函数参数后面。

在我们的例子中,只有一个参数,就是一个候选者数组。第三个参数是一个哈希,我们用来指定部署代码所需的 gas。gas 数量会随着你的合约大小而变化。对于投票合约, 290000 就足够了。

更新 truffle 配置文件

像下面这样更新 truffle.js 的内容:

require('babel-register')
module.exports = {networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*',
gas: 470000
} } }

你会注意到,之前的 truffle.js 与我们更新的文件唯一区别在于 gas 选项。
这是一个会应用到所有 migration 的全局变量。比如,如果你没有指定
2_deploy_contracts.js gas 值为 290000,migration 就会采用默认值 470000.

合约代码Voting.sol
之前我们已经完成了编码工作,无须额外改动即可用于 truffle。将文件从
simple_voting_dapp 复制到 contracts 目录即可。

创建账户(可用 metamask 上账户转币)

在能够部署合约之前,我们需要一个里面有一些以太的账户。当我们用
ganache 的时候,它创建了 10 个测试账户,每个账户里面有 100 个测试以
太。但是对于测试网和主网,我们必须自己创建账户,并往里面打一些以太。

在之前的 ganache 应用里,我们曾单独启动了一个 node 控制台,并初始
化了 web3 对象。当我们执行 truffle 控制台时,truffle 会帮我们做好所有准备,我们会有一个立即可用的 web3 对象。现在我们有一个账户,地址为
‘0x95a94979d86d9c32d1d2ab5ace2dcc8d1b446fa1’ (你会得到一个不同的地址),账户余额为 0。

 >truffle console
// Replace 'verystrongpassword' with a good strong password.
truffle(development)>
web3.personal.newAccount('verystrongpassword') ' 0xbaeec91f6390a4eedad8729aea4bf47bf8769b15'
truffle(development)>
web3.eth.getBalance('0xbaeec91f6390a4eedad8729aea4bf47bf8769b1
5')
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }
truffle(development)>
web3.personal.unlockAccount('0xbaeec91f6390a4eedad8729aea4bf47
bf8769b15', 'verystrongpassword', 15000)

部署

如果已经有了一些以太,我们就可以继续编译并把合约部署到区块链上。你
可以在下面找到相关命令,如果一切顺利,就会出现以下输出。

>truffle compile
Compiling Migrations.sol...Compiling Voting.sol...Writing
artifacts to ./build/contracts
>truffle migrate
Running migration: 1_initial_migration.js
Deploying Migrations...
Migrations: 0x3cee101c94f8a06d549334372181bc5a7b3a8bee
Saving successful migration to network...
Saving artifacts...
Running migration: 2_deploy_contracts.js
Deploying Voting...
Voting: 0xd24a32f0ee12f5e9d233a2ebab5a53d4d4986203
Saving successful migration to network...
Saving artifacts...

如果你有多个账户,确保相关账户未被锁定。默认情况,第一个账户
web3.eth.accounts[0] 会用于部署。

可能出现的问题和解决方案

  1. 如果由于 gas 不足而部署失败,尝试将
    migrations/2_deploy_contracts.js 里面的 gas account 增加至
    500000。比如:deployer.deploy(Voting, [‘Rama’, ‘Nick’, ‘Jose’],
    {gas: 500000});
  2. 如果你有多个账户,并且更喜欢自选一个账户,而不是 accounts[0],你可以在 truffle.js 中指定想要使用的账户地址。在 network_id 后面添
    加 ‘from: your address’,truffle 将会使用你指定的地址来部署和交互。

如果部署顺利,你可以通过控制台和网页与合约进行交互

新建 JavaScript 文件 app/scripts/index.js

   // Import the page's CSS. Webpack will know what to do with it.
import "../styles/app.css";
// Import libraries we need.
import { default as Web3} from 'web3';
import { default as contract } from 'truffle-contract'
import voting_artifacts from '../../build/contracts/Voting.json'
var Voting = contract(voting_artifacts);
let candidates = {"Alice": "candidate-1", "Bob": "candidate-2",
"Cary": "candidate-3"}
window.voteForCandidate = function(candidate) { let candidateName = $("#candidate").val(); try { $("#msg").html("Vote has been submitted. The vote count will increment as soon as the vote is recorded on the blockchain. Please wait.") $("#candidate").val("");Voting.deployed().then(function(contractInstance) { contractInstance.voteForCandidate(candidateName, {gas: 140000,from:web3.eth.accounts[0]}).then(function() { let div_id = candidates[candidateName]; returncontractInstance.totalVotesFor.call(candidateName).then(function(v) { $("#" + div_id).html(v.toString()); $("#msg").html(""); }); }); }); } catch (err) { console.log(err); }
}$( document ).ready(function() { if (typeof web3 !== 'undefined') { console.warn("Using web3 detected from external source like Metamask") // Use Mist/MetaMask's provider window.web3 = new Web3(web3.currentProvider); } else { console.warn("No web3 detected. Falling back to http://localhost:8545. You should remove this fallback when you deploy live, as it's inherently insecure. Consider switching to Metamask for development. More info here: http://truffleframework.com/tutorials/truffle-and-metamask"); // fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail) window.web3 = new Web3(newWeb3.providers.HttpProvider("http://localhost:8545")); }Voting.setProvider(web3.currentProvider); let candidateNames = Object.keys(candidates); for (var i = 0; i < candidateNames.length; i++) { let name = candidateNames[i]; Voting.deployed().then(function(contractInstance) { contractInstance.totalVotesFor.call(name).then(function(v) { $("#" + candidates[name]).html(v.toString()); }); }); }
});

Line 7: 当你编译部署好投票合约时,truffle 会将 abi 和部署好的地址存储
到一个 build 目录下面的 json 文件。我们已经在之前讨论了 abi 。我们会用
这个信息来启动一个 Voting 抽象。我们将会随后用这个 abstraction 创建一个Voting 合约的实例。

Line 14: Voting.deployed() 返回一个合约实例。truffle 的每一个调用会返
回一个 promise,这就是为什么我们在每一个交易调用时都使用 then().

控制台交互需要重新打开一个新的 console

>truffle console
truffle(default)>
Voting.deployed().then(function(contractInstance)
{contractInstance.voteForCandidate('Alice').then(function(v)
{console.log(v)})})
{ blockHash:
'0x7229f668db0ac335cdd0c4c86e0394a35dd471a1095b8fafb52ebd76714
33156',
blockNumber: 469628,
contractAddress: null,
....
....
truffle(default)>
Voting.deployed().then(function(contractInstance)
{contractInstance.totalVotesFor.call('Alice').then(function(v)
{console.log(v)})})
{ [String: '1'] s: 1, e: 0, c: [ 1] }

在调用 voteForCandidate 方法之后需要稍等一下,因为发送交易需要时间;
注意,truffle 的所有调用都会返回一个 promise,这就是为什么会看到每个
响应被包装在 then() 函数下面;另外 totalVoteFor() 方法也可以不加.call() 直
接调用,不会发送交易。

发出的交易可以在 geth 的 log 输出文件中查到;如果我们连接的是测试网
络,可以在 etherscan 上 https://rinkeby.etherscan.io 查询。

可以看到 truffle 默认的 gasPrice 是 100GWei,如果心疼,可以在 truffle.js 中更改,加上 gasPrice: 1000000000 将其改为 1GWei,重启 truffle console 生效。

网页交互
在控制台用 webpack 启动服务器:

>npm run dev

默认端口 8080,在浏览器访问 localhost:8080 即可看到页面。
如果安装了 metamask,index.js 中会自动检测并使用 metamask 作为 web3
Provider;所以应该注意把 metamask 切换到我们当前连接的网络。

以太坊开发框架——Truffle的基础使用相关推荐

  1. 【web3实践 | 以太坊开发框架Truffle使用】

    Truffle简介 Truffle是一个面向以太坊的开发框架,提供一整套构建.测试.部署以及管理智能合约的开发工具.Truffle可以与以太坊节点交互,使开发人员能够在本地开发.测试和部署智能合约. ...

  2. (四)以太坊——运用truffle框架部署第一个DAPP ---- Pet-Shop

    内容大纲: 本项目是在以太坊上开的一个宠物领养的DAPP,借助了truffle框架和ganache进行合约部署.同时实现web端与区块链的交互. 1.设置开发环境 2.使用 Truffle Box 创 ...

  3. 120 以太坊 ethereum truffle : 编写自动化智能合约测试

    • 介绍 • 关于测试 • 设置测试环境 • 编写单元测试 • 执行复杂的断言 • truffle Tutorials 教程 • Contact 联系方式 • 介绍 在区块链环境中,一个错误可能会花费 ...

  4. 以太坊:Truffle 和 MetaMask 配合

    Truffle 和 MetaMask 配合 在浏览器中与智能合约进行交互之前,请确保合约已经编译及部署,并且我们是通过客户端JavaScript中的web3与合约进行交互. Truffle 建议使用t ...

  5. 以太坊Web3.js开发基础

    简介 web3.js是一个通过RPC调用和本地以太坊节点进行通信的js库.web3.js可以与任何暴露了RPC接口的以太坊节点连接 .web3中提供了eth对象 - web3.eth来与以太坊区块链进 ...

  6. 以太坊 – 使用truffle console访问智能合约

  7. 如何开始学习以太坊及区块链

    一.    以太坊和区块链的关系 从区块链历史上来说,先诞生了比特币,当时并没有区块链这个技术和名词,然后业界从比特币中提取了技术架构和体系,称之为区块链技术.从比特币提取的区块链技术称之为区块链1. ...

  8. 第一课 以太坊开发从入门到精通学习导航

    辉哥认为,区块链是人类社会伟大的革命,改变了生产关系.但是作为技术人员,有必要了解全部底层技术和算法吗?依稀记得,以前有些培训机构培训使用电脑时先教五笔输入法,然后才开始学习使用WINDOWS,让很多 ...

  9. 【区块链】以太坊区块链技术初探

    2019独角兽企业重金招聘Python工程师标准>>> [国内首家]以太坊区块链实战教学:http://edu.csdn.net/course/detail/6455 LinApex ...

最新文章

  1. MySQL 中 6 个常见的日志问题
  2. Java-工具类之发送邮件
  3. spring boot: 计划任务@ EnableScheduling和@Scheduled
  4. SAP 电商云 Spartacus UI 里的 InjectionToken 应用场景
  5. 排得更好VS估得更准VS搜的更全「推荐、广告、搜索」算法间到底有什么区别?...
  6. C# Word 转PDF
  7. weblogic jms消息 删除_利用 Kafka 设置可靠的高性能分布式消息传递基础架构
  8. mysql5.7.17主从_mysql5.7.17主从同步配置
  9. MRTK 当进入某个物体时调用的函数
  10. 基于BP神经网络识别手写字体MINST字符集
  11. echarts 实现世界地图地域流向炫酷效果
  12. 利用代理爬取搜狗微信文章
  13. 1050ti比1050强多少 gtx1050和gtx1050ti差距大吗
  14. 884.两句话中的不常见单词
  15. amd显卡多屏识别了 但是屏幕不亮_最近发布:针对AMD显卡多屏显示设置的完整解决方案。ppt28...
  16. 获取手机信息(UIDevice、NSLocale、NSBundle)
  17. 企业微信【加入群聊】群活码十问十答
  18. arduino如何加载OLED屏幕库
  19. WEB漏洞-逻辑越权之登录脆弱及支付修改
  20. 自己动手搭建NAS(一)|简介

热门文章

  1. 生成符合SCI论文投稿要求的高清图方法
  2. 初等函数——幂函数(Power Function)
  3. css隐藏滚动条兼容IE,火狐,chrom
  4. 《Java入门从笨鸟到菜鸟》读后感(三)
  5. 初学怕python画图工具pen以及初学个人感悟
  6. 华为腾讯汉能:叫响世界的三大中国自主创新企业
  7. 单片机串口通讯RXD与TXD如何对接详解
  8. 跟着老猫来搞GO——启程
  9. 【论文阅读】Adaptive Clustering-based Malicious Traffic Classification at the Network Edge
  10. 递归解决年龄问题---c语言实现