type
status
date
slug
summary
tags
category
icon
password
🚩 uint
在 solidity 中,uint 是 uint256 的别称。如果只写 uint,那么编译器会把它理解为 uint256。
uint256 的取值范围是 0~2^256-1。
在以太坊虚拟机 EVM 中,uint256 是最高效的类型之一,因为 EVM 以 256 位(32 字节)为单位操作数据。使用更小的类型,在某些情况下可能不会节省 Gas,因为 EVM 仍会将其填充到 32 字节。
🚩 solidity 中变量的存储方式
在 solidity 中,变量的存储方式一共有 3 种:
1️⃣:storage(存储)
- 永久存储在链上
- 状态变量默认存储在storage中
- 修改storage会消耗较多的 gas(因为这样会永久改变区块链状态)
2️⃣:memory(内存)
- 临时存储,仅在函数执行期间存在
- 函数参数和局部变量默认使用 memory
- 操作 memory 消耗的 gas 较少
3️⃣:calldata
- 类似于 memory,但是专门用于函数参数
- 不可修改 immutable
- 通常用于外部函数调用的参数
🚩 动态数组的优势
动态数组可以灵活的存储和管理结构化数据,相比单独声明多个变量,使用数组更节省存储空间,从而节省 gas
🚩 函数内的变量
习惯上,函数里的变量都用
_作为开头,用来区分全局变量,但也不是硬性规定。🚩 solidity 的函数修饰符
函数的修饰符用于控制函数的可见性和行为,主要是下面的几种:
- 可见性修饰符
- public:函数可以被外部合约、内部合约和外部交易调用
- private:函数只能在合约内部调用,子合约和外部合约均无法访问,习惯性的在 private 函数名字前面加上
_ - internal:函数可以在当前合约和继承它的子合约中调用,但外部合约无法调用
- external:函数只能被外部合约或交易调用,不能在当前合约内部直接调用(除非使用 this.funcName( ))
为了安全性,优先使用
private 或 internal,仅在需要的时候开放为 public 或 external- 状态可变性修饰符
- view:函数承诺不会修改状态(仅读取数据)
- pure:函数承诺既不读取也不修改状态(仅计算)
- payable:函数可以接受 ETH(默认情况下函数会拒绝 ETH)
- 其他修饰符
- virtual:允许函数在子合约中被重写(用于继承)
- override:表示函数重写了父合约中的虚函数
🚩 msg.sender
在 solidity 中,功能执行始终需要从外部调用者开始。一个合约只会在区块链上什么都不做,除非有人从外部调用其中的函数。所以,
msg.sender 总是存在的。🚩 接口
接口的核心思想,接口定义【做什么】,合约实现【怎么做】:
- 接口就像是功能说明书,只定义了有哪些函数
- 接口本身不实现任何功能
- 其他合约按照说明书来实现功能
接口的基本定义:
实现接口的合约:
接口的特性:
- 只能声明函数,不能实现函数
- 所有的函数都是 external,不能是private/public/internal
- 不能定义状态变量
- 不能定义构造函数
🚩 接口的简单调用示例
先定义一个简单的接口:
使用:
上面的这句代码可以这样理解:
NumberInterface接口类型
numberContract变量名称,是一个合约引用,是指向某个已部署合约的“指针”
NumberInterface(NumberInterfaceAddress)这是关键部分,它做了3 件事:- 类型转换,把address 类型转为NumberInterface 类型
- 合约绑定,告诉 solidity,这个地址对应的合约实现了NumberInterface 接口
- 创建引用,创建了一个可以调用目标合约函数的引用
numberContract = ...把合约函数的引用存储到变量中,后续可以通过调用这个变量实现对目标合约函数的调用
🚩 字符串比较
在 solidity 中,比较字符串,需要比较他们的 keccak256哈希码:
🚩 关于 ABI
ABI 的全称是 Application Binary Interface,是智能合约的说明书,它定义了:
1️⃣ 如何与合约交互
- 哪些函数可以调用
- 每个函数需要什么参数
- 函数会返回什么
2️⃣ 如何解析原始区块链数据
- 如何解码交易输入数据
- 如何解析事件日志
- 如何理解合约状态
看几个示例:
- 函数调用
这个示例告诉 web3:
- 调用函数
transfer的时候,需要传递什么参数
- 如何将这些参数编码成区块链能理解的二进制格式
- 事件解析
这个示例告诉 web3:
- 如何识别区块链中的 Transfer 事件
- 将二进制日志数据解码为可读格式
- 跨系统通信协议
- 前端 DApp 与 区块链
- 合约与合约
- 开发工具与区块链

总结:ABI 是由 solidity 编译器产生的,连接人类可读代码和 EVM二进制世界,供所有需要与合约交互的系统使用。
🚩 智能协议的永固性
虽然 solidity 长得很像 JavaScript,但是DApp跟普通的 App 有着天壤之别。
当你把智能协议上传到以太坊之后,它就变得不可更改,这种永固性意味着你的代码永远不可能被调整和更新。
你编译的程序会一直、永久的、不可更改的存在与以太坊上。
即便是你的智能协议有漏洞,你也没办法修补,只能让用户放弃这个协议,转移到新的协议上去。但这也是智能合约的一大优势,代码说明一切。
🚩 函数修饰符
修饰符是solidity 中非常重要的概念,它就像是给函数加上的“过滤器”或者是“插件”,可以在函数执行前后添加额外的逻辑。
solidity 中的主要修饰符有可见性修饰符、状态可变性修饰符、自定义修饰符。
可见性修饰符:
修饰符 | 通俗比喻 | 作用 |
public | 公共区域 | 谁都可以访问 |
private | 你的卧室 | 只有你可以进入 |
internal | 你的家 | 只有你和家人可以进入 |
external | 对外办事窗口 | 只有从外部可以进入 |
pure | 心算 | 不需要任何外部信息 |
view | 只看菜单但是不点菜 | 只获取信息 |
payable | 收银台 | 可以收费 |
自定义修饰符 | 自己设置的检查制度 | 符合要求才能进入 |
自定义修饰符:
修饰符执行顺序,当多个修饰符叠加时,按照从右往左,从下到上的顺序执行:
自定义修饰符的最佳实践:
- 语义化命名,onlyOwner比 check1 要好
- 修饰符应该简洁,避免过长的逻辑
- 谨慎使用后置逻辑,避免造成理解困难
- 组合使用,多个简单修饰符组合比一个复杂的修饰符要好
🚨 常见错误
- 遗忘
_;导致函数体永不执行
- 修饰符顺序错误
function test() payable onlyOwner {},这里应该把onlyOwner放在前面
- Author:web3a8
- URL:http://preview.tangly1024.com/article/26ac4e82-97f6-8050-abe4-d0e88126b98f
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!




