变量
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract HelloWorld {string public myString = "hello world"; // 自带get()方法bool public b = false; // 默认值 falseuint public u = 123; // uint8/uint16/uint256 0 to 2^8-1 默认值0int public i = -123; // -2^255 to 2^255-1 默认值0int public minInt = type(int).min;int public maxInt = type(int).max;address public addr = 0x0000000000000000000000000000000000000000; // 地址 私钥算公钥,公钥算地址 默认值40个0byte32 public b32 = 0x0000000000000000000000000000000000000000000000000000000000000000; // 32位16进制 默认值64个0}
状态变量&局部变量
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract HelloWorld {uint public i;bool public b;address public myAddress;function foo() external {uint x = 123;bool f = false;x += 456;f = true;i = 123;b = true;myAddress = address(1);}}

全局变量
链上和账户
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract HelloWorld {// view 可以读取全局变量和状态变量function globalVars() external view returns (address,uint,uint){address sender = msg.sender; // 全局变量-账户内容,调用这个函数的地址(上一个调用者,可能是人或合约)是什么uint timestamp = block.timestamp; // 区块时间戳,只读。写入方法就是出块的时间uint blockNum = block.number;return (sender,timestamp,blockNum);}}

常量
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;// 21442 gas 常量消耗更少的gas值,不修改的值定义为常量contract Contracts {address public constant MY_ADDRESS = 0x000000000000000000000000000000000000000F;uint public constant MY_UINT = 123;}// 23575 gascontract Var {address public MY_ADDRESSS = 0x000000000000000000000000000000000000000C;}
数组
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Array {uint[] public nums= [4,2,3]; // 变长数组uint[] public nums2 = [1,2,3]; // 变长数组uint[3] public numsFixed = [4,5,6]; // 定长数组function examples() external {nums.push(4); // 添加元素uint x = nums[0]; // 访问元素nums[0] = 3; // 修改元素delete nums[0]; // 删除元素(不影响数组长度,被删元素位置变成默认值)nums.pop(); // 弹出元素uint len = nums.length; // 元素长度// 内存中创建数组(内存中的数组长度固定)uint[] memory a = new uint[](5);a[1] = 123;}// 返回数组function returnArray() external view returns (uint[] memory){return nums;}}
删除数组元素 | 移动元素
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;// 缺点:浪费gas// 优点:顺序不变contract Array {uint[] public arr;function examples() external {arr = [1,2,3];delete arr[1]; // [1,0,3]}function remove(uint _index) public{require(_index < arr.length, "index out of bound");for(uint i = _index; i < arr.length-1; i++){arr[i]=arr[i+1];}arr.pop();}// 285955 gasfunction test() external {arr = [1,2,3,4,5];remove(2);//[1,2,4,5]assert(arr[0] == 1);assert(arr[1] == 2);assert(arr[2] == 4);assert(arr[3] == 5);assert(arr.length == 4);arr = [1];remove(0);assert(arr.length == 0);}}
删除数组元素 | 交换元素
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;// 缺点:顺序变化// 优点:节约gascontract Array {uint[] public arr;function examples() external {arr = [1,2,3];delete arr[1]; // [1,0,3]}function remove(uint _index) public{require(_index < arr.length, "index out of bound");arr[_index]=arr[arr.length-1];arr.pop();}// 284651 gasfunction test() external {arr = [1,2,3,4,5];remove(2);//[1,2,5,4]assert(arr[0] == 1);assert(arr[1] == 2);assert(arr[2] == 5);assert(arr[3] == 4);assert(arr.length == 4);arr = [1];remove(0);assert(arr.length == 0);}}
Map
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Mapping {mapping(address => uint) public balances; // 地址余额mapping(address => mapping(address => bool)) public isFriend; // 嵌套mapaddress public thisAddr;address public sender;function examples() external {balances[msg.sender] = 123; // 设置数据uint bal = balances[msg.sender]; // 获取数据uint bal2 = balances[address(1)]; // 返回一个不存在的数据,默认值0balances[msg.sender] +=456; // 增加数据// delete balances[msg.sender]; // 删除数据(数据变为0)isFriend[msg.sender][address(this)] = true;sender = msg.sender;thisAddr = address(this);}}
函数
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract HelloWorld {/*external 外部函数,只能被外部读取,当前合约内部不能调用pure 纯函数,不能读写状态变量,只能读写局部变量,即不会对链上有任何操作*/function add(uint x,uint y) external pure returns (uint){return x + y;}function sub(uint x,uint y) external pure returns (uint){return x - y;}}

// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract HelloWorld {uint public count;// 因为要读取状态变量,所以不能带 view或者purefunction inc() external {count +=1;}function dec() external {count -=1;}}
函数修改器
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Contracts {bool public paused;uint public count;function setPause(bool _paused) external {paused = _paused;}modifier whenNotPaused(){require(!paused,"paused");_;}function inc() external whenNotPaused{count += 1;}function dec() external whenNotPaused{count -= 1;}modifier cap(uint _x){require(_x<100,"x >= 100");_;}function incBy(uint _x) external whenNotPaused cap(_x){count += _x;}}
构造函数
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;// 仅能执行一次,用于初始化账号地址等contract Contracts {address public owner;uint public x;constructor(uint _x){owner = msg.sender;x = _x;}}
返回值
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract FunctionOutputs {// 返回值未命名function returnMany() public pure returns (uint,bool){return (1,true);}// 返回值被命名-1function named() public pure returns (uint x,bool b){return (1,true);}// 返回值被命名-2function assigned() public pure returns (uint x,bool b){x = 1;b = true;}// 接收返回值function destructingAssigments() public pure {(uint x,bool b) = returnMany(); // 接收所有返回值(,bool t) = returnMany(); // 接收部分返回值}}
结构体
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Structs {struct Car {string model;uint year;address owner;}Car public car;Car[] public cars;mapping(address =>Car[]) public carsByOwner;function examples() external {Car memory toyota = Car("Toyota", 1990, msg.sender);Car memory lambo = Car({model:"Lamorghini", year:1980, owner: msg.sender});Car memory tesla;tesla.model = "Tesla";tesla.year = 2010;tesla.owner = msg.sender;cars.push(toyota);cars.push(lambo);cars.push(tesla);cars.push(Car("Ferrari", 2020, msg.sender));Car memory _car = cars[0]; // memory 不可修改 只可读取_car.model;_car.year;_car.owner;Car storage __car = cars[0]; // storage 可修改__car.year = 1999;delete _car.owner; // 删除一个变量为默认值delete cars[1]; // 下标1的元素的所有属性变为默认值}}
枚举
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Enum {enum Status {None, // 第一个值为默认值Pending,Shipped,Completed,Rejected,Canceled}Status public status;struct Order {address buyer;Status status;}Order[] public orders;function get() view external returns (Status){return status;}function set(Status _status) external {status = _status;}function ship() external {status = Status.Shipped;}function reset() external {delete status;}}
结构控制
if else
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Contracts {function example(uint _x) external pure returns (uint){if(_x<10){return 1;} else if (_x<20){return 2;} else {return 3;}}function ternary(uint _x) external pure returns (uint){return _x < 10 ? 1 : 2 ;}}
for while
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Contracts {function loops() external pure {for(uint i=0; i<10; i++){if(i==3){continue;}if(i==8){break;}}uint j = 0;while (j < 10){j++;}}}
报错控制
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;// require , revert , assert// gas费退还,状态回滚// 8.0可以自定义错误,节约gascontract Contracts {function testRequire(uint _i) public pure {require(_i <= 10, "i > 10");}function testRevert(uint _i) public pure {if(_i>10){revert("i>10");}}uint public num = 123;function testAssert() public view {assert(num == 123);}function foo(uint _i) public {num += 1;// require(_i<10);if(_i>10){revert("i>10");}}// 自定义报错error MyError(address caller, uint i);function testCustomError(uint _i) public view {if (_i > 10){revert MyError(msg.sender,_i);}}}
综合练习 - 权限控制
// SPDX-License-Identifier: GPL-3.0pragma solidity >=0.7.0 <0.9.0;contract Ownable {address public owner;constructor(){owner = msg.sender;}modifier onlyOwner(){require(msg.sender == owner,"not owner");_;}function setOwner(address _newOwner) external onlyOwner{require(_newOwner != address(0),"invalid address");owner = _newOwner;}function onlyOwnerCanCallThisFunc() external onlyOwner {// code}function anyOneCanCall() external{// code}}
