Created
July 21, 2018 22:56
-
-
Save jin10086/0cc55436ff07b34d05a8fb1f8a7c0fe1 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.24+commit.e67f0147.js&optimize=false&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.24; | |
library SafeMath { | |
/** | |
* @dev Multiplies two numbers, throws on overflow. | |
*/ | |
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
// Gas optimization: this is cheaper than asserting 'a' not being zero, but the | |
// benefit is lost if 'b' is also tested. | |
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 | |
if (a == 0) { | |
return 0; | |
} | |
c = a * b; | |
assert(c / a == b); | |
return c; | |
} | |
/** | |
* @dev Integer division of two numbers, truncating the quotient. | |
*/ | |
function div(uint256 a, uint256 b) internal pure returns (uint256) { | |
// assert(b > 0); // Solidity automatically throws when dividing by 0 | |
// uint256 c = a / b; | |
// assert(a == b * c + a % b); // There is no case in which this doesn't hold | |
return a / b; | |
} | |
/** | |
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). | |
*/ | |
function sub(uint256 a, uint256 b) internal pure returns (uint256) { | |
assert(b <= a); | |
return a - b; | |
} | |
/** | |
* @dev Adds two numbers, throws on overflow. | |
*/ | |
function add(uint256 a, uint256 b) internal pure returns (uint256 c) { | |
c = a + b; | |
assert(c >= a); | |
return c; | |
} | |
} | |
contract Ownable { | |
address public owner; | |
event OwnershipRenounced(address indexed previousOwner); | |
event OwnershipTransferred( | |
address indexed previousOwner, | |
address indexed newOwner | |
); | |
/** | |
* @dev The Ownable constructor sets the original `owner` of the contract to the sender | |
* account. | |
*/ | |
constructor() public { | |
owner = msg.sender; | |
} | |
/** | |
* @dev Throws if called by any account other than the owner. | |
*/ | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
/** | |
* @dev Allows the current owner to relinquish control of the contract. | |
* @notice Renouncing to ownership will leave the contract without an owner. | |
* It will not be possible to call the functions with the `onlyOwner` | |
* modifier anymore. | |
*/ | |
function renounceOwnership() public onlyOwner { | |
emit OwnershipRenounced(owner); | |
owner = address(0); | |
} | |
/** | |
* @dev Allows the current owner to transfer control of the contract to a newOwner. | |
* @param _newOwner The address to transfer ownership to. | |
*/ | |
function transferOwnership(address _newOwner) public onlyOwner { | |
_transferOwnership(_newOwner); | |
} | |
/** | |
* @dev Transfers control of the contract to a newOwner. | |
* @param _newOwner The address to transfer ownership to. | |
*/ | |
function _transferOwnership(address _newOwner) internal { | |
require(_newOwner != address(0)); | |
emit OwnershipTransferred(owner, _newOwner); | |
owner = _newOwner; | |
} | |
} | |
contract ERC20 { | |
using SafeMath for uint256; | |
string public name; | |
string public symbol; | |
uint8 public decimals; | |
uint256 public totalSupply; | |
mapping(address => uint256) balances; | |
event Transfer(address indexed from, address indexed to, uint256 value); | |
constructor () public{ | |
name = 'Good Man'; | |
symbol = 'GMP'; | |
decimals = 18; | |
} | |
function balanceOf(address who) public view returns (uint256){ | |
return balances[who]; | |
} | |
} | |
contract Savemylife is Ownable,ERC20{ | |
event SendEth(uint256 id,address from,uint256 amount); | |
event ReturnEth(uint256 id,address from,uint256 amount); | |
event Saveme(uint256 id,address owner,uint256 amount); | |
event Start(uint256 id,address owner,uint256 totalBalance,uint256 endtime); | |
event Active(uint256 id); | |
event Stop(uint256 id); | |
event NotStop(uint256 id); | |
struct Balances { | |
address addr; | |
uint256 amount; | |
} | |
struct ICO { | |
address owner; //发起人 | |
uint256 totalBalance; //一共需要多少钱 | |
uint256 balance; //当前余额 | |
uint256 canUserAmount;//可用的钱 | |
uint256 endtime; //ICO 结束时间 | |
uint256 id; | |
bool status; //状态 | |
bool stop; //是否暂停ICO | |
mapping(uint256 => Balances) balances; // 捐款详情 | |
} | |
using SafeMath for uint256; | |
uint256 public icoid; | |
mapping (uint256 => ICO) public ico; | |
function start (uint256 totalBalance,uint256 endtime) public{ | |
icoid = icoid.add(1); | |
ico[icoid] = ICO(msg.sender,totalBalance,0,0,endtime,0,false,false); | |
emit Start(icoid,msg.sender,totalBalance,endtime); | |
} | |
function sendEth(uint256 id) payable public { | |
require(isActive(id)); | |
require(notStop(id)); | |
ICO storage c = ico[id]; | |
require(c.endtime>now); | |
uint256 _totalBalance = c.balance.add(msg.value); | |
uint256 send = msg.value; | |
if (_totalBalance > c.totalBalance){ | |
uint256 ret = _totalBalance.sub(c.totalBalance); | |
msg.sender.transfer(ret); | |
emit ReturnEth(id,msg.sender,ret); | |
c.status = false; | |
c.balance = c.totalBalance; | |
send = msg.value.sub(ret); | |
}else{ | |
c.balance = c.balance.add(send); | |
} | |
// c.balances[msg.sender] = msg.value; | |
c.id = c.id.add(1); | |
c.canUserAmount = c.canUserAmount.add(send); | |
c.balances[c.id] = Balances({addr: msg.sender, amount: send}); | |
emit SendEth(id,msg.sender,send); | |
balances[msg.sender] = balances[msg.sender].add(send); | |
emit Transfer(0x0,msg.sender,send); | |
totalSupply = totalSupply.add(send); | |
} | |
function safeWithdrawl(uint256 id,uint256 amount) public returns (bool){ | |
require(isIcoOwner(id)); | |
require(notStop(id)); | |
ICO storage c = ico[id]; | |
uint256 canWithdrawAmout = c.canUserAmount; | |
require(amount <= canWithdrawAmout); | |
msg.sender.transfer(amount); | |
emit Saveme(id,msg.sender,amount); | |
c.canUserAmount = c.canUserAmount.sub(amount); | |
} | |
function getBalances(uint256 icoId) view public returns (address[] _address, uint256[] _amount){ | |
ICO storage c = ico[icoId]; | |
uint256 length = c.id; | |
address[] memory ADDRESS = new address[](length); | |
uint256[] memory AMOUNT = new uint[](length); | |
for (uint i = 0; i < length; i++) { | |
ADDRESS[i] = c.balances[i+1].addr; | |
AMOUNT[i] = c.balances[i+1].amount; | |
} | |
return (ADDRESS,AMOUNT); | |
} | |
constructor () public { | |
start(10 ether,1632173131); | |
} | |
function active(uint256 id) onlyOwner public { | |
require(!isActive(id)); | |
ICO storage c = ico[id]; | |
c.status = true; | |
emit Active(id); | |
} | |
function isActive(uint256 id) view public returns (bool status){ | |
require(id<=icoid); | |
ICO storage c = ico[id]; | |
return c.status; | |
} | |
function isIcoOwner(uint256 id) view public returns (bool status){ | |
require(id<=icoid); | |
ICO storage c = ico[id]; | |
return msg.sender == c.owner; | |
} | |
function notStop(uint256 id) view public returns (bool){ | |
ICO storage c = ico[id]; | |
return c.stop == false; | |
} | |
function stop(uint256 id) onlyOwner public { | |
require(notStop(id)); | |
ICO storage c = ico[id]; | |
c.stop = true; | |
emit Stop(id); | |
} | |
function notstop(uint256 id) onlyOwner public { | |
require(!notStop(id)); | |
ICO storage c = ico[id]; | |
c.stop = false; | |
emit NotStop(id); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment