区块链系列

solidity基础

Posted by samll_ant on March 5, 2023

SOLIDITY 基础

介绍

Solidity是一种语法类似JavaScript的高级语言。它被设计成以编译的方式生成以太坊虚拟机代码。在后续内容中你将会发现,使用它很容易创建用于投票、众筹、封闭拍卖、多重签名钱包等等的合约。

关键词

名称 作用
external 外部函数,合约内部不可调用
public 公开,合约中其它函数都可以调用
private 私有函数
internal 内部函数
pure 不操作函数外部数据,纯函数
view 可以读取全局变量
virtual 函数可以被重写
override 覆盖父合约函数
constant 大写常量不可修改,节省部分gas
returns 函数返回参数定义
memory 内存中局部变量的定义
storage 存储变量
calldata 只能用在输入参数中
immutable 成功后变为常量
payable 能够发送主币
event 事件
emit 触发事件
indexed 事件检索

错误控制

require 错误

require(i<=10,"i > 10") // 表达式+错误信息

revert 错误

revert("i > 10") // 不包含表达式直接返回错误信息

assert 错误

assert(i<=10) // 不包含错误信息

自定义错误

error MyError(string msg);  // 更节省gas
revert MyError("error string");

函数修改器 modifier

使复用代码简化

modifier func(){
    require(i<=10,"i > 10");
    _;
}

function demo() external func {
    revert("err")
}

构造函数 Constructor

只能在合约部署的时候调用

address public owner
constructor(){
    owner = msg.sender;
}

Ownable 合约

contract ownable{

    address public owner;
    
    contructor(){
        owner = msg.sender;
    }
    
    modifier onlyOwner(){
        require(msg.sender == owner, "not owner");
        _;
    }
    
    function setOwner(address _newOwner) external onlyOwner{
        require(_newOwner != address(0), "inviald address");
        owner = _newOwner;
    }
    
}

数组 array

内存中不能使用不定长数组

unit[] public nums; // 不定长数组
unit[10] public _nums; // 数组长度为3固定
nums.push(1); // 向数组添加
unit a = nums[0]; // 访问数组
nums[2] = 77; // 修改数组
delete nums[2]; // 删除数组,不改变长度
nums.pop(); // 删除数组最后一个,改变长度
uint len = nums.length; 获取数组长度

映射 mapping

键值对形式,类似json

mapping( address => uint ) public balances;
mapping( address => mapping(address => bool) ) public isFriend;
balances[msg.sender] = 123; // 写入值
uint bal = balances[msg.sender]; // 读取值
delete balances[msg.sender]; // 删除数据后返回默认值

结构体 struct

struct Car{
    string model;
    uint year;
    address owner;
}
Car public car; // 定义一个结构体
Car[] public cars; // 结构体数组
mapping(address => Car[]) public carsByOwener; // 结构体键值对
Car public myCar = Car("222",1,address(0)); 

枚举 enum

enum status{
    None,
    Pending,
    Shipped,
    Complted,
    Rejected,
    Canceled
}

合约中部署合约

contract 1{
    address public owner;
}

contract 2{
    contructor(){
        new 1();
    }
}

继承合约

contract 1{
    address public owner;
}

contract 2 is 1{ // 继承自合约1
    contructor(){
        new 1();
    }
}

回退函数 fallback 合约发送接收主币

fallback() external payable{}
recive() external payable {}

interface 接口

// 定义函数	
interface ICounter{
    function count() external view returns (uint);
}

library 库合约

library Math{
    function max(uint x,uint y) internal pure returns(uint){
        return x > y ? x : y;
    }
}

abi.encode 和 abi.encodepacked

abi.encode 在参数中补0

自毁合约

selfdesctruct(msg.sender)

节省gas

use calldata
load state variables as memory
i++ 改为 ++1
array.length 赋值为一个memory 变量
判断语句放在一起