【问题标题】:Smart contract limitations in Ethereum & Fabric以太坊和 Fabric 中的智能合约限制
【发布时间】:2017-03-24 02:18:22
【问题描述】:

我正在尝试制作智能合约以自动实现以下目标。但我坚持实施。如何在没有 B 签署 Tx 的情况下运行 (2) Tx,即:我希望它在 (1) 被激活并且条件 (2) 准备好后自动运行。

伪代码(一):

A send 50 to B        (1)
if (B > 50)           (2)
    B send 10 to C    (3)

上面的代码涉及多个所有者,即。 A、B 和 C。首先,A 通过运行/签署 Tx (1) 来激活合约。然后合约检查条件(2)。现在,但是如何在不必强制 B 签名的情况下自动运行(3)呢?

最终,合同是否能够根据 B 的行为签署(或代理签署)?


编辑

下面的任何链码呢?是否可以自动运行,即没有D必须使用(3)中D的私钥签名?

伪代码(二):

A send 50 to B        (1)
if (something is true, say Z > 50)           (2)
    D send 10 to F    (3)

【问题讨论】:

    标签: ethereum solidity smartcontracts


    【解决方案1】:

    最终,合同是否能够根据 B 的行为签署(或代理签署)?

    没有。

    A通过向合约发送必要的资金开始交易,然后合约根据规则分散资金。所以,A -> 合同,合同 -> B,可能还有合同 -> C。

    虽然它不在提出的问题范围内,但如果 B 和/或 C 是​​不受信任的合同,它可能会帮助您避免以后进行重构以观察分离两个发送的最佳实践。您只需在存款步骤中进行会计处理,然后使用提款模式,因为 B & C 要求他们的权利(单独的交易)。

    希望对您有所帮助。

    更新:

    这是一个粗略的大纲,可能会给您一些想法。我不确定 > 50 是历史总数还是单次付款 > 50。这是一个人为的示例,希望您为 B 和 C 传递两个有效地址,以便合约知道它们的地址。

    您可以从任何地址 (A) 发送金额,并且合约将跟踪 owedToBowedToC

    您应该能够从 B 或 C 向 withdraw() 发送交易以索取欠款。

    设置所有内容以进行完整测试有点费时,因此只需“按原样”呈现即可。

    pragma solidity ^0.4.6;
    
    contract Royalty {
    
      address public B;
      address public C;
      uint public owedToB;
      uint public owedToC;
    
      event LogPaymentReceived(address sender, uint amount);
      event LogPaid(address recipient, uint amount);
    
      // pass in two addresses, B & C for this simple constructor
    
      function Royalty(address addressB, address addressC) {
        B = addressB;
        C = addressC;
      }
    
      function pay()
        public
        payable
        returns(bool success)
      {
        owedToB += msg.value;
    
        // You can do B.balance > 50 but beware how it drops below 50 after withdrawal
        // A little more involved, but you can have totalReceipts AND totalPayments so owedToB is totalReceipts - totalPayments
        // It all depends on the business terms you're trying to enforce.
    
        if(msg.value > 50) {
          owedToC += 10;
          owedToB -= 10;
        }
    
        LogPaymentReceived(msg.sender, msg.value);
        return true;
      }
    
      function withdraw() 
        public
        returns(uint amountSent)
      {
        if(msg.sender != B && msg.sender != C) throw; // only B & C can withdraw
    
        uint amount;
        if(msg.sender == B) {
            amount = owedToB;
            owedToB = 0;
            if(!B.send(amount)) throw;
            LogPaid(B,amount);
            return amount;
        }
        if(msg.sender == C) {
            amount = owedToC;
            owedToC = 0;
            if(!C.send(amount)) throw;
            LogPaid(C,amount);
            return amount;
        }
        // we shouldn't make it this far
        throw;
      }
    
    }
    

    【讨论】:

    • 感谢您的回复。如果我理解正确,我必须在存款步骤中进行计算。但现在的问题是我只想在条件 if (B > 50) 为真时 B 发送 C 金额 10,而这又是基于 A 向 B 发送 50 的结果
    • 非常感谢这个很好的例子。 if (B > 50) 的条件是检查 B 当前的总余额。这是在 B 收到 A 的 50 付款后检查的。那么第一,合约可以检查 B 的余额吗?第二,如果 B.balance > 50,我们想要 B.send (10) 给 C。在你的例子中,你使用/分配了所有的存款给 owedToB。然后你检查了条件。如果条件为真,您将 10 分配给 owedToC。这 10 个来自哪里,A、B 还是 C?在我最初的问题中,我希望 B 将 10(B 的一部分)发送给 C。
    • 你是对的。应该有一个 owedToB -= 10。修复它。可以看到平衡,但实际上这可能不是最好的方法。例如,uint BBalance = B.balance;这样做的问题是它可能会随着存款和取款而上下浮动,所以大多数合约都是基于资金流动的,也就是说,你不会根据检查账户余额来触发事情;而是某种累积的收据。无论如何,这个例子的想法只是为了展示退出模式。算法可以适应这种情况。
    • 感谢您的及时回复。即使使用 owedToB -= 10 也只能修复此示例。如果我的 (3) 是 B.send(20) 给 C 怎么办。通过上述修复,它变为 owedToB -= 20。现在我们冒着“透支”B 帐户的风险。
    • 这显然是一个人为的例子来解决第一个问题(一个)并说明如何使用算术和提款来移动资产。
    猜你喜欢
    • 2019-04-07
    • 1970-01-01
    • 2021-02-24
    • 2019-07-27
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多