## web3.js
为了让你的DAPP能够访问区块链上的数据,一种选择是使用web3.js提供的`web3`对象。底层实现上,它通过RPC 调用与本地节点通信。web3.js可以与任何暴露了RPC接口的区块链节点连接。
#### 引入方式
首先引入web3.js到项目中。可以使用以下方法完成:
+ npm: npm install web3
+ bower: bower install web3
+ meteor: meteor add ethereum:web3
+ vanilla: link the dist/web3.min.js
#### 创建web3实例
然后创建一个web3实例,设置一个节点`provider`。为了确保不会覆盖已经设置的`provider`,请先检查`web3`是否可用:
```js
//初始化过程
//node环境
var Web3 = require('web3');
//or 传统脚本引入
<script src="./dist/web3.min.js"></script>
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:6789"));
}
```
成功引入后,就可以使用`web3`的相关API了。
#### 重点API介绍
#### web3.setProvider
描述:设置`Provider`
请求参数:
无
返回参数:
>undefined
示例:
`web3.setProvider(new web3.providers.HttpProvider('http://localhost:6789'));`
##### web3.eth.call
描述:
web3.eth.call(callObject [, defaultBlock] [, callback])
在节点的VM中,直接执行消息调用交易。但不会将数据合并区块链中(这样的调用不会修改状态)。
请求参数:
| 名称 | 类型 | 是否必须| 描述 |
| -------------------- | -------|-------|------- |
| callObject | Object | 是|返回一个交易对象,同web3.eth.sendTransaction。与sendTransaction的区别在于,from属性是可选的。 |
| defaultBlock | Number/String|否|获取u-key地址 |
| callback |Function|否 |回调函数,用于支持异步的方式执行|
返回参数:
| 名称 | 类型 | 描述 |
| -------------------- | -------|------- |
| String | String | 函数调用返回的值。 |
示例:
```js
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.sendRawTransaction
描述:发送一个已经签名的交易。比如可以用下述签名的例子:[https://github.com/SilentCicero/ethereumjs-accounts](https://github.com/SilentCicero/ethereumjs-accounts)
请求参数:
| 名称 | 类型 | 是否必须| 描述 |
| -------------------- | -------|-------|------- |
| signedTransactionData| Object | 是|返回一个交易对象,同web3.eth.sendTransaction。与sendTransaction的区别在于,from属性是可选的。|
| defaultBlock | Number/String|否|获取u-key地址 |
| callback |Function|否 |回调函数,用于支持异步的方式执行|
返回参数:
| 名称 | 类型 | 描述 |
| -------------------- | -------|------- |
| String | String | 32字节的16进制格式的交易哈希串。如果交易是一个合约创建,请使用`web3.eth.getTransactionReceipt()`在交易完成后获取合约的地址。|
示例:
```js
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.getTransactionReceipt
描述:通过一个交易哈希,返回一个交易的收据。备注:处于pending状态的交易,收据是不可用的。
请求参数:
| 名称 | 类型 | 是否必须| 描述 |
| -------------------- | -------|-------|------- |
| hashString| Object | 是| 交易的哈希|
| callback |Function|否 |回调函数,用于支持异步的方式执行|
返回参数:
| 名称 | 类型 | 描述 |
| -------------------- | -------|------- |
| blockHash | String |32字节,这个交易所在区块的哈希|
| blockNumber | Number |交易所在区块的块号|
| transactionHash | String |32字节,交易的哈希值|
| transactionIndex | Number |交易在区块里面的序号,整数|
| from | String | 20字节,交易发送者的地址|
| to | String | 20字节,交易接收者的地址。如果是一个合约创建的交易,返回`null`|
| cumulativeGasUsed | Number |当前交易执行后累计花费的`gas`总值|
| gasUsed | Number |执行当前这个交易单独花费的`gas`|
| contractAddress | String |20字节,创建的合约地址。如果是一个合约创建交易,返回合约地址,其它情况返回`null`|
| logs | Array |这个交易产生的日志对象数组|
示例:
```js
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.contract
描述:创建一个Solidity的合约对象,用来在某个地址上初始化合约。
请求参数:
| 名称 | 类型 | 是否必须| 描述 |
| -------------------- | -------|-------|------- |
| abiArray| Array | 是| 一到多个描述合约的函数,事件的ABI对象|
返回参数:
| 名称 | 类型 | 描述 |
| -------------------- | -------|------- |
| String | String | 32字节的16进制格式的交易哈希串。如果交易是一个合约创建,请使用`web3.eth.getTransactionReceipt()`在交易完成后获取合约的地址。|
示例:
```js
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'
```
##### 合约对象的方法
描述:合约对象内封装了使用合约的相关方法。可以通过传入参数,和交易对象来使用方法。
请求参数:
| 名称 | 类型 |是否必须| 描述 |
| -------------------- | -------|------- |------- |
| param1 | String/Number |是|32字节,这个交易所在区块的哈希|
| transactionObject | Object |否|最后一个参数(如果传了callback,则是倒数第二个参数),可以是一个交易对象。查看`web3.eth.sendTransaction`的第一个参数说明来了解更多。注意,这里不需要填`data`和`to`属性|
| defaultBlock |String/Number|否|如果不设置此值使用`web3.eth.defaultBlock`设定的块,否则使用指定的块|
| callback |Function|否|回调函数,用于支持异步的方式执行|
返回参数:
| 名称 | 类型 | 描述 |
| -------------------- | -------|------- |
| String | String |如果发起的是一个`call`,对应的是返回结果。如果是`transaction`,则要么是一个创建的合约地址,或者是一个`transaction`的哈希值|
示例:
```js
// 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..'
```
```js
// 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`部分API,更多的API,可以参考以下第三方文档:
中文参考文档:[http://web3.tryblockchain.org/ethereum-web3.js-入门说明.html](http://web3.tryblockchain.org/ethereum-web3.js-入门说明.html)
英文参考文档:[https://github.com/ethereum/wiki/wiki/JavaScript-API](https://github.com/ethereum/wiki/wiki/JavaScript-API)