1. 提问 function retrieve() public view returns (uint256){
return number;
}
我在看 solidity solidity 的代码我有个疑问就是 这个 public 还能理解表示公有函数,那么这个 view 和 这个 returns 都是什么作用呢
view 作用是告诉函数为只读的状态,这样可以节省gas费用
returns(uint256)
对比 pure
view:可读取状态变量,但不能修改。
pure:既不能读取也不能修改状态变量(仅使用输入参数和常量)。
定义返回值类型
returns 用于声明函数的输出参数类型和名称(可选)。语法为:
returns (<类型> [参数名])
多返回值支持
可返回多个值,用逗号分隔:
function getData() public view returns (uint256, bool) {
return (number, isActive);
}
modifier isOwner 的使用
require 的参数含义
在代码 require(msg.sender == owner, "Not the owner") 中:
第一个参数:布尔条件,若为 false 则触发回滚。
第二个参数:错误信息(可选),交易回滚时返回给调用方。
此处的 require 用于确保只有合约部署者(owner)能调用 update_account 函数,否则抛出错误
_; 下划线的核心作用
执行标记
_; 表示原始函数体的插入位置。例如:
复制
modifier isOwner() {
require(msg.sender == owner, "Not the owner");
_; // 在此处执行被修饰函数的代码
}
若将 _; 放在 require 前,则先执行函数体,再验证权限(通常不符合预期)
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract exampleModifier {
address public owner;
uint256 public account;
constructor() {
owner = msg.sender;
account = 0;
}
modifier isOwner() {
require (msg.sender == owner, "Not the owner");
_;
}
function update_account (uint256 _account) public isOwner{
account = _account;
}
}
原代码
每次测试的时候都要删除和重新部署

提问
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract exampleEvent {
event Deposit(address _from, string _name, uint256 _value);
function deposit(string memory _name) public payable {
emit Deposit(msg.sender, _name, msg.value)
}
}
首先我有个问题就是 这个 Deposit 的参数怎么这么怪 是 string memory 类型 参数只有一个 _name 然后这个 public payable 是干什么用的
首先一个点 事件和函数不能够重名
payable 允许函数接收 ETH,未标记时附带 ETH 的交易会失败
memory 声明参数存储位置,避免直接操作合约存储(节省 Gas) 区块链日志层是免费的,这个非常好,然后log的值在remix的log可以看见, 这个在调试阶段的话就很赞
关于后端抓取的问题
contract.on("Transfer", (from, to, value) => {
console.log(`Transfer: ${value} from ${from} to ${to}`);
});
这是 ethers.js 的监听方法,批量监听它这边推荐使用 WebSocket (WSS)
通过 WebSocket (WSS) 长连接实时接收节点推送的事件,无需主动轮询。这是 ethers.js 和 web3.js 的标准做法。
但是要一个私有的RPC节点去租也行买也行,需要一个节点服务
const provider = new ethers.providers.WebSocketProvider('wss://your-rpc-node');
const contract = new ethers.Contract(contractAddress, abi, provider);
// 监听事件(自动处理实时推送)
contract.on("Transfer", (from, to, value) => {
console.log(`Transfer: ${value} from ${from} to ${to}`);
});
这是它给的监听思路。
优势:低延迟、低资源消耗(节点推送而非轮询)
劣势:需要稳定 WSS 连接,网络波动可能导致中断




提问
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.2 <0.9.0;
contract enumExample {
enum Status { OFF, ON }
Status status;
function getStatus() view external returns (Status) {
return status;
}
function setStatus(Status _status) external {
status = _status;
}
}
这个问题 这个 view external 是什么意思, 然后就是 下面的这个 setStatus 这个set 函数为什么不用return
setStatus 為何不需要返回值?
在 Solidity 中,狀態修改函數(如 setStatus)通常不需要返回值,原因包括:
交易性質
當外部調用 setStatus 時,這會產生一個交易並消耗 Gas。交易本身會記錄狀態變化,無需額外返回值確認
設計慣例
設置函數(Setter)的標準做法是專注於修改狀態,若需確認操作是否成功,應改用 require 或 assert 進行條件檢查
一、無 view 修飾符的影響
Gas 消耗
若函數實際僅讀取狀態但未聲明 view,調用時會額外消耗 Gas(Solidity 會將其視為可能修改狀態嘅函數,觸發完整交易檢查)
例如:若 getBalance() 函數未加 view,外部調用需支付 Gas 費用;加上 view 後,外部調用可免 Gas 費用
編譯報錯
若函數嘗試修改狀態但未聲明 view 或 pure,不會直接報錯
但若錯誤聲明為 view 或 pure(例如函數內修改狀態),則編譯器會報錯
二、無 external 修飾符的影響
Gas 效率
若函數參數為數組或複雜類型,使用 public 會自動複製參數到內存(memory),而 external 可直接從 calldata 讀取,public 會消耗更多 Gas
例如:function updateList(uint[] list) public 比 external 版本多耗 Gas
調用限制
external 函數無法在合約內部直接調用(需通過 this.func()),若誤用 public 則可能增加內部調用風險
此類錯誤不會報錯,但可能導致邏輯問題或 Gas 浪費
所以调用状态是必须得


Solidity的函数和状态变量有四种可见性:public、private、internal和external。internal表示函数只能在当前合约或继承合约中调用,不能从外部访问。
virtual
“virtual”的用法。比如,父合约中的函数如果标记为virtual,那么子合约可以使用override来重写它。同时,Solidity可能还要求重写函数必须明确使用override修饰符,以确保代码的清晰性和安全性。
文章采用 知识共享署名 4.0 国际许可协议 进行许可,转载时请注明原文链接。