├── qrcode.jpg ├── xiaomi.jpg ├── owned.sol ├── simpleToken.sol ├── erc20interface.sol ├── README.md ├── erc20.sol ├── ico.sol └── advanceToken.sol /qrcode.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xilibi2003/learnSmartContractByToken/HEAD/qrcode.jpg -------------------------------------------------------------------------------- /xiaomi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xilibi2003/learnSmartContractByToken/HEAD/xiaomi.jpg -------------------------------------------------------------------------------- /owned.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.22 <0.7.0; 2 | 3 | contract owned { 4 | address public owner; 5 | 6 | constructor () public { 7 | owner = msg.sender; 8 | } 9 | 10 | modifier onlyOwner { 11 | require(msg.sender == owner); 12 | _; 13 | } 14 | 15 | function transferOwnerShip(address newOwer) public onlyOwner { 16 | owner = newOwer; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /simpleToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract SimpleToken { 4 | 5 | mapping(address => uint256) public balanceOf; 6 | event Transfer(address indexed receiver, uint256 value ); 7 | 8 | constructor (uint256 initialSupply) public { 9 | balanceOf[msg.sender] = initialSupply; 10 | } 11 | 12 | function transfer(address _to, uint256 _value) public { 13 | require(balanceOf[msg.sender] >= _value); 14 | require(balanceOf[_to] + _value >= balanceOf[_to]); 15 | 16 | balanceOf[msg.sender] -= _value; 17 | balanceOf[_to] += _value; 18 | 19 | emit Transfer( _to, _value); 20 | } 21 | } -------------------------------------------------------------------------------- /erc20interface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.22 <0.7.0; 2 | 3 | contract ERC20Interface { 4 | 5 | function balanceOf(address tokenOwner) external view returns (uint balance); 6 | 7 | function allowance(address tokenOwner, address spender) external view returns (uint remaining); 8 | function approve(address spender, uint tokens) external returns (bool success); 9 | 10 | function transfer(address to, uint tokens) external returns (bool success); 11 | function transferFrom(address from, address to, uint tokens) public returns (bool success); 12 | 13 | 14 | event Transfer(address indexed from, address indexed to, uint tokens); 15 | event Approval(address indexed tokenOwner, address indexed spender, uint tokens); 16 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 通过代币学智能合约开发 2 | 3 | 此库是视频课程代码,由[深入浅出区块链](https://learnblockchain.cn)博主,以太坊基金会讲师 Tiny熊出品,[在线视频地址请戳](https://ke.qq.com/course/317230) 4 | 5 | 欢迎关注登链公众号![](qrcode.jpg) 6 | 及时获取最新的课程信息。 7 | 8 | # 视频大纲 9 | 10 | ## 1. 智能合约与Token代币介绍 11 | 理解什么是以太坊智能合约,以及如何用代币智能合约 12 | 13 | ## 2. 实现简单代币Token 14 | Remix简单介绍;学习编写简单的合约;solidity mapping的使用 15 | 16 | ## 3. ERC20 标准代币介绍 17 | 学习ERC20 标准协议, 以及合约接口定义 18 | 19 | ## 4. ERC20 标准代币实现 20 | 21 | 学习合约的继承,事件定义,触发事件。 22 | 23 | ## 5. ERC20 代币部署、转账及代码验证 24 | 25 | 学习使用Remix + MetaMask 把合约部署到以太坊网络; 26 | 学习在以太坊网络查询合约信息; 27 | 学习提交代码验证。 28 | 29 | ## 6. 实现代币管理者 30 | 学习函数修饰器的用法(定义修饰器及使用修饰器)。 31 | 32 | ## 7. 实现代币增发功能(挖矿) 33 | 学习合约的多重继承 以及 如何调用父合约构造方法。 34 | 35 | ## 8 实现资产冻结功能 36 | 学习使用函数重载, 重载transfer 及 transferFrom函数 添加冻结功能。 37 | 38 | ## 9. 实现代币销毁 39 | 梳理代币销毁逻辑及实现 40 | 41 | ## 10. 代币高级功能总结及众筹介绍 42 | 代币高级功能总结,介绍锁定(或逐步释放)等高级功能。 43 | 介绍实现众筹合约的要素 44 | 45 | ## 11. 实现代币众筹(ICO) 46 | 学习使用回退函数(Fallback)及 payable 使用来实现众筹合约 47 | 48 | ## 12. 实现代币众筹(ICO) 49 | 学习使用回退函数(Fallback)及 payable 使用来实现众筹合约 50 | 51 | ## 13. 部署及演示如何参与众筹及空投、阶梯定价 52 | 部署及演示如何参与众筹及扩展的空投、阶梯定价实现介绍 53 | 54 | 55 | 56 | 57 | 欢迎大家加入国内高质量的区块链[技术问答交流社区](https://learnblockchain.cn/2019/01/12/about-qa/) 58 | ![](xiaomi.jpg) 59 | -------------------------------------------------------------------------------- /erc20.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.22 <0.7.0; 2 | 3 | import './erc20interface.sol'; 4 | 5 | contract ERC20 is ERC20Interface { 6 | 7 | 8 | string public name; 9 | string public constant symbol = "SYM"; 10 | uint8 public constant decimals = 18; // 18 is the most common number of decimal places 11 | // 0.0000000000000000001 个代币 12 | 13 | uint public totalSupply; 14 | 15 | // 对自动生成对应的balanceOf方法 16 | mapping(address => uint256) internal _balances; 17 | 18 | // allowed保存每个地址(第一个address) 授权给其他地址(第二个address)的额度(uint256) 19 | mapping(address => mapping(address => uint256)) allowed; 20 | 21 | constructor(string memory _name) public { 22 | name = _name; // "UpChain"; 23 | totalSupply = 1000000; 24 | _balances[msg.sender] = totalSupply; 25 | } 26 | 27 | function balanceOf(address tokenOwner) public view returns (uint balance) { 28 | return _balances[tokenOwner]; 29 | } 30 | 31 | // 转移 32 | function transfer(address _to, uint256 _value) public returns (bool success) { 33 | require(_to != address(0)); 34 | require(_balances[msg.sender] >= _value); 35 | require(_balances[ _to] + _value >= _balances[ _to]); // 防止溢出 36 | 37 | 38 | _balances[msg.sender] -= _value; 39 | _balances[_to] += _value; 40 | 41 | // 发送事件 42 | emit Transfer(msg.sender, _to, _value); 43 | 44 | return true; 45 | } 46 | 47 | 48 | function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { 49 | require(_to != address(0)); 50 | require(allowed[_from][msg.sender] >= _value); 51 | require(_balances[_from] >= _value); 52 | require(_balances[ _to] + _value >= _balances[ _to]); 53 | 54 | _balances[_from] -= _value; 55 | _balances[_to] += _value; 56 | 57 | allowed[_from][msg.sender] -= _value; 58 | 59 | emit Transfer(msg.sender, _to, _value); 60 | return true; 61 | } 62 | 63 | function approve(address _spender, uint256 _value) public returns (bool success) { 64 | allowed[msg.sender][_spender] = _value; 65 | 66 | emit Approval(msg.sender, _spender, _value); 67 | return true; 68 | } 69 | 70 | function allowance(address _owner, address _spender) public view returns (uint256 remaining) { 71 | return allowed[_owner][_spender]; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /ico.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.22 <0.7.0; 2 | 3 | interface token { 4 | function transfer(address receiver, uint amount) external ; 5 | } 6 | 7 | contract Ico { 8 | address payable public beneficiary; 9 | uint public fundingGoal; 10 | uint public amountRaised; 11 | 12 | uint public deadline; 13 | uint public price; 14 | token public tokenReward; 15 | 16 | mapping(address => uint256) public balanceOf; 17 | bool crowdsaleClosed = false; 18 | 19 | event GoalReached(address recipient, uint totalAmountRaised); 20 | event FundTransfer(address backer, uint amount, bool isContribution); 21 | 22 | 23 | constructor ( 24 | uint fundingGoalInEthers, 25 | uint durationInMinutes, 26 | uint etherCostOfEachToken, 27 | address addressOfTokenUsedAsReward 28 | ) public { 29 | beneficiary = msg.sender; 30 | fundingGoal = fundingGoalInEthers * 1 ether; 31 | deadline = now + durationInMinutes * 1 minutes; 32 | price = etherCostOfEachToken * 1 ether; 33 | tokenReward = token(addressOfTokenUsedAsReward); 34 | } 35 | 36 | 37 | function () external payable { 38 | require(!crowdsaleClosed); 39 | 40 | uint amount = msg.value; // wei 41 | balanceOf[msg.sender] += amount; 42 | 43 | amountRaised += amount; 44 | 45 | tokenReward.transfer(msg.sender, amount / price); 46 | 47 | emit FundTransfer(msg.sender, amount, true); 48 | } 49 | 50 | modifier afterDeadline() { 51 | if (now >= deadline) { 52 | _; 53 | } 54 | } 55 | 56 | 57 | function checkGoalReached() public afterDeadline { 58 | if (amountRaised >= fundingGoal) { 59 | emit GoalReached(beneficiary, amountRaised); 60 | } 61 | crowdsaleClosed = true; 62 | } 63 | 64 | 65 | function safeWithdrawal() public afterDeadline { 66 | 67 | if (amountRaised < fundingGoal) { 68 | uint amount = balanceOf[msg.sender]; 69 | balanceOf[msg.sender] = 0; 70 | if (amount > 0) { 71 | msg.sender.transfer(amount); 72 | emit FundTransfer(msg.sender, amount, false); 73 | } 74 | } 75 | 76 | if (fundingGoal <= amountRaised && beneficiary == msg.sender) { 77 | beneficiary.transfer(amountRaised); 78 | emit FundTransfer(beneficiary, amountRaised, false); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /advanceToken.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.22 <0.7.0; 2 | 3 | import './owned.sol'; 4 | import './erc20.sol'; 5 | 6 | contract AdvanceToken is ERC20, owned { 7 | 8 | mapping (address => bool) public frozenAccount; 9 | 10 | event AddSupply(uint amount); 11 | event FrozenFunds(address target, bool frozen); 12 | event Burn(address target, uint amount); 13 | 14 | constructor (string memory _name) ERC20(_name) public { 15 | 16 | } 17 | 18 | function mine(address target, uint amount) public onlyOwner { 19 | totalSupply += amount; 20 | _balances[target] += amount; 21 | 22 | emit AddSupply(amount); 23 | emit Transfer(address(0), target, amount); 24 | } 25 | 26 | function freezeAccount(address target, bool freeze) public onlyOwner { 27 | frozenAccount[target] = freeze; 28 | emit FrozenFunds(target, freeze); 29 | } 30 | 31 | 32 | function transfer(address _to, uint256 _value) public returns (bool success) { 33 | success = _transfer(msg.sender, _to, _value); 34 | } 35 | 36 | 37 | function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { 38 | require(allowed[_from][msg.sender] >= _value); 39 | success = _transfer(_from, _to, _value); 40 | allowed[_from][msg.sender] -= _value; 41 | } 42 | 43 | function _transfer(address _from, address _to, uint256 _value) internal returns (bool) { 44 | require(_to != address(0)); 45 | require(!frozenAccount[_from]); 46 | 47 | require(_balances[_from] >= _value); 48 | require(_balances[ _to] + _value >= _balances[ _to]); 49 | 50 | _balances[_from] -= _value; 51 | _balances[_to] += _value; 52 | 53 | emit Transfer(_from, _to, _value); 54 | return true; 55 | } 56 | 57 | function burn(uint256 _value) public returns (bool success) { 58 | require(_balances[msg.sender] >= _value); 59 | 60 | totalSupply -= _value; 61 | _balances[msg.sender] -= _value; 62 | 63 | emit Burn(msg.sender, _value); 64 | return true; 65 | } 66 | 67 | function burnFrom(address _from, uint256 _value) public returns (bool success) { 68 | require(_balances[_from] >= _value); 69 | require(allowed[_from][msg.sender] >= _value); 70 | 71 | totalSupply -= _value; 72 | _balances[msg.sender] -= _value; 73 | allowed[_from][msg.sender] -= _value; 74 | 75 | emit Burn(msg.sender, _value); 76 | return true; 77 | } 78 | } 79 | --------------------------------------------------------------------------------