当前位置:首页 > 其他 > 正文内容

Solidity:assembly

邻居的猫1个月前 (12-09)其他1630

在Solidity中,assembly是一个内嵌的初级语言,它答应开发者直接编写EVM(以太坊虚拟机)字节码。这种才能使得开发者能够更精密地操控智能合约的行为,并且在某些情况下能够进步功能和削减gas费用。但是,运用assembly也增加了代码的杂乱性和犯错的或许性,因而应慎重运用。

为什么运用Assembly

  1. 功能优化:某些操作运用Solidity自身或许功率不高,直接运用汇编语言能够更高效。
  2. 精密操控:供给对EVM的精密操控,能够履行一些在高档语言中无法直接完成的操作,比方精密的内存操作和特定的EVM指令。
  3. 节约Gas:在某些情况下,能够经过assembly削减合约的字节码巨细,然后削减布置本钱。

assembly 语法

assembly块能够在Solidity函数内部或外部运用,语法如下:

assembly {
    // 内嵌的初级EVM指令
}

根本示例

以下是一个简略的示例,展现如安在Solidity中运用assembly

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

contract AssemblyExample {
    function add(uint256 a, uint256 b) public pure returns (uint256 result) {
        assembly {
            result := add(a, b)
        }
    }
}

在这个示例中,咱们运用了EVM的add指令来完成两个数字的加法。

常用指令

以下是一些常用的EVM汇编指令:

  • Arithmetic Operations
    • add(x, y): 加法
    • sub(x, y): 减法
    • mul(x, y): 乘法
    • div(x, y): 除法
    • mod(x, y): 取模
  • Logical Operations
    • and(x, y): 按位与
    • or(x, y): 按位或
    • xor(x, y): 按位异或
    • not(x): 按位取反
  • Comparison
    • lt(x, y): 小于
    • gt(x, y): 大于
    • eq(x, y): 等于
    • iszero(x): 是否为零
  • Memory Operations
    • mload(p): 从内存地址p加载数据
    • mstore(p, v): 将数据v存储到内存地址p
    • mstore8(p, v): 将字节v存储到内存地址p
  • Storage Operations
    • sload(p): 从存储地址p加载数据
    • sstore(p, v): 将数据v存储到存储地址p
  • Control Flow
    • jump(label): 跳转到标签label
    • jumpi(label, condition): 条件跳转到标签label
    • stop(): 中止履行
    • return(p, s): 从内存地址p回来巨细为s的数据

高档示例

以下是一个更杂乱的示例,展现怎么运用assembly读取和写入存储:

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

contract StorageExample {
    uint256 public storedData;

    function set(uint256 x) public {
        assembly {
            sstore(0, x)
        }
    }

    function get() public view returns (uint256) {
        uint256 result;
        assembly {
            result := sload(0)
        }
        return result;
    }
}

在这个示例中,咱们运用assembly块直接操作存储方位0,然后完成对storedData变量的读写。

内联汇编中的变量

assembly块中,能够运用Solidity中的变量。以下是一个示例:

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

contract InlineAssembly {
    function multiply(uint256 a, uint256 b) public pure returns (uint256 result) {
        assembly {
            let temp := mul(a, b)
            result := temp
        }
    }
}

在这个示例中,咱们运用了let关键字界说了一个暂时变量temp,并将乘法成果存储在其间。

运用内存

assembly块中,能够直接操作内存。以下是一个示例:

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

contract MemoryExample {
    function useMemory(uint256 x) public pure returns (uint256 result) {
        assembly {
            let memPtr := mload(0x40) // 获取自在内存指针
            mstore(memPtr, x) // 将x存储在自在内存指针方位
            result := mload(memPtr) // 从自在内存指针方位读取值
        }
    }
}

在这个示例中,咱们运用了mloadmstore指令来操作内存。

调用其他函数

assembly中,能够运用call指令调用其他函数。以下是一个示例:

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

contract CallExample {
    function externalCall(address target, uint256 value) public returns (bool success) {
        bytes4 sig = bytes4(keccak256("someFunction(uint256)"));
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, sig)
            mstore(add(ptr, 0x04), value)
            success := call(gas(), target, 0, ptr, 0x24, 0, 0)
        }
    }
}

在这个示例中,咱们结构了一个函数调用的签名并运用call指令进行外部调用。

注意事项

  1. 安全性:运用assembly或许会引进安全漏洞,有必要十分慎重。
  2. 可读性assembly代码一般不易读懂和保护,应尽量削减运用。
  3. 调试:调试assembly代码相对困难,应保证充沛测验。

孟斯特

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=762

标签: Solidity学习
分享给朋友:

“Solidity:assembly” 的相关文章

Ubuntu 22.04 LTS下经过第三方apt源装置php8.3.x

Ubuntu 22.04 LTS下经过第三方apt源装置php8.3.x

原文地址:https://techvblogs.com/blog/install-php-8-3-on-ubuntu-22-04 更新体系:首要经过apt更新 Ubuntu 软件库房。sudo apt update && apt upgrade -y 增加 Ondrej Sury...

【译】为什么命名“它”为依靠特点(DependencyProperty)

【译】为什么命名“它”为依靠特点(DependencyProperty)

当咱们创立新的类和成员时,咱们花费了许多的时刻和精力是它们尽可能的好用,好了解,好发现。一般咱们会遵从.Net结构规划攻略,尤其是会不断地研讨这个新类与其他类,未来方案等内容之间的联系。 当命名依靠特点(DependencyProperty)和依靠目标(DependencyObject)的时分也是遵...

P1979 [NOIP2013 进步组] 华容道

P1979 [NOIP2013 进步组] 华容道

标题粗心 具体标题传送门 \(n\times m\) 的华容道盘,有妨碍。多组问询,每组妨碍不变。其间要将初始在 \((sx,sy)\) 的棋子移动到 \((tx,ty)\)。初始空白的方位在 \((ex,ey)\)。求至少多少次移动完结方针,无法完结输出 -1。 \(n,m\leq30,q\leq...

读数据维护:作业负载的可恢复性06备份的内容

读数据维护:作业负载的可恢复性06备份的内容

1. 误解 1.1. RAID不需求备份 1.1.1. 运用冗余磁盘体系来保存数据,并不意味着不需求备份这些数据 1.1.2. RAID所能供给的冗余都是在硬件这一层面规划的 1.1.3. 之所以不能替代备份,其间一项重要的原因就在于:RAID维护的是卷,而不是卷里边的文件体系 1.2...

一款 IDEA 必备的 JSON 处理东西插件 — Json Assistant

一款 IDEA 必备的 JSON 处理东西插件 — Json Assistant

Json Assistant 是根据 IntelliJ IDEs 的 JSON 东西插件,让 JSON 处理变得更轻松! 主要功用 彻底支撑 JSON5 JSON 窗口(多选项卡) 选项卡更名 移动至主修改器 用新窗口翻开选项卡内容 JSONPath 查询 历史记载 JSON 导出 JSON 格...

区块链开发工程师,未来科技浪潮中的关键角色

区块链开发工程师是一个涉及多个领域的职位,主要职责包括设计、开发、测试和维护基于区块链技术的软件系统。这个职位通常需要具备以下技能和知识:1. 编程语言:区块链开发工程师需要掌握至少一种编程语言,如Solidity(用于智能合约开发)、JavaScript、Python、Java等。2. 区块链技术...