本次範例模擬一個正式的Token合約,增加使用OpenZeppelin的SafeMath Module,提高運算安全性,並在contract設計上增加設定價格、買token、燒毀token、挖token、摧毀合約等幾個function。
pragma solidity^0.4.25;
library SafeMath{
function add(uint a, uint b) internal pure returns (uint c) {
c = a + b;
require(c >= a);
}
function sub(uint a, uint b) internal pure returns (uint c) {
require(b <= a);
c = a - b;
}
function mul(uint a, uint b) internal pure returns (uint c) {
c = a * b;
require(a == 0 || c / a == b);
}
function div(uint a, uint b) internal pure returns (uint c) {
require(b > 0);
c = a / b;
}
}
contract ERC20_interface{
address owner;
mapping(address=>uint) balances;
mapping(address=>mapping(address=>uint)) allowed;
event Approval(
address indexed owner,
address indexed spender,
uint value
);
event Tansfer(
address indexed from,
address indexed to,
uint value
);
function balanceOf() public view returns(uint256);
function allowance(address _owner,address _spender) public view returns(uint256);
function transfer(address _to,uint _value) public returns(bool);
function transferFrom(address _owner,address _spender,uint _value) public returns(bool);
function approve(address _spender,uint _value) public returns(bool);
}
contract ERC20 is ERC20_interface{
using SafeMath for uint;
function balanceOf(address _owner) public view returns(uint256){
return balances[_owner];
}
function allowance(address _owner,address _spender) public view returns(uint256){
return allowed[_owner][_spender];
}
function transfer(address _to,uint _value) public returns(bool){
require(balances[msg.sender] >= _value);
balances[msg.sender].sub(_value);
balances[_to].add(_value);
emit Transfer(msg.sender,_spender,_value);
return true;
}
function transferFrom(address _owner,address _spender,uint _value) public returns(bool){
uint allowance = allowed[_owner][_spender];
require(balances[_owner] >= _value,"owner haven't enough money to transfer");
require(_value <= allowance,"_value can't more than allowance");
balances[_owner].sub(_value);
balances[_spender].add(_value);
allowed[_owner][_spender].sub(_value);
emit Transfer(_owner,_spender,_value);
return true;
}
function approve(address _spender,uint _value) public returns(bool){
allowed[msg.sender][_spender].add(_value);
emit Approval(msg.sender,_spender,_value);
return true;
}
}
contract Token is ERC20{
string public TokenName;//token名稱
string public TokenSymbol; //token符號
uint256 public decimal;
uint256 public Price;
uint256 public TotalSupply;
uint256 pbulic BurnAmount;
uint256 private weiToEther = 10**18;
event Burn(address indexed _owner, uint256 _burnAmount);
event Mint(address indexed _someone,uint256 _mintAmount);
modifier onlyOwner{
require(msg.sender == owner,"You are not Owner");
_;
}
constructor(
uint256 _initialSupply,
string _tokenName,
string _tokenSymbol,
uint _decimal
)
public
{
TotalSupply = _inititalSupply;
TokenName = _tokenName;
TokenSymbol = _tokenSymbol;
owner = msg.sender;
balances[owner] = TotalSupply;
}
function setPrice(uint256 _setPrice) public onlyOwner{
buyPrice = _setPrice;
}
function buy() public payable {
uint _amount = msg.value / BuyPrice* 10**uint(decimals)/weiToEther;
//買的價格除以賣的價格(價格*10**最小單位/ether最小單位)
balances[msg.sender] = balances[msg.sender].add(_amount);
}
function burn(uint256 _burnAmount) public{
require(balances[msg.sender] > 0 && _burnAmount > 0);
TotalSupply = TotalSupply.sub(_burnAmount);//剩餘多少token總量
BurnAmount = BurnAmount.add(_burnAmount); //總共燒毀多少token
balances[msg.sender] = balances[msg.sender].sub(_burnAmount);
emit Transfer(msg.sender,0x0,_burnAmount);
emit Burn(msg.sender,BurnAmount);
}
function mint(address _to, uint256 _amount) public{
TotalSupply = TotalSupply.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Mint(_to,_amount);
}
function withdraw(uint256 _amount) public onlyOwner{
owner.transfer(_amount);
}
function kill() public onlyOwner{
selfdestruct(owner);
}
}
(待補)