unchecked

在 Solidity 0.8.0 及以上版本中,引入了一个新的关键字 unchecked。在 unchecked 块中,算术运算将不会进行溢出检查,这意味着如果结果超过了类型的最大值,它将回滚到类型的最小值,反之亦然。

这是一个使用 unchecked 的例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract UncheckedExample {
    function add(uint256 x, uint256 y) external pure returns (uint256) {

        // gas: 949
        return x + y;

        // // gas: 770
        // unchecked {
        //     return x + y;
        // }
    }

    function overflow() public pure returns (uint256) {
        uint256 max = type(uint256).max;
        // gas: 329
        // 1
        unchecked {
            return max + 2;
        }
    }

    function underflow() public pure returns (uint256) {
        uint256 min = type(uint256).min;

        // gas: 372
        // 115792089237316195423570985008687907853269984665640564039457584007913129639935
        unchecked {
            return min - 1;
        }
    }
}

在这个例子中,overflow 函数返回的结果将是 0,因为 uint 类型的最大值加 1 将回滚到 0。同样,underflow 函数返回的结果将是 uint 类型的最大值,因为 uint 类型的最小值减 1 将回滚到 uint 类型的最大值。

需要注意的是,unchecked 关键字只影响其块内的算术运算。在 unchecked 块外的算术运算仍然会进行溢出检查。因此,你应该只在你确定溢出不会导致问题的情况下使用 unchecked 块。

此外,unchecked 块也可以嵌套。在嵌套的 unchecked 块中,算术运算仍然不会进行溢出检查。

assembly

在Solidity中,assembly关键字用于引入一段内联汇编代码。内联汇编可以让你直接编写EVM(以太坊虚拟机)的汇编语言代码,这可以让你实现一些Solidity本身不支持的底层操作,或者优化你的代码以减少gas消耗。

以下是一个使用assembly关键字的例子:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.25;

contract AssemblyExampl {
    function assemblyExample() public pure returns (uint256 _ret) {
        assembly {
            _ret := add(1, 2)
        }
    }
}

在这个例子中,我们使用内联汇编来计算1+2的结果。add是EVM的一个汇编指令,它从栈顶取出两个元素,将它们相加,然后将结果放回栈顶。

使用assembly关键字,你可以直接编写EVM(以太坊虚拟机)的汇编语言代码,这可以让你实现一些Solidity本身不支持的底层操作。以下是一些例子:

  1. 直接访问存储:在Solidity中,你不能直接访问存储的特定位置。但在汇编中,你可以使用sloadsstore指令来直接读写存储。
  2. 更低级别的跳转:Solidity的控制流语句(如iffor等)在编译后会转换为EVM的跳转指令。在汇编中,你可以直接使用这些跳转指令,实现更复杂的控制流。
  3. 访问特定的系统操作码:EVM有一些系统操作码,如gasblockhashdifficulty等,这些在Solidity中无法直接访问,但在汇编中可以。
  4. 优化代码以减少gas消耗:有时,你可以通过直接编写汇编代码,绕过Solidity的一些抽象,来优化你的代码以减少gas消耗。

需要注意的是,虽然使用汇编可以实现更底层的操作,但它也更容易出错,而且对于阅读和理解代码的人来说,它也更难理解。因此,除非有必要,否则一般不建议在Solidity代码中直接使用汇编。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特