You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Solidity ^0.8.7中含mapping的Struct构造报错如何解决?

问题根因

Solidity从0.7.0版本开始收紧了包含mapping的结构体的初始化规则:mapping是仅能存在于storage的引用类型,无法在memory空间构造完整的结构体实例,所以不再支持用结构体字面量直接初始化包含mapping的结构体,你之前的旧版本代码能编译是因为旧语法对这类操作的约束更宽松。

修复方案

不需要修改结构体定义,仅需调整submitTransaction函数的初始化逻辑:

  1. 先给transactions数组push一个空结构体实例,拿到新插入元素的storage引用
  2. 再给这个storage引用的非mapping字段逐个赋值即可,mapping字段会默认初始化为所有取值对应类型默认值(这里就是所有地址对应的bool值都为false)

修改后的代码如下:

function submitTransaction (address _to, uint _value, bytes memory _data) public onlyOwner{
    uint txIndex = transactions.length;
    // 先push空结构体,获取storage位置的新交易引用
    transactions.push();
    Transaction storage newTx = transactions[txIndex];
    // 逐个赋值非mapping字段
    newTx.to = _to;
    newTx.value = _value;
    newTx.data = _data;
    newTx.executed = false;
    newTx.numConfirmations = 0;
    
    emit SubmitTransaction(msg.sender, txIndex, _to, _value, _data);
}
补充注意事项
  • 包含mapping的结构体只能声明为storage类型的变量,不能用memory/calldata类型承载
  • 后续操作结构体中的isConfirmed字段时,直接通过storage引用读写即可,示例:
// 确认交易的代码示例
function confirmTransaction(uint txIndex) public {
    Transaction storage targetTx = transactions[txIndex];
    require(!targetTx.isConfirmed[msg.sender], "已确认过该交易");
    targetTx.isConfirmed[msg.sender] = true;
    targetTx.numConfirmations += 1;
}

内容的提问来源于stack exchange,提问作者Lcob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 12:24:08