以所有者身份调用Solidity智能合约触发权限报错排查
问题原因
- 首先是测试时的认知偏差:你合约里的
GetAdmin函数返回的是合约存储的部署者地址Owner,根本不是本次调用的发起地址msg.sender。你看到返回值和你的账户地址一致,只能证明合约部署时确实把你设成了所有者,完全不能证明调用请求的msg.sender是你的账户。 - 核心故障点:所有不上链的本地模拟调用(也就是调用
view/pure函数时默认发的eth_call请求),如果调用方没有显式指定from(交易发送方)参数,节点会默认把msg.sender设为零地址0x0000000000000000000000000000000000000000。不管是你用的NethereumCallAsync方法,还是MyEtherWallet的默认调用配置,你都没手动指定发送方地址,所以实际执行时msg.sender是零地址,和你存储的Owner地址不匹配:- 带
require权限校验的GetNumOne、GetNumTwo直接触发预设的权限报错 - 走
if/else判断的GetNumThree走到else分支返回2 - 完全不依赖
msg.sender的纯函数GetNumFour不受影响,正常返回2
- 带
修复方法
- 可以先加个辅助函数快速验证问题,调用后你会发现返回值是零地址,直接实锤判断:
function GetCaller() public view returns(address) { return msg.sender; } - 修复Nethereum端调用代码,调用
CallAsync时显式传入你的账户地址作为发送方参数:var _result = await _function.CallAsync<int>(from: _account.Address); - 用MyEtherWallet、Remix等可视化工具交互时,在函数调用面板找到「发送方地址/From」选项,手动选中你的所有者账户地址后再发起调用即可。
内容的提问来源于stack exchange,提问作者NGDeveloper
相关产品推荐
相关产品推荐

