Solidity

在前端松露合約實例中未觀察到發射的 Solidity 事件

  • September 29, 2019

所以,我一直在閱讀很多關於 Solidity 事件以及如何在前端與它們互動的頁面,但我對此仍然很陌生,似乎有很多變化,因為我看到的許多網站都使用過時的方法來注意 Solidity 事件的變化。我讓它在某個時候工作,但它突然無緣無故停止工作。

我在所有 4 個 Solidity 事件中都嘗試了這個,為簡單起見,我將只用一種方法展示我的範例

pragma solidity ^0.5.0;

contract Platoonfactory {
   event PlatoonCreated(address owner, uint256 platoonId);

   uint256 public currentPlatoonID = 1;
   uint256 public contractBalance = address(this).balance;

   /**
    * A platoon has atleast one truck driving in front and 0..n trucks following
    */
   struct Platoon {
       uint256 platoonId;
       address payable owner;
       uint costPerMinute;
       uint startDate;
       uint endDate;
       // participants contains all joined trucks inside this platoon
       mapping(uint /* index */ => TruckInPlatoon) participants;
       uint participantsSize;
   }

   /**
    * A TruckInPlatoon struct describes exactly one truck inside a platoon *besides* the leaders
    */
   struct TruckInPlatoon {
       uint platoonId;
       address truckOwner;
       uint startDate;
       uint allowedParticipationUntilDate;
       uint payedAmountOfWei;
   }

   // map the owner of a platoon to the unique ID
   mapping(address => uint) public platoonOwners;
   // map the unique ID to each platoon
   mapping(uint => Platoon) public platoons;


   /**
    * Create a new platoon with required cost to join and the amount of hours in which this platoon is available
    */
   function createPlatoon(uint cpm, uint endDate) public returns (uint) {
       require(platoonOwners[msg.sender] == 0, "You have already started a platoon");
       require(endDate >= 1, "Platoon must at least be available for one hour");

       // create a new platoon and push it to the storage
       platoons[currentPlatoonID] = Platoon({platoonId: currentPlatoonID, owner: msg.sender, costPerMinute: cpm, startDate: now, endDate: (now + endDate*3600), participantsSize:0});
       platoonOwners[msg.sender] = currentPlatoonID;

       //Increment current ID
       currentPlatoonID++;

       // fire event
       emit PlatoonCreated(msg.sender, currentPlatoonID);
       return currentPlatoonID - 1;
   }

}

JavaScript:

App = {
   contracts: {},
   address: "",
   web3js: null,
   PlatoonContract: null,

   init: function () {
       return App.initWeb3();
   },

   initWeb3: function () {
       if (typeof web3 !== 'undefined') {
           App.web3js = new Web3(web3.currentProvider);
       } else {
           App.web3js = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));
       }
       return App.initHTML();
   },

   initHTML: function () {
       App.web3js.eth.getAccounts((err, accounts) => {
           if (!err) {
               document.getElementById("account-id").innerHTML = accounts[0];
               App.address = accounts[0];
           } else {
               console.log(err);
           }
       });
       return App.initContract();
   },

   initContract: function () {
       $.getJSON('../build/contracts/Platoonfactory.json', function (data) {
           var PlatoonArtifact = data;
           App.contracts.Platoonfactory = TruffleContract(PlatoonArtifact);
           App.contracts.Platoonfactory.setProvider(web3.currentProvider);

           App.contracts.Platoonfactory.deployed().then(function (instance) {
               App.PlatoonContract = instance;
               return App.listenFor();
           });
       });
   },

   listenFor: function () {
       App.PlatoonContract.PlatoonCreated({}, {fromBlock:0, toBlock: 'latest'}).watch(function(err, result) {
           if (err) {
               console.log(err);
           }

           if (result) {
               console.log(result);
               document.getElementById("platoonList").innerText = "ID: " + res.args.platoonId.c[0] + " Owner: " + res.args.owner;
           }
       });
       return App.bindEvents();
   },

   bindEvents: function () {
       $("#btnCreatePlatoon").click(event => {
           event.preventDefault();
           let cpm = document.getElementById("costPerMinute").value;
           let duration = document.getElementById("hoursAvailable").value;
           App.PlatoonContract.createPlatoon(cpm, duration);
       });

       $("#btnContractBalance").click(event => {
           event.preventDefault();
           App.PlatoonContract.contractBalance().then(result => console.log(result.c[0]));
       });
   },

};

$(function () {
   $(window).load(function () {
       App.init();
   });
});

在這種情況下,HTML 應該無關緊要。將近一周以來,我一直在嘗試解決此問題,並且已經開始對此感到瘋狂,因為有很多過時的文章。如果有人最終能找到問題所在,我將非常感激。我在 Remix 中測試了 Solidity 程式碼,所有方法都執行良好,Ganache 甚至辨識了契約選項卡上的事件,錯誤似乎出現在我附加監聽器的地方。

補充:我正在使用 Truffle、Ganache 和 Metamask 來測試我的 DApp

所以我終於修好了!似乎事件處理程序中指定 fromBlock 和 toBlock 的第二個參數與 Metamask 不兼容。在我刪除了 toBlock 參數後它起作用了。工作片段:

App.PlatoonContract.PlatoonCreated({}, {fromBlock:0}).watch(function(err, result) {
       if (err) {
           console.log(err);
       }

       if (result) {
           console.log(result);
           document.getElementById("platoonList").innerText = "ID: " + res.args.platoonId.c[0] + " Owner: " + res.args.owner;
       }
   });

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