Solidity

沒有觸發 Solidity 事件

  • June 29, 2020

我正在嘗試從 NodeJS 監聽我在 remix IDE 上創建的事件。我從觸發事件的位置呼叫智能合約方法,我在控制台中等待它……但我沒有收到任何東西:(

我正在使用帶有 ExpressJS Web3 版本的 NodeJS:1.0.0-beta.46

智能合約程式碼類似於:

pragma solidity >= 0.4.22 < 0.6.0;

contract Test {


event test1(address a,uint16 b,uint16 c,uint16 d,uint16 e);
event test2(address a,uint128 f,uint16 g);
event test3(address a,uint128 f,bool h);

//method 1
function method1(uint16 a,uint16 b,uint16 c,uint16 d) external payable {
// ... some code ... //

//here I trigger the event
   emit test1(msg.sender,a,b,c,d);
}

//method 2
function method2(uint128 f,uint16 g) external payable {
// ... some code ... //

//here I trigger the event
   emit test2(msg.sender,f,g);
}

//method 3
function method3(uint128 f) external payable {
// ... some code ... //

//here I trigger the event
   emit test3(msg.sender,f,true);
}


}

這就是我在 NodeJS 中監聽事件的方式:

SmartContract.events.test1({fromBlock: 0, toBlock: 'latest'} , (error, event) => { console.log(JSON.stringify(event)); })
.on('data', (event) => {
console.log("The event is : " + JSON.stringify(event));
}).on('changed', (event) => {
console.log("Changed event : " + JSON.stringify(event));
}).on('error', console.error);

我也嘗試在沒有任何參數(如 fromBlock 或 toBlock)的情況下聽,但沒有奏效……我沒有收到任何錯誤或其他東西。我在執行智能合約方法之前和執行之後開始收聽

收到的探勘塊的狀態為“0x1”,所以交易正常。但我不知道為什麼監聽器不工作……

編輯:智能合約的實例化:

const address = "0xB740096F1a6642190c816EfE37697891c65Afc92";
const theABI = require('./getABI.js');
var SmartContract = new web3.eth.Contract(theABI.getABI() , address);

getABI.js 文件只有 1 個返回 ABI 的函式。我確定並且我剛剛重新檢查過,ABI 包含事件。這是 ABI 中存在事件的程式碼片段:

   {
           "anonymous": false,
           "inputs": [
                   {
                           "indexed": false,
                           "name": "a",
                           "type": "address"
                   },
                   {
                           "indexed": false,
                           "name": "f",
                           "type": "uint128"
                   },
                   {
                           "indexed": false,
                           "name": "g",
                           "type": "uint16"
                   }
           ],
           "name": "test2",
           "type": "event"
   },

web3 的實例化:

const Web3 = require('web3');
const web3 = new Web3(Web3.givenProvider || "ws://IP SERVER:PORT");

我也嘗試過以下方法:

// Receives all events from the smart contract
const listener = SmartContract.events.allEvents({}, (error, event) =>{ console.log("THE CALLBACK EVENT IS : " + JSON.stringify(event)); })
.on('data', async (event) => { console.log("THE EVENT IS : " + JSON.stringify(event)); })
.on('receipt', async function(result) { console.log("THE RECEIPT EVENT IS : " + JSON.stringify(event)); })
.on('transactionHash', function(hash){ console.log("THE HASH EVENT IS : " + JSON.stringify(event)); })
.on('error', function(error){ console.log("THE ERROR EVENT IS : " + JSON.stringify(event)); });

事件監聽器仍然沒有輸出……

問題解決了 :

探勘的智能合約地址不正確,因此事件沒有監聽。

您可以使用 subscribe 作為替代方案,稍微複雜一點

web3.eth.subscribe('logs',........);

web3.eth.subscribe 函式讓您訂閱區塊鏈中的特定事件。

https://web3js.readthedocs.io/en/1.0/web3-eth-subscribe.html

// 更新

嘗試 truffle 以及 truffle-contract 庫

我在我的 Angular-App 中使用它並且效果很好,如果您正在尋找範例,它會在一些 Truffle-boxes 中使用

https://github.com/trufflesuite/truffle-contract

看起來像這樣的打字稿中的組件

constructor(private web3Service: Web3Service) {
   console.log('Constructor: ' + web3Service);
}

ngOnInit(): void {
   console.log('OnInit: ');
   this.web3Service.artifactsToContract(MyToken_artifacts)
     .then((MyTokenAbstraction) => {
       this.MyToken = MyTokenAbstraction;
       this.MyToken.deployed().then(deployed => {
         console.log(deployed);
         deployed.Transfer({}, (err, ev) => {
           console.log('Transfer event came in, refreshing balance');
         });
       });

     });
 }

並在 artifactsToContract 方法中-> 類似這樣

const contractAbstraction = contract(artifacts);
contractAbstraction.setProvider(this.web3.currentProvider);

引用自:https://ethereum.stackexchange.com/questions/70338