VueBloghyhero6

remix 学习基础零散

2025-05-10 / 2025-05-10 / 43次浏览
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修饰符,以确保代码的清晰性和安全性。