pragma solidity ^0.4.24;
/******************************************/
/* Netkiller Crowdsale Contract */
/******************************************/
/* Author netkiller <netkiller@msn.com> */
/* Home http://www.netkiller.cn */
/* Version 2018-06-07 - Solc ver: 0.4.24 */
/******************************************/
interface token {
function transfer(address receiver, uint amount) external;
}
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);
/**
* Constructor function
*
* Setup the owner
*/
constructor(
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);
emit 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;
emit 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)) {
emit FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (beneficiary.send(amountRaised)) {
emit FundTransfer(beneficiary, amountRaised, false);
} else {
//If we fail to send the funds to beneficiary, unlock funders balance
fundingGoalReached = false;
}
}
}
}
pragma solidity ^0.4.21;
interface token {
function transfer(address receiver, uint amount) external;
}
contract Crowdsale {
address public beneficiary; // 募資成功後的收款地址
uint public fundingGoal; // 募資額度
uint public amountRaised; // 參與數量
uint public deadline; // 募資截止期
uint public price; // token 與以太坊的匯率, token賣多少錢
token public tokenReward; // 要賣的token
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);
/**
* 建構子, 設置相關屬性
*/
function Crowdsale(
address ifSuccessfulSendTo,
uint fundingGoalInEthers,
uint durationInMinutes,
uint finneyCostOfEachToken,
address addressOfTokenUsedAsReward) public {
beneficiary = ifSuccessfulSendTo; //募資成功後的收款賬號
fundingGoal = fundingGoalInEthers * 1 ether; //募資額度
deadline = now + durationInMinutes * 1 minutes; //募資時間
price = finneyCostOfEachToken * 1 finney; //每個代幣的價格, 這裡為了方便使用了單位finney及值為:1 (1 ether = 1000 finney)
tokenReward = token(addressOfTokenUsedAsReward); // 代幣合約地址。傳入已發佈的 token 合約的地址來創建實例
}
/**
* 無函數名的Fallback函數,
* 在向合約轉賬時,這個函數會被調用
*/
function () payable public {
require(!crowdsaleClosed);
uint amount = msg.value;
balanceOf[msg.sender] += amount;
amountRaised += amount;
tokenReward.transfer(msg.sender, amount / price);
emit FundTransfer(msg.sender, amount, true);
}
/**
* 定義函數修改器modifier
* 用於在函數執行前檢查某種前置條件(判斷通過之後才會繼續執行該方法)
* _ 表示繼續執行之後的代碼
**/
modifier afterDeadline() { if (now >= deadline) _; }
/**
* 判斷眾籌是否完成融資目標, 這個方法使用了afterDeadline函數修改器
*
*/
function checkGoalReached() afterDeadline public{
if (amountRaised >= fundingGoal) {
fundingGoalReached = true;
emit GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}
/**
* 完成融資目標時,融資款發送到收款方
* 未完成融資目標時,執行退款
*
*/
function safeWithdrawal() afterDeadline public{
if (!fundingGoalReached) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
if (msg.sender.send(amount)) {
emit FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (beneficiary.send(amountRaised)) {
emit FundTransfer(beneficiary, amountRaised, false);
} else {
//If we fail to send the funds to beneficiary, unlock funders balance
fundingGoalReached = false;
}
}
}
}