Цель децентрализованного приложения/смарт-контракта
Я отправляю x количество эфира на адрес "AAA" с адреса "000"
Если через 10 минут, если вновь полученный адрес «AAA» все еще имеет все x количество эфира. Он должен вернуть весь эфир обратно на адрес «000», регистр «неиспользованный» для этой транзакции.
Может ли кто-нибудь показать этот PoC с помощью Solidity-Browser?
Спасибо
Если Алиса заплатит Бобу, мы не сможем заставить Боба вернуть деньги.
Алиса может заплатить по контракту и указать, что Боб является единственным лицом, уполномоченным тратить эти средства. Мы можем дополнительно указать крайний срок, после которого Боб больше не имеет права тратить средства, а Алиса имеет право требовать возмещения.
Еще одна сложность заключается в том, что у Боба может быть много таких депозитов, каждый со своими крайними сроками, и поэтому становится довольно неудобно иметь дело с ним как с единовременной суммой чистого остатка. Вместо этого в приведенном ниже примере каждый транш отслеживается как конкретный депозит со своим крайним сроком, и каждый раз, когда Боб пересылает средства, он указывает, какой транш (с именем DepositNumber) он тратит.
Он использует ленивый процесс вывода средств, чтобы вернуть средства Алисе, если они не перенаправлены кому-то еще до истечения срока. Алиса заинтересована в получении возмещения, поэтому она проверит контракт и заплатит за газ, чтобы обработать его.
Ниже просто наспех задуманная мазня без проверки. Это приближает идею. Надеюсь, поможет.
pragma solidity ^0.4.6;
// Alice gives Bob ETH to spend before deadline, or Alice gets it back.
// Alice = sender
// Bob = spender
// recipient is whomever Bob decides to forward to
contract ForcedForward {
struct DepositStruct {
address sender;
uint amount;
uint blockNumber;
uint deadline;
}
mapping(address => DepositStruct[]) spenderDepositStructs;
event LogReceived (address spender, uint depositNumber, uint amount, uint deadline, address sender);
event LogForwarded(address spender, uint depositNumber, uint amount, address recipient);
event LogWithdrawn(address spender, uint depositNumber, uint amount, address sender);
//////////////////////////////////
// Send funds and authorize
// someone else to spend before
// a certain deadline (block)
function deposit(address spender, uint deadline)
public
payable
returns(bool success)
{
if(deadline <= block.number) throw; // must be in the future
if(msg.value==0) throw; // no money sent
DepositStruct memory d;
d.sender = msg.sender;
d.amount = msg.value;
d.deadline = deadline;
spenderDepositStructs[spender].push(d);
LogReceived(spender, spenderDepositStructs[spender].length-1, msg.value, deadline, msg.sender);
return true;
}
//////////////////////////////////
// Forward funds if authorized to
// before the deadline is passed
function forward(address recipient, uint depositNumber)
public
returns(bool success)
{
DepositStruct d = spenderDepositStructs[msg.sender][depositNumber];
if(d.deadline < block.number) throw; // too late
uint amount = d.amount;
if(amount == 0) throw; // no money
spenderDepositStructs[msg.sender][depositNumber].amount = 0; // zero out the balance
if(!recipient.send(d.amount)) throw;
LogForwarded(msg.sender, depositNumber, amount, recipient);
return true;
}
//////////////////////////////////
// Clawback funds
function withdraw(address spender, uint depositNumber)
public
returns(bool success)
{
DepositStruct d = spenderDepositStructs[spender][depositNumber];
if(d.sender != msg.sender) throw; // not originator. not entitled to it. Error.
if(d.deadline > block.number) throw; // too soon
uint amount = d.amount;
spenderDepositStructs[spender][depositNumber].amount = 0; // zero out the balance.
if(amount==0) throw; // no money
if(!msg.sender.send(amount)) throw; // try to send it back
LogWithdrawn(spender, depositNumber, amount, msg.sender);
return true;
}
///////////////////////////////////////////
// Getter functions for visibility
function getSpenderDepositCount(address spender)
public
constant
returns(uint spenderDepositCount)
{
return spenderDepositStructs[spender].length;
}
function getSpenderDeposit(address spender, uint depositNumber)
public
constant
returns(address sender, uint amount, uint deadline)
{
DepositStruct d;
d = spenderDepositStructs[spender][depositNumber];
return(d.sender, d.amount, d.deadline);
}
}