web3.js编译Solidity,发布,调用全部流程(手把手教程)
web3.js编译Solidity,发布,调用全部流程(手把手教程)
下面教程是打算在尽量牵涉可能少的以太坊的相关工具,主要使用web3.js这个以太坊提供的工具包,来完成合约的编译,发布,合约方法调用的一整个流程。一方面来了解以太坊开发到底需要什么,另一方面来对web3.js的API有个基本的了解。由于所有其它工具都或多或少的是对web3.js的底层函数的包装,所以对web3.js使用流程有个认识之后,也能更好的入门,使用相关的工具。
http://web3.tryblockchain.org/web3-js-in-action.html
1. 准备工作
1.1 安装Node.js
由于我们要使用web3.js1。这里使用Node来集成web3.js模块(当然,你还可以使用其它的方式)。你可以通过参考官网文档安装2。
1.1.1 Ubuntu
如果你使用ubuntu,可以使用下述命令:
//安装Node
sudo apt-get install nodejs
//安装Node的包管理器
sudo apt-get install npm
1.1.2 MAC
如果你使用Homebrew
,可以使用下述命令:
//安装Node
brew install node
//安装Node的包管理器
brew install npm
1.1.3 安装检查
安装成功后,可以查看下当前的版本,确认正常安装:
$ node -v
v7.2.0
1.2 以太坊的节点
由于整个合约代码的执行需要一个虚拟机环境,所以在开始之前,我们不得不安装一个实现了以太坊虚拟机的节点。
可以选择一个轻量级的节点,比如EtherumJS TestRPC
,它是一个完整的在内存中的区块链仅仅存在于你开发的设备上。它在执行交易时是实时返回,而不等待默认的出块时间,这样你可以快速验证你新写的代码,当出现错误时,也能即时反馈给你。
npm install -g ethereumjs-testrpc
安装好后,你就可以通过testrpc
命令来启动了,启动与大多数以太坊节点一样,运行在localhost:8545
。
如果你安装geth
这样的客户端也是可以的。
1.3 Web3的支持
安装web3
的模块1:
npm install web3
2. 合约编译
2.1 一个简单的合约
我们打算用来测试的合约如下:
pragma solidity ^0.4.0;
contract Calc{
/*区块链存储*/
uint count;
/*执行会写入数据,所以需要`transaction`的方式执行。*/
function add(uint a, uint b) returns(uint){
count++;
return a + b;
}
/*执行不会写入数据,所以允许`call`的方式执行。*/
function getCount() constant returns (uint){
return count;
}
}
add()
方法用来返回输入两个数据的和,并会对add()
方法的调用次数进行计数。需要注意的是这个计数是存在区块链上的,对它的调用需要使用transaction
。
getCount()
返回add()
函数的调用次数。由于这个函数不会修改区块链的任何状态,对它的调用使用call
就可以了。
2.2 编译合约
由于合约是使用Solidity
编写,所以我们可以使用web3.eth.compile.solidity
来编译合约3:
//编译合约
let source = "pragma solidity ^0.4.0;contract Calc{ /*区块链存储*/ uint count; /*执行会写入数据,所以需要`transaction`的方式执行。*/ function add(uint a, uint b) returns(uint){ count++; return a + b; } /*执行不会写入数据,所以允许`call`的方式执行。*/ function getCount() returns (uint){ return count; }}";
let calc = web3.eth.compile.solidity(source);
如果编译成功,结果如下:
{
code: '0x606060405234610000575b607e806100176000396000f3606060405260e060020a6000350463771602f781146026578063a87d942c146048575b6000565b3460005760366004356024356064565b60408051918252519081900360200190f35b3460005760366077565b60408051918252519081900360200190f35b6000805460010190558181015b92915050565b6000545b9056',
info: {
source: 'pragma solidity ^0.4.0;contract Calc{ /*区块链存储*/ uint count; /*执行会写入数据,所以需要`transaction`的方式执行。*/ function add(uint a, uint b) returns(uint){ count++; return a + b; } /*执行不会写入数据,所以允许`call`的方式执行。*/ function getCount() returns (uint){ return count; }}',
language: 'Solidity',
languageVersion: '0.4.6+commit.2dabbdf0.Emscripten.clang',
compilerVersion: '0.4.6+commit.2dabbdf0.Emscripten.clang',
abiDefinition: [
[
Object
],
[
Object
]
],
userDoc: {
methods: {
}
},
developerDoc: {
methods: {
}
}
}
}
3. 发布合约
web3.js
其实也像框架一样对合约的操作进行了封装。发布合约时,可以使用web3.eth.contract
的new
方法4。
let myContractReturned = calcContract.new({
data: deployCode,
from: deployeAddr
}, function(err, myContract) {
if (!err) {
// 注意:这个回调会触发两次
//一次是合约的交易哈希属性完成
//另一次是在某个地址上完成部署
// 通过判断是否有地址,来确认是第一次调用,还是第二次调用。
if (!myContract.address) {
console.log("contract deploy transaction hash: " + myContract.transactionHash) //部署合约的交易哈希值
// 合约发布成功
} else {
}
});
部署过程中需要主要的是,new
方法的回调会执行两次,第一次是合约的交易创建完成,第二次是在某个地址上完成部署。需要注意的是只有在部署完成后,才能进行方法该用,否则会报错TypeError: myContractReturned.add is not a function
。
4. 调用合约
由于web3.js
封装了合约调用的方法。我们可以使用可以使用web3.eth.contract
的里的sendTransaction
来修改区块链数据。在这里有个坑,有可能会出现Error: invalid address
,原因是没有传from
,交易发起者的地址。在使用web3.js
的API都需留意,出现这种找不到地址的,都看看from字段吧。
//使用transaction方式调用,写入到区块链上
myContract.add.sendTransaction(1, 2,{
from: deployeAddr
});
console.log("after contract deploy, call:" + myContract.getCount.call());
需要注意的是,如果要修改区块链上的数据,一定要使用sendTransaction
,这会消耗gas
。如果不修改区块链上的数据,使用call
,这样不会消耗gas
。
5. 使用web3.js编译,发布,调用的完整源码
let Web3 = require('web3');
let web3;
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
let from = web3.eth.accounts[0];
//编译合约
let source = "pragma solidity ^0.4.0;contract Calc{ /*区块链存储*/ uint count; /*执行会写入数据,所以需要`transaction`的方式执行。*/ function add(uint a, uint b) returns(uint){ count++; return a + b; } /*执行不会写入数据,所以允许`call`的方式执行。*/ function getCount() constant returns (uint){ return count; }}";
let calcCompiled = web3.eth.compile.solidity(source);
console.log(calcCompiled);
console.log("ABI definition:");
console.log(calcCompiled["info"]["abiDefinition"]);
//得到合约对象
let abiDefinition = calcCompiled["info"]["abiDefinition"];
let calcContract = web3.eth.contract(abiDefinition);
//2. 部署合约
//2.1 获取合约的代码,部署时传递的就是合约编译后的二进制码
let deployCode = calcCompiled["code"];
//2.2 部署者的地址,当前取默认账户的第一个地址。
let deployeAddr = web3.eth.accounts[0];
//2.3 异步方式,部署合约
let myContractReturned = calcContract.new({
data: deployCode,
from: deployeAddr
}, function(err, myContract) {
if (!err) {
// 注意:这个回调会触发两次
//一次是合约的交易哈希属性完成
//另一次是在某个地址上完成部署
// 通过判断是否有地址,来确认是第一次调用,还是第二次调用。
if (!myContract.address) {
console.log("contract deploy transaction hash: " + myContract.transactionHash) //部署合约的交易哈希值
// 合约发布成功后,才能调用后续的方法
} else {
console.log("contract deploy address: " + myContract.address) // 合约的部署地址
//使用transaction方式调用,写入到区块链上
myContract.add.sendTransaction(1, 2,{
from: deployeAddr
});
console.log("after contract deploy, call:" + myContract.getCount.call());
}
// 函数返回对象`myContractReturned`和回调函数对象`myContract`是 "myContractReturned" === "myContract",
// 所以最终`myContractReturned`这个对象里面的合约地址属性也会被设置。
// `myContractReturned`一开始返回的结果是没有设置的。
}
});
//注意,异步执行,此时还是没有地址的。
console.log("returned deployed didn't have address now: " + myContractReturned.address);
//使用非回调的方式来拿到返回的地址,但你需要等待一段时间,直到有地址,建议使用上面的回调方式。
/*
setTimeout(function(){
console.log("returned deployed wait to have address: " + myContractReturned.address);
console.log(myContractReturned.getCount.call());
}, 20000);
*/
//如果你在其它地方已经部署了合约,你可以使用at来拿到合约对象
//calcContract.at(["0x50023f33f3a58adc2469fc46e67966b01d9105c4"]);
参考资料
web3.js编译Solidity,发布,调用全部流程(手把手教程)的更多相关文章
- 【阿菜用工具】利用 Web3.js 在 ganache 上部署以及调用智能合约
合约部署 要部署的合约 pragma solidity ^0.4.23; contract test { uint256 value; function setValue(uint256 _value ...
- web3.js支持SimpleChain跨链调用
SimpleChain的跨链协议已经对外开放很久了,很多应用也已经慢慢支持Simplechain的跨链.最近社区开发者web3.js中集成了Simplechain的跨链接口,开发者只需用npm安装包文 ...
- Web3.js API 中文文档
Web3.js API 中文文档 http://web3.tryblockchain.org/Web3.js-api-refrence.html web3对象提供了所有方法. 示例: //初始化过程 ...
- ionic实战系列(一):ionic的开发环境配置和编译、发布
我的ionic实战系列是基于<<Ionic实战>>[美]Jeremy Wilken著-这本书的读书笔记,有诸多借鉴,不详细的地方请参考书籍本身的内容. 1.1技术栈模型 Ion ...
- Web3.js 0.20.x API 中文版翻译
文档原始链接为:https://web3.learnblockchain.cn/0.2x.x/,欢迎大家前往查阅,本文只是节选开头部分的介绍及API列表索引,以下为翻译正文: 为了开发一个基于以太坊的 ...
- cocos2d-html5将js编译为jsc
在d:\DevTool\cocos2d-x-2.2.2\cocos2d-x-2.2.2\tools\cocos2d-console\console 有 cocos2d_jscompile.py coc ...
- cocos2d-html5的jsb模式下如何在编译时自动将js编译为jsc
cocos2d-html5是一个用JS来开发游戏的框架,通过javascript Binding的方式可以将游戏编译到手机上.这对前端开发人员来说非常方便,开发效率也比使用c++开发要快的多. jsb ...
- 再深刻理解下web3.js中estimateGas如何计算智能合约消耗的gas量
我们可使用web3.js框架的estimateGas函数获得一个以太坊智能合约的Gas估计值 ,通过执行一个消息调用或交易,该消息调用或交易直接在节点的VM中执行,并未在区块链中确认,函数会返回估算使 ...
- 使用web3.js监听以太坊智能合约event
传送门: 柏链项目学院 使用web3.js监听以太坊智能合约event 当我们在前端页面调用合约时发现有些数据不会立即返回,这时还需要再调用更新数据的函数.那么这样的方法使用起来非常不便,监听ev ...
随机推荐
- bat删除过期文件(FORFILES)
关键词:bat删除过期文件,bat,FORFILES 原文:https://blog.csdn.net/sandy9919/article/details/82932460 --最佳实践 :: IIS ...
- mysql 1,2,3 关联查询出数字代表的具体意思
建表 TEST1 CREATE TABLE `TEST1` (`ID` int(11) NOT NULL,`IID` varchar(200) DEFAULT NULL,PRIMARY KEY (`I ...
- 【设计模式】用追MM来解释23种设计模式,转
创建型模式 1.FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了.麦当劳和肯德基 ...
- word2vec 评测 size_diff
This is a test for word2vecWed Nov 07 16:47:19 2018dir of model1: ./model/window3_ min_count2_worker ...
- [LeetCode] 系统刷题5_Dynamic Programming
Dynamic Programming 实际上是[LeetCode] 系统刷题4_Binary Tree & Divide and Conquer的基础上,加上记忆化的过程.就是说,如果这个题 ...
- IntelliJ IDEA 普通java工程如何转为maven工程
1.项目上右键 Add Framework Support. 2.选择maven,点击OK.
- 启动及更改tomcat 配置
到tomcat安装的bin目录下面,双击那个startup.bat文件,启动Tomcat 去浏览器输入 http://localhost:8080/ 然后出现下面的界面,那就说明你的tomcat配置 ...
- 《大道至简》第一章读后感Java伪代码
在<大道至简>第一章中,周爱民先生引用一则<愚公移山>的寓言,引出了编程的根本:顺序.选择.循环.“愚公移山”的工程虽然庞大,但是可以通过极其简单的变成来完成.我身边的有一些人 ...
- 转 EasyUi日期控件datebox设置,只显示年月,也只能选择年月
1.引入Jquery和easyui,注低版本的Jquery和easy不能使用,这里使用的Jquery是1.8.2easyui是1.6.1.1.easyui下载地址:http://www.jeasyui ...
- eclipse签名使用的key文件(android生成keystore)
命令行(或终端)生成keystore文件 在命令行(或终端)输入命令: keytool -genkey -alias Gallery.keystore -keyalg RSA -validit ...