Solidity
在前端松露合約實例中未觀察到發射的 Solidity 事件
所以,我一直在閱讀很多關於 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; } });