Skip to content

Instantly share code, notes, and snippets.

@stephenlb stephenlb/
Last active Sep 15, 2019

What would you like to do?
Solidity Smart Contract all-in-one that allows the crowd-sale of custom tokens for as long as the owner wallet balance is above zero. See readme for more details.

Simplified Modifiable ERC20 Token Details

Controllable Crowd-sale and transferable ownership allows you to change ownership and change exchange rates.

  • Owner Wallet receives ETH funds.
  • Owner Wallet holds TOKEN's for sale.
  • Moving tokens from owner wallet to another removes publicly purchaseable token inventory.
  • Custom Exchange Rate ETH for YOUR TOKEN. Default is 1:10 One ETH = 10 YOUR TOKEN.
  • Changable Exchange Rate at any time!
  • Exchange ETH for YOURTOKEN at a custom exchange rate.
  • An investor sends ETH to your Contract Address. Investor receives YOURTOKEN and you receive ETH.
  • Modify your exchange rate at any time.
  • You can stop the crowd-sale by moving the tokens out of the owner's account into a different account.
  • You can re-start the crowd-sale by adding tokens back to the owner account.
  • You can cap the total volume of token sales by placing only the desired amount of tokens in the owner's balance.
  • To change the owner, call transferOwnership(address newOwner) as the owner.
  • You also may want to transfer to the new owner's address as well by calling transfer(newOwner, XXXX) as the original owner balance holder.
  • To change the Exchange Rate, call changeExhangeRate(uint256 newRate) as the owner.
  • To change the Ticker Symbol, call changeTokenSymbol(string newSymbol) as the owner.
  • To change the Ticker Name, call changeTokenName(string newName) as the owner.

How to use (test mode)

  1. Download MetaMask
  2. Select KOVAN Network "Kovan Test Net".
  3. Copy your Account Address from MetaMask
  4. Paste your Account Address into the Kovan Chat (sign in using Twitter/GitHub)
  5. Copy controllable-crowd-sale-token.sol (find lower down on this page!)
  6. Paste into Ethereum Editor
  7. Click CREATE Button
  8. Done!

You will see some new buttons after the contract was deployed (after clicking CREATE).
Paste in your address "0x0000" make sure to use "Quotes". Click the balanceOf button and see your balance.

You can change the COIN name using the other methods.

pragma solidity ^0.4.19;
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
uint256 c = a * b;
assert(c / a == b);
return c;
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
return c;
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function Ownable() public {
owner = msg.sender;
modifier isOwner() {
require(msg.sender == owner);
function transferOwnership(address newOwner) public isOwner {
require(newOwner != address(0));
OwnershipTransferred(owner, newOwner);
owner = newOwner;
contract StandardToken {
using SafeMath for uint256;
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
uint256 public totalSupply;
function totalSupply() public constant returns (uint256 supply) {
return totalSupply;
function transfer(address _to, uint256 _value) public returns (bool success) {
if (balances[msg.sender] >= _value && _value > 0) {
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
Transfer(msg.sender, _to, _value);
return true;
} else { return false; }
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
balances[_to] = balances[_to].add(_value);
balances[_from] = balances[_from].sub(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
Transfer(_from, _to, _value);
return true;
} else { return false; }
function balanceOf(address _owner) public constant returns (uint256 balance) {
return balances[_owner];
function approve(address _spender, uint256 _value) public returns (bool success) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
return allowed[_owner][_spender];
contract ERC20Token is StandardToken, Ownable {
using SafeMath for uint256;
string public name;
string public symbol;
string public version = '1.0';
uint256 public totalCoin;
uint8 public decimals;
uint8 public exchangeRate;
event TokenNameChanged(string indexed previousName, string indexed newName);
event TokenSymbolChanged(string indexed previousSymbol, string indexed newSymbol);
event ExhangeRateChanged(uint8 indexed previousRate, uint8 indexed newRate);
function ERC20Token() public {
decimals = 18;
totalCoin = 10000000; // Total Supply of Coin
totalSupply = totalCoin * 10**uint(decimals); // Total Supply of Coin
balances[owner] = totalSupply; // Total Supply sent to Owner's Address
exchangeRate = 100; // 100 Coins per ETH (changable)
symbol = "TICKER"; // Your Ticker Symbol (changable)
name = "YourCoinNameHere"; // Your Coin Name (changable)
function changeTokenName(string newName) public isOwner returns (bool success) {
TokenNameChanged(name, newName);
name = newName;
return true;
function changeTokenSymbol(string newSymbol) public isOwner returns (bool success) {
TokenSymbolChanged(symbol, newSymbol);
symbol = newSymbol;
return true;
function changeExhangeRate(uint8 newRate) public isOwner returns (bool success) {
ExhangeRateChanged(exchangeRate, newRate);
exchangeRate = newRate;
return true;
function () public payable {
function fundTokens() public payable {
require(msg.value > 0);
uint256 tokens = msg.value.mul(exchangeRate);
require(balances[owner].sub(tokens) > 0);
balances[msg.sender] = balances[msg.sender].add(tokens);
balances[owner] = balances[owner].sub(tokens);
Transfer(msg.sender, owner, msg.value);
function forwardFunds() internal {
function approveAndCall(
address _spender,
uint256 _value,
bytes _extraData
) public returns (bool success) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
)) { revert(); }
return true;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.