├── DateTime.sol ├── README.md ├── begin.sol ├── first.sol ├── first_interface.sol ├── hello.sol ├── mathLib.sol ├── temp.txt ├── testAbi.sol ├── testAddr.sol ├── testAdvAddr.sol ├── testAdvAddr2.sol ├── testArr.sol ├── testBlockApi.sol ├── testBool.sol ├── testCast.sol ├── testContractApi.sol ├── testDebug.sol ├── testError.sol ├── testEvent.sol ├── testFallback.sol ├── testFixed.sol ├── testFunc.sol ├── testInherit.sol ├── testInt.sol ├── testIntOverflow.sol ├── testLib.sol ├── testLiteral.sol ├── testLoc.sol ├── testMapping.sol ├── testMath.sol ├── testModify.sol ├── testModifyAdv.sol ├── testPayable.sol ├── testStr.sol ├── testStruct.sol ├── testTime.sol ├── testView.sol ├── testenum.sol └── xiaomi.jpg /DateTime.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.16; 2 | 3 | library DateTime { 4 | /* 5 | * Date and Time utilities for ethereum contracts 6 | * 7 | */ 8 | struct _DateTime { 9 | uint16 year; 10 | uint8 month; 11 | uint8 day; 12 | uint8 hour; 13 | uint8 minute; 14 | uint8 second; 15 | uint8 weekday; 16 | } 17 | 18 | uint constant DAY_IN_SECONDS = 86400; 19 | uint constant YEAR_IN_SECONDS = 31536000; 20 | uint constant LEAP_YEAR_IN_SECONDS = 31622400; 21 | 22 | uint constant HOUR_IN_SECONDS = 3600; 23 | uint constant MINUTE_IN_SECONDS = 60; 24 | 25 | uint16 constant ORIGIN_YEAR = 1970; 26 | 27 | function isLeapYear(uint16 year) public pure returns (bool) { 28 | if (year % 4 != 0) { 29 | return false; 30 | } 31 | if (year % 100 != 0) { 32 | return true; 33 | } 34 | if (year % 400 != 0) { 35 | return false; 36 | } 37 | return true; 38 | } 39 | 40 | function leapYearsBefore(uint year) public pure returns (uint) { 41 | year -= 1; 42 | return year / 4 - year / 100 + year / 400; 43 | } 44 | 45 | function getDaysInMonth(uint8 month, uint16 year) public pure returns (uint8) { 46 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { 47 | return 31; 48 | } 49 | else if (month == 4 || month == 6 || month == 9 || month == 11) { 50 | return 30; 51 | } 52 | else if (isLeapYear(year)) { 53 | return 29; 54 | } 55 | else { 56 | return 28; 57 | } 58 | } 59 | 60 | function parseTimestamp(uint timestamp) internal pure returns (_DateTime dt) { 61 | uint secondsAccountedFor = 0; 62 | uint buf; 63 | uint8 i; 64 | 65 | // Year 66 | dt.year = getYear(timestamp); 67 | buf = leapYearsBefore(dt.year) - leapYearsBefore(ORIGIN_YEAR); 68 | 69 | secondsAccountedFor += LEAP_YEAR_IN_SECONDS * buf; 70 | secondsAccountedFor += YEAR_IN_SECONDS * (dt.year - ORIGIN_YEAR - buf); 71 | 72 | // Month 73 | uint secondsInMonth; 74 | for (i = 1; i <= 12; i++) { 75 | secondsInMonth = DAY_IN_SECONDS * getDaysInMonth(i, dt.year); 76 | if (secondsInMonth + secondsAccountedFor > timestamp) { 77 | dt.month = i; 78 | break; 79 | } 80 | secondsAccountedFor += secondsInMonth; 81 | } 82 | 83 | // Day 84 | for (i = 1; i <= getDaysInMonth(dt.month, dt.year); i++) { 85 | if (DAY_IN_SECONDS + secondsAccountedFor > timestamp) { 86 | dt.day = i; 87 | break; 88 | } 89 | secondsAccountedFor += DAY_IN_SECONDS; 90 | } 91 | 92 | // Hour 93 | dt.hour = getHour(timestamp); 94 | 95 | // Minute 96 | dt.minute = getMinute(timestamp); 97 | 98 | // Second 99 | dt.second = getSecond(timestamp); 100 | 101 | // Day of week. 102 | dt.weekday = getWeekday(timestamp); 103 | } 104 | 105 | function getYear(uint timestamp) public pure returns (uint16) { 106 | uint secondsAccountedFor = 0; 107 | uint16 year; 108 | uint numLeapYears; 109 | 110 | // Year 111 | year = uint16(ORIGIN_YEAR + timestamp / YEAR_IN_SECONDS); 112 | numLeapYears = leapYearsBefore(year) - leapYearsBefore(ORIGIN_YEAR); 113 | 114 | secondsAccountedFor += LEAP_YEAR_IN_SECONDS * numLeapYears; 115 | secondsAccountedFor += YEAR_IN_SECONDS * (year - ORIGIN_YEAR - numLeapYears); 116 | 117 | while (secondsAccountedFor > timestamp) { 118 | if (isLeapYear(uint16(year - 1))) { 119 | secondsAccountedFor -= LEAP_YEAR_IN_SECONDS; 120 | } 121 | else { 122 | secondsAccountedFor -= YEAR_IN_SECONDS; 123 | } 124 | year -= 1; 125 | } 126 | return year; 127 | } 128 | 129 | function getMonth(uint timestamp) public pure returns (uint8) { 130 | return parseTimestamp(timestamp).month; 131 | } 132 | 133 | function getDay(uint timestamp) public pure returns (uint8) { 134 | return parseTimestamp(timestamp).day; 135 | } 136 | 137 | function getHour(uint timestamp) public pure returns (uint8) { 138 | return uint8((timestamp / 60 / 60) % 24); 139 | } 140 | 141 | function getMinute(uint timestamp) public pure returns (uint8) { 142 | return uint8((timestamp / 60) % 60); 143 | } 144 | 145 | function getSecond(uint timestamp) public pure returns (uint8) { 146 | return uint8(timestamp % 60); 147 | } 148 | 149 | function getWeekday(uint timestamp) public pure returns (uint8) { 150 | return uint8((timestamp / DAY_IN_SECONDS + 4) % 7); 151 | } 152 | 153 | function toTimestamp(uint16 year, uint8 month, uint8 day) public pure returns (uint timestamp) { 154 | return toTimestamp(year, month, day, 0, 0, 0); 155 | } 156 | 157 | function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour) public pure returns (uint timestamp) { 158 | return toTimestamp(year, month, day, hour, 0, 0); 159 | } 160 | 161 | function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute) public pure returns (uint timestamp) { 162 | return toTimestamp(year, month, day, hour, minute, 0); 163 | } 164 | 165 | function toTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) public pure returns (uint timestamp) { 166 | uint16 i; 167 | 168 | // Year 169 | for (i = ORIGIN_YEAR; i < year; i++) { 170 | if (isLeapYear(i)) { 171 | timestamp += LEAP_YEAR_IN_SECONDS; 172 | } 173 | else { 174 | timestamp += YEAR_IN_SECONDS; 175 | } 176 | } 177 | 178 | // Month 179 | uint8[12] memory monthDayCounts; 180 | monthDayCounts[0] = 31; 181 | if (isLeapYear(year)) { 182 | monthDayCounts[1] = 29; 183 | } 184 | else { 185 | monthDayCounts[1] = 28; 186 | } 187 | monthDayCounts[2] = 31; 188 | monthDayCounts[3] = 30; 189 | monthDayCounts[4] = 31; 190 | monthDayCounts[5] = 30; 191 | monthDayCounts[6] = 31; 192 | monthDayCounts[7] = 31; 193 | monthDayCounts[8] = 30; 194 | monthDayCounts[9] = 31; 195 | monthDayCounts[10] = 30; 196 | monthDayCounts[11] = 31; 197 | 198 | for (i = 1; i < month; i++) { 199 | timestamp += DAY_IN_SECONDS * monthDayCounts[i - 1]; 200 | } 201 | 202 | // Day 203 | timestamp += DAY_IN_SECONDS * (day - 1); 204 | 205 | // Hour 206 | timestamp += HOUR_IN_SECONDS * (hour); 207 | 208 | // Minute 209 | timestamp += MINUTE_IN_SECONDS * (minute); 210 | 211 | // Second 212 | timestamp += second; 213 | 214 | return timestamp; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [视频课程]深入详解以太坊智能合约语言Solidity 2 | 3 | 此库是视频课程代码,由[深入浅出区块链](https://learnblockchain.cn)博主,以太坊基金会讲师 Tiny熊出品 4 | 5 | 目前市面上最全面深入介绍Solidity的课程,内容包括但不限于: 6 | * 以太坊核心概念… 7 | * 语言类型:基本类型、结构体、映射… 8 | * 函数、修饰器、API 、事件、错误处理… 9 | * 继承、库、重载… 10 | * MetaMask, Remix 的高级用法… 11 | * 各种工具库的使用… 12 | 13 | 14 | 欢迎关注“登链学院”公众号,回复“02”获取课程。 15 | 登链学院让每个程序员都懂区块链 16 | 17 | 欢迎大家加入国内最高质量的区块链交流社区 18 | ![](xiaomi.jpg) 19 | -------------------------------------------------------------------------------- /begin.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; // 0.4.25 - 0.5 2 | 3 | contract SimpleStorage { 4 | uint storedData; 5 | 6 | function set(uint x) public { 7 | storedData = x; 8 | } 9 | 10 | function get() public constant returns (uint) { 11 | return storedData; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /first.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; // 0.4.25 - 0.5 2 | 3 | 4 | // 引入一个合约接口文件: 使用路径及文件名 ./ 表示当前目录 5 | import "./first_interface.sol"; 6 | 7 | // This is a test Contract 8 | 9 | /* 10 | * 作者:Tiny熊@登链 11 | * 版权归登链学院所有 12 | */ 13 | 14 | 15 | contract SimpleStorage { 16 | uint storedData; 17 | 18 | event Set(uint value); // 事件是不需要实现的。 19 | Circle c; 20 | 21 | // 自定义类型 22 | struct Circle { 23 | uint radius; 24 | } 25 | 26 | // 定义一个函数修改器 27 | modifier mustOver10 (uint value) { 28 | require(value >= 10); 29 | _; 30 | } 31 | 32 | function set(uint x) public mustOver10(x) { 33 | storedData = x; 34 | c = Circle(x); 35 | emit Set(x); 36 | } 37 | 38 | function get() public constant returns (uint) { 39 | return storedData; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /first_interface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | // This is a Contract; 4 | 5 | contract FirstBase { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /hello.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.16; 2 | 3 | contract HelloWorld { 4 | function hello() public pure returns (string) { 5 | return "Hello World"; 6 | } 7 | } 8 | 9 | contract testMsg { 10 | function msgCall(HelloWorld toAddr) public returns (string) { 11 | // 一些其他逻辑 12 | address addr = toAddr; 13 | addr.transfer(10); 14 | 15 | // call function 16 | bytes4 methodId = bytes4(keccak256("hello()")); 17 | addr.call.gas(30000)(methodId); 18 | 19 | return toAddr.hello(); 20 | 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /mathLib.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | library mathlib { 4 | 5 | function plus(uint a, uint b) public returns (uint) { 6 | uint c = a + b; 7 | assert(c>=a && c>=b); 8 | return c; 9 | } 10 | 11 | function getThis() public returns (address) { 12 | return this; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /temp.txt: -------------------------------------------------------------------------------- 1 | 2 | int a = 1; 3 | a = "Upchain"; 4 | 5 | var b; 6 | 7 | 8 | b = "hello"; 9 | 10 | b = 10; 11 | 12 | a = 10 + 10 + 2; 13 | 14 | -------------------------------------------------------------------------------- /testAbi.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract testAbi { 4 | 5 | uint storedData; 6 | 7 | function set(uint x) public { 8 | storedData = x; 9 | } 10 | 11 | function abiEncode() public constant returns (bytes) { 12 | return abi.encode(1, 2); // 计算set(uint x) 的ABI编码 13 | // return abi.encodePacked(1, 2); 14 | // return abi.encodeWithSignature("set(uint256)" ,1); //计算函数ABI编码 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /testAddr.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract TestAddr { 4 | 5 | constructor() public payable { 6 | 7 | } 8 | 9 | // 获取一个账号的余额,注意把地址替换为自己的账号地址 10 | function testBlance() public constant returns (uint) { 11 | address a = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c; 12 | return a.balance; // wei 1eth = 10e18wei 13 | } 14 | 15 | // 参看合约地址余额,在创建账号的时候附加一个以太币 16 | function testSelfBlance() public constant returns (uint) { 17 | address a = this; 18 | return a.balance; 19 | } 20 | 21 | 22 | // 地址如何作为参数 : 注意加上引号 23 | function balance(address a) public constant returns (uint) { 24 | return a.balance; 25 | } 26 | 27 | function testTransfer(address a) public { 28 | address myAddress = this; 29 | 30 | // 转移1eth (1eth = 10^18wei) 31 | if (myAddress.balance >= 1e18) { 32 | 33 | // 思考谁来支付矿工费呢? 查看一下合约余额 34 | a.transfer(1e18); 35 | } 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /testAdvAddr.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract Called{ 4 | event logdata(bytes data); 5 | 6 | // 这是一个回退函数, 收到以太币会被调用 7 | function() public payable { 8 | emit logdata(msg.data); 9 | } 10 | 11 | function getBalance() public view returns (uint) { 12 | return this.balance; 13 | } 14 | 15 | } 16 | 17 | contract CallTest{ 18 | 19 | constructor() public payable { 20 | } 21 | 22 | function transferEther(address towho) public returns (bool) { 23 | towho.transfer(1 ether); 24 | return true; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /testAdvAddr2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract Called { 4 | uint public n; 5 | address public sender; 6 | 7 | function setN(uint _n) { 8 | n = _n; 9 | sender = msg.sender; 10 | } 11 | 12 | event logdata(bytes data); 13 | 14 | function () public payable { 15 | emit logdata(msg.data); 16 | } 17 | 18 | function getBalance() public view returns (uint) { 19 | return this.balance; 20 | } 21 | } 22 | 23 | contract CallTest { 24 | uint public n; 25 | address public sender; 26 | 27 | // 只是调用代码,合约环境还是当前合约。 28 | function delegatecallSetN(address _e, uint _n) { 29 | bytes4 methodId = bytes4(keccak256("setN(uint256)")); 30 | _e.delegatecall(methodId, _n); 31 | } 32 | 33 | function callSetN(address _e, uint _n) { 34 | bytes4 methodId = bytes4(keccak256("setN(uint256)")); 35 | _e.call(methodId, _n); 36 | // _e.call.gas(1000)(methodId, _n); 37 | // _e.call.gas(1000).value(1 ether)(methodId, _n); 38 | } 39 | 40 | function callNoFunc(address addr) returns (bool){ 41 | return addr.call("tinyxiong", 1234); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /testArr.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract testArr { 4 | 5 | uint [10] tens; 6 | uint [] us; 7 | 8 | uint [] public u = [1, 2, 3]; // 生成函数 9 | uint[] public b = new uint[](7); //storage 10 | 11 | 12 | function get() public view returns (uint) { 13 | tens[0] = 1; 14 | return tens[0]; 15 | } 16 | 17 | uint[][5] public a; 18 | function setA() public { 19 | a[1] = [1,2]; 20 | a[2] = [1,2,3]; 21 | // a[6] = [1,2,3]; 22 | } 23 | 24 | function getLen() public view returns (uint) { 25 | return tens.length; 26 | } 27 | 28 | function modifyLenAndPush() public returns (uint) { 29 | b.length = 10; //可以修改storage的数组 30 | 31 | b[7] = 100; 32 | b.push(20); 33 | // tens.push(10); 34 | 35 | 36 | uint[] memory a = new uint[](7); 37 | // a.push(10); 38 | // a.length = 10; 39 | 40 | return b.length; 41 | } 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /testBlockApi.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.16; 2 | 3 | contract called { 4 | 5 | function testCalled() public returns (address addr) { 6 | return msg.sender; // tx.origin; 7 | } 8 | } 9 | 10 | contract testBlockApi { 11 | 12 | function getValue() public returns (address , uint) { 13 | return (msg.sender, msg.value); 14 | } 15 | 16 | function diffGas() public returns ( uint) { 17 | uint g1 = gasleft(); 18 | uint a = 1 + 2; 19 | uint g2 = gasleft(); 20 | 21 | return g1 - g2; 22 | } 23 | 24 | function testCall() public returns (address) { 25 | return new called().testCalled(); 26 | } 27 | 28 | function testf() public returns (bytes4) { 29 | return this.testf.selector; 30 | // return msg.sig; // 0xf39581ad 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /testBool.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract TestBool { 4 | 5 | } 6 | 7 | contract TestBool { 8 | 9 | bool a = true; 10 | bool b = false; 11 | 12 | function test1() public constant returns (bool) { 13 | return a && b; 14 | } 15 | 16 | function test2() public constant returns (bool) { 17 | return a || b; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /testCast.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract testCast { 4 | 5 | function add() public pure returns (uint) { 6 | uint8 i = 10; 7 | uint16 j = 20; 8 | 9 | // i会隐式转换为uint16 10 | uint16 k = i + j; 11 | 12 | // k会隐式转换为uint256 13 | return k; 14 | } 15 | 16 | // 17 | function force() public pure returns (uint , uint16 ) { 18 | int8 y = -3; 19 | uint x = uint(y); // 0xfffff..fd (64个16进制数) 20 | 21 | uint32 a = 0x12345678; 22 | uint16 b = uint16(a); // b = 0x5678 23 | 24 | return (x, b); 25 | } 26 | 27 | struct CustomType { 28 | bool myBool; 29 | uint myInt; 30 | } 31 | 32 | function testDel() public view returns (bool, address) { 33 | bool b = true; 34 | delete b; // b = false; 35 | 36 | uint a = 1; 37 | delete a ; // a = 0 38 | 39 | address addr = msg.sender; 40 | delete addr ; // addr = 0x0 41 | 42 | bytes memory bs = "123"; 43 | delete bs; // bs = 0x0 44 | 45 | string memory str = "tiny xiong"; 46 | delete str; // str = "" 47 | 48 | // 变长数组 49 | uint[] memory arr = new uint[](7); 50 | delete arr; // a.length = 0; 51 | 52 | CustomType memory ct = CustomType(true, 100); 53 | delete ct; // ct.myBool = false ; myInt = 0; 54 | 55 | return (b, addr); 56 | } 57 | 58 | uint data; 59 | uint[] dataArray; 60 | 61 | function f() public { 62 | //值传递 63 | uint x = data; 64 | delete x; // 删除x不会影响data 65 | delete data; // 删除data,同样也不会影响x,因为是值传递,它存的是一份原值的拷贝。 66 | 67 | //引用赋值 68 | uint[] storage y = dataArray; 69 | //删除dataArray会影响y,y也将被赋值为初值。 70 | delete dataArray; 71 | //报错,因为删除是一个赋值操作,不能向引用类型的storage直接赋值从而报错 72 | /* delete y; */ 73 | 74 | } 75 | 76 | mapping(address=>uint) balances; 77 | function deleteMap() public { 78 | // 非法 79 | // delete balances; 80 | delete balances[msg.sender]; 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /testContractApi.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract testContract { 4 | 5 | address owner; 6 | 7 | constructor() { 8 | owner = msg.sender; 9 | } 10 | 11 | function hello() public view returns (string) { 12 | return "hello"; 13 | } 14 | 15 | function kill() public { 16 | require(msg.sender == owner); 17 | selfdestruct(owner); // 销毁合约 18 | } 19 | 20 | function innocence() public { 21 | selfdestruct(owner); // 销毁合约 22 | } 23 | } 24 | 25 | contract testCall { 26 | 27 | function hello() public view returns (string) { 28 | return "hello"; 29 | } 30 | 31 | function call(address a) { 32 | a.delegatecall(bytes4(sha3("innocence()"))); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /testDebug.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract Test { 4 | uint public x; 5 | function() public payable { 6 | uint a = 1 + x; 7 | uint double_a = 2 * a + 1; 8 | x = double_a; 9 | } 10 | } 11 | 12 | contract Caller { 13 | constructor() public payable { 14 | } 15 | 16 | function getBalance() public view returns (uint) { 17 | return this.balance; 18 | } 19 | 20 | function callTest(address test) public { 21 | test.transfer(1 ether); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /testError.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract testError { 4 | 5 | function testdiv(uint x, uint y) public { 6 | require(x > y); 7 | 8 | assert(x >= x/y); 9 | 10 | if (x/y == 1) { 11 | revert(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /testEvent.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract testEvent { 4 | 5 | constructor() public payable { 6 | } 7 | 8 | event Deposit(address _from, uint _value); 9 | 10 | 11 | function deposit() public payable { 12 | emit Deposit(msg.sender, msg.value); 13 | } 14 | } 15 | 16 | contract testEvent2 is testEvent { 17 | 18 | function deposit2() public payable { 19 | emit Deposit(msg.sender, msg.value); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /testFallback.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract Test { 4 | 5 | uint public x; 6 | // 由于没有payable , 向这个合约转账会有异常。 7 | function() public { x = 1; } 8 | } 9 | 10 | contract Caller { 11 | 12 | constructor() public payable { 13 | } 14 | 15 | function callTest(address test) public { 16 | test.call(0xabcdef01); // 不存在的hash 17 | 18 | // 无法编译,通过其他方式发送则失败 19 | // test.send(2 ether); 20 | 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testFixed.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract TestFixed { 4 | ufixed32x1 f; 5 | 6 | // uint == uint256 7 | 8 | bytes1 bt1 = 0x01; // byte 等价 bytes1 9 | bytes2 bt2 = "ab"; 10 | bytes3 bt3 = "abc"; 11 | string a = "abc"; 12 | 13 | // 比较运算 位运算 14 | function testCompare() public constant returns (bytes3 ) { 15 | return bt2 & bt3; 16 | } 17 | 18 | function getFirst() public constant returns (byte ) { 19 | return bt3[0]; 20 | } 21 | 22 | 23 | function getLength() public constant returns (uint ) { 24 | return bt2.length; 25 | } 26 | 27 | // 对比gas 消耗 28 | bytes10 constant bt10 = "Tiny Xiong"; 29 | bytes32 constant bt32 = "Tiny Xiong"; 30 | 31 | function getByte10() payable public returns(bytes11) { 32 | return bt10; 33 | } 34 | 35 | function getByte32() payable public returns(bytes32) { 36 | return bt32; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /testFunc.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | contract TestFunc { 4 | 5 | function a(uint x) external returns (uint z) { 6 | return x * x; 7 | } 8 | 9 | function b(uint x) external returns (uint z) { 10 | return 2 * x; 11 | } 12 | 13 | // 变量f 可以被赋值为函数a 或 函数b 14 | function select(function (uint) external returns (uint) f, uint x) external returns (uint z) { 15 | return f(x); 16 | } 17 | 18 | // 函数作为返回值的类型 19 | function getfun() public view returns (function (uint) external returns (uint) ) { 20 | return this.b; 21 | } 22 | 23 | 24 | function callTest(bool useB, uint x) external returns (uint z) { 25 | // 变量f 可以被赋值为 函数a 或 函数b 26 | function (uint) external returns (uint) f; 27 | if (useB) { 28 | f = this.b; 29 | } else { 30 | f = this.a; 31 | } 32 | return f(x); 33 | } 34 | 35 | 36 | // 0x26121ff0 37 | function f() public view returns (bytes4) { 38 | return this.f.selector; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /testInherit.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract base { 4 | function privateHello() private { 5 | } 6 | 7 | function internalHello() internal { 8 | } 9 | 10 | function externalHello() external { 11 | } 12 | 13 | function publicHello() public { 14 | } 15 | } 16 | 17 | contract Sub is base { 18 | 19 | function hello() { 20 | internalHello(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /testInt.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | contract testInt { 4 | int8 a = -1; 5 | int16 b = 2; 6 | 7 | uint32 c = 10; 8 | uint8 d = 16; 9 | 10 | function add(uint x, uint y) public pure returns (uint z) { 11 | z = x + y; 12 | } 13 | 14 | function divide(uint x, uint y ) public pure returns (uint z) { 15 | z = x / y; 16 | } 17 | 18 | function leftshift(int x, uint y) public pure returns (int z){ 19 | z = x << y; 20 | } 21 | 22 | function rightshift(int x, uint y) public pure returns (int z){ 23 | z = x >> y; 24 | } 25 | 26 | function testPlusPlus() public pure returns (uint ) { 27 | uint x = 1; 28 | uint y = ++x; // c = ++a; 29 | return y; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /testIntOverflow.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | contract TestFlow { 4 | uint256 public zero = 0; 5 | uint256 public max = 2**256 - 1; 6 | uint256 public mm = 2**255; 7 | 8 | function subUnderFlow() public constant returns (uint) { 9 | uint256 a = zero - 1; 10 | return a; 11 | } 12 | 13 | function addOverFlow() public constant returns (uint) { 14 | uint256 a = max + 1; 15 | return a; 16 | } 17 | 18 | function mulOverFlow() public constant returns (uint) { 19 | uint256 a = mm * 2; 20 | return a; 21 | } 22 | 23 | uint8 c; 24 | 25 | function add(uint8 a, uint8 b ) public returns (uint8) { 26 | c = a + b; 27 | return c; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /testLib.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "./mathLib.sol"; 4 | 5 | contract testLib { 6 | 7 | using mathlib for uint; 8 | 9 | function add (uint x, uint y) public returns (uint) { 10 | return x.plus(y); 11 | // return mathlib.plus(x,y); 12 | 13 | 14 | } 15 | 16 | function getThis() public view returns (address) { 17 | 18 | return mathlib.getThis(); 19 | } 20 | 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /testLiteral.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.18; 2 | 3 | contract testLiteral{ 4 | 5 | function test() public pure returns (int ) { 6 | return -2e10; 7 | } 8 | 9 | function test2() public pure returns (uint ) { 10 | uint a = 5/2 + 5/2; 11 | return a; 12 | } 13 | 14 | function testSoBig() public pure returns (uint) { 15 | return ((2**800 + 1) - 2**800); 16 | } 17 | 18 | // 数字常量表达式,一旦其中含有非常量表达式,它就会被转为一个非常量类型,不同类型的之间没法进行运算, 19 | function test3() public { 20 | uint128 a = 1; // a 不再是常量类型 21 | uint128 b = 2.5 + a + 0.5; 22 | } 23 | 24 | function testEn() public pure returns (string) { 25 | return "abc"; 26 | } 27 | 28 | function testChinese() public pure returns (string) { 29 | return "登链科技"; 30 | } 31 | 32 | function testString() public pure returns (string) { 33 | // "\x61\x62" 34 | return "Tiny\u718A"; 35 | } 36 | 37 | function hexLiteralBytes() public pure returns (bytes2, bytes1, bytes1) { 38 | bytes2 a = hex"aabb"; 39 | return (a, a[0], a[1]); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /testLoc.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract TestLoc { 4 | uint[] x; // x的存储位置是storage 5 | 6 | // memoryArray的存储位置是 memory 7 | function f(uint[] memoryArray) public returns (uint[]) { 8 | x = memoryArray; // 从 memory 复制到 storage 9 | 10 | uint[] y = x; // storage 引用传递局部变量y(y 是一个 storage 引用) 11 | y[1] = 2; // x y 都会被修改 12 | 13 | // 错误, 不能将memory赋值给局部变量 14 | // y = memoryArray; 15 | 16 | g(x); // 引用传递, g可以改变x的内容 17 | h(x); // 拷贝到memory, h无法改变x的内容 18 | return x; 19 | } 20 | 21 | function g(uint[] storage storageArray) internal { 22 | storageArray[2] = 3; 23 | } 24 | 25 | function h(uint[] memoryArray) public { 26 | memoryArray[2] = 4; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /testMapping.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "./iterable_mapping.sol"; 4 | 5 | 6 | contract TestMapping { 7 | 8 | // 生成对应函数 9 | mapping(address => uint) public balances; 10 | 11 | function update(uint newBalance) public { 12 | balances[msg.sender] = newBalance; 13 | } 14 | 15 | function test() { 16 | mapping(address => uint) a; 17 | } 18 | 19 | IterableMapping.itmap data; 20 | 21 | function insert(uint k, uint v) public returns (uint size) { 22 | IterableMapping.insert(data, k, v); 23 | return data.size; 24 | } 25 | 26 | function sum() public returns (uint s) { 27 | for (uint i = IterableMapping.iterate_start(data); IterableMapping.iterate_valid(data, i); i = IterableMapping.iterate_next(data, i)) 28 | { 29 | uint key; 30 | uint value; 31 | (key, value) = IterableMapping.iterate_get(data, i); 32 | s += value; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /testMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract testMath { 4 | 5 | function testAddmod() public view returns (uint) { 6 | uint x = 2**256 - 1; 7 | uint y = 1; 8 | uint k = 100; 9 | 10 | return addmod(x , y, k); 11 | // return (x + y) % 100; 12 | 13 | // return mulmod(2**256 - 1 , 2**256 - 1, 100); 14 | } 15 | 16 | function testsha3() public view returns (bytes32) { 17 | return keccak256("set(uint256)"); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /testModify.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract owned { 4 | function owned() public { owner = msg.sender; } 5 | address owner; 6 | 7 | 8 | // 定义了一个函数修改器,可被继承 9 | // 修饰时,函数体被插入到 “_;” 处 10 | // 不符合条件时,将抛出异常 11 | modifier onlyOwner { 12 | require(msg.sender == owner); 13 | _; 14 | } 15 | } 16 | 17 | contract testModifty is owned { 18 | 19 | modifier over18(uint age) { 20 | if (age >= 18) { 21 | _; 22 | } 23 | } 24 | 25 | function kill(uint age) public onlyOwner over18(age) { 26 | selfdestruct(owner); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /testModifyAdv.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract Mutex { 4 | 5 | bool public locked; 6 | 7 | modifier noReentrancy() { 8 | require(!locked); 9 | locked = true; 10 | _; 11 | locked = false; 12 | } 13 | 14 | // 防止递归调用 15 | // return 7 之后,locked = false 依然会执行 16 | 17 | function f() public noReentrancy returns (uint) { 18 | return 7; 19 | } 20 | } 21 | 22 | // 运行test1()之后,状态变量a的值是多少 23 | contract modifysample { 24 | uint a = 10; 25 | 26 | modifier mf1 (uint b) { 27 | uint c = b; 28 | _; 29 | c = a; 30 | a = 11; 31 | } 32 | 33 | modifier mf2 () { 34 | uint c = a; 35 | _; 36 | } 37 | 38 | modifier mf3() { 39 | a = 12; 40 | return ; 41 | _; 42 | a = 13; 43 | } 44 | 45 | function test1() mf1(a) mf2 mf3 public { 46 | a = 1; 47 | } 48 | 49 | function get_a() public constant returns (uint) { 50 | return a; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /testPayable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract testPayable { 4 | 5 | constructor() public payable { 6 | 7 | } 8 | 9 | function () public payable { 10 | 11 | } 12 | 13 | function deposit() public payable { 14 | 15 | } 16 | } 17 | 18 | contract call { 19 | 20 | constructor() public payable { 21 | } 22 | 23 | function testTransfer(address a) public { 24 | address myAddress = this; 25 | if (myAddress.balance >= 1e18) { 26 | a.transfer(1e18); 27 | } 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /testStr.sol: -------------------------------------------------------------------------------- 1 | 2 | pragma solidity ^0.4.24; 3 | 4 | import "github.com/Arachnid/solidity-stringutils/strings.sol"; 5 | 6 | contract testStr { 7 | 8 | string public str1 = "登链学院"; 9 | 10 | // https://www.qqxiuzi.cn/bianma/Unicode-UTF.php 11 | bytes public bs1 = "登链学院"; 12 | 13 | // utf 编码长度 14 | function getLen() public view returns (uint) { 15 | return bytes(str1).length; 16 | } 17 | 18 | function getbyte(uint i) public view returns (byte) { 19 | return bytes(str1)[i]; 20 | } 21 | 22 | using strings for *; //表示库strings中的函数可以关联到任意的类型上。 23 | function getStrLen() public view returns (uint len) { 24 | len = str1.toSlice().len(); 25 | } 26 | 27 | 28 | 29 | function testStart() public pure returns (bool ) { 30 | strings.slice memory s = "ABCDE".toSlice(); 31 | return s.startsWith("AB".toSlice()); 32 | 33 | } 34 | 35 | // 转为小写。 36 | function toLower(string str) internal view returns (string) { 37 | bytes memory bStr = bytes(str); 38 | bytes memory bLower = new bytes(bStr.length); 39 | for (uint i = 0; i < bStr.length; i++) { 40 | // 大写字母 41 | if ((bStr[i] >= 0x41) && (bStr[i] <= 0x5A)) { 42 | // 加 0x20 变为小写 43 | bLower[i] = bytes1(int(bStr[i]) + 32); 44 | } else { 45 | bLower[i] = bStr[i]; 46 | } 47 | } 48 | return string(bLower); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /testStruct.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | // 引入试验版本 4 | pragma experimental ABIEncoderV2; 5 | 6 | contract testStruct { 7 | 8 | struct CustomType { 9 | bool myBool; 10 | uint myInt; 11 | // CustomType aa; 12 | } 13 | 14 | struct CustomType2 { 15 | CustomType[] cts; 16 | mapping(string=>CustomType2) indexs; 17 | } 18 | 19 | struct CustomType3 { 20 | string name; 21 | mapping(string=>uint) score; 22 | int age; 23 | } 24 | 25 | // 仅声明变量,不初始化 26 | CustomType ct1; 27 | 28 | // 按成员顺序(结构体声明时的顺序)初始化 29 | CustomType ct2 = CustomType(true, 2); 30 | CustomType3 ct3 = CustomType3("Tiny", 18); // 跳过对mapping的初始化 31 | 32 | function init() { 33 | CustomType memory ct3 = CustomType(true, 2); // 在函数内声明 34 | } 35 | 36 | // 命名方式的初始 37 | CustomType ct = CustomType({ myBool: true, myInt: 2}); 38 | 39 | function getSet() public returns (bool) { 40 | ct.myBool = false; 41 | return ct.myBool; 42 | } 43 | 44 | // 合法 45 | function interFunc(CustomType ct) internal { 46 | } 47 | 48 | // 非法 49 | function exterFunc(CustomType ct) public { 50 | 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /testTime.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.16; 2 | 3 | import "./Datetime.sol"; 4 | 5 | contract testTime { 6 | 7 | using DateTime for uint; 8 | 9 | uint lastTs; 10 | 11 | 12 | function currTimeStamp() public view returns (uint256){ 13 | return now; 14 | } 15 | 16 | function doSomething() public { 17 | if (now >= lastTs + 1 days) { 18 | // ... 19 | } 20 | lastTs = now; 21 | } 22 | 23 | function getCurrYearMonth() public view returns (uint, uint) { 24 | return (now.getYear(), now.getMonth()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /testView.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.20; 2 | 3 | contract testView { 4 | uint public b; 5 | 6 | 7 | function f(uint a) public returns (uint) { 8 | b = a * 2; 9 | return b; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /testenum.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.0; 2 | 3 | contract TestEnum { 4 | 5 | // 使用枚举自定义一个类型 ActionChoices 6 | enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } 7 | 8 | // 定义一个ActionChoices类型的变量 9 | ActionChoices choice; 10 | 11 | ActionChoices defaultChoice = ActionChoices.GoStraight; 12 | 13 | function setGoStraight() { 14 | choice = ActionChoices.GoStraight; 15 | } 16 | 17 | function getChoice() returns (ActionChoices) { 18 | return choice; 19 | } 20 | 21 | function getDefaultChoice() public constant returns (uint) { 22 | return uint(defaultChoice); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /xiaomi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xilibi2003/leanSolidity/cf4ee068b77175b69c4d0475b5af183e9653c5d3/xiaomi.jpg --------------------------------------------------------------------------------