以太坊研究系列【web3交互】
此文档为个人整理学习使用,部分内容来源于网络,也期待能给你带来益处。
web3.js
web3.js是以太坊提供的一个Javascript库,它封装了以太坊的JSON RPC API,提供了一系列与区块链交互的Javascript对象和函数,包括查看网络状态,查看本地账户、查看交易和区块、发送交易、编译/部署智能合约、调用智能合约等,其中最重要的就是与智能合约交互的API。
添加web3到项目
新建Nodejs项目,并下载web3.js到项目中
Chaim:workspace Chaim$ mkdir web3eth && cd web3eth
Chaim:web3eth Chaim$ npm init
Chaim:web3eth Chaim$ npm install web3 --save
创建web3对象
找到几种方式,现在用的是ipc方式
// 创建web3对象
var Web3 = require("web3");
// var web3 = new Web3('http://localhost:8545');
// or
// var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
// change provider
// web3.setProvider('ws://localhost:8546');
// or
// web3.setProvider(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
// Using the IPC provider in node.js
var net = require('net');
// var web3 = new Web3('/Users/Chaim/Documents/workspace/ethPri/geth.ipc', net); // mac os path
// or
var web3 = new Web3(new Web3.providers.IpcProvider('/Users/Chaim/Documents/workspace/ethPri/geth.ipc', net)); // mac os path
// on windows the path is: "\\\\.\\pipe\\geth.ipc"
// on linux the path is: "/users/myuser/.ethereum/geth.ipc"
web3.eth.getAccounts(console.log);
使用web3admin
web3admin提供了一些管理的方法,如miner等
Chaim:web3eth Chaim$ npm install web3admin
但是使用web3admin还是出错,如下
/Users/Chaim/Documents/workspace/web3eth/node_modules/[email protected]@web3admin/web3admin.js:9
new web3._extend.Method({
^
TypeError: Cannot read property 'Method' of undefined
at Object.extend (/Users/Chaim/Documents/workspace/web3eth/node_modules/[email protected]@web3admin/web3admin.js:9:34)
at Timeout._onTimeout (/Users/Chaim/Documents/workspace/web3eth/index.js:22:15)
at ontimeout (timers.js:475:11)
at tryOnTimeout (timers.js:310:5)
at Timer.listOnTimeout (timers.js:270:5)
部署合约
先在mist钱包中部署合约,可以参考【mist】相关内容,也可以按参考链接的用代码进行部署,部署完成后先取abi接口和合约地址,就可以用代码调用了。
// 合约ABI
var abi = [{}]
//合约地址
var address = "0x799782D30Dd9F2c3E1E63d76E85729F93D46144B"
// 通过ABI和地址获取已部署的合约对象
var svf = new web3.eth.Contract(abi, null, {from:address})
svf就是获取的合约对象实例,可以直接调用合约中的函数,这个合约在【代币发行】中已有说明。
查询合约
合约部署成功以后,有了地址就可以根据地址来查询合约的状态,查询合约状态并不需要发起事务,也不需要花费gas
// 通过ABI和地址获取已部署的合约对象
var svf = new web3.eth.Contract(abi, address);
svf.methods.name().call(function(error, result){
console.log("contract name "+result);
});
svf.methods.symbol().call(function(error, result){
console.log("contract symbol "+result);
});
svf.methods.totalSupply().call(function(error, result){
console.log("contract totalSupply "+result);
});
调用合约
合约的函数除了指明返回值是constant的以外,都需要发起事务,这时候就需要指定调用者,因为要花费该账户的gas。
需要先把帐号进行解锁,可以在geth终端调用personal.unlockAccount()进行解锁
svf.methods.transfer("0x54b865714068f5F03574ACe39a1F3279C4E83E2c", 1).send({from: "0x068a7A0022a0e20d78682F39aA75547A0A260A2A"})
.on('transactionHash', function(hash){
console.log("transactionHash:", hash);
})
.on('confirmation', function(confirmationNumber, receipt){
console.log("confirmation:", confirmationNumber);
})
.on('receipt', function(receipt){
// receipt example
console.log("receipt:", receipt); //查询这里可以得到结果
})
.on('error', console.error); // If a out of gas error, the second parameter is the receipt.
运行以后(开启挖矿哦)结果如下:
Chaim:web3eth Chaim$ node index.js
contract name SuperVipFlag
contract totalSupply 10000000000000000000
contract symbol SVF
transactionHash: 0x3b295a0ac7875e0ba62f017ab14e463ec91bcbc1df7ff89a085474f0f30db78f
confirmation: 0
receipt: { blockHash: '0x39cb5d8c8b91f5a6d297eec71fa250cc06937f90b87601fac68099837d7a70fb',
后面还会有确认“confirmation”的每次日志!
到这明白那个小数位了,缺省指定18位会换成整数,和以太币一样了。
监听事件
调用transfer的时候还会触发合约的事件Transfer,如果程序关注谁给谁进行了转账,那么就可以通过监听该事件。
通过指定fromBlock,toBlock可以限制事件发生的范围,除了这个还有一个filter参数可以进行更详细的限制。
//监听事件
svf.events.Transfer({
fromBlock: 0,
toBlock:'latest'
}, function(error, event){ /*console.log("result:\n"+JSON.stringify(event)); */})
.on('data', function(event){
console.log(event); // same results as the optional callback above
})
.on('changed', function(event){
// remove event from local database
})
.on('error', console.error);
需要说明的是,这个监听不仅传送历史事件,未来所有事件也会传送。
通过mist钱包转帐也监听到事件,如下:
{ address: '0x799782D30Dd9F2c3E1E63d76E85729F93D46144B',
blockNumber: 7947,
transactionHash: '0x566f08f954bbf6cee08a16b4c88d7b98ffad95211a77d46daa7b927fd1256176',
transactionIndex: 0,
blockHash: '0x3e4a72c9a57268541f76af5d70a70ecc59c1ce980f0fbc30a8ac0635ab1279ff',
logIndex: 0,
removed: false,
id: 'log_87480a1a',
returnValues:
Result {
'0': '0x068a7A0022a0e20d78682F39aA75547A0A260A2A',
'1': '0x54b865714068f5F03574ACe39a1F3279C4E83E2c',
'2': '1000000000000000000',
from: '0x068a7A0022a0e20d78682F39aA75547A0A260A2A',
to: '0x54b865714068f5F03574ACe39a1F3279C4E83E2c',
value: '1000000000000000000' },
event: 'Transfer',
signature: '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
raw:
{ data: '0x0000000000000000000000000000000000000000000000000de0b6b3a7640000',
topics:
[ '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
'0x000000000000000000000000068a7a0022a0e20d78682f39aa75547a0a260a2a',
'0x00000000000000000000000054b865714068f5f03574ace39a1f3279c4e83e2c' ] } }
到这我就想明白怎么用网页来处理了,可以用nodejs在后台与以太坊通信,读取相关数据,网页前端通知nodejs做相关操作。
参考
https://github.com/ethereum/wiki/wiki/JSON-RPC
https://github.com/DecentricCorp/web3admin
这篇不错,都是跟着它来进行测试的!
https://www.cnblogs.com/baizx/p/7474774.html
https://bitshuo.com/topic/5954b6764a7a061b785db726
web3js
https://web3js.readthedocs.io/en/1.0/index.html
***************************************
作者简介
老鱼,从事互联网技术十余年,知名上市公司CTO;炒股十余年,从亏损几十万到略有盈利;顺应创业大潮多次创业,在传统行业和手游行业有所获;研习佛学易理,性格淡泊清净!
欢迎有兴趣的朋友加入微信群和电报群,一起学习探讨,一起实现咱们的小目标!
- 百分百区块链群,微信扫码后会再显示一个二维码,长按图片“识别图中二维码”加入!
- 电报群 https://t.me/blockchain100 希望以后能给先加入的人送一份大礼!
@chaimyu, 学习受教了!
互相学习