Solidity ^0.8.7中含mapping的Struct构造报错如何解决?
问题根因
Solidity从0.7.0版本开始收紧了包含mapping的结构体的初始化规则:mapping是仅能存在于storage的引用类型,无法在memory空间构造完整的结构体实例,所以不再支持用结构体字面量直接初始化包含mapping的结构体,你之前的旧版本代码能编译是因为旧语法对这类操作的约束更宽松。
修复方案
不需要修改结构体定义,仅需调整submitTransaction函数的初始化逻辑:
- 先给
transactions数组push一个空结构体实例,拿到新插入元素的storage引用 - 再给这个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
相关产品推荐
相关产品推荐

