В конечном счете, может ли контракт подписываться (или подписываться по доверенности) на поведении 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