首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何自动执行智能合同代码?

如何自动执行智能合同代码?
EN

Stack Overflow用户
提问于 2022-06-05 10:03:19
回答 4查看 166关注 0票数 -1

我有两个契约: PolicyFactory (构建策略契约的契约)和Policy。

在我的creation应用程序中,任何用户都可以申请保单(我有一个不集中的人寿保险应用程序),从而为每个保单创建了一个策略契约。

我希望实现一个逻辑,关闭策略并在策略的结束日期到期时自动将资金发送给所有者(我将结束日期存储为智能契约中的uint256 )。

我用Chainlink Keeper尝试过,但是我发现这是不可能的,因为我需要一个守门员来处理每一个新的政策契约。

我如何为我的用户拥有的每一项策略自动执行此操作?

这些是我的合同:

代码语言:javascript
复制
import "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/KeeperCompatible.sol";

contract PolicyFactory {
    //address[] public deployedPolicies;
    mapping(address => address[]) private deployedPoliciesByUser;
    address[] private deployedPolicies;
    address private admin = 0x3402c11c6f40e28b1D3996f11E5e54a937161fb9;

    event PolicyCreation(address policyAddress, string applicationId);

    modifier restricted(){
        require(msg.sender == admin, 'Not admin!');
        _;
    }

    function createPolicy(uint timePeriod, uint premium, address owner, uint startDate, string memory applicationId, uint endDate) public restricted returns (address){
       Policy newPolicy = new Policy(owner, premium, timePeriod, startDate, applicationId, endDate);
       deployedPoliciesByUser[owner].push(address(newPolicy));
       deployedPolicies.push(address(newPolicy));
       emit PolicyCreation(address(newPolicy), applicationId);    
    }

    function getDeployedPoliciesByUser(address user) public view returns (address[] memory)  {
        require(user != address(0));
        return deployedPoliciesByUser[user];
    }

    function getDeployedPolicies() public view restricted returns (address[] memory) { 
        return deployedPolicies;
    }
}

contract Policy is KeeperCompatibleInterface {
    address public owner;
    address public admin = 0x3402c11c6f40e28b1D3996f11E5e54a937161fb9;
    string public applicationId;
    uint public timePeriod;
    uint public premium;
    uint public startDate;
    uint public endDate;
    uint public nrPremiumsPayed;
    bool public active = true;

    event LogDeposit(address _from, uint amount, uint date);
    event LogWithdraw(address _to, uint amount, uint date);


    modifier restrictedAdminAndOwner(){
        require(address(msg.sender) == admin || address(msg.sender) == owner);
        _;
    }

    constructor(address _owner, uint _premium, uint _period, uint _startDate, string memory _applicationId, uint _endDate) public {
       owner = _owner;
       timePeriod = _period;
       premium = _premium;
       startDate = _startDate;
       endDate = _endDate;
       applicationId = _applicationId;
   }

   function checkUpkeep(bytes calldata /* checkData */) external view override returns (bool upkeepNeeded, bytes memory /* performData */) {
        upkeepNeeded = (endDate - block.timestamp) <= 100000;
    }

    function performUpkeep(bytes calldata /* performData */) external override {
        if((endDate - block.timestamp) <= 100000) {
            active = false;
            (bool sent, ) = address(owner).call{value: address(this).balance}("");
            require(sent);
        }
    }

    // de intregrat cu oracle de ipfs sa trimita automat cand se gaseste document.
   function sendCompensation () public restrictedAdminAndOwner {
       require(owner != address(0) && active == false);
        (bool sent, ) = address(owner).call{value: address(this).balance}("");
        require(sent);
   }

   function getSummary () public view returns(address, address, uint, uint, uint, bool, uint, uint){
       return (
           owner, admin, timePeriod,premium,startDate,active,address(this).balance, endDate
       );
   }

    function withdraw (uint amount, bool closePolicy) public {
        require(msg.sender == owner && amount <= address(this).balance && active == true);
        (bool sent, ) = address(owner).call{value: amount}("");
        require(sent);
        if(closePolicy == true){
            active = false;
            sendCompensation();
        }
        emit LogWithdraw(address(owner), amount, block.timestamp);
    }

    function deposit () public payable {
        require(active == true);
        emit LogDeposit(address(msg.sender), msg.value, block.timestamp);
    } 
}
EN

回答 4

Stack Overflow用户

发布于 2022-06-08 04:16:51

您可以使用Chainlink Keepers以下列方式自动化此智能契约函数。

选项一:单独的维护契约循环遍历所有“活动”策略

创建一个单独的保管人兼容的终身制合同.它将调用工厂上的getDeployedPolicies(),然后迭代checkUpkeep中的每个策略,以检测哪些策略应该关闭。然后构建一个需要过期的新策略列表,将其编码并作为performData传递到performUpkeep函数中。在performUpkeep中,您可以对abi进行解码,然后重新验证它们确实需要被关闭。我还建议您调用的balance_return函数应该在返回funds.This之前检查合同是否仍有关闭的资格,这类似于一些用户今天实现限制订单的方式。

这种方法的一个限制因素是,目前您只能在checkUpkeep中进行650万气体的计算。用户可以通过使用相同的函数加上一个checkData输入来拆分列表来解决这个问题。这样您就可以使用相同的维护契约,只需传入不同的checkData来检查合同列表的不同部分。

注意,我不确定getDeployedPolicies是否会返回所有策略,或者仅仅返回尚未关闭的策略。附带问题:您在什么地方触发到期前的保单?

我会有时间在这里添加伪代码。

选项二:通过直接与Keepers注册表交互,自动创建维护,作为newPolicy创建的一部分

对于您部署的每个策略,将Chainlink Keeper维护的部署自动化,作为工厂合同的一部分。这也许是一个更清洁的解决方案,但目前更为复杂。考虑到今天涉及的手动审批过程,您需要一些后续逻辑来获取维护的最终ID。注意,我们正在这方面做一些工作,这将使将来更容易做。

这里可能有用的另一种方法就是能够在特定日期和特定时间调用关闭,而无需进行所有这些检查。

声明:我在Chainlink实验室工作

票数 1
EN

Stack Overflow用户

发布于 2022-06-05 14:51:57

让合同在区块链上自动执行是不可能的,但是有一些替代的解决方案。

一些简单的想法

  1. 您可以使用ethers.js或web3.jslibary与块链交互。但是要注意,如果您想要更改区块链上的任何数据。您将花费一定数额的煤气费(如自动发送资金给业主)。
  2. 您可以创建一个dapp,当时间成熟时,dapp将向人们展示他们可以在那里申领自己的基金。(因为执行者是索赔人。)

如果我有任何新的想法,我会更新ASAF。:)

票数 0
EN

Stack Overflow用户

发布于 2022-06-05 23:36:28

您可以做一个cron作业,检查每个用户的endDate,如果日期过了,它将发送一个事务,将资金撤回给所有者。

或者就像疯狂冲床人说的,这是人们可以在withdraw()函数中做的一件事,比如:

代码语言:javascript
复制
require(now >= endDate, "you can't withdraw");

然后,只有在足够的时间过去时,dapp才会显示退出按钮,而人们将按自己的方式退出。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72506416

复制
相关文章

相似问题

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