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

Solidity 0.8.9:公开映射含结构体报错,参考Compound合约存疑

为啥会报这个错?

Solidity 0.8.x 对公开状态变量的类型规则卡得更严。你要暴露的bravoProposals是个映射,值类型是包含mapping的ProposalVote结构体——但Solidity没法给这种变量自动生成合法的getter函数。因为mapping是引用类型,不能被复制或直接返回,而公开变量默认会生成返回整个值的getter,这在0.8.x里直接不允许。

Compound的GovernorBravo用的是旧版Solidity(比如0.5.16),旧版本对这种情况管得松:自动生成的getter会跳过结构体里的mapping字段,只返回其他普通值类型的内容。但就算在旧版本,这个自动生成的getter也碰不到结构体里的mapping,Compound实际上也是自己写了自定义函数来获取receipts这类映射内容的。

怎么解决?

别把这个映射设为public,改成internal或者private,然后自己写函数来暴露需要的数据:

  1. 先把状态变量改成内部可见:
mapping(uint256 => ProposalVote) internal bravoProposals;
  1. 给结构体里的普通字段写个getter:
struct ProposalVote {
    uint256 againstVotes;
    uint256 forVotes;
    uint256 abstainVotes;
    mapping(address => Receipt) receipts;
}

function getProposalVoteStats(uint256 proposalId) external view returns (uint256 against, uint256 forVotes, uint256 abstain) {
    ProposalVote storage vote = bravoProposals[proposalId];
    return (vote.againstVotes, vote.forVotes, vote.abstainVotes);
}
  1. 针对结构体里的mapping,单独写函数拿指定条目:
function getVoterReceipt(uint256 proposalId, address voter) external view returns (Receipt memory) {
    return bravoProposals[proposalId].receipts[voter];
}

这么写既符合0.8.9的语法要求,也能实现和Compound合约一样的外部访问能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:25:51