1. 文章摘要
【本文目标】
了解ETH生态下DAPP去中心化应用程序的框架和交互流程,了解WEB3.JS的作用和接口函数。
【前置条件】
完成了《第六课 技术小白如何开发一个DAPP区块链应用(以宠物商店为例)》的学习实践,对智能合约了解。
【技术收获】
1). DAPP架构
2). ETH节点框架
3).宠物商店的APP.js文件的业务处理流程图和函数介绍
4).web3.js接口
【实操课程列表】
第一课 如何在WINDOWS环境下搭建以太坊开发环境
第二课 如何实现以太坊最简智能合约“Hello World”的运行
第四课 以太坊开发框架Truffle从入门到实战
第六课 技术小白如何开发一个DAPP区块链应用(以宠物商店为例)
第七课 技术小白如何在45分钟内发行通证(TOKEN)并上线交易
第八课 如何调试以太坊官网的智能合约众筹案例
第九课 如何在Remix环境下进行Solidity代码单步调试
第十课 Solidity语言编辑器REMIX指导大全
第十一课 从宠物商店案例看DAPP架构和WEB3.JS交互接口
【说明】未列出的课程为知识普及的非实操类课程,所有区块链文章参考“区块链入口”专栏。
2. 以太坊节点和DAPP框架
2.1 以太坊节点架构
以太坊是一种区块链的实现。在以太坊网络中,众多的节点彼此连接,构成了以太坊网络。
以太坊节点软件提供两个核心功能:数据存储、合约代码执行。
在每个以太坊全节点中,都保存有完整的区块链数据。以太坊不仅将交易数据保存在链上,编译后 的合约代码同样也保存在链上。以太坊全节点中,同时还提供了一个虚拟机来执行合约代码。
交易数据
以太坊中每笔交易都存储在区块链上。当你部署合约时,一次部署就是一笔交易。当你为候选者投票时,一次投票 又是另一笔交易。所有的这些交易都是公开的,每个人都可以看到并进行验证。这个数据永远也无法篡改。
为了确保网络中的所有节点都有着同一份数据拷贝,并且没有向数据库中写入任何无效数据,以太坊 目前使用工作量证明 (POW:Proof Of Work
)算法来保证网络安全,即通过矿工挖矿(Mining
)来达成共识(Consensus
)—— 将数据同步到所有节点。
工作量证明不是达成共识的唯一算法,挖矿也不是区块链的唯一选择。现在,我们只需要了解,共识是指各节点 的数据实现了一致,POW
只是众多用于建立共识的算法中的一种,这种算法需要通过矿工的挖矿来实现非可信环境下的 可信交易。共识是目的,POW是手段。
合约代码
以太坊不仅仅在链上存储交易数据,它还可以在链上存储合约代码。
在数据库层面,区块链的作用就是存储交易数据。那么给候选者投票、或者检索投票结果的逻辑放在哪儿呢? 在以太坊的世界里,你可以使用Solidity
语言来编写业务逻辑/应用代码(也就是合约:Contract
), 然后将合约代码编译为以太坊字节码,并将字节码部署到区块链上:
编写合约代码也可以使用其他的语言,不过 Solidity是到目前为止最流行的选择。
以太坊虚拟机
以太坊区块链不仅存储数据和代码,每个节点中还包含一个虚拟机(EVM:Ethereum Virtual Machine)来执行 合约代码 —— 听起来就像计算机操作系统。
事实上,这一点是以太坊区别于比特币(Bitcoin)的最核心的一点:虚拟机的存在使区块链迈入了2.0 时代,也让区块链第一次成为应用开发者友好的平台。
2.2 DAPP架构
下图给出了基于以太坊的去中心化应用架构:
每个客户端(浏览器)都是与各自的节点应用实例进行交互,而不是向 一个中心化的服务器请求服务。
在一个理想的去中心化环境中,每个想要跟DApp交互的人,都需要在他们的计算机或手机上面运行 一个的完整区块链节点 —— 简言之,每个人都运行一个全节点。这意味着,在能够真正使用一个 去中心化应用之前,用户不得不下载整个区块链。
不过我们并非生活在一个乌托邦里,期待每个用户都先运行一个全节点,然后再使用你的应用是不现实的。 但是去中心化背后的核心思想,就是不依赖于中心化的服务器。所以,区块链社区已经出现了 一些解决方案,例如提供公共区块链节点的Infura, 以及浏览器插件Metamask等。通过这些方案, 你就不需要花费大量的硬盘、内存和时间去下载并运行完整的区块链节点,同时也可以利用去中心化 的优点。
Web3.js是以太坊官方的Javascript API,可以帮助智能合约开发者使用HTTP或者IPC与本地的或者远程的以太坊节点交互。实际上就是一个库的集合,主要包括下面几个库:
-
web3-eth
用来与以太坊区块链和智能合约交互 -
web3-shh
用来控制whisper协议与p2p通信以及广播 -
web3-bzz
用来与swarm协议交互 -
web3-utils
包含了一些Dapp开发有用的功能
Web3与geth通信使用的是 JSON-RPC ,这是一种轻量级的RPC(Remote Procedure Call)协议,整个通信的模型可以抽象为下图。
3. 以宠物商店为例WEB3.JS代码
第六课 技术小白如何开发一个DAPP区块链应用(以宠物商店为例) 这篇文章详细介绍了一个宠物商店DAPP的案例。本节重点分析引用WEB3.JS相关接口代码。
3.1 加注释的app.js代码
App = {
web3Provider: null,
contracts: {},
init: function() {
/*加载宠物名字,图片,年龄,位置等信息*/
// Load pets.
$.getJSON('../pets.json', function(data) {
var petsRow = $('#petsRow');
var petTemplate = $('#petTemplate');
for (i = 0; i < data.length; i ++) {
petTemplate.find('.panel-title').text(data[i].name);
petTemplate.find('img').attr('src', data[i].picture);
petTemplate.find('.pet-breed').text(data[i].breed);
petTemplate.find('.pet-age').text(data[i].age);
petTemplate.find('.pet-location').text(data[i].location);
petTemplate.find('.btn-adopt').attr('data-id', data[i].id);
petsRow.append(petTemplate.html());
}
});
return App.initWeb3();
},
initWeb3: function() {
/*如果web3事先被定义,则使用当前web3实例的钱包对象。例如remix下JavaScript VM创建的虚拟钱包(有4个含100个 ETH的账户);
或者MetaMask链接后的账户钱包;或者mist钱包*/
if (typeof web3 !== 'undefined') {
App.web3Provider = web3.currentProvider;
} else {
// If no injected web3 instance is detected, fall back to Ganache
/*如果web3不存在,则启动本地启动的Ganache钱包。[前提:要启动好本地的Ganache环境哦,否则会创建不成功]*/
App.web3Provider = new Web3.providers.HttpProvider('http://localhost:7545');
}
/*创建Web3实例,入口参数为刚才配置的App.web3Provider*/
web3 = new Web3(App.web3Provider);
/*调用初始化合约函数*/
return App.initContract();
},
initContract: function() {
/*参考 http://www.w3school.com.cn/jquery/ajax_getjson.asp 获取getJSON到的方法*/
$.getJSON('Adoption.json', function(data) {
// Get the necessary contract artifact file and instantiate it with truffle-contract
var AdoptionArtifact = data;
App.contracts.Adoption = TruffleContract(AdoptionArtifact);
// 设置当前合约的web3Provider钱包提供者
App.contracts.Adoption.setProvider(App.web3Provider);
// 使用我们的合约去提取和标识已领养的宠物
return App.markAdopted();
});
/*返回绑定事件*/
return App.bindEvents();
},
/*点击含有'.btn-adopt'类的click事件会触发handleAdopt(处理领养)的函数*/
bindEvents: function() {
$(document).on('click', '.btn-adopt', App.handleAdopt);
},
/*如果该宠物已被领养,则文字显示为"Success",按钮不可点击*/
markAdopted: function(adopters, account) {
var adoptionInstance;
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
return adoptionInstance.getAdopters.call();
}).then(function(adopters) {
for (i = 0; i < adopters.length; i++) {
/*如果领养者的地址不是为0,则设置按钮字体和状态,*/
if (adopters[i] !== '0x0000000000000000000000000000000000000000') {
$('.panel-pet').eq(i).find('button').text('Success').attr('disabled', true);
}
}
}).catch(function(err) {
console.log(err.message);
});
},
handleAdopt: function(event) {
event.preventDefault();
/*parseInt() 函数可解析一个字符串,并返回一个整数。*/
var petId = parseInt($(event.target).data('id'));
var adoptionInstance;
/*获取当前ETH钱包的账号*/
web3.eth.getAccounts(function(error, accounts) {
if (error) {
console.log(error);
}
/*取第一个钱包账号*/
var account = accounts[0];
/*ES6的then函数调用,链式调用*/
App.contracts.Adoption.deployed().then(function(instance) {
adoptionInstance = instance;
// 通过发送账户执行adopt领养函数的交易的返回值
// 此处没有搞懂,智能合约Adoption.adopt只有一个入参,此处为什么增加了第二个{from: account}参数呢?
//TINY熊认为,把它当做语法就可以, 要么提前设置默认账号, 要么调用时指定
return adoptionInstance.adopt(petId, {from: account});
}).then(function(result) {
/*标识领养状态*/
return App.markAdopted();
/*输出错误*/
}).catch(function(err) {
console.log(err.message);
});
});
}
};
/*窗口加载即调用App.init函数*/
$(function() {
$(window).load(function() {
App.init();
});
});
3.2 app.js调用WEB3流程分析
4. Web3 JavaScript app API 参考
Web3的官网文档给出了详细的接口文档和说明。
- web3
- web3.version.api
- web3.version.node
- web3.version.network
- web3.version.ethereum
- web3.version.whisper
- web3.isConnected
- web3.setProvider
- web3.currentProvider
- web3.reset
- web3.sha3
- web3.toHex
- web3.toAscii
- web3.fromAscii
- web3.toDecimal
- web3.fromDecimal
- web3.fromWei
- web3.toWei
- web3.toBigNumber
- web3.net
- web3.net.listening
- web3.net.peerCount
- web3.eth
- web3.eth.defaultAccount
- web3.eth.defaultBlock
- web3.eth.syncing
- web3.eth.isSyncing
- web3.eth.coinbase
- web3.eth.mining
- web3.eth.hashrate
- web3.eth.gasPrice
- web3.eth.accounts
- web3.eth.blockNumber
- web3.eth.register
- web3.eth.unRegister
- web3.eth.getBalance
- web3.eth.getStorageAt
- web3.eth.getCode
- web3.eth.getBlock
- web3.eth.getBlockTransactionCount
- web3.eth.getUncle
- web3.eth.getTransaction
- web3.eth.getTransactionFromBlock
- web3.eth.getTransactionReceipt
- web3.eth.getTransactionCount
- web3.eth.sendTransaction
- web3.eth.sendRawTransaction
- web3.eth.sign
- web3.eth.call
- web3.eth.estimateGas
- web3.eth.filter
- web3.eth.contract
- 合约对象的方法
- 合约对象的事件
- 合约 allEvents
- web3.eth.getCompilers
- web3.eth.compile.solidity
- web3.eth.compile.lll
- web3.eth.compile.serpent
- web3.eth.namereg
- web3.db
- web3.db.putString
- web3.db.getString
- web3.db.putHex
- web3.db.getHex
web3
web3
对象提供了所有方法。
示例:
//初始化过程
var Web3 = require('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"));
}
web3.version.api
web3.version.api
返回值:
String
- 以太坊js的api版本
示例:
//省略初始化过程
var version = web3.version.api;
console.log(version);
$ node test.js
0.18.2
web3.version.node
同步方式:
web3.verison.node
异步方式:
web3.version.getNode(callback(error, result){ ... })
返回值:
String
- 客户端或节点的版本信息
示例:
//省略初始化过程
var version = web3.version.node;
console.log(version);
$ node test.js
EthereumJS TestRPC/v3.0.3/ethereum-js
web3.version.network
同步方式:
web3.version.network
异步方式:
web3.version.getNetwork(callback(error, result){ ... })
返回值:
String
- 网络协议版本
示例:
//省略初始化过程
var version = web3.version.network;
console.log(version);
$ node test.js
1488546587563
web3.version.ethereum
同步方式:
web3.version.ethereum
异步方式:
web3.version.getEthereum(callback(error, result){ ... })
返回值:
String
- 以太坊的协议版本
示例:
//省略初始化过程
var version = web3.version.ethereum;
console.log(version);
$ node test.js
60
注意:EthereumJS testRPC
客户端不支持这个命令,报错Error: Error: RPC method eth_protocolVersion not supported.
web3.version.whisper
同步方式:
web3.version.whisper
异步方式:
web3.version.getWhisper(callback(error, result){ ... })
返回值:
String
- whisper
协议的版本
示例:
//省略初始化过程
var version = web3.version.whisper;
console.log(version);
$ node test.js
20
注意:EthereumJS testRPC
客户端不支持这个命令,报错Error: Error: RPC method shh_version not supported.
web3.isConnected
web3.isConnected
可以用来检查到节点的连接是否存在(connection to node exist)。
参数:
无
返回值:
Boolean
示例:
//省略初始化过程
var connected = web3.isConnected();
if(!connected){
console.log("node not connected!");
}else{
console.log("node connected");
}
web3.setProvider
web3.setProvider
设置Provider
参数:
无
返回值:
undefined
示例:
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
web3.currentProvider
web3.currentProvider
如果已经设置了Provider
,则返回当前的Provider
。这个方法可以用来检查在使用mist
浏览器等情况下已经设置过Provider
,避免重复设置的情况。
返回值:
Object - null 或 已经设置的Provider
。
示例:
if(!web3.currentProvider)
web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545"));
web3.reset
web3.reset
用来重置web3
的状态。重置除了manager
以外的其它所有东西。卸载filter
,停止状态轮询。
参数:
- Boolean - 如果设置为
true
,将会卸载所有的filter
,但会保留web3.eth.isSyncing()
的状态轮询。
返回值:
undefined
示例:
//省略初始化过程
console.log("reseting ... ");
web3.reset();
console.log("is connected:" + web3.isConnected());
$ node test.js
reseting ...
is connected:true
web3.sha3
web3.sha3(string, options)
参数:
-
String
- 传入的需要使用Keccak-256 SHA3
算法进行哈希运算的字符串。 -
Object
- 可选项设置。如果要解析的是hex
格式的十六进制字符串。需要设置encoding
为hex
。因为JS中会默认忽略0x
。
返回值:
String
- 使用Keccak-256 SHA3
算法哈希过的结果。
示例:
//省略初始化过程
var hash = web3.sha3("Some string to be hashed");
console.log(hash);
var hashOfHash = web3.sha3(hash, {encoding: 'hex'});
console.log(hashOfHash);
web3.toHex
web3.toHex
将任何值转为HEX
。
参数:
-
String|Number|Object|Array|BigNumber
- 需要转化为HEX
的值。如果是一个对象或数组类型,将会先用JSON.stringify
1进行转换成字符串。如果传入的是BigNumber
2,则将得到对应的Number
的HEX
。
示例:
//初始化基本对象
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var BigNumber = require('bignumber.js');
var str = "abcABC";
var obj = {abc: 'ABC'};
var bignumber = new BigNumber('12345678901234567890');
var hstr = web3.toHex(str);
var hobj = web3.toHex(obj);
var hbg = web3.toHex(bignumber);
console.log("Hex of Sring:" + hstr);
console.log("Hex of Object:" + hobj);
console.log("Hex of BigNumber:" + hbg);
$ node test.js
Hex of Sring:0x616263414243
Hex of Object:0x7b22616263223a22414243227d
Hex of BigNumber:0xab54a98ceb1f0ad2
web3.toAscii
web3.toAscii(hexString)
将HEX
字符串转为ASCII
3字符串
参数:
-
String
- 十六进制字符串。
返回值:
String
- 给定十六进制字符串对应的ASCII
码值。
示例:
var str = web3.toAscii("0x657468657265756d000000000000000000000000000000000000000000000000");
console.log(str); // "ethereum"
web3.fromAscii
web3.fromAscii
将任何的ASCII
码字符串转为HEX
字符串。
参数:
-
String
-ASCII
码字符串 -
Number
- 返回的字符串字节大小,不够长会自动填充。
返回值:
String
- 转换后的HEX
字符串。
示例:
var str = web3.fromAscii('ethereum');
console.log(str); // "0x657468657265756d"
var str2 = web3.fromAscii('ethereum', 32);
console.log(str2); // "0x657468657265756d000000000000000000000000000000000000000000000000"
$ node test.js
0x657468657265756d
0x657468657265756d
备注: 填充padding
功能好像不可用4。
web3.toDecimal
web3.toDecimal
将一个十六进制转为一个十进制的数字
参数:
-
String
- 十六进制字符串
返回:
Number
- 传入字符串所代表的十六进制值。
示例:
var number = web3.toDecimal('0x15');
console.log(number); // 21
web3.fromDecimal
web3.fromDecimal
将一个数字,或者字符串形式的数字转为一个十六进制串。
参数:
-
Number|String
- 数字
返回值:
String
- 给定数字对应的十六进制表示。
示例:
var value = web3.fromDecimal('21');
console.log(value); // "0x15"
web3.fromWei
web3.fromWei(number, 单位)
以太坊货币单位之间的转换。将以wei
为单位的数量,转为下述的单位,可取值如下:
- kwei/ada
- mwei/babbage
- gwei/shannon
- szabo
- finney
- ether
- kether/grand/einstein
- mether
- gether
- tether
参数:
-
Number|String|BigNumber
- 数字或BigNumber
。 -
String
- 单位字符串
返回值:
String|BigNumber
- 根据传入参数的不同,分别是字符串形式的字符串,或者是BigNumber
。
示例:
var value = web3.fromWei('21000000000000', 'finney');
console.log(value); // "0.021"
web3.toWei
web3.toWei(number, 单位)
按对应货币转为以wei
为单位。可选择的单位如下:
- kwei/ada
- mwei/babbage
- gwei/shannon
- szabo
- finney
- ether
- kether/grand/einstein
- mether
- gether
- tether
参数:
-
Number|String|BigNumber
- 数字或BigNumber
-
String
- 字符串单位
返回值:
String|BigNumber
- 根据传入参数的不同,分别是字符串形式的字符串,或者是BigNumber
。
示例:
var value = web3.toWei('1', 'ether');
console.log(value); // "1000000000000000000"
web3.toBigNumber
web3.toBigNumber(数字或十六进制字符串)
将给定的数字或十六进制字符串转为BigNumber
5。
参数:
-
Number|String
- 数字或十六进制格式的数字
返回值:
BigNumber
- BigNumber
的实例
示例:
var value = web3.toBigNumber('200000000000000000000001');
console.log(value); // instanceOf BigNumber
console.log(value.toNumber()); // 2.0000000000000002e+23
console.log(value.toString(10)); // '200000000000000000000001'
web3.net
web3.net.listening
同步方式:
web3.net.listening
异步方式:
web3.net.getListener(callback(error, result){ ... })
此属性是只读的,表示当前连接的节点,是否正在listen
网络连接与否。listen
可以理解为接收。
返回值:
Boolean
- true
表示连接上的节点正在listen
网络请求,否则返回false
。
示例:
var listening = web3.net.listening;
console.log("client listening: " + listening);
$ node test.js
client listening: true
备注: 如果关闭我们要连接的测试节点,会报错Error: Invalid JSON RPC response: undefined
。所以这个方法返回的是我们连上节点的listen
状态。
web3.net.peerCount
同步方式:
web3.net.peerCount
异步方式:
web3.net.getPeerCount(callback(error, result){ ... })
属性是只读的,返回连接节点已连上的其它以太坊节点的数量。
返回值:
Number
- 连接节点连上的其它以太坊节点的数量
示例:
var peerCount = web3.net.peerCount;
console.log("Peer count: " + peerCount);
$ node test.js
Peer count: 0
web3.eth
包含以太坊区块链相关的方法
示例:
var eth = web3.eth;
web3.eth.defaultAccount
web3.eth.defaultAccount
默认的地址在使用下述方法时使用,你也可以选择通过指定from
属性,来覆盖这个默认设置。
- web3.eth.sendTransaction()
- web3.eth.call()
默认值为undefined
,20字节大小,任何你有私匙的你自己的地址。
返回值:
String
- 20字节的当前设置的默认地址。
示例:
console.log("Current default: " + web3.eth.defaultAccount);
web3.eth.defaultAccount = '0x8888f1f195afa192cfee860698584c030f4c9db1';
console.log("Current default: " + web3.eth.defaultAccount);
$ node test.js
Current default: undefined
Current default: 0x8888f1f195afa192cfee860698584c030f4c9db1
web3.eth.defaultBlock
web3.eth.defaultBlock
使用下述方法时,会使用默认块设置,你也可以通过传入defaultBlock
来覆盖默认配置。
- web3.eth.getBalance()
- web3.eth.getCode()
- web3.eth.getTransactionCount()
- web3.eth.getStorageAt()
- web3.eth.call()
- contract.myMethod.call()
- contract.myMethod.estimateGas()
可选的块参数,可能下述值中的一个:
-
Number
- 区块号 -
String
-earliest
,创世块。 -
String
-latest
,最近刚出的最新块,当前的区块头。 -
String
-pending
,当前正在mine
的区块,包含正在打包的交易。
默认值是latest
返回值:
Number|String
- 默认要查状态的区块号。
示例:
console.log("defaultBlock: " + web3.eth.defaultBlock);
web3.eth.defaultBlock = 231;
console.log("defaultBlock: " + web3.eth.defaultBlock);
$ node test.js
defaultBlock: latest
defaultBlock: 231
web3.eth.syncing
同步方式:
web3.eth.syncing
异步方式:
web3.eth.getSyncing(callback(error, result){ ... })
这个属性是只读的。如果正在同步,返回同步对象。否则返回false
。
返回值:
Object|Boolean
- 如果正在同步,返回含下面属性的同步对象。否则返回false
。
返回值:
-
startingBlock
:Number
- 同步开始区块号 -
currentBlock
:Number
- 节点当前正在同步的区块号 -
highestBlock
:Number
- 预估要同步到的区块
var sync = web3.eth.syncing;
console.log(sync);
$ node test.js
false
//正在sync的情况
$ node test.js
{
startingBlock: 300,
currentBlock: 312,
highestBlock: 512
}
web3.eth.isSyncing
web3.eth.isSyncing(callback)
提供同步开始,更新,停止的回调函数方法。
返回值:
Object
- 一个syncing
对象,有下述方法:
-
syncing.addCallback()
: 增加另一个回调函数,在节点开始或停止调用时进行调用。 -
syncing.stopWatching()
: 停止同步回调。
回调返回值:
-
Boolean
- 同步开始时,此值为true
,同步停止时此回调值为false
。 -
Object
- 当正在同步时,会返回同步对象。-
startingBlock
:Number
- 同步开始区块号 -
currentBlock
:Number
- 节点当前正在同步的区块号 -
highestBlock
:Number
- 预估要同步到的区块
-
示例:
//初始化基本对象
var Web3 = require('web3');
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var BigNumber = require('bignumber.js');
web3.eth.isSyncing(function(error, sync){
if(!error) {
// stop all app activity
if(sync === true) {
// we use `true`, so it stops all filters, but not the web3.eth.syncing polling
web3.reset(true);
// show sync info
} else if(sync) {
console.log(sync.currentBlock);
// re-gain app operation
} else {
// run your app init function...
}
}
});
web3.eth.coinbase
同步方式:
web3.eth.coinbase
异步方式:
web3.eth.getCoinbase(callback(error, result){ ... })
只读属性,节点配置的,如果挖矿成功奖励的地址。
返回值:
String
- 节点的挖矿奖励地址。
示例:
var coinbase = web3.eth.coinbase;
console.log(coinbase); // "0x407d73d8a49eeb85d32cf465507dd71d507100c1"
web3.eth.mining
同步方式:
web3.eth.mining
异步方式:
web3.eth.getMining(callback(error, result){ ... })
属性只读,表示该节点是否配置挖矿。
返回值:
Boolean
- true
表示配置挖矿,否则表示没有。
var mining = web3.eth.mining;
console.log(mining); // true or false
web3.eth.hashrate
同步方式:
web3.eth.hashrate
异步方式:
web3.eth.getHashrate(callback(error, result){ ... })
属性只读,表示的是当前的每秒的哈希难度。
返回值:
Number
- 每秒的哈希数
示例:
var hashrate = web3.eth.hashrate;
console.log(hashrate);
web3.eth.gasPrice
同步方式:
web3.eth.gasPrice
异步方式:
web3.eth.getGasPrice(callback(error, result){ ... })
属性是只读的,返回当前的gas价格。这个值由最近几个块的gas价格的中值6决定。
返回值:
BigNumber
- 当前的gas价格的BigNumber
实例,以wei
为单位。
var gasPrice = web3.eth.gasPrice;
console.log(gasPrice.toString(10)); // "10000000000000"
web3.eth.accounts
同步方式:
web3.eth.accounts
异步方式:
web3.eth.getAccounts(callback(error, result){ ... })
只读属性,返回当前节点持有的帐户列表。
返回值:
Array
- 节点持有的帐户列表。
示例:
var accounts = web3.eth.accounts;
console.log(accounts);
web3.eth.blockNumber
同步方式:
web3.eth.blockNumber
异步方式:
web3.eth.getBlockNumber(callback(error, result){ ... })
属性只读,返回当前区块号。
var number = web3.eth.blockNumber;
console.log(number); // 2744
web3.eth.register
web3.eth.register(addressHexString [, callback])
(暂未实现)将给定地址注册到web3.eth.accounts
。这将允许无私匙的帐户,如合约被关联到有私匙的帐户,如合约钱包。
参数:
-
String
- 要注册的地址。 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
待确定
示例:
web3.eth.register("0x407d73d8a49eeb85d32cf465507dd71d507100ca")
web3.eth.unRegister
异步方式
web3.eth.unRegister(addressHexString [, callback])
(暂未实现)取消注册给定地址
参数:
-
String
- 要取消注册的地址 -
Function
- (可选) 回调函数,用于支持异步的方式执行7。
返回值:
待确定
示例:
web3.eth.unRegister("0x407d73d8a49eeb85d32cf465507dd71d507100ca")
web3.eth.getBalance
web3.eth.getBalance(addressHexString [, defaultBlock] [, callback])
获得在指定区块时给定地址的余额。
参数:
-
String
- 要查询余额的地址。 -
Number|String
-(可选)如果不设置此值使用web3.eth.defaultBlock
设定的块,否则使用指定的块。 -
Funciton
- (可选)回调函数,用于支持异步的方式执行7。
返回值:
String
- 一个包含给定地址的当前余额的BigNumber
实例,单位为wei
。
示例:
var balance = web3.eth.getBalance("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(balance); // instanceof BigNumber
console.log(balance.toString(10)); // '1000000000000'
console.log(balance.toNumber()); // 1000000000000
web3.eth.getStorageAt
web3.eth.getStorageAt(addressHexString, position [, defaultBlock] [, callback])
获得某个地址指定位置的存储的状态值。
合约由控制执行的EVM字节码和用来保存状态的
Storage
两部分组成。Storage
在区块链上是以均为32字节的键,值对的形式进行存储8。
参数:
-
String
- 要获得存储的地址。 -
Number
- 要获得的存储的序号 -
Number|String
-(可选)如果未传递参数,默认使用web3.eth.defaultBlock
定义的块,否则使用指定区块。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
String
- 给定位置的存储值
示例:
var state = web3.eth.getStorageAt("0x407d73d8a49eeb85d32cf465507dd71d507100c1", 0);
console.log(state); // "0x03"
web3.eth.getCode
web3.eth.getCode(addressHexString [, defaultBlock] [, callback])
获取指定地址的代码
参数:
-
String
- 要获得代码的地址。 -
Number|String
-(可选)如果未传递参数,默认使用web3.eth.defaultBlock
定义的块,否则使用指定区块。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
String
- 给定地址合约编译后的字节代码。
示例:
var code = web3.eth.getCode("0xd5677cf67b5aa051bb40496e68ad359eb97cfbf8");
console.log(code); // "0x600160008035811a818181146012578301005b601b6001356025565b8060005260206000f25b600060078202905091905056"
web3.eth.getBlock
web3.eth.getBlock(blockHashOrBlockNumber [, returnTransactionObjects] [, callback])
返回块号或区块哈希值所对应的区块
参数:
-
Number|String
-(可选)如果未传递参数,默认使用web3.eth.defaultBlock
定义的块,否则使用指定区块。 -
Boolean
-(可选)默认值为false
。true
会将区块包含的所有交易作为对象返回。否则只返回交易的哈希。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值 - 区块对象:
-
Number
- 区块号。当这个区块处于pending
将会返回null
。 -
hash
- 字符串,区块的哈希串。当这个区块处于pending
将会返回null
。 -
parentHash
- 字符串,32字节的父区块的哈希值。 -
nonce
- 字符串,8字节。POW生成的哈希。当这个区块处于pending
将会返回null
。 -
sha3Uncles
- 字符串,32字节。叔区块的哈希值。 -
logsBloom
- 字符串,区块日志的布隆过滤器9。当这个区块处于pending
将会返回null
。 -
transactionsRoot
- 字符串,32字节,区块的交易前缀树的根。 -
stateRoot
- 字符串,32字节。区块的最终状态前缀树的根。 -
miner
- 字符串,20字节。这个区块获得奖励的矿工。 -
difficulty
-BigNumber
类型。当前块的难度,整数。 -
totalDifficulty
-BigNumber
类型。区块链到当前块的总难度,整数。 -
extraData
- 字符串。当前块的extra data
字段。 -
size
-Number
。当前这个块的字节大小。 - gasLimit -
Number
,当前区块允许使用的最大gas
。 -
gasUsed
- 当前区块累计使用的总的gas
。 -
timestamp
-Number
。区块打包时的unix
时间戳。 -
transactions
- 数组。交易对象。或者是32字节的交易哈希。 -
uncles
- 数组。叔哈希的数组。
示例:
var info = web3.eth.getBlock(3150);
console.log(info);
/*
{
"number": 3,
"hash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
"parentHash": "0x2302e1c0b972d00932deb5dab9eb2982f570597d9d42504c05d9c2147eaf9c88",
"nonce": "0xfb6e1a62d119228b",
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"transactionsRoot": "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee",
"stateRoot": "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb",
"miner": "0x8888f1f195afa192cfee860698584c030f4c9db1",
"difficulty": BigNumber,
"totalDifficulty": BigNumber,
"size": 616,
"extraData": "0x",
"gasLimit": 3141592,
"gasUsed": 21662,
"timestamp": 1429287689,
"transactions": [
"0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b"
],
"uncles": []
}
*/
web3.eth.getBlockTransactionCount
web3.eth.getBlockTransactionCount(hashStringOrBlockNumber [, callback])
返回指定区块的交易数量。
参数:
-
Number|String
-(可选)如果未传递参数,默认使用web3.eth.defaultBlock
定义的块,否则使用指定区块。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
Nubmer
- 给定区块的交易数量。
示例:
var number = web3.eth.getBlockTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(number); // 1
web3.eth.getUncle
web3.eth.getUncle(blockHashStringOrNumber, uncleNumber [, returnTransactionObjects] [, callback])
通过指定叔位置,返回指定叔块。
参数:
-
Number|String
-(可选)如果未传递参数,默认使用web3.eth.defaultBlock
定义的块,否则使用指定区块。 -
Number
- 叔的序号。 -
Boolean
-(可选)默认值为false
。true
会将区块包含的所有交易作为对象返回。否则只返回交易的哈希。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
Object
- 返回的叔块。返回值参考web3.eth.getBlock()
。
备注: 叔块没有自己的交易数据。
示例:
var uncle = web3.eth.getUncle(500, 0);
console.log(uncle); // see web3.eth.getBlock
web3.eth.getTransaction
web3.eth.getTransaction(transactionHash [, callback])
返回匹配指定交易哈希值的交易。
参数:
-
String
- 交易的哈希值。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
Object
- 一个交易对象
-
hash
:String
- 32字节,交易的哈希值。 -
nonce
:Number
- 交易的发起者在之前进行过的交易数量。 -
blockHash
:String
- 32字节。交易所在区块的哈希值。当这个区块处于pending
将会返回null
。 -
blockNumber
:Number
- 交易所在区块的块号。当这个区块处于pending
将会返回null
。 -
transactionIndex
:Number
- 整数。交易在区块中的序号。当这个区块处于pending
将会返回null
。 -
from
:String
- 20字节,交易发起者的地址。 -
to
:String
- 20字节,交易接收者的地址。当这个区块处于pending
将会返回null
。 -
value
:BigNumber
- 交易附带的货币量,单位为Wei
。 -
gasPrice
:BigNumber
- 交易发起者配置的gas
价格,单位是wei
。 -
gas
:Number
- 交易发起者提供的gas
。. -
input
:String
- 交易附带的数据。
示例:
var blockNumber = 668;
var indexOfTransaction = 0
var transaction = web3.eth.getTransaction(blockNumber, indexOfTransaction);
console.log(transaction);
/*
{
"hash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
"nonce": 2,
"blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
"blockNumber": 3,
"transactionIndex": 0,
"from": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"to": "0x6295ee1b4f6dd65047762f924ecd367c17eabf8f",
"value": BigNumber,
"gas": 314159,
"gasPrice": BigNumber,
"input": "0x57cb2fc4"
}
*/
web3.eth.getTransactionFromBlock
getTransactionFromBlock(hashStringOrNumber, indexNumber [, callback])
返回指定区块的指定序号的交易。
参数:
-
String
- 区块号或哈希。或者是earliest
,latest
或pending
。查看web3.eth.defaultBlock
了解可选值。 -
Number
- 交易的序号。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
Object
- 交易对象,详见web3.eth.getTransaction
示例:
var transaction = web3.eth.getTransactionFromBlock('0x4534534534', 2);
console.log(transaction); // see web3.eth.getTransaction
web3.eth.getTransactionReceipt
web3.eth.getTransactionReceipt(hashString [, callback])
通过一个交易哈希,返回一个交易的收据。
备注:处于pending
状态的交易,收据是不可用的。
参数:
-
String
- 交易的哈希 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
Object
- 交易的收据对象,如果找不到返回null
-
blockHash
:String
- 32字节,这个交易所在区块的哈希。 -
blockNumber
:Number
- 交易所在区块的块号。 -
transactionHash
:String
- 32字节,交易的哈希值。 -
transactionIndex
:Number
- 交易在区块里面的序号,整数。 -
from
:String
- 20字节,交易发送者的地址。 -
to
:String
- 20字节,交易接收者的地址。如果是一个合约创建的交易,返回null
。 -
cumulativeGasUsed
:Number
- 当前交易执行后累计花费的gas
总值10。 -
gasUsed
:Number
- 执行当前这个交易单独花费的gas
。 -
contractAddress
:String
- 20字节,创建的合约地址。如果是一个合约创建交易,返回合约地址,其它情况返回null
。 -
logs
:Array
- 这个交易产生的日志对象数组。
示例:
var receipt = web3.eth.getTransactionReceipt('0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b');
console.log(receipt);
{
"transactionHash": "0x9fc76417374aa880d4449a1f7f31ec597f00b1f6f3dd2d66f4c9c6c445836d8b",
"transactionIndex": 0,
"blockHash": "0xef95f2f1ed3ca60b048b4bf67cde2195961e0bba6f70bcbea9a2c4e133e34b46",
"blockNumber": 3,
"contractAddress": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"cumulativeGasUsed": 314159,
"gasUsed": 30234,
"logs": [{
// logs as returned by getFilterLogs, etc.
}, ...]
}
web3.eth.getTransactionCount
web3.eth.getTransactionCount(addressHexString [, defaultBlock] [, callback])
返回指定地址发起的交易数。
参数:
-
String
- 要获得交易数的地址。 -
Number|String
-(可选)如果未传递参数,默认使用web3.eth.defaultBlock
定义的块,否则使用指定区块。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
Number
- 指定地址发送的交易数量。
示例:
var number = web3.eth.getTransactionCount("0x407d73d8a49eeb85d32cf465507dd71d507100c1");
console.log(number); // 1
web3.eth.sendTransaction
web3.eth.sendTransaction(transactionObject [, callback])
发送一个交易到网络。
参数:
-
Object
- 要发送的交易对象。-
from
:String
- 指定的发送者的地址。如果不指定,使用web3.eth.defaultAccount
。 -
to
:String
- (可选)交易消息的目标地址,如果是合约创建,则不填. -
value
:Number|String|BigNumber
- (可选)交易携带的货币量,以wei
为单位。如果合约创建交易,则为初始的基金。 -
gas
:Number|String|BigNumber
- (可选)默认是自动,交易可使用的gas
,未使用的gas
会退回。 -
gasPrice
:Number|String|BigNumber
- (可选)默认是自动确定,交易的gas
价格,默认是网络gas
价格的平均值 。 -
data
:String
- (可选)或者包含相关数据的字节字符串,如果是合约创建,则是初始化要用到的代码。 -
nonce
:Number
- (可选)整数,使用此值,可以允许你覆盖你自己的相同nonce
的,正在pending
中的交易11。
-
-
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
String
- 32字节的交易哈希串。用16进制表示。
如果交易是一个合约创建,请使用web3.eth.getTransactionReceipt()
在交易完成后获取合约的地址。
示例:
// compiled solidity source code using https://chriseth.github.io/cpp-ethereum/
var code = "603d80600c6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463c6888fa18114602d57005b6007600435028060005260206000f3";
web3.eth.sendTransaction({data: code}, function(err, address) {
if (!err)
console.log(address); // "0x7f9fade1c0d57a7af66ab4ead7c2eb7b11a91385"
});
web3.eth.sendRawTransaction
web3.eth.sendRawTransaction(signedTransactionData [, callback])
发送一个已经签名的交易。比如可以用下述签名的例子:https://github.com/SilentCicero/ethereumjs-accounts
参数:
-
String
- 16进制格式的签名交易数据。 -
Function
- 回调函数,用于支持异步的方式执行7。
返回值:
String
- 32字节的16进制格式的交易哈希串。
如果交易是一个合约创建,请使用web3.eth.getTransactionReceipt()
在交易完成后获取合约的地址。
示例:
var Tx = require('ethereumjs-tx');
var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')
var rawTx = {
nonce: '0x00',
gasPrice: '0x09184e72a000',
gasLimit: '0x2710',
to: '0x0000000000000000000000000000000000000000',
value: '0x00',
data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'
}
var tx = new Tx(rawTx);
tx.sign(privateKey);
var serializedTx = tx.serialize();
//console.log(serializedTx.toString('hex'));
//0xf889808609184e72a00082271094000000000000000000000000000000000000000080a47f74657374320000000000000000000000000000000000000000000000000000006000571ca08a8bbf888cfa37bbf0bb965423625641fc956967b81d12e23709cead01446075a01ce999b56a8a88504be365442ea61239198e23d1fce7d00fcfc5cd3b44b7215f
web3.eth.sendRawTransaction(serializedTx.toString('hex'), function(err, hash) {
if (!err)
console.log(hash); // "0x7f9fade1c0d57a7af66ab4ead79fade1c0d57a7af66ab4ead7c2c2eb7b11a91385"
});
web3.eth.sign
web3.eth.sign(address, dataToSign, [, callback])
使用指定帐户签名要发送的数据,帐户需要处于unlocked
状态。
参数:
-
String
- 签名使用的地址 -
String
- 要签名的数据 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
String
- 签名后的数据。
返回的值对应的是ECDSA(Elliptic Curve Digital Signature Algorithm)
12签名后的字符串。
r = signature[0:64]
s = signature[64:128]
v = signature[128:130]
需要注意的是,如果你使用ecrecover
,这里的v
值是00
或01
,所以如果你想使用他们,你需要把这里的v
值转成整数,再加上27
。最终你要用的值将是27
或28
13。
示例:
var result = web3.eth.sign("0x135a7de83802408321b74c322f8558db1679ac20",
"0x9dd2c369a187b4e6b9c402f030e50743e619301ea62aa4c0737d4ef7e10a3d49"); // second argument is web3.sha3("xyz")
console.log(result); // "0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400"
备注:如果你使用以太坊的客户端进行签名时,它们会在你要签名的数据前增加前缀\x19Ethereum Signed Message:\n
14,感谢读者@刘兵同学的反馈。
eth_sign
The sign method calculates an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))).
By adding a prefix to the message makes the calculated signature recognisable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim.
web3.eth.call
web3.eth.call(callObject [, defaultBlock] [, callback])
在节点的VM中,直接执行消息调用交易。但不会将数据合并区块链中(这样的调用不会修改状态)。
参数:
-
Object
- 返回一个交易对象,同web3.eth.sendTransaction
。与sendTransaction
的区别在于,from
属性是可选的。 -
Number|String
-(可选)如果不设置此值使用web3.eth.defaultBlock
设定的块,否则使用指定的块。 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
String
- 函数调用返回的值。
示例:
var Web3 = require('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"));
}
var from = web3.eth.accounts[0];
//部署合约的发布地址
/*合约内容如下
pragma solidity ^0.4.0;
contract Calc{
function add(uint a, uint b) returns (uint){
return a + b;
}
}
*/
var to = "0xa4b813d788218df688d167102e5daff9b524a8bc";
//要发送的数据
//格式说明见: http://me.tryblockchain.org/Solidity-call-callcode-delegatecall.html
var data = "0x771602f700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002";
var result = web3.eth.call({
from : from,
to : to,
data : data
});
//返回结果32字长的结果3
console.log(result);
web3.eth.estimateGas
web3.eth.estimateGas(callObject [, callback])
在节点的VM节点中执行一个消息调用,或交易。但是不会合入区块链中。返回使用的gas
量。
参数:
同web3.eth.sendTransaction
,所有的属性都是可选的。
返回值:
Number
- 模拟的call/transcation
花费的gas
。
示例:
var result = web3.eth.estimateGas({
to: "0xc4abd0339eb8d57087278718986382264244252f",
data: "0xc6888fa10000000000000000000000000000000000000000000000000000000000000003"
});
console.log(result); // "0x0000000000000000000000000000000000000000000000000000000000000015"
web3.eth.filter
参数:
-
String|Object
- 字符串的可取值[latest,pending]。latest
表示监听最新的区块变化,pending
表示监听正在pending
的区块。如果需要按条件对象过滤,如下:-
fromBlock
:Number|string
- 起始区块号(如果使用字符串latest
,意思是最新的,正在打包的区块),默认值是latest
。 -
toBlock
:Number|string
- 终止区块号(如果使用字符串latest
,意思是最新的,正在打包的区块),默认值是latest
。 -
address
:String
- 单个或多个地址。获取指定帐户的日志。 -
topics
:String[]
- 在日志对象中必须出现的字符串数组。顺序非常重要,如果你想忽略主题,使用null
。如,[null,'0x00...'],你还可以为每个主题传递一个单独的可选项数组,如[null,['option1','option1']]。
-
返回值:
Object
- 有下述方法的过滤对象。
-
filter.get(callback)
: 返回满足过滤条件的日志。 -
filter.watch(callback)
: 监听满足条件的状态变化,满足条件时调用回调7。 -
filter.stopWatching()
: 停止监听,清除节点中的过滤。你应该总是在监听完成后,执行这个操作。
监听回调返回值:
-
String
- 当使用latest
参数时。返回最新的一个区块哈希值。 -
String
- 当使用pending
参数时。返回最新的pending
中的交易哈希值。 -
Object
- 当使用手工过滤选项时,将返回下述的日志对象。-
logIndex
:Number
- 日志在区块中的序号。如果是pending
的日志,则为null
。 -
transactionIndex
:Number
- 产生日志的交易在区块中的序号。如果是pending
的日志,则为null
。 -
transactionHash
:String
,32字节 - 产生日志的交易哈希值。 -
blockHash
:String
,32字节 - 日志所在块的哈希。如果是pending
的日志,则为null
。 -
blockNumber
:Number
- 日志所在块的块号。如果是pending
的日志,则为null
。 -
address
:String
,32字节 - 日志产生的合约地址。 -
data
:string
- 包含日志一个或多个32字节的非索引的参数。 -
topics
:String[]
- 一到四个32字节的索引的日志参数数组。(在Solidity中,第一个主题是整个事件的签名(如,Deposit(address,bytes32,uint256)
),但如果使用匿名的方式定义事件的情况除外)
-
事件监听器的返回结果,见后合约对象的事件
。
示例:
var filter = web3.eth.filter('pending');
filter.watch(function (error, log) {
console.log(log); // {"address":"0x0000000000000000000000000000000000000000", "data":"0x0000000000000000000000000000000000000000000000000000000000000000", ...}
});
// get all past logs again.
var myResults = filter.get(function(error, logs){ ... });
...
// stops and uninstalls the filter
filter.stopWatching();
web3.eth.contract
web3.eth.contract(abiArray)
创建一个Solidity的合约对象,用来在某个地址上初始化合约。
参数:
-
Array
- 一到多个描述合约的函数,事件的ABI对象。
返回值:
Object
- 一个合约对象。
示例:
var MyContract = web3.eth.contract(abiArray);
// instantiate by address
var contractInstance = MyContract.at([address]);
// deploy new contract
var contractInstance = MyContract.new([contructorParam1] [, contructorParam2], {data: '0x12345...', from: myAccount, gas: 1000000});
// Get the data to deploy the contract manually
var contractData = MyContract.new.getData([contructorParam1] [, contructorParam2], {data: '0x12345...'});
// contractData = '0x12345643213456000000000023434234'
你可以或者使用一个在某个地址上已经存在的合约,或者使用编译后的字节码部署一个全新的的合约。
// Instantiate from an existing address:
var myContractInstance = MyContract.at(myContractAddress);
// Or deploy a new contract:
// Deploy the contract asyncronous from Solidity file:
...
const fs = require("fs");
const solc = require('solc')
let source = fs.readFileSync('nameContract.sol', 'utf8');
let compiledContract = solc.compile(source, 1);
let abi = compiledContract.contracts['nameContract'].interface;
let bytecode = compiledContract.contracts['nameContract'].bytecode;
let gasEstimate = web3.eth.estimateGas({data: bytecode});
let MyContract = web3.eth.contract(JSON.parse(abi));
var myContractReturned = MyContract.new(param1, param2, {
from:mySenderAddress,
data:bytecode,
gas:gasEstimate}, function(err, myContract){
if(!err) {
// NOTE: The callback will fire twice!
// Once the contract has the transactionHash property set and once its deployed on an address.
// e.g. check tx hash on the first call (transaction send)
if(!myContract.address) {
console.log(myContract.transactionHash) // The hash of the transaction, which deploys the contract
// check address on the second call (contract deployed)
} else {
console.log(myContract.address) // the contract address
}
// Note that the returned "myContractReturned" === "myContract",
// so the returned "myContractReturned" object will also get the address set.
}
});
// Deploy contract syncronous: The address will be added as soon as the contract is mined.
// Additionally you can watch the transaction by using the "transactionHash" property
var myContractInstance = MyContract.new(param1, param2, {data: myContractCode, gas: 300000, from: mySenderAddress});
myContractInstance.transactionHash // The hash of the transaction, which created the contract
myContractInstance.address // undefined at start, but will be auto-filled later
示例:
// contract abi
var abi = [{
name: 'myConstantMethod',
type: 'function',
constant: true,
inputs: [{ name: 'a', type: 'string' }],
outputs: [{name: 'd', type: 'string' }]
}, {
name: 'myStateChangingMethod',
type: 'function',
constant: false,
inputs: [{ name: 'a', type: 'string' }, { name: 'b', type: 'int' }],
outputs: []
}, {
name: 'myEvent',
type: 'event',
inputs: [{name: 'a', type: 'int', indexed: true},{name: 'b', type: 'bool', indexed: false}]
}];
// creation of contract object
var MyContract = web3.eth.contract(abi);
// initiate contract for an address
var myContractInstance = MyContract.at('0xc4abd0339eb8d57087278718986382264244252f');
// call constant function
var result = myContractInstance.myConstantMethod('myParam');
console.log(result) // '0x25434534534'
// send a transaction to a function
myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000});
// short hand style
web3.eth.contract(abi).at(address).myAwesomeMethod(...);
// create filter
var filter = myContractInstance.myEvent({a: 5}, function (error, result) {
if (!error)
console.log(result);
/*
{
address: '0x8718986382264244252fc4abd0339eb8d5708727',
topics: "0x12345678901234567890123456789012", "0x0000000000000000000000000000000000000000000000000000000000000005",
data: "0x0000000000000000000000000000000000000000000000000000000000000001",
...
}
*/
});
合约对象的方法
// Automatically determines the use of call or sendTransaction based on the method type
myContractInstance.myMethod(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);
// Explicitly calling this method
myContractInstance.myMethod.call(param1 [, param2, ...] [, transactionObject] [, defaultBlock] [, callback]);
// Explicitly sending a transaction to this method
myContractInstance.myMethod.sendTransaction(param1 [, param2, ...] [, transactionObject] [, callback]);
// Get the call data, so you can call the contract through some other means
var myCallData = myContractInstance.myMethod.getData(param1 [, param2, ...]);
// myCallData = '0x45ff3ff6000000000004545345345345..'
合约对象内封装了使用合约的相关方法。可以通过传入参数,和交易对象来使用方法。
参数:
-
String|Number
- (可选)零或多个函数参数。如果传入一个字符串,需要使用十六进制编码,如,0xdedbeef
。 -
Object
- (可选)最后一个参数(如果传了callback
,则是倒数第二个参数),可以是一个交易对象。查看web3.eth.sendTransaction
的第一个参数说明来了解更多。注意,这里不需要填data
和to
属性。 -
Number|String
-(可选)如果不设置此值使用web3.eth.defaultBlock
设定的块,否则使用指定的块。 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
String
- 如果发起的是一个call
,对应的是返回结果。如果是transaction
,则要么是一个创建的合约地址,或者是一个transaction
的哈希值。查看web3.eth.sendTransaction
了解更多。
示例:
// creation of contract object
var MyContract = web3.eth.contract(abi);
// initiate contract for an address
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');
var result = myContractInstance.myConstantMethod('myParam');
console.log(result) // '0x25434534534'
myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... });
合约对象的事件
你可以像web3.eth.filter
这样使用事件,他们有相同的方法,但需要传递不同的对象来创建事件过滤器。
参数:
-
Object
- 你想返回的索引值(过滤哪些日志)。如,{'valueA': 1, 'valueB': [myFirstAddress, mySecondAddress]}
。默认情况下,所以有过滤项被设置为null
。意味着默认匹配的是合约所有的日志。 -
Object
- 附加的过滤选项。参见web3.eth.filter
的第一个参数。默认情况下,这个对象会设置address
为当前合约地址,同时第一个主题为事件的签名。 -
Function
-(可选)传入一个回调函数,将立即开始监听,这样就不用主动调用myEvent.watch(function(){})
7。
回调返回值:
Object
- 事件对象,如下:
-
address
:String,32字节
- 日志产生的合约地址。 -
args
:Object
- 事件的参数。 -
blockHash
:String,32字节
- 日志所在块的哈希。如果是pending
的日志,则为null
。 -
blockNumber
:Number
- 日志所在块的块号。如果是pending
的日志,则为null
。 -
logIndex
:Number
- 日志在区块中的序号。如果是pending
的日志,则为null
。 -
event
:String
- 事件名称。 -
removed
:bool
- 标识产生事件的这个交易是否被移除(因为孤块),或从未生效(被拒绝的交易)。 -
transactionIndex
:Number
- 产生日志的交易在区块中的序号。如果是pending
的日志,则为null
。 -
transactionHash
:String,32字节
- 产生日志的交易哈希值。
示例:
var MyContract = web3.eth.contract(abi);
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');
// watch for an event with {some: 'args'}
var myEvent = myContractInstance.MyEvent({some: 'args'}, {fromBlock: 0, toBlock: 'latest'});
myEvent.watch(function(error, result){
...
});
// would get all past logs again.
var myResults = myEvent.get(function(error, logs){ ... });
...
// would stop and uninstall the filter
myEvent.stopWatching();
合约 allEvents
var events = myContractInstance.allEvents([additionalFilterObject]);
// watch for changes
events.watch(function(error, event){
if (!error)
console.log(event);
});
// Or pass a callback to start watching immediately
var events = myContractInstance.allEvents([additionalFilterObject,] function(error, log){
if (!error)
console.log(log);
});
调用合约创建的所有事件的回调。
参数:
-
Object
- 附加的过滤选项。参见web3.eth.filter
的第一个参数。默认情况下,这个对象会设置address
为当前合约地址,同时第一个主题为事件的签名。 -
Function
-(可选)传入一个回调函数,将立即开始监听,这样就不用主动调用myEvent.watch(function(){})
7。
回调返回值:
Object
- 详见合约对象的事件
了解更多。
示例:
var MyContract = web3.eth.contract(abi);
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');
// watch for an event with {some: 'args'}
var events = myContractInstance.allEvents({fromBlock: 0, toBlock: 'latest'});
events.watch(function(error, result){
...
});
// would get all past logs again.
events.get(function(error, logs){ ... });
...
// would stop and uninstall the filter
myEvent.stopWatching();
web3.eth.getCompilers
web3.eth.getCompilers([callback])
返回可用的编译器。
参数值:
-
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
Array
- 返回一个字符串数组,可用的编译器。
web3.eth.compile.solidity
web3.eth.compile.solidity(sourceString [, callback])
编译Solidity源代码。
参数:
-
String
- Solidity源代码。 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
Object
- 合约和编译信息。
示例:
var source = "" +
"contract test {\n" +
" function multiply(uint a) returns(uint d) {\n" +
" return a * 7;\n" +
" }\n" +
"}\n";
var compiled = web3.eth.compile.solidity(source);
console.log(compiled);
// {
"test": {
"code": "0x605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056",
"info": {
"source": "contract test {\n\tfunction multiply(uint a) returns(uint d) {\n\t\treturn a * 7;\n\t}\n}\n",
"language": "Solidity",
"languageVersion": "0",
"compilerVersion": "0.8.2",
"abiDefinition": [
{
"constant": false,
"inputs": [
{
"name": "a",
"type": "uint256"
}
],
"name": "multiply",
"outputs": [
{
"name": "d",
"type": "uint256"
}
],
"type": "function"
}
],
"userDoc": {
"methods": {}
},
"developerDoc": {
"methods": {}
}
}
}
}
web3.eth.compile.lll
web3. eth.compile.lll(sourceString [, callback])
编译LLL源代码。
参数:
-
String
- LLL源代码。 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
String
- 十六进制格式编译后的LLL编码。
示例:
var source = "...";
var code = web3.eth.compile.lll(source);
console.log(code); // "0x603880600c6000396000f3006001600060e060020a600035048063c6888fa114601857005b6021600435602b565b8060005260206000f35b600081600702905091905056"
web3.eth.compile.serpent
web3.eth.compile.serpent(sourceString [, callback])
编译serpent源代码。
参数:
-
String
- serpent源代码。 -
Function
-(可选)回调函数,用于支持异步的方式执行7。
返回值:
String
- 十六进制格式的编译后的serpent编码。
web3.eth.namereg
web3.eth.namereg
返回一个全球注意的对象。
使用方式:
查看这里的例子:https://github.com/ethereum/web3.js/blob/master/example/namereg.html
web3.db
web3.db.putString
web3.db.putString(db, key, value)
这个方法应当在我们打算以一个本地数据库的级别存储一个字符串时使用。
参数:
-
String
- 存储使用的数据库。 -
String
- 存储的键。 -
String
- 存储的值。
返回值:
Boolean
- true
表示成功,否则返回false
。
示例:
web3.db.putString('testDB', 'key', 'myString') // true
web3.db.getString
web3.db.getString(db, key)
从本地的leveldb数据库中返回一个字符串。
参数:
-
String
- 存储使用的数据库。 -
String
- 存储的键。
返回值:
String
- 存储的值。
示例:
var value = web3.db.getString('testDB', 'key');
console.log(value); // "myString"
web3.db.putHex
web3.db.putHex(db, key, value)
在本地的leveldb中存储二进制数据。
参数:
-
String
- 存储使用的数据库。 -
String
- 存储的键。 -
String
- 十六进制格式的二进制。
返回值:
Boolean
- 成功返回true
,失败返回false
。
示例:
web3.db.putHex('testDB', 'key', '0x4f554b443'); // true
web3.db.getHex
web3.db.getHex(db, key)
返回本地的leveldb中的二进制数据。
参数:
-
String
- 存储使用的数据库。 -
String
- 存储的键。
返回值:
String
- 存储的十六进制值。
示例:
var value = web3.db.getHex('testDB', 'key');
console.log(value); // "0x4f554b443"
5. 参考文档
1] Web3 JavaScript app API英文官网接口文档
2] Web3 JavaScript Ðapp API
3] WEB3.JS代码
4] WEB3的中文帮助文档地址
5] 以太坊DApp开发入门教程——区块链投票系统 - 汇智网
6] Web3与智能合约交互实战 - 熊丽兵