1

Dapp/SmartContract Goal

I send x amount of ether to Address "AAA" from Address "000"

If after 10 min if the newly received address "AAA" still has all x amount of ether. It should return all the ether back to address "000" register "unused" to that transaction.

Can someone show this PoC using Solidity-Browser?

thanks

1

If Alice pays Bob, we have no way to force Bob to give it back.

Alice can pay a contract and stipulate that Bob is the only person authorized to spend those funds. We can further stipulate a deadline afterwhich Bob is no longer authorized to spend the funds, and Alice IS authorized to claim a refund.

There's a further complication in that Bob may have many such deposits, each with their own deadlines and so it becomes quite awkward to deal with it as a lump sum net balance. Instead, the example below tracks each tranche as specific deposit with its own deadline, and each time Bob forwards funds, he specifies which tranche (called depositNumber) he's spending.

It uses a lazy withdrawal process to return funds to Alice if they aren't forwarded to someone else before the deadline. Alice is motivated to receive the refund, so she will check the contract and pay the gas fee to process it.

Below is just a hastily conceived scribble with no testing. It approximates the idea. Hope it helps.

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

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.