Solidity
顯示 Gas 限制錯誤的 CrowdSale 基本合約樣本
您好,我已經從官方網站https://ethereum.org/crowdsale複製了基本合約
我是 Solidity 和乙太坊開發的初學者
它已由 Remix 成功編譯,但是當我點擊“執行”選項卡下的“創建”時,它顯示錯誤
創建 Crowdsale 錯誤:所需的氣體超過限制:300000。重要的氣體估計也可能是契約程式碼中存在問題的跡象。請檢查循環並確保您沒有將值發送到非應付函式(這也是強氣體估計的原因)。
我不確定為什麼會顯示
這是我的程式碼
pragma solidity ^0.4.16; interface token { function transfer(address receiver, uint amount) public; } contract Crowdsale { address public beneficiary; uint public fundingGoal; uint public amountRaised; uint public deadline; uint public price; token public tokenReward; mapping(address => uint256) public balanceOf; bool fundingGoalReached = false; bool crowdsaleClosed = false; event GoalReached(address recipient, uint totalAmountRaised); event FundTransfer(address backer, uint amount, bool isContribution); /** * Constrctor function * * Setup the owner */ function Crowdsale( address ifSuccessfulSendTo, uint fundingGoalInEthers, uint durationInMinutes, uint etherCostOfEachToken, address addressOfTokenUsedAsReward ) public { beneficiary = ifSuccessfulSendTo; fundingGoal = fundingGoalInEthers * 1 ether; deadline = now + durationInMinutes * 1 minutes; price = etherCostOfEachToken * 1 ether; tokenReward = token(addressOfTokenUsedAsReward); } /** * Fallback function * * The function without name is the default function that is called whenever anyone sends funds to a contract */ function () payable public{ require(!crowdsaleClosed); uint amount = msg.value; balanceOf[msg.sender] += amount; amountRaised += amount; tokenReward.transfer(msg.sender, amount / price); FundTransfer(msg.sender, amount, true); } modifier afterDeadline() { if (now >= deadline) _; } /** * Check if goal was reached * * Checks if the goal or time limit has been reached and ends the campaign */ function checkGoalReached() afterDeadline public { if (amountRaised >= fundingGoal){ fundingGoalReached = true; GoalReached(beneficiary, amountRaised); } crowdsaleClosed = true; } /** * Withdraw the funds * * Checks to see if goal or time limit has been reached, and if so, and the funding goal was reached, * sends the entire amount to the beneficiary. If goal was not reached, each contributor can withdraw * the amount they contributed. */ function safeWithdrawal() afterDeadline public { if (!fundingGoalReached) { uint amount = balanceOf[msg.sender]; balanceOf[msg.sender] = 0; if (amount > 0) { if (msg.sender.send(amount)) { FundTransfer(msg.sender, amount, false); } else { balanceOf[msg.sender] = amount; } } } if (fundingGoalReached && beneficiary == msg.sender) { if (beneficiary.send(amountRaised)) { FundTransfer(beneficiary, amountRaised, false); } else { //If we fail to send the funds to beneficiary, unlock funders balance fundingGoalReached = false; } } } }
所以請幫我找出確切的問題以及如何解決它。
事實證明,您正在嘗試部署價值為1 ether的合約。為此,您應該添加
payable
到您的建構子Crowdsale()
:/** * Constrctor function * * Setup the owner */ function Crowdsale( address ifSuccessfulSendTo, uint fundingGoalInEthers, uint durationInMinutes, uint etherCostOfEachToken, address addressOfTokenUsedAsReward ) public payable { beneficiary = ifSuccessfulSendTo; fundingGoal = fundingGoalInEthers * 1 ether; deadline = now + durationInMinutes * 1 minutes; price = etherCostOfEachToken * 1 ether; tokenReward = token(addressOfTokenUsedAsReward); }
價值 1 乙太沒有證明然後這段程式碼執行:
pragma solidity ^0.4.16; interface token { function transfer(address receiver, uint amount) public; } contract Crowdsale { address public beneficiary; uint public fundingGoal; uint public amountRaised; uint public deadline; uint public price; token public tokenReward; mapping(address => uint256) public balanceOf; bool fundingGoalReached = false; bool crowdsaleClosed = false; event GoalReached(address recipient, uint totalAmountRaised); event FundTransfer(address backer, uint amount, bool isContribution); /** * Constrctor function * * Setup the owner */ function Crowdsale( address ifSuccessfulSendTo, uint fundingGoalInEthers, uint durationInMinutes, uint etherCostOfEachToken, address addressOfTokenUsedAsReward ) public { beneficiary = ifSuccessfulSendTo; fundingGoal = fundingGoalInEthers * 1 ether; deadline = now + durationInMinutes * 1 minutes; price = etherCostOfEachToken * 1 ether; tokenReward = token(addressOfTokenUsedAsReward); } /** * Fallback function * * The function without name is the default function that is called whenever anyone sends funds to a contract */ function () payable public{ require(!crowdsaleClosed); uint amount = msg.value; balanceOf[msg.sender] += amount; amountRaised += amount; tokenReward.transfer(msg.sender, amount / price); FundTransfer(msg.sender, amount, true); } modifier afterDeadline() { if (now >= deadline) _; } /** * Check if goal was reached * * Checks if the goal or time limit has been reached and ends the campaign */ function checkGoalReached() afterDeadline public { if (amountRaised >= fundingGoal){ fundingGoalReached = true; GoalReached(beneficiary, amountRaised); } crowdsaleClosed = true; } /** * Withdraw the funds * * Checks to see if goal or time limit has been reached, and if so, and the funding goal was reached, * sends the entire amount to the beneficiary. If goal was not reached, each contributor can withdraw * the amount they contributed. */ function safeWithdrawal() afterDeadline public { if (!fundingGoalReached) { uint amount = balanceOf[msg.sender]; balanceOf[msg.sender] = 0; if (amount > 0) { if (msg.sender.send(amount)) { FundTransfer(msg.sender, amount, false); } else { balanceOf[msg.sender] = amount; } } } if (fundingGoalReached && beneficiary == msg.sender) { if (beneficiary.send(amountRaised)) { FundTransfer(beneficiary, amountRaised, false); } else { //If we fail to send the funds to beneficiary, unlock funders balance fundingGoalReached = false; } } } }
除非礦工增加區塊氣體限制,否則您唯一的選擇是將合約拆分為多個合約
所以每個合約都有自己的地址,你可以在它們之間進行呼叫。例如,ICO 眾籌可以分為:
1 Crowdsale:管理眾籌,代幣如何分配,獎勵,開啟,關閉 2 Token:實現 ERC20,可以創建代幣,批准轉賬 3 Wallet:管理眾籌期間收到的資金
由於每個契約的範圍有限,因此拆分也有助於安全審計。
謝謝試試