Solidity8.0-01
对应崔棉大师 1-25课程
https://www.bilibili.com/video/BV1yS4y1N7yu/?spm_id_from=333.788&vd_source=c81b130b6f8bb3082bdb42226729d69c
Solidity8.0新特性
1.安全数学
unit 溢出 unchecked {x--;}
2.自定义异常
error Unauthorized(address caller);
revert(msg.sender);
3.合约外函数 类似library
4.起别名 as
5.create2
Hello World
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract HelloWorld{
string public myStirng = "'hello world123'";
}
类型和值
1.bool
2.uint
3.int
type(int).min
type(int).max
4.address
5.bytes32
函数
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Func{
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: MIT
pragma solidity ^0.8.7;
contract Variable{
//状态变量
bool public b;
uint public u;
address public add;
function get() external returns(bool,uint,address,uint,bool,address,uint,uint) {
b = true;
u = 111;
add = address(2);
//局部变量
uint c = 122;
bool g = false;
//全局变量
address send = msg.sender;
uint times = block.timestamp;
uint numer = block.number;
return (b,u,add,c,g,send,times,numer);
}
}
只读函数/纯函数
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract ViewAndPure {
uint public x = 1;
// 读取了状态变量
function addToX(uint y) public view returns (uint) {
return x + y;
}
// 没有读取状态变量
function add(uint i, uint j) public pure returns (uint) {
return i + j;
}
}
计数器合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract counter{
uint public count;
function inc() external{
count +=1;
}
function dec() external{
count -=1;
}
}
默认值
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract counter{
bool public bool_value; //false
uint public uint_value; //0
address public address_value; //0x0000000000000000000000000000000000000000
bytes32 public bytes32_value; //0x0000000000000000000000000000000000000000000000000000000000000000
}
常量
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Constants {
// coding convention to uppercase constant variables
address public constant MY_ADDRESS = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc;
uint public constant MY_UINT = 123;
}
contract Var {
// coding convention to uppercase constant variables
address public MY_ADDRESS = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc;
uint public MY_UINT = 123;
}
节省gas:部署时gas不同,写入函数去读取时区分是否是常量节省gas
结构控制/三元运算符
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract IfElse {
function foo(uint x) public pure returns (uint) {
if (x < 10) {
return 0;
} else if (x < 20) {
return 1;
} else {
return 2;
}
}
function ternary(uint _x) public pure returns (uint) {
// if (_x < 10) {
// return 1;
// }
// return 2;
// shorthand way to write if / else statement
return _x < 10 ? 1 : 2;
}
}
循环
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Loop {
function loop() public {
// for loop
for (uint i = 0; i < 10; i++) {
if (i == 3) {
// Skip to next iteration with continue
continue;
}
if (i == 5) {
// Exit loop with break
break;
}
}
// while loop
uint j;
while (j < 10) {
j++;
}
}
}
报错控制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Error {
function testRequire(uint _i) public pure {
// 退回剩余gas
require(_i > 10, "Input must be greater than 10");
}
function testRevert(uint _i) public pure {
// 退回剩余gas,复杂逻辑使用revert
if (_i <= 10) {
revert("Input must be greater than 10");
}
}
uint public num;
function testAssert() public view {
// 不退回gas
assert(num == 0);
}
// custom error
error InsufficientBalance(uint balance, uint withdrawAmount);
function testCustomError(uint _withdrawAmount) public view {
uint bal = address(this).balance;
if (bal < _withdrawAmount) {
revert InsufficientBalance({balance: bal, withdrawAmount: _withdrawAmount});
}
}
}
节省gas:revert,require 退回剩余gas
函数修改器/构造函数
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract FunctionModifier {
address public owner;
//构造函数 constructor() {
owner = msg.sender;
}
//定义函数修改器
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
//定义函数修改器
modifier validAddress(address _addr) {
require(_addr != address(0), "Not valid address");
_;
}
//使用函数修改器 function changeOwner(address _newOwner) public onlyOwner validAddress(_newOwner) {
owner = _newOwner;
}
}
Ownable合约
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Ownable{
address public owner;
constructor(){
owner = msg.sender;
}
modifier onlyOwner(){
require(msg.sender == owner, "not owner");
_;
}
function setOwner(address newOwner) external onlyOwner(){
require(msg.sender != address(0),"not address 0!");
owner = newOwner;
}
function ownerCall() external onlyOwner(){
}
function anyoneCall() external {
}
}
函数返回值
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract output{
function returnMany() public pure returns(uint ,bool){
return (1,true);
}
function returnMany1() external pure returns(uint ,bool){
return (1,true);
}
function returnMany2() external pure returns(uint x ,bool b){
return (1,true);
}
function returnMany3() external pure returns(uint x ,bool b){
x = 1;
b = true;
}
function callReturnMany() public pure returns(uint x ,bool b){
(uint x1,bool b1) = returnMany();
return (x1,b1);
}
function callReturnManyOne() public pure returns(uint x ,bool b){
(,bool b1) = returnMany();
return (x, b1);
}
function callReturnManyOne1() public pure returns(uint x ,bool b){
return returnMany();
}
}
数组
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Array{
uint[] public nums = [1,2,3];
uint[3] public numsFixed = [4,5,6];
uint public len;
function examples() external returns(uint){
nums.push(123); //[1,2,3,123]
uint x = nums[1]; // x = 2
nums[2] =999; //[1,2,999,123]
delete nums[0]; //[0,2,999,123]
nums.pop(); //[0,2,999]
len = nums.length; // len = 3
//局部变量数组必须是定长数组 不能使用push pop
uint[] memory num_memory = new uint[](10);
num_memory[1] =111;
return x;
}
function returnArray() external view returns(uint[] memory){
return nums;
}
function returnArray1() external view returns(uint){
return nums[1];
}
}
数组删除元素通过移动位置
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract deleteArray1{
uint[] public nums = [ 1,2,3,4,5,6];
function remove(uint _index) public {
require(_index<nums.length,"_index out of bound");
//指定位置后的元素左移一位然后弹出最后一个元素
for (uint i = _index;i<nums.length -1 ;i++){
nums[i] = nums[i+1];
}
nums.pop();
}
function setNums(uint[] memory input) external {
nums = input;
}
function test() external view returns(uint[] memory arr){
arr = nums;
}
}
删除数组元素通过替换
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract deleteArray2 {
uint256[] public nums = [1, 2, 3, 4, 5, 6];
function remove(uint256 _index) public {
require(_index < nums.length, "_index out of bound");
nums[_index] = nums[nums.length - 1];
nums.pop();
}
function test() external view returns (uint256[] memory arr) {
arr = nums;
}
}
映射(字典)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
contract Mapping {
// Mapping from address to uint
mapping(address => uint) public myMap;
function get(address _addr) public view returns (uint) {
// Mapping always returns a value.
// If the value was never set, it will return the default value.
return myMap[_addr];
}
function set(address _addr, uint _i) public {
// Update the value at this address
myMap[_addr] = _i;
}
function remove(address _addr) public {
// Reset the value to the default value.
delete myMap[_addr];
}
}
contract NestedMapping {
// Nested mapping (mapping from address to another mapping)
mapping(address => mapping(uint => bool)) public nested;
function get(address _addr1, uint _i) public view returns (bool) {
// You can get values from a nested mapping
// even when it is not initialized
return nested[_addr1][_i];
}
function set(
address _addr1,
uint _i,
bool _boo
) public {
nested[_addr1][_i] = _boo;
}
function remove(address _addr1, uint _i) public {
delete nested[_addr1][_i];
}
}
映射迭代
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract IterableMapping{
mapping(address => uint) public balances;
mapping(address => bool) public inserted;
address[] public keys;
function set(address _key,uint val) external {
balances[_key] = val;
if(!inserted[_key]){
inserted[_key] = true;
keys.push(_key);
}
}
function get(uint _index) external view returns(uint){
require(_index<keys.length,"out of bound keys");
return balances[keys[_index]];
}
function getSize() external view returns(uint){
return keys.length;
}
}
结构体
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract structs{
struct Car {
string model;
uint year;
address owner;
}
Car public car;
Car[] public cars;
mapping(address => Car[]) public carsByOwner;
function temp1() external {
Car memory toyota = Car("Toyota",1990,msg.sender);
Car memory audi = Car({model:"audi",year:1919,owner:msg.sender});
Car memory tesla;
tesla.model = "Tesla";
tesla.year = 2020;
tesla.owner = msg.sender;
cars.push(toyota);
cars.push(audi);
cars.push(tesla);
cars.push(Car("ferrari",2020,msg.sender));
carsByOwner[msg.sender] = cars;
}
function test() external{
Car storage _car = cars[0];
_car.year = 2101;
delete _car.owner;
delete cars[1];
}
}
枚举
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
contract Enum {
//枚举实际显示的是数字索引 默认值是0
enum Status {
None,
Pending,
Rejected,
Canceled
}
Status public status;
struct Order{
address buyer;
Status status;
}
Order[] public orders;
function get() external view returns(Status){
return status;
}
function set(Status _status) external {
status = _status;
}
function cancel( ) external {
status = Status.Canceled;
}
function reset( ) external {
delete status;
}
function test( ) external {
orders.push(Order(msg.sender,Status.Pending));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)