forked from PAY-IT-FORWARD/contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReceipter.sol
129 lines (110 loc) · 4.6 KB
/
Receipter.sol
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! The receipting contract. Just records who sent what.
//!
//! Copyright 2017 Gavin Wood, Parity Technologies Ltd.
//!
//! Licensed under the Apache License, Version 2.0 (the "License");
//! you may not use this file except in compliance with the License.
//! You may obtain a copy of the License at
//!
//! http://www.apache.org/licenses/LICENSE-2.0
//!
//! Unless required by applicable law or agreed to in writing, software
//! distributed under the License is distributed on an "AS IS" BASIS,
//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//! See the License for the specific language governing permissions and
//! limitations under the License.
pragma solidity ^0.4.7;
/// Will accept Ether "contributions" and record each both as a log and in a
/// queryable record.
contract Receipter {
/// Constructor. `_admin` has the ability to pause the
/// contribution period and, eventually, kill this contract. `_treasury`
/// receives all funds. `_beginBlock` and `_endBlock` define the begin and
/// end of the period.
function Receipter(address _admin, address _treasury, uint _beginBlock, uint _endBlock) {
admin = _admin;
treasury = _treasury;
beginBlock = _beginBlock;
endBlock = _endBlock;
}
// Can only be called by _admin.
modifier only_admin { if (msg.sender != admin) throw; _; }
// Can only be called by prior to the period.
modifier only_before_period { if (block.number >= beginBlock) throw; _; }
// Can only be called during the period when not halted.
modifier only_during_period { if (block.number < beginBlock || block.number >= endBlock || isHalted) throw; _; }
// Can only be called during the period when halted.
modifier only_during_halted_period { if (block.number < beginBlock || block.number >= endBlock || !isHalted) throw; _; }
// Can only be called after the period.
modifier only_after_period { if (block.number < endBlock || isHalted) throw; _; }
// The value of the message must be sufficiently large to not be considered dust.
modifier is_not_dust { if (msg.value < dust) throw; _; }
/// Some contribution `amount` received from `recipient`.
event Received(address indexed recipient, uint amount);
/// Period halted abnormally.
event Halted();
/// Period restarted after abnormal halt.
event Unhalted();
/// Fallback function: receive a contribution from sender.
function() payable {
receiveFrom(msg.sender);
}
/// Receive a contribution from `_recipient`.
function receiveFrom(address _recipient) payable only_during_period is_not_dust {
if (!treasury.call.value(msg.value)()) throw;
record[_recipient] += msg.value;
total += msg.value;
Received(_recipient, msg.value);
}
/// Halt the contribution period. Any attempt at contributing will fail.
function halt() only_admin only_during_period {
isHalted = true;
Halted();
}
/// Unhalt the contribution period.
function unhalt() only_admin only_during_halted_period {
isHalted = false;
Unhalted();
}
/// Kill this contract.
function kill() only_admin only_after_period {
suicide(treasury);
}
// How much is enough?
uint public constant dust = 100 finney;
// Who can halt/unhalt/kill?
address public admin;
// Who gets the stash?
address public treasury;
// When does the contribution period begin?
uint public beginBlock;
// When does the period end?
uint public endBlock;
// Are contributions abnormally halted?
bool public isHalted = false;
mapping (address => uint) public record;
uint public total = 0;
}
contract SignedReceipter is Receipter {
function Receipter(address _admin, address _treasury, uint _beginBlock, uint _endBlock, bytes32 _sigHash) {
admin = _admin;
treasury = _treasury;
beginBlock = _beginBlock;
endBlock = _endBlock;
sigHash = _sigHash;
}
modifier when_signed(address who, uint8 v, bytes32 r, bytes32 s) { if (ecrecover(sigHash, v, r, s) != who) throw; _; }
function() payable { throw; }
/// Fallback function: receive a contribution from sender.
function receive(uint8 v, bytes32 r, bytes32 s) payable {
receiveFrom(msg.sender, v, r, s);
}
/// Receive a contribution from `_recipient`.
function receiveFrom(address _source, uint8 v, bytes32 r, bytes32 s) payable only_during_period is_not_dust when_signed(_source, v, r, s) {
if (!treasury.call.value(msg.value)()) throw;
record[_source] += msg.value;
total += msg.value;
Received(_source, msg.value);
}
bytes32 sigHash;
}