Ограничения смарт-контрактов в Ethereum и Fabric

Я пытаюсь заключить смарт-контракт для автоматического достижения следующих целей. Но я застрял в реализации. Как я могу запустить (2) Tx, не имея B для подписи 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). Теперь, но как можно запустить (3) автоматически, не заставляя B подписывать?

В конечном счете, может ли контракт подписываться (или подписываться по доверенности) на поведении B?


изменить

А что насчет ниже в любом цепном коде? Может ли он работать автоматически, то есть без D должен подписываться с использованием закрытого ключа D в (3)?

Псевдокод (два):

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

person wildcolor    schedule 24.03.2017    source источник


Ответы (1)


В конечном счете, может ли контракт подписываться (или подписываться по доверенности) на поведении B?

Нет.

A начинает транзакции, отправляя необходимые средства в контракт, а затем контракт распределяет средства в соответствии с правилами. Итак, A -> контракт, контракт -> B и, возможно, контракт -> C.

Хотя это выходит за рамки поднятого вопроса, это, возможно, поможет вам избежать последующего рефакторинга, чтобы соблюсти передовую практику разделения двух посылок, если B и / или C являются ненадежными контрактами. Вы просто будете вести учет на этапе депозита, а затем использовать схему снятия средств, поскольку B & C заявляют свои права (отдельные транзакции).

Надеюсь, это поможет.

Обновлено:

Вот примерный план, который может дать вам некоторые идеи. Я не был уверен, было ли> 50 общей суммой за все время или единичным платежом> 50. Это надуманный пример, который ожидает, что вы передадите два действительных адреса для B & C, чтобы контракт знал их адреса.

Вы можете отправлять суммы с любого адреса (A), и в контракте будут учтены owedToB и owedToC.

У вас должна быть возможность отправить транзакцию на withdraw() от B или C, чтобы потребовать причитающуюся сумму.

Настройка всего для полного тестирования занимает немного времени, поэтому просто представляйте «как есть».

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;
  }

}
person Rob Hitchens    schedule 24.03.2017
comment
Спасибо за ваш ответ. Если я вас правильно понял, мне нужно произвести расчет на этапе депозита. Но теперь проблема в том, что я хочу, чтобы B отправлял C сумму 10 только тогда, когда условие if (B ›50) истинно, что, в свою очередь, основано на результате A send 50 to B - person wildcolor; 27.03.2017
comment
большое спасибо за отличный пример. условие if (B> 50) означает проверку текущего общего баланса B. Это проверяется после того, как B получит платеж 50 от A. Итак, во-первых, может ли контракт проверить баланс B? и во-вторых, если B.balance> 50, мы хотим отправить B.send (10) на C. В вашем примере вы использовали / назначили весь депозит на owedToB. Затем вы проверили условие. Если условие истинно, вы назначили 10 для owedToC. Откуда эта 10, A, B или C? В моем исходном вопросе я хочу, чтобы B отправил 10 (часть B) C. - person wildcolor; 27.03.2017
comment
Ты прав. Должно быть owedToB - = 10. Исправлено. Можно увидеть баланс, но на практике это может быть не лучшим способом. Например, uint BBalance = B.balance; Проблема заключается в том, что он может плавать вверх и вниз с депозитами и снятием средств, поэтому большинство контрактов основаны на денежных потоках, то есть вы не будете запускать действия, основанные на проверке баланса счета; скорее какие-то накопленные квитанции. В любом случае идея примера - просто показать схему вывода средств. Арифметика адаптируется к ситуации. - person Rob Hitchens; 27.03.2017
comment
Спасибо за быстрый ответ. Даже с owedToB - = 10 исправлен только этот пример. Что, если мой (3) - B. send (20) to C. С указанным выше исправлением он становится owedToB - = 20. Теперь мы рискуем «овердрафтом» счета B. - person wildcolor; 27.03.2017
comment
Это явно надуманный пример для ответа на первый вопрос (один) и демонстрации того, как использовать арифметику и снятие средств для перемещения активов. - person Rob Hitchens; 27.03.2017