aboutsummaryrefslogtreecommitdiffstats
path: root/contracts/chequebook/contract/chequebook.sol
blob: 8d6e85d11978c13ed3d773161b8a094d9f11f39d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
pragma solidity ^0.4.18;

import "https://github.com/ethereum/solidity/std/mortal.sol";

/// @title Chequebook for Ethereum micropayments
/// @author Daniel A. Nagy <daniel@ethereum.org>
contract chequebook is mortal {
    // Cumulative paid amount in wei to each beneficiary
    mapping (address => uint256) public sent;

    /// @notice Overdraft event
    event Overdraft(address deadbeat);

    /// @notice Cash cheque
    ///
    /// @param beneficiary beneficiary address
    /// @param amount cumulative amount in wei
    /// @param sig_v signature parameter v
    /// @param sig_r signature parameter r
    /// @param sig_s signature parameter s
    /// The digital signature is calculated on the concatenated triplet of contract address, beneficiary address and cumulative amount
    function cash(address beneficiary, uint256 amount,
        uint8 sig_v, bytes32 sig_r, bytes32 sig_s) {
        // Check if the cheque is old.
        // Only cheques that are more recent than the last cashed one are considered.
        require(amount > sent[beneficiary]);
        // Check the digital signature of the cheque.
        bytes32 hash = keccak256(address(this), beneficiary, amount);
        require(owner == ecrecover(hash, sig_v, sig_r, sig_s));
        // Attempt sending the difference between the cumulative amount on the cheque
        // and the cumulative amount on the last cashed cheque to beneficiary.
        uint256 diff = amount - sent[beneficiary];
        if (diff <= this.balance) {
        // update the cumulative amount before sending
            sent[beneficiary] = amount;
            beneficiary.transfer(diff);
        } else {
            // Upon failure, punish owner for writing a bounced cheque.
            // owner.sendToDebtorsPrison();
            Overdraft(owner);
            // Compensate beneficiary.
            selfdestruct(beneficiary);
        }
    }
}