Solidity
智能合約錯誤:所需氣體超過 300000000
我從本教程中獲得了以下程式碼:
pragma solidity ^0.4.11; contract Casino { uint minimumBet; uint totalBet; uint numberOfBets; uint maximumAmountsOfBets = 100; address[] players; struct Player { uint amountBet; uint numberSelected; } mapping(address => Player) playerInfo; address owner; // Long string from metamask function Casino(uint _minimumBet) public{ // Constructor : has the same name as the contract , used to set up //contract owner owner = msg.sender; if(_minimumBet !=0) minimumBet = _minimumBet; } //To be for a number btw 1 & 10 both inclusive function bet(uint number) payable public { require(checkPlayerExists(msg.sender) ); require(number >= 1 && number <= 10); require(msg.value >= minimumBet); playerInfo[msg.sender].amountBet = msg.value; playerInfo[msg.sender].numberSelected = number; numberOfBets += 1; players.push(msg.sender); totalBet += msg.value; if(numberOfBets >= maximumAmountsOfBets) generateNumberWinner(); } function checkPlayerExists(address player) public view returns(bool) { for( uint i = 0 ; i < players.length; i++){ if(players[i] == player) return true; } return false; } /* Generate Winner : Generates a number between 1 & 10 */ function generateNumberWinner() public{ uint numberGenerated = block.number % 10 + 1; // This isnt secure distributePrizes(numberGenerated); } /* Distribute Prizes : Sends the correspondng ether to each winner depending on the total bets */ function distributePrizes(uint numberWinner) public { address[100] memory winners ; // We have to create a temporary in memory array with fixed size uint count = 0; // This is the count for the array of winners for(uint i = 0; i < players.length ; i++) { address playerAddress = players[i]; if(playerInfo[playerAddress].numberSelected == numberWinner){ winners[count] = playerAddress; count ++; } delete playerInfo[playerAddress]; // Delete all the players array } players.length = 0; //Delete all the players array uint winnerEtherAmount = totalBet / winners.length; // How much each player gets for(uint j = 0; j < count; j++) { if(winners[j] !=address(0)) // Check the address in the fixed array is not empty winners[j].transfer(winnerEtherAmount); } } /* Annonymous Fallback function: In case someone sends ether to the contract so it doesnt get lost */ function() payable private{} /* Kill function: Used to destroy contract whenever we want. Only owner has the ability to kill the contract */ function kill() private{ if(msg.sender == owner) selfdestruct(owner); } }
它編譯得很好,但是當我嘗試
bet
它時,REMIX 會拋出以下錯誤:向 Casino.bet 交易錯誤:所需氣體超出限制:3000000。重要的氣體估計也可能表明契約程式碼存在問題。請檢查循環並確保您沒有將值發送到不可支付的函式(這也是強氣體估計的原因)。
如果有人能指出我正確的方向,我將不勝感激。
我相信這條線:
require(checkPlayerExists(msg.sender));
實際上應該說相反:
require(!checkPlayerExists(msg.sender));
玩家第一次呼叫時不可能存在
bet
,因此require
中止了事務。假設您正在關注https://medium.com/@merunasgrincalaitis/the-ultimate-end-to-end-tutorial-to-create-and-deploy-a-fully-descentralized-dapp-in-ethereum-18f0cf6d7e0e,請注意,他們有這條線,這大致相當於我的建議。(但我認為
require
這裡比 . 更合適assert
。)assert(checkPlayerExists(msg.sender) == false);