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,然后自己写函数来暴露需要的数据:
- 先把状态变量改成内部可见:
mapping(uint256 => ProposalVote) internal bravoProposals;
- 给结构体里的普通字段写个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); }
- 针对结构体里的
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
相关产品推荐
相关产品推荐

