Solidity
Oraclize 不返回答案
當我呼叫函式 selectWinner() 時遇到問題,用它發送一些乙太幣來支付 Oraclize。我將 Rinkeby 與 Infura 和 metamask 一起用於測試帳戶。我在元遮罩中收到一個錯誤,上面寫著:
交易錯誤。合約程式碼中拋出異常。
然後交易失敗。
pragma solidity ^0.4.23; contract Lottery is usingOraclize { uint lotteryFee = 0.1 ether; uint8 counter = 0; address[10] participants; mapping (address => bool) checkParticipant; address public owner; bytes32 public oraclizeID; uint public winnerNumber; modifier onlyOnce() { require(checkParticipant[msg.sender] == false); _; } function participate() external payable onlyOnce returns(address) { require(msg.value == lotteryFee); checkParticipant[msg.sender] = true; counter = counter + 1; participants[counter] = msg.sender; return(participants[counter]); } function getBalance() public view returns (uint) { uint contractBalance = address(this).balance; return(contractBalance); } function selectWinner() payable public { oraclizeID = oraclize_query("WolframAlpha", "random number between 1 and 10"); } function __callback(bytes32 _oraclizeID, string _result){ if(msg.sender != oraclize_cbAddress()) throw; testString = _result; winnerNumber = parseInt(_result); uint maxRange = counter; uint randomNumber = uint(sha3(_result)) % maxRange; } function payTheReward() external returns(address){ address winnerAddress = participants[winnerNumber]; uint currentBalance = getBalance(); winnerAddress.transfer(currentBalance); deleteParticipants(); return (winnerAddress); } function deleteParticipants() internal { uint8 a = counter; for(uint8 i = 0; i < a; i++) { checkParticipant[participants[i]] = false; participants[i] = 0; } counter = 0; } }
我正在使用 Javascript 來呼叫它:
selectTheWinner: function(){ App.contractInstance.selectWinner( { from: App.account, value: App.web3.toWei(0.1, "ether") } ).then(function(addr){ console.log(addr)}) .catch(function(error){ console.log(error); });
我的契約號是:
0xFD05EE7F1660fcaDF5BB618cA5b09e6C564F99cF
您的契約原樣甚至無法編譯。您首先需要刪除
testString
__callback 函式下未聲明的標識符。其次,Oraclize 僅支持 solc 0.4.20,因為在更高版本中存在/可能存在破壞契約的錯誤,這是您想要做的另一個更改。
完成以下更改後,您的契約對我來說工作得很好,有 2 個使用者參與,然後呼叫 selectWinner,它從 WA 返回 1 作為隨機數。
您可能需要對 selectWinner 進行額外的檢查/修改,因為有人可能會使用該功能耗盡合約的資金。