1.額外實(shí)現(xiàn)功能包括代幣和eth的按比例自動兌換放吩、賬戶的凍結(jié)鎖定、代幣的增發(fā)羽杰、代幣的銷毀等渡紫。
2.如果不繼承StandardToken,自己實(shí)現(xiàn)ERC20接口可以在發(fā)布的時(shí)候節(jié)約大概100萬gas考赛,該示意繼承了StandardToken
3.必須使用SafeMath庫防止計(jì)算溢出帶來的BUG
pragma solidity ^0.4.24;
import 'zeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
// ERC20 standard token
contract JB is StandardToken {
address public admin; // 管理員
string public name = "JB Token"; // 代幣名稱
string public symbol = "JB"; // 代幣符號
uint8 public decimals = 18; // 代幣精度
uint256 public INITIAL_SUPPLY = 8000000000000000000000000000; // 總量80億 *10^18
// 同一個(gè)賬戶滿足任意凍結(jié)條件均被凍結(jié)
mapping (address => bool) public frozenAccount; //無限期凍結(jié)的賬戶
mapping (address => uint256) public frozenTimestamp; // 有限期凍結(jié)的賬戶
bool public exchangeFlag = true; // 代幣兌換開啟
// 不滿足條件或募集完成多出的eth均返回給原賬戶
uint256 public minWei = 1; //最低打 1 wei 1eth = 1*10^18 wei
uint256 public maxWei = 20000000000000000000000; // 最多一次打 20000 eth
uint256 public maxRaiseAmount = 20000000000000000000000; // 募集上限 20000 eth
uint256 public raisedAmount = 0; // 已募集 0 eth
uint256 public raiseRatio = 200000; // 兌換比例 1eth = 20萬token
// event 通知
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
// 構(gòu)造函數(shù)
constructor() public {
totalSupply_ = INITIAL_SUPPLY;
admin = msg.sender;
balances[msg.sender] = INITIAL_SUPPLY;
}
// fallback 向合約地址轉(zhuǎn)賬 or 調(diào)用非合約函數(shù)觸發(fā)
// 代幣自動兌換eth
function()
public payable {
require(msg.value > 0);
if (exchangeFlag) {
if (msg.value >= minWei && msg.value <= maxWei){
if (raisedAmount < maxRaiseAmount) {
uint256 valueNeed = msg.value;
raisedAmount = raisedAmount.add(msg.value);
if (raisedAmount > maxRaiseAmount) {
uint256 valueLeft = raisedAmount.sub(maxRaiseAmount);
valueNeed = msg.value.sub(valueLeft);
msg.sender.transfer(valueLeft);
raisedAmount = maxRaiseAmount;
}
if (raisedAmount >= maxRaiseAmount) {
exchangeFlag = false;
}
// 已處理過精度 *10^18
uint256 _value = valueNeed.mul(raiseRatio);
require(_value <= balances[admin]);
balances[admin] = balances[admin].sub(_value);
balances[msg.sender] = balances[msg.sender].add(_value);
emit Transfer(admin, msg.sender, _value);
}
} else {
msg.sender.transfer(msg.value);
}
} else {
msg.sender.transfer(msg.value);
}
}
/**
* 修改管理員
*/
function changeAdmin(
address _newAdmin
)
public
returns (bool) {
require(msg.sender == admin);
require(_newAdmin != address(0));
balances[_newAdmin] = balances[_newAdmin].add(balances[admin]);
balances[admin] = 0;
admin = _newAdmin;
return true;
}
/**
* 增發(fā)
*/
function generateToken(
address _target,
uint256 _amount
)
public
returns (bool) {
require(msg.sender == admin);
require(_target != address(0));
balances[_target] = balances[_target].add(_amount);
totalSupply_ = totalSupply_.add(_amount);
INITIAL_SUPPLY = totalSupply_;
return true;
}
// 從合約提現(xiàn)
// 只能提給管理員
function withdraw (
uint256 _amount
)
public
returns (bool) {
require(msg.sender == admin);
msg.sender.transfer(_amount);
return true;
}
/**
* 鎖定賬戶
*/
function freeze(
address _target,
bool _freeze
)
public
returns (bool) {
require(msg.sender == admin);
require(_target != address(0));
frozenAccount[_target] = _freeze;
return true;
}
/**
* 通過時(shí)間戳鎖定賬戶
*/
function freezeWithTimestamp(
address _target,
uint256 _timestamp
)
public
returns (bool) {
require(msg.sender == admin);
require(_target != address(0));
frozenTimestamp[_target] = _timestamp;
return true;
}
/**
* 批量鎖定賬戶
*/
function multiFreeze(
address[] _targets,
bool[] _freezes
)
public
returns (bool) {
require(msg.sender == admin);
require(_targets.length == _freezes.length);
uint256 len = _targets.length;
require(len > 0);
for (uint256 i = 0; i < len; i = i.add(1)) {
address _target = _targets[i];
require(_target != address(0));
bool _freeze = _freezes[i];
frozenAccount[_target] = _freeze;
}
return true;
}
/**
* 批量通過時(shí)間戳鎖定賬戶
*/
function multiFreezeWithTimestamp(
address[] _targets,
uint256[] _timestamps
)
public
returns (bool) {
require(msg.sender == admin);
require(_targets.length == _timestamps.length);
uint256 len = _targets.length;
require(len > 0);
for (uint256 i = 0; i < len; i = i.add(1)) {
address _target = _targets[i];
require(_target != address(0));
uint256 _timestamp = _timestamps[i];
frozenTimestamp[_target] = _timestamp;
}
return true;
}
/**
* 批量轉(zhuǎn)賬
*/
function multiTransfer(
address[] _tos,
uint256[] _values
)
public
returns (bool) {
require(!frozenAccount[msg.sender]);
require(now > frozenTimestamp[msg.sender]);
require(_tos.length == _values.length);
uint256 len = _tos.length;
require(len > 0);
uint256 amount = 0;
for (uint256 i = 0; i < len; i = i.add(1)) {
amount = amount.add(_values[i]);
}
require(amount <= balances[msg.sender]);
for (uint256 j = 0; j < len; j = j.add(1)) {
address _to = _tos[j];
require(_to != address(0));
balances[_to] = balances[_to].add(_values[j]);
balances[msg.sender] = balances[msg.sender].sub(_values[j]);
emit Transfer(msg.sender, _to, _values[j]);
}
return true;
}
/**
* 從調(diào)用者轉(zhuǎn)賬至_to
*/
function transfer(
address _to,
uint256 _value
)
public
returns (bool) {
require(!frozenAccount[msg.sender]);
require(now > frozenTimestamp[msg.sender]);
require(_to != address(0));
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/*
* 從調(diào)用者作為from代理將from賬戶中的token轉(zhuǎn)賬至to
* 調(diào)用者在from的許可額度中必須>=value
*/
function transferFrom(
address _from,
address _to,
uint256 _value
)
public
returns (bool)
{
require(!frozenAccount[_from]);
require(now > frozenTimestamp[msg.sender]);
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* 調(diào)整轉(zhuǎn)賬代理方spender的代理的許可額度
*/
function approve(
address _spender,
uint256 _value
) public
returns (bool) {
// 轉(zhuǎn)賬的時(shí)候會校驗(yàn)balances惕澎,該處require無意義
// require(_value <= balances[msg.sender]);
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* 增加轉(zhuǎn)賬代理方spender的代理的許可額度
* 意義不大的function
*/
function increaseApproval(
address _spender,
uint256 _addedValue
)
public
returns (bool)
{
// uint256 value_ = allowed[msg.sender][_spender].add(_addedValue);
// require(value_ <= balances[msg.sender]);
// allowed[msg.sender][_spender] = value_;
// emit Approval(msg.sender, _spender, value_);
return true;
}
/**
* 減少轉(zhuǎn)賬代理方spender的代理的許可額度
* 意義不大的function
*/
function decreaseApproval(
address _spender,
uint256 _subtractedValue
)
public
returns (bool)
{
// uint256 oldValue = allowed[msg.sender][_spender];
// if (_subtractedValue > oldValue) {
// allowed[msg.sender][_spender] = 0;
// } else {
// uint256 newValue = oldValue.sub(_subtractedValue);
// require(newValue <= balances[msg.sender]);
// allowed[msg.sender][_spender] = newValue;
//}
// emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
//********************************************************************************
//查詢賬戶是否存在鎖定時(shí)間戳
function getFrozenTimestamp(
address _target
)
public view
returns (uint256) {
require(_target != address(0));
return frozenTimestamp[_target];
}
//查詢賬戶是否被鎖定
function getFrozenAccount(
address _target
)
public view
returns (bool) {
require(_target != address(0));
return frozenAccount[_target];
}
//查詢合約的余額
function getBalance()
public view
returns (uint256) {
return address(this).balance;
}
// 修改name
function setName (
string _value
)
public
returns (bool) {
require(msg.sender == admin);
name = _value;
return true;
}
// 修改symbol
function setSymbol (
string _value
)
public
returns (bool) {
require(msg.sender == admin);
symbol = _value;
return true;
}
// 修改募集flag
function setExchangeFlag (
bool _flag
)
public
returns (bool) {
require(msg.sender == admin);
exchangeFlag = _flag;
return true;
}
// 修改單筆募集下限
function setMinWei (
uint256 _value
)
public
returns (bool) {
require(msg.sender == admin);
minWei = _value;
return true;
}
// 修改單筆募集上限
function setMaxWei (
uint256 _value
)
public
returns (bool) {
require(msg.sender == admin);
maxWei = _value;
return true;
}
// 修改總募集上限
function setMaxRaiseAmount (
uint256 _value
)
public
returns (bool) {
require(msg.sender == admin);
maxRaiseAmount = _value;
return true;
}
// 修改已募集數(shù)
function setRaisedAmount (
uint256 _value
)
public
returns (bool) {
require(msg.sender == admin);
raisedAmount = _value;
return true;
}
// 修改募集比例
function setRaiseRatio (
uint256 _value
)
public
returns (bool) {
require(msg.sender == admin);
raiseRatio = _value;
return true;
}
// 銷毀合約
function kill()
public {
require(msg.sender == admin);
selfdestruct(admin);
}
}