以太坊学习(6)关于web3.js 1.0版本中event事件无法触发的问题

关于web3.js 1.0版本中event事件无法触发的问题


写在最前:请检查你的provider连接方式,http provider已不支持event事件的触发了

具体请看官方源文档


一、问题还原:

(1)先给出智能合约代码

  • 合约内容比较简单
  • deposit()函数,对合约地址发起交易,可发送以太币。。相当于存钱到合约地址
  • event transfer()  事件
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
});

【运行前,请先确保你的节点已经启动,并且合约已经部署过了,否则你没有合约的地址,无法发起交易】

 

运行步骤:

1.node 形式启动

 2.看起来是连接上了,但是后面报错说是没有解锁

解锁账户: personal.unlockAccount(eth.accounts[0])

3.再次启动

左图是geth客户端可以看见有一笔交易提交,右图是启动后

4.启动挖矿,确认交易

  miner.start()

 5.已经挖矿确认了,但是node.js运行这边直接退出了,并没有输出事件event

以太坊学习(6)关于web3.js 1.0版本中event事件无法触发的问题_第1张图片

 


二、解决方案

如果是上述的问题,那么很可能就是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事件并输出了

以太坊学习(6)关于web3.js 1.0版本中event事件无法触发的问题_第2张图片

三、另外的问题

问题简述:web3.js 1.0版本下有好多的beta 版本,不同的beta版本可能会导致一些奇怪的问题。2018-10-17下直接使用npm install web3 ,会下载 web3.js 1.0 beta36

使用 beta36版本,事件可以触发,但是输出的时候会报错如下:

以太坊学习(6)关于web3.js 1.0版本中event事件无法触发的问题_第3张图片

解决方案:

引入指定版本的web3.js

 npm install [email protected]    #指定安装版本

即可解决问题。 

你可能感兴趣的:(区块链学习)