Solidity

智能合約事件顯示“未擷取的類型錯誤:contract_instance.NumberIsIncreased 不是函式”

  • July 16, 2018

我的功能是:

function watchEvents(){
               myEvent = contract_instance.NumberIsIncreased({},{fromBlock: 'latest', toBlock: 'latest'});
               console.log(myEvent);
               myEvent.watch(function(error, result){
                   if(error){
                       console.log(error);
                   } else{
                       console.log(result);
                       document.getElementById("events").innerHTML = document.getElementById("events").innerHTML + "<br />" + JSON.stringify(result);
                   }
               });

           }

這是契約:

event NumberIsIncreased(address indexed whoIncreased, uint256 indexed oldNumber, uint256 indexed newNumber);


function setMyNumber(uint256 myNewNumber) public {
       NumberIsIncreased(msg.sender, myNumber, myNewNumber);
       myNumber = myNewNumber;
   }

雖然我可以訪問智能合約上的其他功能,但當我呼叫事件時,它會顯示錯誤Uncaught TypeError: contract_instance.NumberIsIncreased is not a function

我也可以在 Mist 瀏覽器中跟踪事件。

我正在使用 geth 版本:1.7.2-stable

編輯1:

我正在使用 web3.js 版本:0.14.0

其他有效的功能:

function getCounter(){
               contract_instance.getMyNumber(function(e,r){
                   document.getElementById("myCounter").innerText = r.toNumber();
               });
           }

function increaseCounter(){
               contract_instance.getMyNumber(function(e,r){
                   currentNumber = r;
                   currentNumber++;
                   web3.eth.getAccounts(function(e,accounts){
                       web3.personal.unlockAccount(accounts,"password", function(e,r){});
                       contract_instance.setMyNumber(currentNumber, {from:accounts[0]  , gas:200000}, function(error, result){
                           if (error){
                               console.error(error);
                           } else {
                               var txHash = result;
                               console.log(txHash);
                               callWhenMined(txHash, getCounter);
                           }
                       });
                   });
               });
           }

我的契約文件:

pragma solidity ^0.4.0;

contract MyContract {
   address creator;
   uint256 myNumber;

   event NumberIsIncreased(address indexed whoIncreased, uint256 indexed oldNumber, uint256 indexed newNumber);

   function MyContract() public {
       creator = msg.sender;
       myNumber = 3;
   }

   function getCreator() public constant returns (address) {
       return creator;
   }

   function getMyNumber() public constant returns (uint256) {
       return myNumber;
   }

   function setMyNumber(uint256 myNewNumber) public {
       NumberIsIncreased(msg.sender, myNumber, myNewNumber);
       myNumber = myNewNumber;
   }


   function kill() public {
       if (msg.sender == creator) {
           selfdestruct(creator);
       }
   }

}

事件不是您可以從合約外部呼叫的函式(contract_instance.NumberIsIncreased()無效);它們僅在智能合約本身的函式中被呼叫。當您呼叫時setMyNumber(),該函式呼叫事件並且事件將記錄在呼叫返回的事務對像中setMyNumber

事件通常在函式結束時和狀態更改後呼叫,只有在函式主體中的計算完成並成功後,才允許記錄和確認函式成功。

記錄事件還允許監視和監視合約上呼叫的函式。

附帶說明一下,建議使用“Log”前綴事件的命名約定(即“LogNumberIsIncreased”),以使程式碼更易於閱讀,從而在呼叫事件時更加清晰。一旦您的契約變得更加複雜並且您記錄的事件越來越多,這將特別有用。

另一個建議的最佳做法是,應該最後呼叫事件,即在您設置數字之後myNumber = myNewNumber。您可能需要一個臨時變數myOldNumber。在這個例子中,它可能沒問題,因為如果設置數字失敗,那麼整個函式將恢復並且它實際上不會記錄事件(即使事件呼叫在數字設置之前出現)。但是作為“快速失敗”的一般最佳實踐,一旦你編寫更複雜的合約,它再次變得更加重要,可能失敗的步驟(這裡改變數字/改變狀態)應該首先出現。如果由於某種原因該操作失敗,通過在操作之後呼叫事件,您不需要浪費任何計算或執行不必要的步驟(記錄事件),因為該函式會在達到現在不必要的計算之前失敗。

由於有人也遇到了這個錯誤,我正在回答我自己的問題。

因此,當我重建契約時,這裡的問題就解決了。

truffle migrate --reset --all

在元遮罩中,您可以重置帳戶。

之後我得到了事件日誌。您也應該能夠在 truffle 控制台中的合約實例中看到您的事件。

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