当前位置: 首页 > article >正文

<<WTF-Solidity>>学习笔记(part 9-12)

part 9 

这一讲,我们介绍Solidity中和常量相关的两个关键字,constant(常量)和immutable(不变量)。状态变量声明这两个关键字之后,不能在初始化后更改数值。这样做的好处是提升合约的安全性并节省gas

另外,只有数值变量可以声明constantimmutablestringbytes可以声明为constant,但不能为immutable

constant和immutable

constant

constant变量必须在声明的时候初始化,之后再也不能改变。尝试改变的话,编译不通过。

// constant变量必须在声明的时候初始化,之后不能改变
uint256 constant CONSTANT_NUM = 10;
string constant CONSTANT_STRING = "0xAA";
bytes constant CONSTANT_BYTES = "WTF";
address constant CONSTANT_ADDRESS = 0x0000000000000000000000000000000000000000;

immutable

immutable变量可以在声明时或构造函数中初始化,因此更加灵活。在Solidity v0.8.21以后,immutable变量不需要显式初始化,未显式初始化的immutable变量将使用数值类型的初始值(见 8. 变量初始值)。反之,则需要显式初始化。 若immutable变量既在声明时初始化,又在constructor中初始化,会使用constructor初始化的值。

part 10:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;
contract InsertionSort {
    // if else
    function ifElseTest(uint256 _number) public pure returns(bool){
        if(_number == 0){
            return(true);
        }else{
            return(false);
        }
    }

    // for loop
    function forLoopTest() public pure returns(uint256){
        uint sum = 0;
        for(uint i = 0; i < 10; i++){
            sum += i;
        }
        return(sum);
    }

    // while
    function whileTest() public pure returns(uint256){
        uint sum = 0;
        uint i = 0;
        while(i < 10){
            sum += i;
            i++;
        }
        return(sum);
    }

    // do-while
    function doWhileTest() public pure returns(uint256){
        uint sum = 0;
        uint i = 0;
        do{
            sum += i;
            i++;
        }while(i < 10);
        return(sum);
    }

    // 三元运算符 ternary/conditional operator
    function ternaryTest(uint256 x, uint256 y) public pure returns(uint256){
        // return the max of x and y
        return x >= y ? x: y; 
    }


    // 插入排序 错误版
    function insertionSortWrong(uint[] memory a) public pure returns(uint[] memory) {
        for (uint i = 1;i < a.length;i++){
            uint temp = a[i];
            uint j=i-1;
            while( (j >= 0) && (temp < a[j])){
                a[j+1] = a[j];
                j--;
            }
            a[j+1] = temp;
        }
        return(a);
    }

    // 插入排序 正确版
    function insertionSort(uint[] memory a) public pure returns(uint[] memory) {
        // note that uint can not take negative value
        for (uint i = 1;i < a.length;i++){
            uint temp = a[i];
            uint j=i;
            while( (j >= 1) && (temp < a[j-1])){
                a[j] = a[j-1];
                j--;
            }
            a[j] = temp;
        }
        return(a);
    }
}

part  11 :

构造函数

构造函数(constructor)是一种特殊的函数,每个合约可以定义一个,并在部署合约的时候自动运行一次。它可以用来初始化合约的一些参数,例如初始化合约的owner地址:

address owner; // 定义owner变量

// 构造函数
constructor(address initialOwner) {
    owner = initialOwner; // 在部署合约的时候,将owner设置为传入的initialOwner地址
}

注意:构造函数在不同的Solidity版本中的语法并不一致,在Solidity 0.4.22之前,构造函数不使用 constructor 而是使用与合约名同名的函数作为构造函数而使用,由于这种旧写法容易使开发者在书写时发生疏漏(例如合约名叫 Parents,构造函数名写成 parents),使得构造函数变成普通函数,引发漏洞,所以0.4.22版本及之后,采用了全新的 constructor 写法。

修饰器

修饰器(modifier)是Solidity特有的语法,类似于面向对象编程中的装饰器(decorator),声明函数拥有的特性,并减少代码冗余。它就像钢铁侠的智能盔甲,穿上它的函数会带有某些特定的行为。modifier的主要使用场景是运行函数前的检查,例如地址,变量,余额等。

part 12:

这一讲,我们用转账ERC20代币为例来介绍Solidity中的事件(event)。

事件

Solidity中的事件(event)是EVM上日志的抽象,它具有两个特点:

  • 响应:应用程序(ethers.js)可以通过RPC接口订阅和监听这些事件,并在前端做响应。
  • 经济:事件是EVM上比较经济的存储数据的方式,每个大概消耗2,000 gas;相比之下,链上存储一个新变量至少需要20,000 gas

声明事件

事件的声明由event关键字开头,接着是事件名称,括号里面写好事件需要记录的变量类型和变量名。以ERC20代币合约的Transfer事件为例:

event Transfer(address indexed from, address indexed to, uint256 value);

我们可以看到,Transfer事件共记录了3个变量fromtovalue,分别对应代币的转账地址,接收地址和转账数量,其中fromto前面带有indexed关键字,他们会保存在以太坊虚拟机日志的topics中,方便之后检索。

释放事件

我们可以在函数里释放事件。在下面的例子中,每次用_transfer()函数进行转账操作的时候,都会释放Transfer事件,并记录相应的变量。

// 定义_transfer函数,执行转账逻辑
function _transfer(
    address from,
    address to,
    uint256 amount
) external {

    _balances[from] = 10000000; // 给转账地址一些初始代币

    _balances[from] -=  amount; // from地址减去转账数量
    _balances[to] += amount; // to地址加上转账数量

    // 释放事件
    emit Transfer(from, to, amount);

Event.sol 在remix上的测试结果


http://www.kler.cn/a/412430.html

相关文章:

  • Rust语言俄罗斯方块(漂亮的界面案例+详细的代码解说+完美运行)
  • 卡尔曼滤波详细推导
  • [代码随想录Day24打卡] 93.复原IP地址 78.子集 90.子集II
  • 新160个crackme - 105-royalaccezzcrackme
  • 双向链表、循环链表、栈
  • 数据库(总结自小林coding)|索引失效的场景、慢查询、原因及如何优化?undo log、redo log、binlog 作用、MySQL和Redis的区别
  • 减速电机的减速比是什么意思?
  • 软件测试丨Pytest 第三方插件与 Hook 函数
  • ffmpeg 预设的值 加速
  • git源码安装
  • 集合卡尔曼滤波(EnKF)的三维滤波(模拟平面定位)例程,带逐行注释
  • Docker容器运行CentOS镜像,执行yum命令提示“Failed to set locale, defaulting to C.UTF-8”
  • mysql window安装(学习使用)
  • 数据库编程(sqlite3)
  • 深度神经网络模型压缩学习笔记二:离线量化算法和工具、实现原理和细节
  • QT入门详解,创建QT应用
  • qsort函数详解+代码展示
  • 低功耗墒情监测站产品详解 如何助力高标准农田项目发展
  • 【面试分享】C++ 中结构体(struct)和类(class)的区别
  • css3移动端布局适配
  • 在同一NAT下配置Linux机器的SSH免密登录指南(ssh-keygen、ssh-copy-id、主机名解析)
  • 【RISC-V CPU debug 专栏 5.1 -- SiFive Nexus Trace 和 Tessent Trace】
  • 大数据技术之Spark :我快呀~
  • 笔记本外接4k显示器只有30Hz刷新率
  • Vue-常用指令
  • 实战OpenCV之物体跟踪