写在最前:请检查你的provider连接方式,http provider已不支持event事件的触发了
具体请看官方源文档
一、问题还原:
(1)先给出智能合约代码
pragma solidity ^0.4.0;
contract Transfer{
event transfer(address indexed _from, address indexed _to, uint indexed value);
function deposit() payable {
address current = this;
uint value = msg.value;
transfer(msg.sender, current, value);
}
function getBanlance() constant returns(uint) {
return this.balance;
}
/* fallback function */
function(){}
}
(2)在通过web3.js对event事件进行测试时,遇到如下event无法触发的情况:
这里给出node.js代码,看不明白的建议先去参见利用Web3.js与节点交互【1】
let Web3=require('web3');
let fs=require('fs');
let web3;
if(typeof web3 !=='undefined'){ //检查是否已有web3实例
web3=new Web3(web3.currentProvider);
}else{
//否则就连接到给出节点
web3=new Web3();
web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546"));
}
web3.eth.getBlock(0, function(error, result){
if(!error)
console.log("connect should be success");
else
console.log("something wrong,the connection might be failed");
})
//abi 直接由solc在外部 solcjs --abi mycontract.sol 编译好,这里直接引用
var abi=JSON.parse(fs.readFileSync("mycontract_sol_Transfer.abi").toString())
var myContractAddress="0x15a27fb5ea1c3842fac984df488df9325ef60829";
var transferContract =new web3.eth.Contract(abi);
transferContract.options.address=myContractAddress;
//event
transferContract.events.transfer({},
function(err,event){
console.log(event);
});
//发起交易,试图触发event
transferContract.methods.deposit().send({
from:"0x2EC12C8e3a8a0df6EdD448688e6EE0E0132ED801",
value:100,
gas:10000000
});
【运行前,请先确保你的节点已经启动,并且合约已经部署过了,否则你没有合约的地址,无法发起交易】
运行步骤:
2.看起来是连接上了,但是后面报错说是没有解锁
解锁账户: personal.unlockAccount(eth.accounts[0])
3.再次启动
左图是geth客户端可以看见有一笔交易提交,右图是启动后
4.启动挖矿,确认交易
miner.start()
5.已经挖矿确认了,但是node.js运行这边直接退出了,并没有输出事件event
二、解决方案
如果是上述的问题,那么很可能就是provider的设置问题,我们选择websocket provider,再尝试
(1)要修改的部分代码:
【具体还是参见利用Web3.js与节点交互【1】】
if(typeof web3 !=='undefined'){ //检查是否已有web3实例
web3=new Web3(web3.currentProvider);
}else{
//否则就连接到给出节点
web3=new Web3();
web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546"));//注意这里注意端口不用一致,直接默认8546即可(若刚刚启动节点的rpc端口是8545的情况下)
}
(2)修改完后的全部代码:
let Web3=require('web3');
let fs=require('fs');
let web3;
if(typeof web3 !=='undefined'){ //检查是否已有web3实例
web3=new Web3(web3.currentProvider);
}else{
//否则就连接到给出节点
web3=new Web3();
web3.setProvider(new Web3.providers.WebsocketProvider("ws://localhost:8546"));
}
web3.eth.getBlock(0, function(error, result){
if(!error)
console.log("connect should be success");
else
console.log("something wrong,the connection might be failed");
})
//abi 直接由solc在外部 solcjs --abi mycontract.sol 编译好,这里直接引用
var abi=JSON.parse(fs.readFileSync("mycontract_sol_Transfer.abi").toString())
var myContractAddress="0x15a27fb5ea1c3842fac984df488df9325ef60829";
var transferContract =new web3.eth.Contract(abi);
transferContract.options.address=myContractAddress;
//event
transferContract.events.transfer({},
function(err,event){
console.log(event);
});
//发起交易,试图触发event
transferContract.methods.deposit().send({
from:"0x2EC12C8e3a8a0df6EdD448688e6EE0E0132ED801",
value:100,
gas:10000000
});
(3)重复之前的启动步骤
挖矿确认后:
可以捕捉到event事件并输出了
三、另外的问题
问题简述:web3.js 1.0版本下有好多的beta 版本,不同的beta版本可能会导致一些奇怪的问题。2018-10-17下直接使用npm install web3 ,会下载 web3.js 1.0 beta36
使用 beta36版本,事件可以触发,但是输出的时候会报错如下:
解决方案:
引入指定版本的web3.js
npm install [email protected] #指定安装版本
即可解决问题。