Solidity:assembly

news/2025/1/23 17:32:12/文章来源:https://www.cnblogs.com/lianshuiwuyi/p/18291837

在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代码相对困难,应确保充分测试。

孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741146.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8s 驱逐场景以及规避方案

Pod 驱逐场景总结从一个 SRE 角度看, Pod 驱逐分为两种情况:较安全驱逐 & 提高稳定性的良性驱逐API 发起驱逐,典型案例:kubectl drain Node Not Ready 时,Controller Manager 发起的驱逐有风险的驱逐节点压力驱逐节点磁盘空间不足、内存不足 或 Pid 不足, kubelet 发…

[二、状态管理]1状态管理概述

在前文的描述中,我们构建的页面多为静态界面。如果希望构建一个动态的、有交互的界面,就需要引入“状态”的概念。 图1 效果图上面的示例中,用户与应用程序的交互触发了文本状态变更,状态变更引起了UI渲染,UI从“Hello World”变更为“Hello ArkUI”。 在声明式UI编程框架…

lazarus 项目用到的控件

官网 https://www.lazarus-ide.org/ 基本上都是原生插件,能同时满足WINDOWS和Linux下开发 用到的控件

设置npm的registry几种方法

https://www.cnblogs.com/luludehuhuan/p/8017014.html相信坚持的力量,日复一日的习惯.

Etcd 高可用故障演练

目的 本次演练旨在测试 Kubernetes 的 etcd 高可用性,检验是否能够在其中一个 etcd 节点发生故障的情况下,其他 etcd 节点能够接管其工作,确保集群仍能正常运行。 集群架构演练场景 在一个三节点的 Kubernetes 集群中,我们将模拟其中一个 etcd 节点的故障,观察剩余的 etcd…

会计工作的关键一步——用免费可视化工具制作财务报表

会计工作中,关键一步就是把那些繁杂的财务数据整理成清晰易懂的财务报表,这就像是把一堆拼图块变成一幅完整的图画。山海鲸可视化这款免费工具,支持实时数据刷新,能够随时随地更新你的财务数据,确保你拿到的永远是最新鲜的“出炉”数据。操作也非常简单,零代码拖拽式界面…

JVM是如何创建一个对象的?

1. Java对象创建的流程是什么样? 2. JVM执行new关键字时都有哪些操作? 3. JVM在频繁创建对象时,如何保证线程安全? 4. Java对象的内存布局是什么样的? 5. 对象头都存储哪些数据?哈喽,大家好🎉,我是世杰。 本文我为大家介绍面试官经常考察的「Java对象创建流程」照例在…

Kubernetes-Master 基准测试

背景 Kubernetes是容器集群管理系统,为容器化的应用提供资源调度、部署运行、滚动升级、扩容缩容等功能。容器集群管理给业务带来了便利,但是随着业务的不断增长,应用数量可能会发生爆发式的增长。那在这种情况下,Kubernetes能否快速地完成扩容、扩容到大规模时Kubernetes管…

硬核案例分享,一文带你拆解PHP语言体系下的容器化改造

本文介绍了PHP语言体系应用现代化案例,实现了许多与业务无关的通用性应用改造方案,如PHP应用容器化架构方案、基于Prometheus的弹性伸缩方案等等,为此类型客户提供了一个可参考的案例。本文分享自华为云社区《PHP语言体系下的容器化改造,助力夺冠集团应用现代化》,作者: …

CoreDNS 概述及运维实践

概述 什么是 DNS ? 域名系统(英语:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用TCP和UDP端口53。 DNS 不仅方便了人们访问不同的互联网服务,更为很多应用提供了,动态服务发…

从0开始装一套 KubeVirt 1.2.1

KubeVirt 架构 架构virt-api : 负责提供一些 KubeVirt 特有的 api,像是 console, vnc, startvm, stopvm 等。 virt-controller : 管理和监控 VMI 对象及其关联的 Pod,对其状态进行更新。 virt-hander : 以 DaemonSet 运行在每一个节点上,监听 VMI 的状态向上汇报,管理 VMI …

夏日狂欢,铁威马众多惊喜福利来袭,这很city!

随着618的尾声悄然落下 你是否还在为错失的优惠而扼腕叹息? 但请放下遗憾,精彩从未真正落幕。 铁威马夏日狂欢季 正是为你量身打造的专属福利时刻 众多优惠活动接踵而至 往下看⬇ 惊喜福利层出不穷 快来参与吧~ 以旧换新,焕新升级 想要换新机的朋友们,铁威马夏日狂欢季为你…