Solidity
眾籌後如何將 ETH 從合約轉移到外部地址?
我正在嘗試學習創建智能合約。作為實踐,我按照 ethereum.org 上的範例創建了代幣和眾籌合約並進行了部署。代幣分配按預期進行,但當合約期限到期(資金目標也達到)時,合約賬戶中的資金不會轉移到受益人賬戶。
這是程式碼:
pragma solidity ^0.4.11; contract token { function transfer(address, uint){ } } 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; event GoalReached(address beneficiary, uint amountRaised); event FundTransfer(address backer, uint amount, bool isContribution); bool crowdsaleClosed = false; /* data structure to hold information about campaign contributors */ /* at initialization, setup the owner */ function Crowdsale( address ifSuccessfulSendTo, uint fundingGoalInEthers, uint durationInMinutes, uint etherCostOfEachToken, token addressOfTokenUsedAsReward ) { beneficiary = ifSuccessfulSendTo; fundingGoal = fundingGoalInEthers * 1 ether; deadline = now + durationInMinutes * 1 minutes; price = etherCostOfEachToken * 1 ether; tokenReward = token(addressOfTokenUsedAsReward); } /* The function without name is the default function that is called whenever anyone sends funds to a contract */ function () payable { if (crowdsaleClosed) revert(); 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) _; } /* checks if the goal or time limit has been reached and ends the campaign */ function checkGoalReached() afterDeadline { if (amountRaised >= fundingGoal){ fundingGoalReached = true; GoalReached(beneficiary, amountRaised); } crowdsaleClosed = true; } function safeWithdrawal() afterDeadline { 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; } } } }
我錯過了什麼嗎?
您可能提供的資訊太少,無法真正提供幫助。
您可以發布契約的地址和用於創建它的參數嗎?
address ifSuccessfulSendTo = uint fundingGoalInEthers = uint durationInMinutes = uint etherCostOfEachToken = token addressOfTokenUsedAsReward =
無論如何,您可以嘗試幾件事:
- 確保您
safeWithdrawal()
從用於創建契約的同一地址撥打電話。如果此事務失敗,則fundingGoalReached
返回到false
,這意味著您必須在再次呼叫之前呼叫checkGoalReached()
將其設置回。true``safeWithdrawal()
- 當呼叫合約的方法時,嘗試發送大量的氣體,例如
200,000
,為了安全起見*(未使用的氣體總是會被退回給你)*。餘額
$$ msg.sender $$=數量;
此外,這似乎有問題,因為它每次都設置存款人的餘額值並且不會增加它,例如。進行多次存款時。
募集金額 += 金額;
最後,通常不建議這樣做,因為它會引發溢出問題。最好使用zeppelin-solidity 的SafeMath.sol 之類的東西。