文件 1 的 1:JCB.sol
pragma solidity ^0.4.23;
library SafeMathLib {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a * b;
assert(a == 0 || c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b > 0);
uint256 c = a / b;
assert(a == b * 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 DateTimeLib {
struct _DateTime {
uint16 year;
uint8 month;
uint8 day;
uint8 hour;
uint8 minute;
uint8 second;
uint8 weekday;
}
uint constant DAY_IN_SECONDS = 86400;
uint constant YEAR_IN_SECONDS = 31536000;
uint constant LEAP_YEAR_IN_SECONDS = 31622400;
uint constant HOUR_IN_SECONDS = 3600;
uint constant MINUTE_IN_SECONDS = 60;
uint16 constant ORIGIN_YEAR = 1970;
function isLeapYear(uint16 year) internal pure returns (bool) {
if (year % 4 != 0) {
return false;
}
if (year % 100 != 0) {
return true;
}
if (year % 400 != 0) {
return false;
}
return true;
}
function leapYearsBefore(uint year) internal pure returns (uint) {
year -= 1;
return year / 4 - year / 100 + year / 400;
}
function getDaysInMonth(uint8 month, uint16 year) internal pure returns (uint8) {
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
return 31;
}
else if (month == 4 || month == 6 || month == 9 || month == 11) {
return 30;
}
else if (isLeapYear(year)) {
return 29;
}
else {
return 28;
}
}
function parseTimestamp(uint timestamp) internal pure returns (_DateTime dt) {
uint secondsAccountedFor = 0;
uint buf;
uint8 i;
dt.year = getYear(timestamp);
buf = leapYearsBefore(dt.year) - leapYearsBefore(ORIGIN_YEAR);
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf;
secondsAccountedFor += YEAR_IN_SECONDS * (dt.year - ORIGIN_YEAR - buf);
uint secondsInMonth;
for (i = 1; i <= 12; i++) {
secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, dt.year);
if (secondsInMonth + secondsAccountedFor > timestamp) {
dt.month = i;
break;
}
secondsAccountedFor += secondsInMonth;
}
for (i = 1; i <= getDaysInMonth(dt.month, dt.year); i++) {
if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) {
dt.day = i;
break;
}
secondsAccountedFor += DAY_IN_SECONDS;
}
dt.hour = getHour(timestamp);
dt.minute = getMinute(timestamp);
dt.second = getSecond(timestamp);
dt.weekday = getWeekday(timestamp);
}
function getYear(uint timestamp) internal pure returns (uint16) {
uint secondsAccountedFor = 0;
uint16 year;
uint numLeapYears;
year = uint16(ORIGIN_YEAR + timestamp / YEAR_IN_SECONDS);
numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR);
secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears;
secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears);
while (secondsAccountedFor > timestamp) {
if (isLeapYear(uint16(year - 1))) {
secondsAccountedFor -= LEAP_YEAR_IN_SECONDS;
}
else {
secondsAccountedFor -= YEAR_IN_SECONDS;
}
year -= 1;
}
return year;
}
function getMonth(uint timestamp) internal pure returns (uint8) {
return parseTimestamp(timestamp).month;
}
function getDay(uint timestamp) internal pure returns (uint8) {
return parseTimestamp(timestamp).day;
}
function getHour(uint timestamp) internal pure returns (uint8) {
return uint8((timestamp / 60 / 60) % 24);
}
function getMinute(uint timestamp) internal pure returns (uint8) {
return uint8((timestamp / 60) % 60);
}
function getSecond(uint timestamp) internal pure returns (uint8) {
return uint8(timestamp % 60);
}
function getWeekday(uint timestamp) internal pure returns (uint8) {
return uint8((timestamp / DAY_IN_SECONDS + 4) % 7);
}
function toTimestamp(uint16 year, uint8 month, uint8 day) internal pure returns (uint timestamp) {
return toTimestamp(year, month, day, 0, 0, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) internal pure returns (uint timestamp) {
return toTimestamp(year, month, day, hour, 0, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) internal pure returns (uint timestamp) {
return toTimestamp(year, month, day, hour, minute, 0);
}
function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) internal pure returns (uint timestamp) {
uint16 i;
for (i = ORIGIN_YEAR; i < year; i++) {
if (isLeapYear(i)) {
timestamp += LEAP_YEAR_IN_SECONDS;
}
else {
timestamp += YEAR_IN_SECONDS;
}
}
uint8[12] memory monthDayCounts;
monthDayCounts[0] = 31;
if (isLeapYear(year)) {
monthDayCounts[1] = 29;
}
else {
monthDayCounts[1] = 28;
}
monthDayCounts[2] = 31;
monthDayCounts[3] = 30;
monthDayCounts[4] = 31;
monthDayCounts[5] = 30;
monthDayCounts[6] = 31;
monthDayCounts[7] = 31;
monthDayCounts[8] = 30;
monthDayCounts[9] = 31;
monthDayCounts[10] = 30;
monthDayCounts[11] = 31;
for (i = 1; i < month; i++) {
timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1];
}
timestamp += DAY_IN_SECONDS * (day - 1);
timestamp += HOUR_IN_SECONDS * (hour);
timestamp += MINUTE_IN_SECONDS * (minute);
timestamp += second;
return timestamp;
}
}
interface IERC20 {
function totalSupply() external constant returns (uint256);
function balanceOf(address _owner) external constant returns (uint256 balance);
function transfer(address _to, uint256 _value) external returns (bool success);
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
function approve(address _spender, uint256 _value) external returns (bool success);
function allowance(address _owner, address _spender) external constant returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address _spender, uint256 _value);
}
contract StandardToken is IERC20,DateTimeLib {
using SafeMathLib for uint256;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) allowed;
string public constant symbol = "JCB";
string public constant name = "JoinCoin";
uint _totalSupply = 1000000000 * 10 ** 8;
uint8 public constant decimals = 8;
function totalSupply() external constant returns (uint256) {
return _totalSupply;
}
function balanceOf(address _owner) external constant returns (uint256 balance) {
return balances[_owner];
}
function transfer(address _to, uint256 _value) public returns (bool success) {
return transferInternal(msg.sender, _to, _value);
}
function transferInternal(address _from, address _to, uint256 _value) internal returns (bool success) {
require(_value > 0 && balances[_from] >= _value);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(_from, _to, _value);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_value > 0 && allowed[_from][msg.sender] >= _value && balances[_from] >= _value);
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;
}
function approve(address _spender, uint256 _value) public returns (bool success) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
}
contract LockableToken is StandardToken {
address internal developerReservedAddress = 0xf4ab0e0269E05163E65608F44E80A125A511a916;
uint[4] internal developerReservedUnlockTimes;
uint256[4] internal developerReservedBalanceLimits;
function getDeveloperReservedBalanceLimit() internal returns (uint256 balanceLimit) {
uint time = now;
for (uint index = 0; index < developerReservedUnlockTimes.length; index++) {
if (developerReservedUnlockTimes[index] == 0x0) {
continue;
}
if (time > developerReservedUnlockTimes[index]) {
developerReservedUnlockTimes[index] = 0x0;
} else {
return developerReservedBalanceLimits[index];
}
}
return 0;
}
function transfer(address _to, uint256 _value) public returns (bool success) {
return transferInternal(msg.sender, _to, _value);
}
function transferInternal(address _from, address _to, uint256 _value) internal returns (bool success) {
require(_from != 0x0 && _to != 0x0 && _value > 0x0);
if (_from == developerReservedAddress) {
uint256 balanceLimit = getDeveloperReservedBalanceLimit();
require(balances[_from].sub(balanceLimit) >= _value);
}
return super.transferInternal(_from, _to, _value);
}
function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
require(_from != 0x0 && _to != 0x0 && _value > 0x0);
if (_from == developerReservedAddress) {
uint256 balanceLimit = getDeveloperReservedBalanceLimit();
require(balances[_from].sub(balanceLimit) >= _value);
}
return super.transferFrom(_from, _to, _value);
}
event UnlockTimeChanged(uint index, uint unlockTime, uint newUnlockTime);
event LockInfo(address indexed publicOfferingAddress, uint index, uint unlockTime, uint256 balanceLimit);
}
contract TradeableToken is LockableToken {
address internal publicOfferingAddress = 0xbdB45923Bf511801F71EAeD4fbd926E48bA43DB5;
uint256 public exchangeRate = 4000;
function buy(address _beneficiary, uint256 _weiAmount) internal {
require(_beneficiary != 0x0);
require(publicOfferingAddress != 0x0);
require(exchangeRate > 0x0);
require(_weiAmount > 0x0);
uint256 exchangeToken = _weiAmount.mul(exchangeRate);
exchangeToken = exchangeToken.div(1 * 10 ** 10);
publicOfferingAddress.transfer(_weiAmount);
super.transferInternal(publicOfferingAddress, _beneficiary, exchangeToken);
}
event ExchangeRateChanged(uint256 oldExchangeRate,uint256 newExchangeRate);
}
contract OwnableToken is TradeableToken {
address internal owner = 0xfe71ea94aD48c03a8B1D5c8A371E36Fc0E05856A;
mapping(address => uint) administrators;
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
modifier onlyAdministrator() {
require(msg.sender == owner || administrators[msg.sender] > 0x0);
_;
}
function transferOwnership(address _newOwner) onlyOwner public {
require(_newOwner != address(0));
owner = _newOwner;
emit OwnershipTransferred(owner, _newOwner);
}
function addAdministrator(address _adminAddress) onlyOwner public {
require(_adminAddress != address(0));
require(administrators[_adminAddress] <= 0x0);
administrators[_adminAddress] = 0x1;
emit AddAdministrator(_adminAddress);
}
function removeAdministrator(address _adminAddress) onlyOwner public {
require(_adminAddress != address(0));
require(administrators[_adminAddress] > 0x0);
administrators[_adminAddress] = 0x0;
emit RemoveAdministrator(_adminAddress);
}
function setExchangeRate(uint256 _exchangeRate) public onlyAdministrator returns (bool success) {
require(_exchangeRate > 0x0);
uint256 oldExchangeRate = exchangeRate;
exchangeRate = _exchangeRate;
emit ExchangeRateChanged(oldExchangeRate, exchangeRate);
return true;
}
function changeUnlockTime(uint _index, uint _unlockTime) public onlyAdministrator returns (bool success) {
require(_index >= 0x0 && _index < developerReservedUnlockTimes.length && _unlockTime > 0x0);
if(_index > 0x0) {
uint beforeUnlockTime = developerReservedUnlockTimes[_index - 1];
require(beforeUnlockTime == 0x0 || beforeUnlockTime < _unlockTime);
}
if(_index < developerReservedUnlockTimes.length - 1) {
uint afterUnlockTime = developerReservedUnlockTimes[_index + 1];
require(afterUnlockTime == 0x0 || _unlockTime < afterUnlockTime);
}
uint oldUnlockTime = developerReservedUnlockTimes[_index];
developerReservedUnlockTimes[_index] = _unlockTime;
emit UnlockTimeChanged(_index,oldUnlockTime,_unlockTime);
return true;
}
function getDeveloperReservedLockInfo(uint _index) public onlyAdministrator returns (uint, uint256) {
require(_index >= 0x0 && _index < developerReservedUnlockTimes.length && _index < developerReservedBalanceLimits.length);
emit LockInfo(developerReservedAddress,_index,developerReservedUnlockTimes[_index],developerReservedBalanceLimits[_index]);
return (developerReservedUnlockTimes[_index], developerReservedBalanceLimits[_index]);
}
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event AddAdministrator(address indexed adminAddress);
event RemoveAdministrator(address indexed adminAddress);
}
contract JCB is OwnableToken {
function JCB() public {
balances[owner] = 500000000 * 10 ** 8;
balances[publicOfferingAddress] = 300000000 * 10 ** 8;
uint256 developerReservedBalance = 200000000 * 10 ** 8;
balances[developerReservedAddress] = developerReservedBalance;
developerReservedUnlockTimes =
[
DateTimeLib.toTimestamp(2019, 7, 1),
DateTimeLib.toTimestamp(2020, 7, 1),
DateTimeLib.toTimestamp(2021, 7, 1),
DateTimeLib.toTimestamp(2022, 7, 1)
];
developerReservedBalanceLimits =
[
developerReservedBalance,
developerReservedBalance - (developerReservedBalance / 4) * 1,
developerReservedBalance - (developerReservedBalance / 4) * 2,
developerReservedBalance - (developerReservedBalance / 4) * 3
];
}
function() public payable {
buy(msg.sender, msg.value);
}
}