如何通过ChainLink自动化调用需管理员地址权限的智能合约函数?
如何用ChainLink自动化调用要求指定msg.sender的合约函数?
当然可以实现,核心思路是调整合约的权限逻辑,让ChainLink自动化的注册表合约地址获得调用权限。下面针对你给出的合约示例,提供两种可行方案:
方案1:扩展权限修饰器,允许ChainLink注册表地址调用
直接修改原合约的权限验证逻辑,让pay函数同时接受管理员和ChainLink注册表地址的调用:
mapping(address => uint256) private _balance; address public admin; address public chainlinkRegistry; // 存储ChainLink自动化的注册表地址 // 部署合约时传入对应网络的ChainLink注册表地址 constructor(address _chainlinkRegistry) { admin = msg.sender; chainlinkRegistry = _chainlinkRegistry; } // 修改权限修饰器,允许管理员或ChainLink注册表地址调用 modifier onlyAuthorized() { require(msg.sender == admin || msg.sender == chainlinkRegistry, "Unauthorized"); _; } // 原pay函数改用新的修饰器 function pay(address _account, uint256 _amount) public onlyAuthorized { _balance[_account] += _amount; } function getBalance(address _account) public view returns(uint256) { return _balance[_account]; }
部署合约时,你需要传入对应区块链网络的ChainLink自动化注册表地址(不同网络地址不同,比如Sepolia测试网、以太坊主网各有专属地址)。注册UpKeep时,直接将调用目标设为pay函数,并传入目标账户和金额参数即可。
方案2:新增专用的自动化调用函数
如果不想改动原pay函数的权限逻辑,可以新增一个仅允许ChainLink注册表地址调用的函数,直接执行余额更新逻辑:
mapping(address => uint256) private _balance; address public admin; address public chainlinkRegistry; constructor(address _chainlinkRegistry) { admin = msg.sender; chainlinkRegistry = _chainlinkRegistry; } modifier onlyAdmin { require(msg.sender == admin, "Only admin"); _; } // 新增仅允许ChainLink调用的修饰器 modifier onlyChainLink() { require(msg.sender == chainlinkRegistry, "Only ChainLink"); _; } // 原pay函数保持原有权限 function pay(address _account, uint256 _amount) public onlyAdmin { _balance[_account] += _amount; } // 供ChainLink自动化调用的专用函数 function autoPay(address _account, uint256 _amount) public onlyChainLink { _balance[_account] += _amount; } function getBalance(address _account) public view returns(uint256) { return _balance[_account]; }
这种方案下,注册UpKeep时要把调用目标设为autoPay函数,传入对应的账户和金额参数即可,原pay函数依然仅对管理员开放。
内容的提问来源于stack exchange,提问作者sam
相关产品推荐
相关产品推荐

