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

Solidity智能合约基础

基础学习使用

remix:ide

Remix - Ethereum IDE

evm:ethreum  virtual machine  evm字节码

强类型脚本语言   compile  =>evm  bytescode =>evm

hello的样例

声明的关键字:contract

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
//pragma solidity ^0.8.0;//大于8.0版本
//pragma solidity >=0.8.0 <0.9.0;//大于等于8.0版本,小于9.0版本contract helloDto {string public  hello="hello 3.0";
}

一、EVM 的数据结构

  • 基于栈的架构:EVM 使用栈来存储数据,最大支持 1024 个栈元素,每个元素是 256 位的字(word),所有计算都在栈上完成。

  • 三类存储结构:

    1. 程序代码存储区(ROM)(栈):1024个solt,每个solt是32个字节>=256bit,不可变,存储智能合约的字节码。
    2. 内存(Memory):可变,临时存储执行期间的数据,随调用结束而清除。
    3. 存储(Storage):持久化存储,每个智能合约都有一个唯一的存储区,存储合约状态。

二、 EVM 中的两种值类型

  • 基本类型(Value Types)

    • 定义:直接存储值的数据类型,变量之间赋值是复制值本身。
    • 常见类型uintintbooladdressbytes1 到 bytes32
    • 存储特性
      • 分配在固定的 storage slot
      • 赋值是值复制(copy by value)
  • 引用类型(Reference Types)

    • 定义:存储的是对数据的“引用”或“指针”,赋值传的是地址。

    • 常见类型array(数组),mapping(映射),struct(结构体)

    • 存储特性

      • 变量本身保存的是对实际数据的引用

      • 赋值是引用复制(copy by reference)

      • 需要 keccak256(slot) 来定位实际数据地址(尤其是动态结构)

evm特性

交易流程图

1. 用户发起交易|↓
2. 创建新的 EVM 实例|↓
3. 加载合约字节码|↓
4. 分配 Stack 空间(1024 slots)|↓
5. 执行合约代码|↓
6. 更新区块链状态(如果需要)|↓
7. 销毁 EVM 实例

详细说明

  1. 用户发起交易

    • 用户签名交易
    • 设定 gas limit 和 gas price
    • 指定目标合约地址和调用数据
  2. 创建新的 EVM 实例

    • 为每笔交易创建独立的 EVM 环境
    • 初始化执行上下文
    • 准备内存和存储空间
  3. 加载合约字节码

    • 从区块链状态中读取合约字节码
    • 将字节码加载到 EVM 中
    • 准备执行环境
  4. 分配 Stack 空间

    • 分配 1024 个 slots
    • 每个 slot 256 位
    • 用于存储临时计算结果
  5. 执行合约代码

    • 逐条执行操作码
    • 进行状态检查和 gas 计算
    • 处理函数调用和返回值
  6. 更新区块链状态

    • 写入存储变更
    • 更新账户余额
    • 触发事件日志
  7. 销毁 EVM 实例

    • 清理内存
    • 释放资源
    • 返回执行结果

注意事项

  • 整个过程是原子性的:要么全部成功,要么全部失败
  • Gas 限制贯穿整个执行过程
  • 状态变更只在交易成功执行后才会提交

EVM 存储结构

1. Stack (栈)
+----------------+
| 基本类型的值    | <- 函数内的局部变量
| 引用的地址      | <- 指向其他存储位置
+----------------+2. Memory (内存)
+----------------+
| 临时数据       | <- 函数执行期间的临时数据
| 函数参数       | <- memory 类型的参数
| 返回数据       | <- 函数返回值
+----------------+3. Storage (存储)
+----------------+
| 状态变量       | <- 合约的永久存储数据
| 映射数据       | <- mapping 数据
| 数组数据       | <- storage 数组
+----------------+

EVM Stack (固定大小的栈空间)

+------------------+
|     空闲空间     | <- 1024 个槽位(slots)
|        ⬇        |    每个槽位 32 字节(256 位)
+------------------+
|    当前使用空间   | <- 随函数执行压入/弹出
+------------------+

Memory: 存在于 EVM 执行环境中 临时性的,交易执行完就清除 线性寻址(0x00, 0x20, 0x40...)

Storage: 存在于区块链状态中 永久性的,写入区块 使用 slot 和 keccak256 哈希定位

基本类型

在 Solidity 中,直接存储在栈(Stack)中的基本类型包括:

1. 整型(Integer)

contract StackTypes {function integerTypes() public pure {// 所有整型都存储在栈中uint256 a = 1;uint8 b = 2;int256 c = -1;int8 d = -2;}
}
2. 布尔型(Boolean)

function booleanTypes() public pure {bool isTrue = true;bool isFalse = false;
}
3. 地址(Address)

function addressTypes() public pure {address addr = 0x123...;address payable payableAddr = payable(0x123...);
}
  1. 固定大小字节数组(Fixed-size Bytes)
function bytesTypes() public pure {bytes1 b1 = 0x12;bytes32 b32 = 0x123...;
}
  1. 枚举(Enum)
enum Status { Active, Inactive }function enumTypes() public pure {Status status = Status.Active;  // 实际存储为 uint8
}

重要说明:

  1. 这些类型在函数(相关文档:数据位置修饰符)调用时:
  • 作为参数传递时是值传递
  • 不需要指定 memory 等位置修饰符
  // ✅ 正确:不需要 memoryfunction example(uint256 num, bool flag, address addr)public pure {// ...}// ❌ 错误:不能为基本类型指定 memoryfunction wrong(uint256 memory num) public pure {// ...}
  1. 大小限制:
function stackLimits() public pure {// EVM 栈深度限制为 1024// 每个值占用一个栈槽(32字节)
}
  1. 与引用类型对比:
contract TypeComparison {// 基本类型:直接存储在栈中uint256 public stackVar = 123;// 引用类型:存储引用在栈中,数据在其他位置string public stringVar = "hello";  // 数据在存储中uint256[] public arrayVar;          // 数据在存储中
}
  1. 在函数(文档地址:数据位置修饰符)中的使用:
contract StackUsa
http://www.lryc.cn/news/610779.html

相关文章:

  • 单目云台双摄像头配置双摄像头的优势
  • 深入理解 Android SO 导出符号:机制与安全优化
  • Spring 的优势
  • 应急响应排查思路
  • 市场与销售协同:CRM如何打破部门数据孤岛?
  • 8.5 CSS3多列布局
  • 深入解析RNN神经网络原理与应用
  • GitCode新手使用教程
  • RabbitMQ面试精讲 Day 11:RabbitMQ集群架构与节点类型
  • 人工智能之数学基础:利用全概率公式如何将复杂事件转为简单事件
  • 大模型|极简说清“数据并行”
  • AcWing 3690:求交点 ← 复旦大学考研机试题 + 克莱姆法则
  • 嵌入式开发学习———Linux环境下IO进程线程学习(四)
  • Python爬虫09_Requests用bs4进行数据解析
  • selenium自动化收集资料
  • linux服务器上word转pdf后乱码问题
  • In-memory不要全加载怎么做?
  • 基于LDA主题的网络舆情与情感分析——以云南某景区话题为例
  • 本机部署K8S集群
  • 基于k8s环境下的pulsar常用命令(上)
  • mq_open系统调用及示例
  • ubutnu20.04更新源报错:E:...签名不再生效
  • C语言学习笔记——动态内存分配
  • 备忘录记事本 任务清单 html
  • 手动开发一个TCP服务器调试工具(一):基础知识与核心类接口
  • HTML 如何转 Markdown
  • 【qt5_study】2.使用Qt Designer构造UI界面(信号与槽)
  • 16核32G硬件服务器租用需要多少钱
  • 工业级 CAN 与以太网桥梁:串口服务器CAN通讯转换器深度解析(下)
  • 前端实用工具方法 —— 持续更新中...