You can use OpenZeppelin. From their SampleCrowdsale.
Standard preamble and we import a few dependencies
pragma solidity ^0.4.18;
import "../crowdsale/CappedCrowdsale.sol";
import "../crowdsale/RefundableCrowdsale.sol";
import '../token/StandardToken.sol';
import '../ownership/Ownable.sol';
We create a token with a fixed supply and assign all the tokens to the creator. In our case the creator will be the Crowdsale contract.
contract SampleFixedSupplyToken is StandardToken, Ownable {
string public constant name = "Sample Fixed Supply Token";
string public constant symbol = "SFST";
uint8 public constant decimals = 18;
function SampleFixedSupplyToken(uint _totalSupply) public {
// Allocate fixed supply to token Creator
totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
Transfer(address(0), msg.sender, _totalSupply);
}
}
In the crowdsale we define the total supply of the token, and override the createCrowdsaleToken function to create our own token with the defined supply.
Additionally we have to modify buyTokens because it will try to mint token, and our token doesn't have such function. We instead transfer tokens owned by the crowdsale contract to our contributor.
contract SampleCrowdsale is CappedCrowdsale, RefundableCrowdsale {
uint256 public constant totalSupply = 1000000*10**18;
function SampleCrowdsale(uint256 _startTime, uint256 _endTime, uint256 _rate, uint256 _goal, uint256 _cap, address _wallet) public
CappedCrowdsale(_cap)
FinalizableCrowdsale()
RefundableCrowdsale(_goal)
Crowdsale(_startTime, _endTime, _rate, _wallet)
{
//As goal needs to be met for a successful crowdsale
//the value needs to less or equal than a cap which is limit for accepted funds
require(_goal <= _cap);
}
function createTokenContract() internal returns (MintableToken) {
// Create Token contract
// The total supply will be assigned to the crowdsale contract
return new SampleCrowdsaleToken(totalSupply);
}
// NOTE: We have to modify buyTokens
// since Crowdsale will try to mint tokens
// but we minted all tokens at creation
function buyTokens(address beneficiary) public payable {
require(beneficiary != address(0));
require(validPurchase());
uint256 weiAmount = msg.value;
// calculate token amount to be created
uint256 tokens = weiAmount.mul(rate);
// update state
weiRaised = weiRaised.add(weiAmount);
// Instead of minting new token transfer from
// those assigned to the Crowdsale contract
// token.mint(beneficiary, tokens);
require(token.transfer(beneficiary, tokens));
TokenPurchase(msg.sender, beneficiary, weiAmount, tokens);
forwardFunds();
}
}