Transaction Hash:
Block:
8763599 at Oct-18-2019 07:42:28 AM +UTC
Transaction Fee:
0.032355 ETH
$80.70
Gas Used:
3,235,500 Gas / 10 Gwei
Emitted Events:
42 |
CardioCoin.OwnershipTransferred( previousOwner=0x0000000000000000000000000000000000000000, newOwner=[Sender] 0x442115375b8d67800db841bc4af68f98e20aa09c )
|
43 |
CardioCoin.Transfer( from=0x0000000000000000000000000000000000000000, to=[Sender] 0x442115375b8d67800db841bc4af68f98e20aa09c, value=12000000000000000000000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x04668Ec2...D451c8F7F
Miner
| (zhizhu.top) | 724.519563167495157783 Eth | 724.551918167495157783 Eth | 0.032355 | |
0x44211537...8e20AA09c | (CardioCoin: Deployer) |
0.25063879 Eth
Nonce: 98
|
0.21828379 Eth
Nonce: 99
| 0.032355 | |
0x88160f65...4bc47B35C |
0 Eth
Nonce: 0
|
0 Eth
Nonce: 1
|
Execution Trace
CardioCoin.60806040( )
{"CardioCoin.sol":{"content":"pragma solidity \u003e= 0.5.0;\n\nimport \"./Ownable.sol\";\nimport \"./SafeMath.sol\";\nimport \"./ERC20.sol\";\n\ncontract CardioCoin is ERC20, Ownable {\n using SafeMath for uint256;\n\n uint public constant UNLOCK_PERIOD = 30 days;\n uint public constant UNLOCK_TIME = 1572566400; // 11월 1일 0시\n\n string public constant name = \"CardioCoin\";\n string public constant symbol = \"CRDC\";\n\n uint8 public constant decimals = 18;\n\n uint256 internal totalSupply_ = 12000000000 * (10 ** uint256(decimals));\n\n struct balance {\n uint256 available;\n uint256 lockedUp;\n }\n\n struct lockUp {\n uint256 amount;\n uint unlockTimestamp;\n uint unlockCount;\n }\n\n struct locker {\n bool isLocker;\n string role;\n uint lockUpPeriod;\n uint unlockCount;\n bool useFixedTime;\n }\n\n mapping(address =\u003e balance) internal _balances;\n mapping(address =\u003e lockUp[]) internal _lockUps;\n mapping(address =\u003e locker) internal _lockerList;\n\n event Burn(address indexed burner, uint256 value);\n event AddToLocker(address indexed owner, string role, uint lockUpPeriod, uint unlockCount);\n event TokenLocked(address indexed owner, uint256 amount);\n event TokenUnlocked(address indexed owner, uint256 amount);\n\n constructor() public Ownable() {\n balance memory b;\n\n b.available = totalSupply_;\n _balances[msg.sender] = b;\n emit Transfer(address(0), msg.sender, totalSupply_);\n }\n\n //Getter Functions\n function lockerInfo(address _operator)public view returns(bool isLocker, string memory role, uint lockUpPeriod, uint unlockCount) {\n locker memory l = _lockerList[_operator];\n isLocker = l.isLocker;\n role = l.role;\n lockUpPeriod = l.lockUpPeriod;\n unlockCount = l.unlockCount;\n }\n\n function balanceInfo(address user) view public returns(uint256 available, uint256 lockedUp) {\n balance memory b = _balances[user];\n available = b.available;\n lockedUp = b.lockedUp;\n }\n\n function lockUpInfo(address user, uint256 index) view public returns (uint256 amount, uint256 unlockTimestamp, uint256 unlockCount) {\n lockUp memory l = _lockUps[user][index];\n amount = l.amount;\n unlockTimestamp = l.unlockTimestamp;\n unlockCount = l.unlockCount;\n }\n\n function lockUpLength(address user) view public returns (uint256) {\n lockUp[] memory l = _lockUps[user];\n return l.length;\n }\n\n // ERC20 Custom\n function totalSupply() public view returns (uint256) {\n return totalSupply_;\n }\n\n function _transfer(address from, address to, uint256 value) internal {\n locker storage l = _lockerList[from];\n\n this.unlockAll(from);\n require(value \u003c= _balances[from].available);\n require(to != address(0));\n _balances[from].available = _balances[from].available.sub(value);\n if (l.isLocker) {\n if (l.useFixedTime) {\n if (UNLOCK_TIME \u003c= now) {\n uint elapsedPeriod = (now - UNLOCK_TIME) / UNLOCK_PERIOD + 1;\n\n if (elapsedPeriod \u003c l.unlockCount) {\n uint unlockedAmount = (value / l.unlockCount).mul(elapsedPeriod);\n\n _balances[to].available = _balances[to].available.add(unlockedAmount);\n addLockedUpTokens(to, value.sub(unlockedAmount), UNLOCK_TIME + UNLOCK_PERIOD * elapsedPeriod - now, l.unlockCount - elapsedPeriod);\n } else {\n l.isLocker = false;\n _balances[to].available = _balances[to].available.add(value);\n }\n } else {\n addLockedUpTokens(to, value, UNLOCK_TIME - now, l.unlockCount);\n }\n } else {\n addLockedUpTokens(to, value, l.lockUpPeriod, l.unlockCount);\n }\n } else {\n _balances[to].available = _balances[to].available.add(value);\n }\n emit Transfer(from, to, value);\n }\n\n function balanceOf(address _owner) public view returns (uint256) {\n return _balances[_owner].available.add(_balances[_owner].lockedUp);\n }\n\n // Burnable\n function burn(uint256 _value) public {\n _burn(msg.sender, _value);\n }\n\n function _burn(address _who, uint256 _value) internal {\n require(_value \u003c= _balances[_who].available);\n\n _balances[_who].available = _balances[_who].available.sub(_value);\n totalSupply_ = totalSupply_.sub(_value);\n emit Burn(_who, _value);\n emit Transfer(_who, address(0), _value);\n }\n\n // Lockup\n function addAddressToLockerList(address _operator, string memory role, uint lockUpPeriod, uint unlockCount, bool useFixedTime)\n public\n onlyOwner {\n locker memory lockerData = _lockerList[_operator];\n\n require(!lockerData.isLocker);\n require(unlockCount \u003e 0);\n lockerData.isLocker = true;\n lockerData.role = role;\n lockerData.lockUpPeriod = lockUpPeriod;\n lockerData.unlockCount = unlockCount;\n lockerData.useFixedTime = useFixedTime;\n _lockerList[_operator] = lockerData;\n emit AddToLocker(_operator, role, lockUpPeriod, unlockCount);\n }\n\n function lockedUpBalanceOf(address _owner) public view returns (uint256) {\n lockUp[] memory lockups = _lockUps[_owner];\n balance memory b = _balances[_owner];\n uint256 lockedUpBalance = b.lockedUp;\n\n for (uint i = 0; i \u003c lockups.length; i++) {\n lockUp memory l = lockups[i];\n\n uint count = calculateUnlockCount(l.unlockTimestamp, l.unlockCount);\n uint256 unlockedAmount = l.amount.mul(count).div(l.unlockCount);\n lockedUpBalance = lockedUpBalance.sub(unlockedAmount);\n }\n\n return lockedUpBalance;\n }\n\n function addLockedUpTokens(address _owner, uint256 amount, uint lockUpPeriod, uint unlockCount)\n internal {\n lockUp[] storage lockups = _lockUps[_owner];\n lockups.length += 1;\n lockUp storage l = lockups[lockups.length - 1];\n l.amount = amount;\n l.unlockTimestamp = now.add(lockUpPeriod);\n l.unlockCount = unlockCount;\n\n balance storage b = _balances[_owner];\n b.lockedUp = b.lockedUp.add(amount);\n emit TokenLocked(_owner, amount);\n }\n\n function unlockAll(address _owner) external returns (bool success) {\n balance storage b = _balances[_owner];\n lockUp[] storage lockupList = _lockUps[_owner];\n uint256 unlocked = 0;\n for (uint i = 0; i \u003c lockupList.length; i++){\n uint256 unlocked_i = _unlock(_owner,i);\n unlocked = unlocked.add(unlocked_i);\n //when fullyUnlocked\n if(lockupList[i].unlockCount == 0) {\n //remove\n lockUp storage temp = lockupList[lockupList.length.sub(1)];\n lockupList[i] = temp;\n lockupList.length--;\n i--;\n }\n }\n //add unlocked to available\n b.available = b.available.add(unlocked);\n //sub unlocked from lockedUp\n b.lockedUp = b.lockedUp.sub(unlocked);\n\n success = true;\n\n emit TokenUnlocked(_owner, unlocked);\n }\n\n function _unlock(address _owner, uint256 index) internal returns(uint256 unlocked) {\n lockUp storage l = _lockUps[_owner][index];\n\n uint count = calculateUnlockCount(l.unlockTimestamp, l.unlockCount);\n if( count == 0 ){\n return 0;\n }\n // if fully unlocked, unlocked amount will match l.amount\n unlocked = l.amount.mul(count).div(l.unlockCount);\n\n l.unlockTimestamp = l.unlockTimestamp.add(UNLOCK_PERIOD * count);\n l.amount = l.amount.sub(unlocked);\n l.unlockCount = l.unlockCount.sub(count);\n }\n\n\n function calculateUnlockCount(uint timestamp, uint unlockCount) view internal returns (uint) {\n if (now \u003c timestamp) {\n return 0;\n }\n uint256 timeCount = (now.sub(timestamp)).div(UNLOCK_PERIOD).add(1);\n if (timeCount \u003e unlockCount){\n return unlockCount;\n }\n else {\n return timeCount;\n }\n }\n}"},"ERC20.sol":{"content":"pragma solidity ^0.5.0;\n\nimport \"./IERC20.sol\";\nimport \"./SafeMath.sol\";\n\n/**\n * @title Standard ERC20 token\n *\n * @dev Implementation of the basic standard token.\n * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md\n * Originally based on code by FirstBlood:\n * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol\n *\n * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for\n * all accounts just by listening to said events. Note that this isn\u0027t required by the specification, and other\n * compliant implementations may not do it.\n */\ncontract ERC20 is IERC20 {\n using SafeMath for uint256;\n\n mapping (address =\u003e uint256) private _balances;\n\n mapping (address =\u003e mapping (address =\u003e uint256)) private _allowed;\n\n uint256 private _totalSupply;\n\n /**\n * @dev Total number of tokens in existence\n */\n function totalSupply() public view returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev Gets the balance of the specified address.\n * @param owner The address to query the balance of.\n * @return An uint256 representing the amount owned by the passed address.\n */\n function balanceOf(address owner) public view returns (uint256) {\n return _balances[owner];\n }\n\n /**\n * @dev Function to check the amount of tokens that an owner allowed to a spender.\n * @param owner address The address which owns the funds.\n * @param spender address The address which will spend the funds.\n * @return A uint256 specifying the amount of tokens still available for the spender.\n */\n function allowance(address owner, address spender) public view returns (uint256) {\n return _allowed[owner][spender];\n }\n\n /**\n * @dev Transfer token for a specified address\n * @param to The address to transfer to.\n * @param value The amount to be transferred.\n */\n function transfer(address to, uint256 value) public returns (bool) {\n _transfer(msg.sender, to, value);\n return true;\n }\n\n /**\n * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.\n * Beware that changing an allowance with this method brings the risk that someone may use both the old\n * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this\n * race condition is to first reduce the spender\u0027s allowance to 0 and set the desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n * @param spender The address which will spend the funds.\n * @param value The amount of tokens to be spent.\n */\n function approve(address spender, uint256 value) public returns (bool) {\n require(spender != address(0));\n\n _allowed[msg.sender][spender] = value;\n emit Approval(msg.sender, spender, value);\n return true;\n }\n\n /**\n * @dev Transfer tokens from one address to another.\n * Note that while this function emits an Approval event, this is not required as per the specification,\n * and other compliant implementations may not emit the event.\n * @param from address The address which you want to send tokens from\n * @param to address The address which you want to transfer to\n * @param value uint256 the amount of tokens to be transferred\n */\n function transferFrom(address from, address to, uint256 value) public returns (bool) {\n _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);\n _transfer(from, to, value);\n emit Approval(from, msg.sender, _allowed[from][msg.sender]);\n return true;\n }\n\n /**\n * @dev Increase the amount of tokens that an owner allowed to a spender.\n * approve should be called when allowed_[_spender] == 0. To increment\n * allowed value is better to use this function to avoid 2 calls (and wait until\n * the first transaction is mined)\n * From MonolithDAO Token.sol\n * Emits an Approval event.\n * @param spender The address which will spend the funds.\n * @param addedValue The amount of tokens to increase the allowance by.\n */\n function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {\n require(spender != address(0));\n\n _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue);\n emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);\n return true;\n }\n\n /**\n * @dev Decrease the amount of tokens that an owner allowed to a spender.\n * approve should be called when allowed_[_spender] == 0. To decrement\n * allowed value is better to use this function to avoid 2 calls (and wait until\n * the first transaction is mined)\n * From MonolithDAO Token.sol\n * Emits an Approval event.\n * @param spender The address which will spend the funds.\n * @param subtractedValue The amount of tokens to decrease the allowance by.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {\n require(spender != address(0));\n\n _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue);\n emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);\n return true;\n }\n\n /**\n * @dev Transfer token for a specified addresses\n * @param from The address to transfer from.\n * @param to The address to transfer to.\n * @param value The amount to be transferred.\n */\n function _transfer(address from, address to, uint256 value) internal {\n require(to != address(0));\n\n _balances[from] = _balances[from].sub(value);\n _balances[to] = _balances[to].add(value);\n emit Transfer(from, to, value);\n }\n\n /**\n * @dev Internal function that mints an amount of the token and assigns it to\n * an account. This encapsulates the modification of balances such that the\n * proper events are emitted.\n * @param account The account that will receive the created tokens.\n * @param value The amount that will be created.\n */\n function _mint(address account, uint256 value) internal {\n require(account != address(0));\n\n _totalSupply = _totalSupply.add(value);\n _balances[account] = _balances[account].add(value);\n emit Transfer(address(0), account, value);\n }\n\n /**\n * @dev Internal function that burns an amount of the token of a given\n * account.\n * @param account The account whose tokens will be burnt.\n * @param value The amount that will be burnt.\n */\n function _burn(address account, uint256 value) internal {\n require(account != address(0));\n\n _totalSupply = _totalSupply.sub(value);\n _balances[account] = _balances[account].sub(value);\n emit Transfer(account, address(0), value);\n }\n\n /**\n * @dev Internal function that burns an amount of the token of a given\n * account, deducting from the sender\u0027s allowance for said account. Uses the\n * internal burn function.\n * Emits an Approval event (reflecting the reduced allowance).\n * @param account The account whose tokens will be burnt.\n * @param value The amount that will be burnt.\n */\n function _burnFrom(address account, uint256 value) internal {\n _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(value);\n _burn(account, value);\n emit Approval(account, msg.sender, _allowed[account][msg.sender]);\n }\n}\n"},"IERC20.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @title ERC20 interface\n * @dev see https://github.com/ethereum/EIPs/issues/20\n */\ninterface IERC20 {\n function transfer(address to, uint256 value) external returns (bool);\n\n function approve(address spender, uint256 value) external returns (bool);\n\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n\n function totalSupply() external view returns (uint256);\n\n function balanceOf(address who) external view returns (uint256);\n\n function allowance(address owner, address spender) external view returns (uint256);\n\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},"Ownable.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @title Ownable\n * @dev The Ownable contract has an owner address, and provides basic authorization control\n * functions, this simplifies the implementation of \"user permissions\".\n */\ncontract Ownable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev The Ownable constructor sets the original `owner` of the contract to the sender\n * account.\n */\n constructor () internal {\n _owner = msg.sender;\n emit OwnershipTransferred(address(0), _owner);\n }\n\n /**\n * @return the address of the owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(isOwner());\n _;\n }\n\n /**\n * @return true if `msg.sender` is the owner of the contract.\n */\n function isOwner() public view returns (bool) {\n return msg.sender == _owner;\n }\n\n /**\n * @dev Allows the current owner to relinquish control of the contract.\n * @notice Renouncing to ownership will leave the contract without an owner.\n * It will not be possible to call the functions with the `onlyOwner`\n * modifier anymore.\n */\n function renounceOwnership() public onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Allows the current owner to transfer control of the contract to a newOwner.\n * @param newOwner The address to transfer ownership to.\n */\n function transferOwnership(address newOwner) public onlyOwner {\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers control of the contract to a newOwner.\n * @param newOwner The address to transfer ownership to.\n */\n function _transferOwnership(address newOwner) internal {\n require(newOwner != address(0));\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n"},"SafeMath.sol":{"content":"pragma solidity ^0.5.0;\n\n/**\n * @title SafeMath\n * @dev Unsigned math operations with safety checks that revert on error\n */\nlibrary SafeMath {\n /**\n * @dev Multiplies two unsigned integers, reverts on overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring \u0027a\u0027 not being zero, but the\n // benefit is lost if \u0027b\u0027 is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b);\n\n return c;\n }\n\n /**\n * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n // Solidity only automatically asserts when dividing by 0\n require(b \u003e 0);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn\u0027t hold\n\n return c;\n }\n\n /**\n * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b \u003c= a);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Adds two unsigned integers, reverts on overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c \u003e= a);\n\n return c;\n }\n\n /**\n * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),\n * reverts when dividing by zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b != 0);\n return a % b;\n }\n}\n"}}