首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何编写支持Chainlink功能的代理和实现契约(Proxy模式通过DELEGATECALL Solity0.6)

如何编写支持Chainlink功能的代理和实现契约(Proxy模式通过DELEGATECALL Solity0.6)
EN

Stack Overflow用户
提问于 2021-05-22 02:19:16
回答 1查看 879关注 0票数 0

我有一个可靠的智能契约,它依赖Chainlink oracles获取外部数据,它具有许多功能代码,这些代码不需要在每个契约的基础上被复制,但是确实改变了契约实例的状态,这就是为什么我决定使用委托调用的代理模式是最有意义的。在代理模式中,我只需要为我的契约函数部署一次字节码,然后我的契约的所有其他实例都将只委托对实现契约的调用,而添加到块链中的唯一新信息将是该特定契约的实例字段。

我能够获得已部署的实现契约,并将已部署的代理指向其函数,但是当我调用代理上的锁函数时,我失败了检查require(owner == msg.sender,"Owner only"),这是没有意义的,因为委托调用应该通过msg.sender,并且在代理的构造函数中将owner字段设置为msg.sender。如果我删除了需求,我可以调用函数而不进行还原,但是lockeddebugAddr字段没有改变,即使锁函数应该改变它们(我以为委托调用是在调用者的上下文中执行的)。有人知道我的代理和实现合同有什么问题吗?我可以猜到这与内存布局或用于执行委托调用的程序集im有关,但我还不能使用我的googling技能找出哪里出了问题,所以如果有人可以发现我的代理合同不正确/格式不正确,请告诉我。

谢谢,本

锁函数代码片段

代码语言:javascript
复制
//Locks in the contract, buyer should have already provided data scientist an upload only API key and their model ID 
function lock() public returns (bool success)
{
    
    debugAddr = msg.sender;
    
    uint tempStamp = now;
    
    //THIS IS THE REQUIRE THAT FAILS WHEN IT SHOULDNT WHEN I UNCOMMENT THIS AND DEPLOY/RUN
    require(msg.sender == owner, "Only owner can lock contract.");
    
    //require(!locked, "Cannot lock contract that is already locked.");
    //require(buyer != address(0),"No buyer to lock.");
    //require(bytes(buyerModelName).length != 0,"No buyerModelName to lock.");
    //require((tempStamp - startTimestamp) < 158400,"Cannot lock contract that was entered by buyer over 44 hours ago.");
    //require((getWeekday(tempStamp) == 0) || (getWeekday(tempStamp) == 1 && getHour(tempStamp) < 14),"Contract can only be locked in between Sunday 00:00 UTC and Monday 14:00 UTC");
    
    LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
    //require(link.balanceOf(address(this)) >= totalFee, "Contract requires 0.5 LINK total to operate once locked, current LINK balance is under 0.5.");
    
    locked = true;
    return true;
}

需要注释的代理契约(也可以查看契约的txs,您可以看到我调用锁):代理指向:https://kovan.etherscan.io/address/0xfb41ea6452da396279cbd9d9d8c136121e38fab6https://kovan.etherscan.io/address/0x1f805d559f6eb7d7b19bf0340db288503f448ae8实现契约

需要未注释的代理契约(也可以查看契约的txs,您可以看到我调用锁和还原):https://kovan.etherscan.io/address/0x2d59aa0c1dd9a77d592167c43f2e65adcb275bfe实现契约代理指向: 0x20a1f27d69f7a257741eddaec433642194af0215

代理代码与实现代码

参考代码:https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Proxy.sol

代理:https://github.com/benschreyer/Steak/blob/main/SteakQuarterly/ProxyPattern/SteakQuarterlyProxy.sol

重要的注意:在我的代理中,我不想声明契约为ChainlinkClient,因为ChainlinkClient的函数将包含在代理中,这是不必要的,因为实现应该已经有了这些方法。相反,我只声明字段和ChainlinkClient。我觉得这是我的实现错误的主要地方,但我不确定需要改变什么/如果这是可行的。

实现:https://github.com/benschreyer/Steak/blob/main/SteakQuarterly/ProxyPattern/SteakQuarterlyDelegate.sol

编辑:仍然失败的最小代码示例()--这个契约应该有最小的要求成为ChainlinkClient的代理,并且只有锁函数和构造函数,我得到了相同的恢复(所有者== msg.sender)。如果我删除了需求,那么锁定代理契约的调用将被确认,但是代理的状态变量保持不变(debugAddr为0,锁定为false)

下面是最小的示例代码(我部署在remix编译的0.6.12上,代理的锁函数是通过使用at地址检索和已编译的委托代码调用的,以便使用委托的abi ):https://github.com/benschreyer/Steak/tree/main/MinimalCodeExample

编辑2: --如果我删除代理的ChainlinkClient部分/字段以及上面链接的实现最小示例,我将得到一个代理契约,它可以正常工作,并且可以接受在实现契约中定义的外部函数调用。

因此,我现在的问题是如何编写支持Chainlink GET请求功能的代理和实现契约?我的代理需要定义或导入哪些字段/常量/事件/接口?我应该在哪里定义/导入这些字段/常量/事件/接口以允许链链接工作?例如,如果我想让我的合同通过Chainlink从API中检索巴黎的温度,同时也是一个代理,这样我就不必修改它的所有功能并节省汽油价格。

到目前为止,我尝试过的任何东西(请参阅最小中断示例)在我将Chainlink添加到混合中后都无法工作,因为我不确定如何构造代理契约类,以便存储代理和访问/写入对实现队列的委托调用。下面是在我删除Chainlink功能之后起作用的最小代码:https://github.com/benschreyer/Steak/tree/main/MinimalCodeExample/WorkingButNoChainlink --我的工作示例代理/实现模式契约的一个版本,但是使用Chainlink功能,或者关于代理契约需要哪些字段/事件/角色的指针,以便它调用oracles,这将是非常感谢的。

EN

回答 1

Stack Overflow用户

发布于 2021-05-27 03:47:08

不要在代理类中定义ChainlinkClient字段,而是编写一个包含ChainlinkClient字段的类ChainlinkClientStorage,然后将代理声明为从ChainlinkClientStorage继承

https://github.com/benschreyer/Steak/blob/main/SteakQuarterly/ProxyPattern/ChainlinkClientStorage.sol

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Proxy.sol

代码语言:javascript
复制
contract MyProxy is ChainlinkClientStorage, MyContractStorage{}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67645526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档