├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── contracts
├── BokkyPooBahsDateTimeContract.sol
├── BokkyPooBahsDateTimeLibrary.sol
└── TestDateTime.sol
├── deployment
├── BokkyPooBahsDateTimeContract_flattened_v1.00.sol
└── deployment-v1.00-prerelease.md
├── docs
├── ConvertingBetweenJulianDatesAndGregorianCalendarDates.pdf
├── timestampFromDateTime.png
└── timestampToDateTime.png
├── flattened
└── TestDateTime_flattened.sol
├── images
└── clocks.png
├── scripts
└── solidityFlattener.pl
└── test
├── 00_runGeth.sh
├── 01_test1.sh
├── 02_attachGeth.sh
├── BokkyPooBahsDateTimeLibrary.js
├── BokkyPooBahsDateTimeLibrary.sol
├── README.md
├── TestDateTime.js
├── TestDateTime.sol
├── deploymentData.js
├── functions.js
├── genesis.json
├── settings
├── test1output.txt
├── test1results.txt
└── testchain
└── keystore
├── UTC--2017-05-20T02-37-30.360937280Z--a00af22d07c87d96eeeb0ed583f8f6ac7812827e
├── UTC--2017-05-20T02-37-58.104082316Z--a11aae29840fbb5c86e6fd4cf809eba183aef433
├── UTC--2017-05-20T02-38-21.169063367Z--a22ab8a9d641ce77e06d98b7d7065d324d3d6976
├── UTC--2017-05-20T02-38-41.707647638Z--a33a6c312d9ad0e0f2e95541beed0cc081621fd0
├── UTC--2017-05-20T02-39-04.584040707Z--a44a08d3f6933c69212114bb66e2df1813651844
├── UTC--2017-05-20T02-42-01.013666678Z--a55a151eb00fded1634d27d1127b4be4627079ea
├── UTC--2017-05-20T02-42-37.426191216Z--a66a85ede0cbe03694aa9d9de0bb19c99ff55bd9
├── UTC--2017-05-20T02-42-58.899396047Z--a77a2b9d4b1c010a22a7c565dc418cef683dbcec
├── UTC--2017-05-20T02-47-09.150580614Z--a88a05d2b88283ce84c8325760b72a64591279a2
├── UTC--2017-05-20T02-47-34.770098207Z--a99a0ae3354c06b1459fd441a32a3f71005d7da0
├── UTC--2017-05-20T02-58-17.400859858Z--aaaa9de1e6c564446ebca0fd102d8bd92093c756
├── UTC--2017-05-20T02-58-35.122799190Z--abba43e7594e3b76afb157989e93c6621497fd4b
├── UTC--2017-05-20T02-58-51.178332229Z--acca534c9f62ab495bd986e002ddf0f054caae4f
├── UTC--2017-05-20T02-59-14.034178720Z--adda9b762a00ff12711113bfdc36958b73d7f915
├── UTC--2017-05-20T02-59-33.471449656Z--aeea63b5479b50f79583ec49dacdcf86ddeff392
├── UTC--2017-05-20T02-59-51.697690594Z--affa4d3a80add8ce4018540e056dacb649589394
├── UTC--2017-11-23T03-46-38.500831000Z--b00bfde102270687324f9205b693859df64f8923
├── UTC--2017-11-23T03-47-13.633282000Z--b11be1d4ef8e94d01cb2695092a79d139a8dad98
├── UTC--2017-11-23T03-47-34.792913000Z--b22be2d9eef0d7e260cf96a64feea0b95ed3e74f
├── UTC--2017-11-23T03-50-14.030093000Z--b33b7ecf5e47be3981c74d989d3af8b665b4b649
├── UTC--2017-11-23T03-51-02.743266000Z--b44b43d59b738b088b690ae276c1e979aba8268d
├── UTC--2017-11-23T03-53-16.250696000Z--b55b57d113b45481e31aaf03d6f4e5ad4ef325f8
├── UTC--2017-11-23T03-53-56.678333000Z--b66bcb4e473de80e2c8a47ced10c22c705a5e602
├── UTC--2017-11-23T03-55-56.546405000Z--b77bbbaa7c1649547ae61de4b80b91568c28351a
├── UTC--2017-11-23T03-58-22.605806000Z--b88b728490b417e29b0784db30535db343830dba
├── UTC--2017-11-23T03-59-11.614985000Z--b99b3d1f72edb05a0321db58eddcf83fd73c4ade
├── UTC--2017-11-23T04-00-06.765694000Z--baab56da883edbe5314b8005be410022c510ccae
├── UTC--2017-11-23T04-00-29.951106000Z--bbbb9809de0456ce0e0cd660e6e4ceabef3f521c
├── UTC--2017-11-23T04-02-29.293263000Z--bccb68dd0ac87ef290aef49870d155f076c87868
├── UTC--2017-11-23T04-02-54.216243000Z--bddb726ee06906e104db210e6d0506f2b062e477
├── UTC--2017-11-23T04-08-54.756436000Z--beeb24ff18203658d0a1d4682ee3f36ad663ec87
└── UTC--2017-11-23T04-09-53.679255000Z--bffbd8f029ef0bd81cf754b53e8b3a5684f8b3ff
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.sol linguist-language=Solidity
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .project
3 | .settings
4 | test/testchain/geth
5 | test/testchain/geth.ipc
6 | test/testchain/history
7 | test/contracts
8 | private
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 The Officious BokkyPooBah / Bok Consulting Pty Ltd
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/contracts/BokkyPooBahsDateTimeContract.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.6.0 <0.9.0;
3 |
4 | // ----------------------------------------------------------------------------
5 | // BokkyPooBah's DateTime Library v1.00 - Contract Instance
6 | //
7 | // A gas-efficient Solidity date and time library
8 | //
9 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
10 | //
11 | // Tested date range 1970/01/01 to 2345/12/31
12 | //
13 | // Conventions:
14 | // Unit | Range | Notes
15 | // :-------- |:-------------:|:-----
16 | // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
17 | // year | 1970 ... 2345 |
18 | // month | 1 ... 12 |
19 | // day | 1 ... 31 |
20 | // hour | 0 ... 23 |
21 | // minute | 0 ... 59 |
22 | // second | 0 ... 59 |
23 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
24 | //
25 | //
26 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018.
27 | //
28 | // GNU Lesser General Public License 3.0
29 | // https://www.gnu.org/licenses/lgpl-3.0.en.html
30 | // ----------------------------------------------------------------------------
31 |
32 | import "BokkyPooBahsDateTimeLibrary.sol";
33 |
34 | contract BokkyPooBahsDateTimeContract {
35 | uint public constant SECONDS_PER_DAY = 24 * 60 * 60;
36 | uint public constant SECONDS_PER_HOUR = 60 * 60;
37 | uint public constant SECONDS_PER_MINUTE = 60;
38 | int public constant OFFSET19700101 = 2440588;
39 |
40 | uint public constant DOW_MON = 1;
41 | uint public constant DOW_TUE = 2;
42 | uint public constant DOW_WED = 3;
43 | uint public constant DOW_THU = 4;
44 | uint public constant DOW_FRI = 5;
45 | uint public constant DOW_SAT = 6;
46 | uint public constant DOW_SUN = 7;
47 |
48 | function _now() public view returns (uint timestamp) {
49 | timestamp = now;
50 | }
51 | function _nowDateTime() public view returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
52 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(now);
53 | }
54 | function _daysFromDate(uint year, uint month, uint day) public pure returns (uint _days) {
55 | return BokkyPooBahsDateTimeLibrary._daysFromDate(year, month, day);
56 | }
57 | function _daysToDate(uint _days) public pure returns (uint year, uint month, uint day) {
58 | return BokkyPooBahsDateTimeLibrary._daysToDate(_days);
59 | }
60 | function timestampFromDate(uint year, uint month, uint day) public pure returns (uint timestamp) {
61 | return BokkyPooBahsDateTimeLibrary.timestampFromDate(year, month, day);
62 | }
63 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (uint timestamp) {
64 | return BokkyPooBahsDateTimeLibrary.timestampFromDateTime(year, month, day, hour, minute, second);
65 | }
66 | function timestampToDate(uint timestamp) public pure returns (uint year, uint month, uint day) {
67 | (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
68 | }
69 | function timestampToDateTime(uint timestamp) public pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
70 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(timestamp);
71 | }
72 |
73 | function isValidDate(uint year, uint month, uint day) public pure returns (bool valid) {
74 | valid = BokkyPooBahsDateTimeLibrary.isValidDate(year, month, day);
75 | }
76 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (bool valid) {
77 | valid = BokkyPooBahsDateTimeLibrary.isValidDateTime(year, month, day, hour, minute, second);
78 | }
79 | function isLeapYear(uint timestamp) public pure returns (bool leapYear) {
80 | leapYear = BokkyPooBahsDateTimeLibrary.isLeapYear(timestamp);
81 | }
82 | function _isLeapYear(uint year) public pure returns (bool leapYear) {
83 | leapYear = BokkyPooBahsDateTimeLibrary._isLeapYear(year);
84 | }
85 | function isWeekDay(uint timestamp) public pure returns (bool weekDay) {
86 | weekDay = BokkyPooBahsDateTimeLibrary.isWeekDay(timestamp);
87 | }
88 | function isWeekEnd(uint timestamp) public pure returns (bool weekEnd) {
89 | weekEnd = BokkyPooBahsDateTimeLibrary.isWeekEnd(timestamp);
90 | }
91 |
92 | function getDaysInMonth(uint timestamp) public pure returns (uint daysInMonth) {
93 | daysInMonth = BokkyPooBahsDateTimeLibrary.getDaysInMonth(timestamp);
94 | }
95 | function _getDaysInMonth(uint year, uint month) public pure returns (uint daysInMonth) {
96 | daysInMonth = BokkyPooBahsDateTimeLibrary._getDaysInMonth(year, month);
97 | }
98 | function getDayOfWeek(uint timestamp) public pure returns (uint dayOfWeek) {
99 | dayOfWeek = BokkyPooBahsDateTimeLibrary.getDayOfWeek(timestamp);
100 | }
101 |
102 | function getYear(uint timestamp) public pure returns (uint year) {
103 | year = BokkyPooBahsDateTimeLibrary.getYear(timestamp);
104 | }
105 | function getMonth(uint timestamp) public pure returns (uint month) {
106 | month = BokkyPooBahsDateTimeLibrary.getMonth(timestamp);
107 | }
108 | function getDay(uint timestamp) public pure returns (uint day) {
109 | day = BokkyPooBahsDateTimeLibrary.getDay(timestamp);
110 | }
111 | function getHour(uint timestamp) public pure returns (uint hour) {
112 | hour = BokkyPooBahsDateTimeLibrary.getHour(timestamp);
113 | }
114 | function getMinute(uint timestamp) public pure returns (uint minute) {
115 | minute = BokkyPooBahsDateTimeLibrary.getMinute(timestamp);
116 | }
117 | function getSecond(uint timestamp) public pure returns (uint second) {
118 | second = BokkyPooBahsDateTimeLibrary.getSecond(timestamp);
119 | }
120 |
121 | function addYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
122 | newTimestamp = BokkyPooBahsDateTimeLibrary.addYears(timestamp, _years);
123 | }
124 | function addMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
125 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMonths(timestamp, _months);
126 | }
127 | function addDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
128 | newTimestamp = BokkyPooBahsDateTimeLibrary.addDays(timestamp, _days);
129 | }
130 | function addHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
131 | newTimestamp = BokkyPooBahsDateTimeLibrary.addHours(timestamp, _hours);
132 | }
133 | function addMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
134 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMinutes(timestamp, _minutes);
135 | }
136 | function addSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
137 | newTimestamp = BokkyPooBahsDateTimeLibrary.addSeconds(timestamp, _seconds);
138 | }
139 |
140 | function subYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
141 | newTimestamp = BokkyPooBahsDateTimeLibrary.subYears(timestamp, _years);
142 | }
143 | function subMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
144 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMonths(timestamp, _months);
145 | }
146 | function subDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
147 | newTimestamp = BokkyPooBahsDateTimeLibrary.subDays(timestamp, _days);
148 | }
149 | function subHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
150 | newTimestamp = BokkyPooBahsDateTimeLibrary.subHours(timestamp, _hours);
151 | }
152 | function subMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
153 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMinutes(timestamp, _minutes);
154 | }
155 | function subSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
156 | newTimestamp = BokkyPooBahsDateTimeLibrary.subSeconds(timestamp, _seconds);
157 | }
158 |
159 | function diffYears(uint fromTimestamp, uint toTimestamp) public pure returns (uint _years) {
160 | _years = BokkyPooBahsDateTimeLibrary.diffYears(fromTimestamp, toTimestamp);
161 | }
162 | function diffMonths(uint fromTimestamp, uint toTimestamp) public pure returns (uint _months) {
163 | _months = BokkyPooBahsDateTimeLibrary.diffMonths(fromTimestamp, toTimestamp);
164 | }
165 | function diffDays(uint fromTimestamp, uint toTimestamp) public pure returns (uint _days) {
166 | _days = BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, toTimestamp);
167 | }
168 | function diffHours(uint fromTimestamp, uint toTimestamp) public pure returns (uint _hours) {
169 | _hours = BokkyPooBahsDateTimeLibrary.diffHours(fromTimestamp, toTimestamp);
170 | }
171 | function diffMinutes(uint fromTimestamp, uint toTimestamp) public pure returns (uint _minutes) {
172 | _minutes = BokkyPooBahsDateTimeLibrary.diffMinutes(fromTimestamp, toTimestamp);
173 | }
174 | function diffSeconds(uint fromTimestamp, uint toTimestamp) public pure returns (uint _seconds) {
175 | _seconds = BokkyPooBahsDateTimeLibrary.diffSeconds(fromTimestamp, toTimestamp);
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/contracts/BokkyPooBahsDateTimeLibrary.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.6.0 <0.9.0;
3 |
4 | // ----------------------------------------------------------------------------
5 | // BokkyPooBah's DateTime Library v1.01
6 | //
7 | // A gas-efficient Solidity date and time library
8 | //
9 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
10 | //
11 | // Tested date range 1970/01/01 to 2345/12/31
12 | //
13 | // Conventions:
14 | // Unit | Range | Notes
15 | // :-------- |:-------------:|:-----
16 | // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
17 | // year | 1970 ... 2345 |
18 | // month | 1 ... 12 |
19 | // day | 1 ... 31 |
20 | // hour | 0 ... 23 |
21 | // minute | 0 ... 59 |
22 | // second | 0 ... 59 |
23 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
24 | //
25 | //
26 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
27 | // ----------------------------------------------------------------------------
28 |
29 | library BokkyPooBahsDateTimeLibrary {
30 |
31 | uint constant SECONDS_PER_DAY = 24 * 60 * 60;
32 | uint constant SECONDS_PER_HOUR = 60 * 60;
33 | uint constant SECONDS_PER_MINUTE = 60;
34 | int constant OFFSET19700101 = 2440588;
35 |
36 | uint constant DOW_MON = 1;
37 | uint constant DOW_TUE = 2;
38 | uint constant DOW_WED = 3;
39 | uint constant DOW_THU = 4;
40 | uint constant DOW_FRI = 5;
41 | uint constant DOW_SAT = 6;
42 | uint constant DOW_SUN = 7;
43 |
44 | // ------------------------------------------------------------------------
45 | // Calculate the number of days from 1970/01/01 to year/month/day using
46 | // the date conversion algorithm from
47 | // https://aa.usno.navy.mil/faq/JD_formula.html
48 | // and subtracting the offset 2440588 so that 1970/01/01 is day 0
49 | //
50 | // days = day
51 | // - 32075
52 | // + 1461 * (year + 4800 + (month - 14) / 12) / 4
53 | // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
54 | // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
55 | // - offset
56 | // ------------------------------------------------------------------------
57 | function _daysFromDate(uint year, uint month, uint day) internal pure returns (uint _days) {
58 | require(year >= 1970);
59 | int _year = int(year);
60 | int _month = int(month);
61 | int _day = int(day);
62 |
63 | int __days = _day
64 | - 32075
65 | + 1461 * (_year + 4800 + (_month - 14) / 12) / 4
66 | + 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
67 | - 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
68 | - OFFSET19700101;
69 |
70 | _days = uint(__days);
71 | }
72 |
73 | // ------------------------------------------------------------------------
74 | // Calculate year/month/day from the number of days since 1970/01/01 using
75 | // the date conversion algorithm from
76 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
77 | // and adding the offset 2440588 so that 1970/01/01 is day 0
78 | //
79 | // int L = days + 68569 + offset
80 | // int N = 4 * L / 146097
81 | // L = L - (146097 * N + 3) / 4
82 | // year = 4000 * (L + 1) / 1461001
83 | // L = L - 1461 * year / 4 + 31
84 | // month = 80 * L / 2447
85 | // dd = L - 2447 * month / 80
86 | // L = month / 11
87 | // month = month + 2 - 12 * L
88 | // year = 100 * (N - 49) + year + L
89 | // ------------------------------------------------------------------------
90 | function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) {
91 | int __days = int(_days);
92 |
93 | int L = __days + 68569 + OFFSET19700101;
94 | int N = 4 * L / 146097;
95 | L = L - (146097 * N + 3) / 4;
96 | int _year = 4000 * (L + 1) / 1461001;
97 | L = L - 1461 * _year / 4 + 31;
98 | int _month = 80 * L / 2447;
99 | int _day = L - 2447 * _month / 80;
100 | L = _month / 11;
101 | _month = _month + 2 - 12 * L;
102 | _year = 100 * (N - 49) + _year + L;
103 |
104 | year = uint(_year);
105 | month = uint(_month);
106 | day = uint(_day);
107 | }
108 |
109 | function timestampFromDate(uint year, uint month, uint day) internal pure returns (uint timestamp) {
110 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
111 | }
112 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (uint timestamp) {
113 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
114 | }
115 | function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) {
116 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
117 | }
118 | function timestampToDateTime(uint timestamp) internal pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
119 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
120 | uint secs = timestamp % SECONDS_PER_DAY;
121 | hour = secs / SECONDS_PER_HOUR;
122 | secs = secs % SECONDS_PER_HOUR;
123 | minute = secs / SECONDS_PER_MINUTE;
124 | second = secs % SECONDS_PER_MINUTE;
125 | }
126 |
127 | function isValidDate(uint year, uint month, uint day) internal pure returns (bool valid) {
128 | if (year >= 1970 && month > 0 && month <= 12) {
129 | uint daysInMonth = _getDaysInMonth(year, month);
130 | if (day > 0 && day <= daysInMonth) {
131 | valid = true;
132 | }
133 | }
134 | }
135 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (bool valid) {
136 | if (isValidDate(year, month, day)) {
137 | if (hour < 24 && minute < 60 && second < 60) {
138 | valid = true;
139 | }
140 | }
141 | }
142 | function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
143 | (uint year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
144 | leapYear = _isLeapYear(year);
145 | }
146 | function _isLeapYear(uint year) internal pure returns (bool leapYear) {
147 | leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
148 | }
149 | function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
150 | weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
151 | }
152 | function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
153 | weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
154 | }
155 | function getDaysInMonth(uint timestamp) internal pure returns (uint daysInMonth) {
156 | (uint year, uint month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
157 | daysInMonth = _getDaysInMonth(year, month);
158 | }
159 | function _getDaysInMonth(uint year, uint month) internal pure returns (uint daysInMonth) {
160 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
161 | daysInMonth = 31;
162 | } else if (month != 2) {
163 | daysInMonth = 30;
164 | } else {
165 | daysInMonth = _isLeapYear(year) ? 29 : 28;
166 | }
167 | }
168 | // 1 = Monday, 7 = Sunday
169 | function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
170 | uint _days = timestamp / SECONDS_PER_DAY;
171 | dayOfWeek = (_days + 3) % 7 + 1;
172 | }
173 |
174 | function getYear(uint timestamp) internal pure returns (uint year) {
175 | (year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
176 | }
177 | function getMonth(uint timestamp) internal pure returns (uint month) {
178 | (,month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
179 | }
180 | function getDay(uint timestamp) internal pure returns (uint day) {
181 | (,,day) = _daysToDate(timestamp / SECONDS_PER_DAY);
182 | }
183 | function getHour(uint timestamp) internal pure returns (uint hour) {
184 | uint secs = timestamp % SECONDS_PER_DAY;
185 | hour = secs / SECONDS_PER_HOUR;
186 | }
187 | function getMinute(uint timestamp) internal pure returns (uint minute) {
188 | uint secs = timestamp % SECONDS_PER_HOUR;
189 | minute = secs / SECONDS_PER_MINUTE;
190 | }
191 | function getSecond(uint timestamp) internal pure returns (uint second) {
192 | second = timestamp % SECONDS_PER_MINUTE;
193 | }
194 |
195 | function addYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
196 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
197 | year += _years;
198 | uint daysInMonth = _getDaysInMonth(year, month);
199 | if (day > daysInMonth) {
200 | day = daysInMonth;
201 | }
202 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
203 | require(newTimestamp >= timestamp);
204 | }
205 | function addMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
206 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
207 | month += _months;
208 | year += (month - 1) / 12;
209 | month = (month - 1) % 12 + 1;
210 | uint daysInMonth = _getDaysInMonth(year, month);
211 | if (day > daysInMonth) {
212 | day = daysInMonth;
213 | }
214 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
215 | require(newTimestamp >= timestamp);
216 | }
217 | function addDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
218 | newTimestamp = timestamp + _days * SECONDS_PER_DAY;
219 | require(newTimestamp >= timestamp);
220 | }
221 | function addHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
222 | newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
223 | require(newTimestamp >= timestamp);
224 | }
225 | function addMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
226 | newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
227 | require(newTimestamp >= timestamp);
228 | }
229 | function addSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
230 | newTimestamp = timestamp + _seconds;
231 | require(newTimestamp >= timestamp);
232 | }
233 |
234 | function subYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
235 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
236 | year -= _years;
237 | uint daysInMonth = _getDaysInMonth(year, month);
238 | if (day > daysInMonth) {
239 | day = daysInMonth;
240 | }
241 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
242 | require(newTimestamp <= timestamp);
243 | }
244 | function subMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
245 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
246 | uint yearMonth = year * 12 + (month - 1) - _months;
247 | year = yearMonth / 12;
248 | month = yearMonth % 12 + 1;
249 | uint daysInMonth = _getDaysInMonth(year, month);
250 | if (day > daysInMonth) {
251 | day = daysInMonth;
252 | }
253 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
254 | require(newTimestamp <= timestamp);
255 | }
256 | function subDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
257 | newTimestamp = timestamp - _days * SECONDS_PER_DAY;
258 | require(newTimestamp <= timestamp);
259 | }
260 | function subHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
261 | newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
262 | require(newTimestamp <= timestamp);
263 | }
264 | function subMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
265 | newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
266 | require(newTimestamp <= timestamp);
267 | }
268 | function subSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
269 | newTimestamp = timestamp - _seconds;
270 | require(newTimestamp <= timestamp);
271 | }
272 |
273 | function diffYears(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _years) {
274 | require(fromTimestamp <= toTimestamp);
275 | (uint fromYear,,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
276 | (uint toYear,,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
277 | _years = toYear - fromYear;
278 | }
279 | function diffMonths(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _months) {
280 | require(fromTimestamp <= toTimestamp);
281 | (uint fromYear, uint fromMonth,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
282 | (uint toYear, uint toMonth,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
283 | _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
284 | }
285 | function diffDays(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _days) {
286 | require(fromTimestamp <= toTimestamp);
287 | _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
288 | }
289 | function diffHours(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _hours) {
290 | require(fromTimestamp <= toTimestamp);
291 | _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
292 | }
293 | function diffMinutes(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _minutes) {
294 | require(fromTimestamp <= toTimestamp);
295 | _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
296 | }
297 | function diffSeconds(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _seconds) {
298 | require(fromTimestamp <= toTimestamp);
299 | _seconds = toTimestamp - fromTimestamp;
300 | }
301 | }
302 |
--------------------------------------------------------------------------------
/contracts/TestDateTime.sol:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity >=0.6.0 <0.9.0;
3 |
4 | import "BokkyPooBahsDateTimeLibrary.sol";
5 |
6 | // ----------------------------------------------------------------------------
7 | // Testing BokkyPooBah's DateTime Library
8 | //
9 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
10 | //
11 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
12 | // ----------------------------------------------------------------------------
13 |
14 | contract TestDateTime {
15 | using BokkyPooBahsDateTimeLibrary for uint;
16 |
17 | uint public nextYear;
18 |
19 | function test() public {
20 | uint today = now;
21 | nextYear = today.addYears(1);
22 | }
23 |
24 | function timestampFromDate(uint year, uint month, uint day) public pure returns (uint timestamp) {
25 | return BokkyPooBahsDateTimeLibrary.timestampFromDate(year, month, day);
26 | }
27 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (uint timestamp) {
28 | return BokkyPooBahsDateTimeLibrary.timestampFromDateTime(year, month, day, hour, minute, second);
29 | }
30 | function timestampToDate(uint timestamp) public pure returns (uint year, uint month, uint day) {
31 | (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
32 | }
33 | function timestampToDateTime(uint timestamp) public pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
34 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(timestamp);
35 | }
36 |
37 | function isLeapYear(uint timestamp) public pure returns (bool leapYear) {
38 | leapYear = BokkyPooBahsDateTimeLibrary.isLeapYear(timestamp);
39 | }
40 | function _isLeapYear(uint year) public pure returns (bool leapYear) {
41 | leapYear = BokkyPooBahsDateTimeLibrary._isLeapYear(year);
42 | }
43 | function isWeekDay(uint timestamp) public pure returns (bool weekDay) {
44 | weekDay = BokkyPooBahsDateTimeLibrary.isWeekDay(timestamp);
45 | }
46 | function isWeekEnd(uint timestamp) public pure returns (bool weekEnd) {
47 | weekEnd = BokkyPooBahsDateTimeLibrary.isWeekEnd(timestamp);
48 | }
49 |
50 | function getDaysInMonth(uint timestamp) public pure returns (uint daysInMonth) {
51 | daysInMonth = BokkyPooBahsDateTimeLibrary.getDaysInMonth(timestamp);
52 | }
53 | function _getDaysInMonth(uint year, uint month) public pure returns (uint daysInMonth) {
54 | daysInMonth = BokkyPooBahsDateTimeLibrary._getDaysInMonth(year, month);
55 | }
56 | function getDayOfWeek(uint timestamp) public pure returns (uint dayOfWeek) {
57 | dayOfWeek = BokkyPooBahsDateTimeLibrary.getDayOfWeek(timestamp);
58 | }
59 |
60 | function isValidDate(uint year, uint month, uint day) public pure returns (bool valid) {
61 | valid = BokkyPooBahsDateTimeLibrary.isValidDate(year, month, day);
62 | }
63 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (bool valid) {
64 | valid = BokkyPooBahsDateTimeLibrary.isValidDateTime(year, month, day, hour, minute, second);
65 | }
66 |
67 | function getYear(uint timestamp) public pure returns (uint year) {
68 | year = BokkyPooBahsDateTimeLibrary.getYear(timestamp);
69 | }
70 | function getMonth(uint timestamp) public pure returns (uint month) {
71 | month = BokkyPooBahsDateTimeLibrary.getMonth(timestamp);
72 | }
73 | function getDay(uint timestamp) public pure returns (uint day) {
74 | day = BokkyPooBahsDateTimeLibrary.getDay(timestamp);
75 | }
76 | function getHour(uint timestamp) public pure returns (uint hour) {
77 | hour = BokkyPooBahsDateTimeLibrary.getHour(timestamp);
78 | }
79 | function getMinute(uint timestamp) public pure returns (uint minute) {
80 | minute = BokkyPooBahsDateTimeLibrary.getMinute(timestamp);
81 | }
82 | function getSecond(uint timestamp) public pure returns (uint second) {
83 | second = BokkyPooBahsDateTimeLibrary.getSecond(timestamp);
84 | }
85 |
86 | function addYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
87 | newTimestamp = BokkyPooBahsDateTimeLibrary.addYears(timestamp, _years);
88 | }
89 | function addMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
90 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMonths(timestamp, _months);
91 | }
92 | function addDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
93 | newTimestamp = BokkyPooBahsDateTimeLibrary.addDays(timestamp, _days);
94 | }
95 | function addHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
96 | newTimestamp = BokkyPooBahsDateTimeLibrary.addHours(timestamp, _hours);
97 | }
98 | function addMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
99 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMinutes(timestamp, _minutes);
100 | }
101 | function addSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
102 | newTimestamp = BokkyPooBahsDateTimeLibrary.addSeconds(timestamp, _seconds);
103 | }
104 |
105 | function subYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
106 | newTimestamp = BokkyPooBahsDateTimeLibrary.subYears(timestamp, _years);
107 | }
108 | function subMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
109 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMonths(timestamp, _months);
110 | }
111 | function subDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
112 | newTimestamp = BokkyPooBahsDateTimeLibrary.subDays(timestamp, _days);
113 | }
114 | function subHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
115 | newTimestamp = BokkyPooBahsDateTimeLibrary.subHours(timestamp, _hours);
116 | }
117 | function subMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
118 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMinutes(timestamp, _minutes);
119 | }
120 | function subSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
121 | newTimestamp = BokkyPooBahsDateTimeLibrary.subSeconds(timestamp, _seconds);
122 | }
123 |
124 | function diffYears(uint fromTimestamp, uint toTimestamp) public pure returns (uint _years) {
125 | _years = BokkyPooBahsDateTimeLibrary.diffYears(fromTimestamp, toTimestamp);
126 | }
127 | function diffMonths(uint fromTimestamp, uint toTimestamp) public pure returns (uint _months) {
128 | _months = BokkyPooBahsDateTimeLibrary.diffMonths(fromTimestamp, toTimestamp);
129 | }
130 | function diffDays(uint fromTimestamp, uint toTimestamp) public pure returns (uint _days) {
131 | _days = BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, toTimestamp);
132 | }
133 | function diffHours(uint fromTimestamp, uint toTimestamp) public pure returns (uint _hours) {
134 | _hours = BokkyPooBahsDateTimeLibrary.diffHours(fromTimestamp, toTimestamp);
135 | }
136 | function diffMinutes(uint fromTimestamp, uint toTimestamp) public pure returns (uint _minutes) {
137 | _minutes = BokkyPooBahsDateTimeLibrary.diffMinutes(fromTimestamp, toTimestamp);
138 | }
139 | function diffSeconds(uint fromTimestamp, uint toTimestamp) public pure returns (uint _seconds) {
140 | _seconds = BokkyPooBahsDateTimeLibrary.diffSeconds(fromTimestamp, toTimestamp);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/deployment/BokkyPooBahsDateTimeContract_flattened_v1.00.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.4.23;
2 |
3 | // ----------------------------------------------------------------------------
4 | // BokkyPooBah's DateTime Library v1.00
5 | //
6 | // A gas-efficient Solidity date and time library
7 | //
8 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
9 | //
10 | // Tested date range 1970/01/01 to 2345/12/31
11 | //
12 | // Conventions:
13 | // Unit | Range | Notes
14 | // :-------- |:-------------:|:-----
15 | // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
16 | // year | 1970 ... 2345 |
17 | // month | 1 ... 12 |
18 | // day | 1 ... 31 |
19 | // hour | 0 ... 23 |
20 | // minute | 0 ... 59 |
21 | // second | 0 ... 59 |
22 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
23 | //
24 | //
25 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018.
26 | //
27 | // GNU Lesser General Public License 3.0
28 | // https://www.gnu.org/licenses/lgpl-3.0.en.html
29 | // ----------------------------------------------------------------------------
30 |
31 | library BokkyPooBahsDateTimeLibrary {
32 |
33 | uint constant SECONDS_PER_DAY = 24 * 60 * 60;
34 | uint constant SECONDS_PER_HOUR = 60 * 60;
35 | uint constant SECONDS_PER_MINUTE = 60;
36 | int constant OFFSET19700101 = 2440588;
37 |
38 | uint constant DOW_MON = 1;
39 | uint constant DOW_TUE = 2;
40 | uint constant DOW_WED = 3;
41 | uint constant DOW_THU = 4;
42 | uint constant DOW_FRI = 5;
43 | uint constant DOW_SAT = 6;
44 | uint constant DOW_SUN = 7;
45 |
46 | // ------------------------------------------------------------------------
47 | // Calculate the number of days from 1970/01/01 to year/month/day using
48 | // the date conversion algorithm from
49 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
50 | // and subtracting the offset 2440588 so that 1970/01/01 is day 0
51 | //
52 | // days = day
53 | // - 32075
54 | // + 1461 * (year + 4800 + (month - 14) / 12) / 4
55 | // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
56 | // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
57 | // - offset
58 | // ------------------------------------------------------------------------
59 | function _daysFromDate(uint year, uint month, uint day) internal pure returns (uint _days) {
60 | int _year = int(year);
61 | int _month = int(month);
62 | int _day = int(day);
63 |
64 | int __days = _day
65 | - 32075
66 | + 1461 * (_year + 4800 + (_month - 14) / 12) / 4
67 | + 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
68 | - 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
69 | - OFFSET19700101;
70 |
71 | _days = uint(__days);
72 | }
73 |
74 | // ------------------------------------------------------------------------
75 | // Calculate year/month/day from the number of days since 1970/01/01 using
76 | // the date conversion algorithm from
77 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
78 | // and adding the offset 2440588 so that 1970/01/01 is day 0
79 | //
80 | // int L = days + 68569 + offset
81 | // int N = 4 * L / 146097
82 | // L = L - (146097 * N + 3) / 4
83 | // year = 4000 * (L + 1) / 1461001
84 | // L = L - 1461 * year / 4 + 31
85 | // month = 80 * L / 2447
86 | // dd = L - 2447 * month / 80
87 | // L = month / 11
88 | // month = month + 2 - 12 * L
89 | // year = 100 * (N - 49) + year + L
90 | // ------------------------------------------------------------------------
91 | function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) {
92 | int __days = int(_days);
93 |
94 | int L = __days + 68569 + OFFSET19700101;
95 | int N = 4 * L / 146097;
96 | L = L - (146097 * N + 3) / 4;
97 | int _year = 4000 * (L + 1) / 1461001;
98 | L = L - 1461 * _year / 4 + 31;
99 | int _month = 80 * L / 2447;
100 | int _day = L - 2447 * _month / 80;
101 | L = _month / 11;
102 | _month = _month + 2 - 12 * L;
103 | _year = 100 * (N - 49) + _year + L;
104 |
105 | year = uint(_year);
106 | month = uint(_month);
107 | day = uint(_day);
108 | }
109 |
110 | function timestampFromDate(uint year, uint month, uint day) internal pure returns (uint timestamp) {
111 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
112 | }
113 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (uint timestamp) {
114 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
115 | }
116 | function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) {
117 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
118 | }
119 | function timestampToDateTime(uint timestamp) internal pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
120 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
121 | uint secs = timestamp % SECONDS_PER_DAY;
122 | hour = secs / SECONDS_PER_HOUR;
123 | secs = secs % SECONDS_PER_HOUR;
124 | minute = secs / SECONDS_PER_MINUTE;
125 | second = secs % SECONDS_PER_MINUTE;
126 | }
127 |
128 | function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
129 | uint year;
130 | uint month;
131 | uint day;
132 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
133 | leapYear = _isLeapYear(year);
134 | }
135 | function _isLeapYear(uint year) internal pure returns (bool leapYear) {
136 | leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
137 | }
138 | function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
139 | weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
140 | }
141 | function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
142 | weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
143 | }
144 | function getDaysInMonth(uint timestamp) internal pure returns (uint daysInMonth) {
145 | uint year;
146 | uint month;
147 | uint day;
148 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
149 | daysInMonth = _getDaysInMonth(year, month);
150 | }
151 | function _getDaysInMonth(uint year, uint month) internal pure returns (uint daysInMonth) {
152 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
153 | daysInMonth = 31;
154 | } else if (month != 2) {
155 | daysInMonth = 30;
156 | } else {
157 | daysInMonth = _isLeapYear(year) ? 29 : 28;
158 | }
159 | }
160 | // 1 = Monday, 7 = Sunday
161 | function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
162 | uint _days = timestamp / SECONDS_PER_DAY;
163 | dayOfWeek = (_days + 3) % 7 + 1;
164 | }
165 |
166 | function getYear(uint timestamp) internal pure returns (uint year) {
167 | uint month;
168 | uint day;
169 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
170 | }
171 | function getMonth(uint timestamp) internal pure returns (uint month) {
172 | uint year;
173 | uint day;
174 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
175 | }
176 | function getDay(uint timestamp) internal pure returns (uint day) {
177 | uint year;
178 | uint month;
179 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
180 | }
181 | function getHour(uint timestamp) internal pure returns (uint hour) {
182 | uint secs = timestamp % SECONDS_PER_DAY;
183 | hour = secs / SECONDS_PER_HOUR;
184 | }
185 | function getMinute(uint timestamp) internal pure returns (uint minute) {
186 | uint secs = timestamp % SECONDS_PER_HOUR;
187 | minute = secs / SECONDS_PER_MINUTE;
188 | }
189 | function getSecond(uint timestamp) internal pure returns (uint second) {
190 | second = timestamp % SECONDS_PER_MINUTE;
191 | }
192 |
193 | function addYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
194 | uint year;
195 | uint month;
196 | uint day;
197 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
198 | year += _years;
199 | uint daysInMonth = _getDaysInMonth(year, month);
200 | if (day > daysInMonth) {
201 | day = daysInMonth;
202 | }
203 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
204 | require(newTimestamp >= timestamp);
205 | }
206 | function addMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
207 | uint year;
208 | uint month;
209 | uint day;
210 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
211 | month += _months;
212 | year += (month - 1) / 12;
213 | month = (month - 1) % 12 + 1;
214 | uint daysInMonth = _getDaysInMonth(year, month);
215 | if (day > daysInMonth) {
216 | day = daysInMonth;
217 | }
218 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
219 | require(newTimestamp >= timestamp);
220 | }
221 | function addDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
222 | newTimestamp = timestamp + _days * SECONDS_PER_DAY;
223 | require(newTimestamp >= timestamp);
224 | }
225 | function addHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
226 | newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
227 | require(newTimestamp >= timestamp);
228 | }
229 | function addMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
230 | newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
231 | require(newTimestamp >= timestamp);
232 | }
233 | function addSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
234 | newTimestamp = timestamp + _seconds;
235 | require(newTimestamp >= timestamp);
236 | }
237 |
238 | function subYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
239 | uint year;
240 | uint month;
241 | uint day;
242 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
243 | year -= _years;
244 | uint daysInMonth = _getDaysInMonth(year, month);
245 | if (day > daysInMonth) {
246 | day = daysInMonth;
247 | }
248 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
249 | require(newTimestamp <= timestamp);
250 | }
251 | function subMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
252 | uint year;
253 | uint month;
254 | uint day;
255 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
256 | uint yearMonth = year * 12 + (month - 1) - _months;
257 | year = yearMonth / 12;
258 | month = yearMonth % 12 + 1;
259 | uint daysInMonth = _getDaysInMonth(year, month);
260 | if (day > daysInMonth) {
261 | day = daysInMonth;
262 | }
263 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
264 | require(newTimestamp <= timestamp);
265 | }
266 | function subDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
267 | newTimestamp = timestamp - _days * SECONDS_PER_DAY;
268 | require(newTimestamp <= timestamp);
269 | }
270 | function subHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
271 | newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
272 | require(newTimestamp <= timestamp);
273 | }
274 | function subMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
275 | newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
276 | require(newTimestamp <= timestamp);
277 | }
278 | function subSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
279 | newTimestamp = timestamp - _seconds;
280 | require(newTimestamp <= timestamp);
281 | }
282 |
283 | function diffYears(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _years) {
284 | require(fromTimestamp <= toTimestamp);
285 | uint fromYear;
286 | uint fromMonth;
287 | uint fromDay;
288 | uint toYear;
289 | uint toMonth;
290 | uint toDay;
291 | (fromYear, fromMonth, fromDay) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
292 | (toYear, toMonth, toDay) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
293 | _years = toYear - fromYear;
294 | }
295 | function diffMonths(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _months) {
296 | require(fromTimestamp <= toTimestamp);
297 | uint fromYear;
298 | uint fromMonth;
299 | uint fromDay;
300 | uint toYear;
301 | uint toMonth;
302 | uint toDay;
303 | (fromYear, fromMonth, fromDay) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
304 | (toYear, toMonth, toDay) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
305 | _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
306 | }
307 | function diffDays(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _days) {
308 | require(fromTimestamp <= toTimestamp);
309 | _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
310 | }
311 | function diffHours(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _hours) {
312 | require(fromTimestamp <= toTimestamp);
313 | _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
314 | }
315 | function diffMinutes(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _minutes) {
316 | require(fromTimestamp <= toTimestamp);
317 | _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
318 | }
319 | function diffSeconds(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _seconds) {
320 | require(fromTimestamp <= toTimestamp);
321 | _seconds = toTimestamp - fromTimestamp;
322 | }
323 | }
324 |
325 |
326 | // ----------------------------------------------------------------------------
327 | // BokkyPooBah's DateTime Library v1.00 - Contract Instance
328 | //
329 | // A gas-efficient Solidity date and time library
330 | //
331 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
332 | //
333 | // Tested date range 1970/01/01 to 2345/12/31
334 | //
335 | // Conventions:
336 | // Unit | Range | Notes
337 | // :-------- |:-------------:|:-----
338 | // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
339 | // year | 1970 ... 2345 |
340 | // month | 1 ... 12 |
341 | // day | 1 ... 31 |
342 | // hour | 0 ... 23 |
343 | // minute | 0 ... 59 |
344 | // second | 0 ... 59 |
345 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
346 | //
347 | //
348 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018.
349 | //
350 | // GNU Lesser General Public License 3.0
351 | // https://www.gnu.org/licenses/lgpl-3.0.en.html
352 | // ----------------------------------------------------------------------------
353 |
354 | contract BokkyPooBahsDateTimeContract {
355 | uint public constant SECONDS_PER_DAY = 24 * 60 * 60;
356 | uint public constant SECONDS_PER_HOUR = 60 * 60;
357 | uint public constant SECONDS_PER_MINUTE = 60;
358 | int public constant OFFSET19700101 = 2440588;
359 |
360 | uint public constant DOW_MON = 1;
361 | uint public constant DOW_TUE = 2;
362 | uint public constant DOW_WED = 3;
363 | uint public constant DOW_THU = 4;
364 | uint public constant DOW_FRI = 5;
365 | uint public constant DOW_SAT = 6;
366 | uint public constant DOW_SUN = 7;
367 |
368 | function _now() public view returns (uint timestamp) {
369 | timestamp = now;
370 | }
371 | function _nowDateTime() public view returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
372 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(now);
373 | }
374 | function _daysFromDate(uint year, uint month, uint day) public pure returns (uint _days) {
375 | return BokkyPooBahsDateTimeLibrary._daysFromDate(year, month, day);
376 | }
377 | function _daysToDate(uint _days) public pure returns (uint year, uint month, uint day) {
378 | return BokkyPooBahsDateTimeLibrary._daysToDate(_days);
379 | }
380 | function timestampFromDate(uint year, uint month, uint day) public pure returns (uint timestamp) {
381 | return BokkyPooBahsDateTimeLibrary.timestampFromDate(year, month, day);
382 | }
383 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (uint timestamp) {
384 | return BokkyPooBahsDateTimeLibrary.timestampFromDateTime(year, month, day, hour, minute, second);
385 | }
386 | function timestampToDate(uint timestamp) public pure returns (uint year, uint month, uint day) {
387 | (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
388 | }
389 | function timestampToDateTime(uint timestamp) public pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
390 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(timestamp);
391 | }
392 |
393 | function isLeapYear(uint timestamp) public pure returns (bool leapYear) {
394 | leapYear = BokkyPooBahsDateTimeLibrary.isLeapYear(timestamp);
395 | }
396 | function _isLeapYear(uint year) public pure returns (bool leapYear) {
397 | leapYear = BokkyPooBahsDateTimeLibrary._isLeapYear(year);
398 | }
399 | function isWeekDay(uint timestamp) public pure returns (bool weekDay) {
400 | weekDay = BokkyPooBahsDateTimeLibrary.isWeekDay(timestamp);
401 | }
402 | function isWeekEnd(uint timestamp) public pure returns (bool weekEnd) {
403 | weekEnd = BokkyPooBahsDateTimeLibrary.isWeekEnd(timestamp);
404 | }
405 |
406 | function getDaysInMonth(uint timestamp) public pure returns (uint daysInMonth) {
407 | daysInMonth = BokkyPooBahsDateTimeLibrary.getDaysInMonth(timestamp);
408 | }
409 | function _getDaysInMonth(uint year, uint month) public pure returns (uint daysInMonth) {
410 | daysInMonth = BokkyPooBahsDateTimeLibrary._getDaysInMonth(year, month);
411 | }
412 | function getDayOfWeek(uint timestamp) public pure returns (uint dayOfWeek) {
413 | dayOfWeek = BokkyPooBahsDateTimeLibrary.getDayOfWeek(timestamp);
414 | }
415 |
416 | function getYear(uint timestamp) public pure returns (uint year) {
417 | year = BokkyPooBahsDateTimeLibrary.getYear(timestamp);
418 | }
419 | function getMonth(uint timestamp) public pure returns (uint month) {
420 | month = BokkyPooBahsDateTimeLibrary.getMonth(timestamp);
421 | }
422 | function getDay(uint timestamp) public pure returns (uint day) {
423 | day = BokkyPooBahsDateTimeLibrary.getDay(timestamp);
424 | }
425 | function getHour(uint timestamp) public pure returns (uint hour) {
426 | hour = BokkyPooBahsDateTimeLibrary.getHour(timestamp);
427 | }
428 | function getMinute(uint timestamp) public pure returns (uint minute) {
429 | minute = BokkyPooBahsDateTimeLibrary.getMinute(timestamp);
430 | }
431 | function getSecond(uint timestamp) public pure returns (uint second) {
432 | second = BokkyPooBahsDateTimeLibrary.getSecond(timestamp);
433 | }
434 |
435 | function addYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
436 | newTimestamp = BokkyPooBahsDateTimeLibrary.addYears(timestamp, _years);
437 | }
438 | function addMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
439 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMonths(timestamp, _months);
440 | }
441 | function addDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
442 | newTimestamp = BokkyPooBahsDateTimeLibrary.addDays(timestamp, _days);
443 | }
444 | function addHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
445 | newTimestamp = BokkyPooBahsDateTimeLibrary.addHours(timestamp, _hours);
446 | }
447 | function addMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
448 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMinutes(timestamp, _minutes);
449 | }
450 | function addSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
451 | newTimestamp = BokkyPooBahsDateTimeLibrary.addSeconds(timestamp, _seconds);
452 | }
453 |
454 | function subYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
455 | newTimestamp = BokkyPooBahsDateTimeLibrary.subYears(timestamp, _years);
456 | }
457 | function subMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
458 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMonths(timestamp, _months);
459 | }
460 | function subDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
461 | newTimestamp = BokkyPooBahsDateTimeLibrary.subDays(timestamp, _days);
462 | }
463 | function subHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
464 | newTimestamp = BokkyPooBahsDateTimeLibrary.subHours(timestamp, _hours);
465 | }
466 | function subMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
467 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMinutes(timestamp, _minutes);
468 | }
469 | function subSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
470 | newTimestamp = BokkyPooBahsDateTimeLibrary.subSeconds(timestamp, _seconds);
471 | }
472 |
473 | function diffYears(uint fromTimestamp, uint toTimestamp) public pure returns (uint _years) {
474 | _years = BokkyPooBahsDateTimeLibrary.diffYears(fromTimestamp, toTimestamp);
475 | }
476 | function diffMonths(uint fromTimestamp, uint toTimestamp) public pure returns (uint _months) {
477 | _months = BokkyPooBahsDateTimeLibrary.diffMonths(fromTimestamp, toTimestamp);
478 | }
479 | function diffDays(uint fromTimestamp, uint toTimestamp) public pure returns (uint _days) {
480 | _days = BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, toTimestamp);
481 | }
482 | function diffHours(uint fromTimestamp, uint toTimestamp) public pure returns (uint _hours) {
483 | _hours = BokkyPooBahsDateTimeLibrary.diffHours(fromTimestamp, toTimestamp);
484 | }
485 | function diffMinutes(uint fromTimestamp, uint toTimestamp) public pure returns (uint _minutes) {
486 | _minutes = BokkyPooBahsDateTimeLibrary.diffMinutes(fromTimestamp, toTimestamp);
487 | }
488 | function diffSeconds(uint fromTimestamp, uint toTimestamp) public pure returns (uint _seconds) {
489 | _seconds = BokkyPooBahsDateTimeLibrary.diffSeconds(fromTimestamp, toTimestamp);
490 | }
491 | }
--------------------------------------------------------------------------------
/deployment/deployment-v1.00-prerelease.md:
--------------------------------------------------------------------------------
1 | # Deployment
2 |
3 | Compiled with Remix with Solidity 0.4.24+commit.e67f0147.Emscripten.clang and optimisation switched on
4 |
5 |
6 |
7 |
8 |
9 | ## Deploy From Remix To Ropsten Via Geth
10 |
11 | ```javascript
12 | var bokkypoobahsdatetimecontractContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_hours","type":"uint256"}],"name":"subHours","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"fromTimestamp","type":"uint256"},{"name":"toTimestamp","type":"uint256"}],"name":"diffMinutes","outputs":[{"name":"_minutes","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getDaysInMonth","outputs":[{"name":"daysInMonth","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOW_TUE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"}],"name":"_daysFromDate","outputs":[{"name":"_days","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"}],"name":"timestampFromDate","outputs":[{"name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getDayOfWeek","outputs":[{"name":"dayOfWeek","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOW_SUN","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fromTimestamp","type":"uint256"},{"name":"toTimestamp","type":"uint256"}],"name":"diffHours","outputs":[{"name":"_hours","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getHour","outputs":[{"name":"hour","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"}],"name":"_getDaysInMonth","outputs":[{"name":"daysInMonth","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_months","type":"uint256"}],"name":"addMonths","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"isWeekEnd","outputs":[{"name":"weekEnd","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_years","type":"uint256"}],"name":"addYears","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_years","type":"uint256"}],"name":"subYears","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_hours","type":"uint256"}],"name":"addHours","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"SECONDS_PER_HOUR","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"},{"name":"hour","type":"uint256"},{"name":"minute","type":"uint256"},{"name":"second","type":"uint256"}],"name":"timestampFromDateTime","outputs":[{"name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"fromTimestamp","type":"uint256"},{"name":"toTimestamp","type":"uint256"}],"name":"diffSeconds","outputs":[{"name":"_seconds","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getDay","outputs":[{"name":"day","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_days","type":"uint256"}],"name":"addDays","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"SECONDS_PER_DAY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fromTimestamp","type":"uint256"},{"name":"toTimestamp","type":"uint256"}],"name":"diffMonths","outputs":[{"name":"_months","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_minutes","type":"uint256"}],"name":"addMinutes","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getSecond","outputs":[{"name":"second","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOW_WED","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_seconds","type":"uint256"}],"name":"addSeconds","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"_days","type":"uint256"}],"name":"_daysToDate","outputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"_nowDateTime","outputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"},{"name":"hour","type":"uint256"},{"name":"minute","type":"uint256"},{"name":"second","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getYear","outputs":[{"name":"year","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_minutes","type":"uint256"}],"name":"subMinutes","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getMonth","outputs":[{"name":"month","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"OFFSET19700101","outputs":[{"name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_months","type":"uint256"}],"name":"subMonths","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"year","type":"uint256"}],"name":"_isLeapYear","outputs":[{"name":"leapYear","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"_now","outputs":[{"name":"timestamp","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"isLeapYear","outputs":[{"name":"leapYear","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_days","type":"uint256"}],"name":"subDays","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOW_SAT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fromTimestamp","type":"uint256"},{"name":"toTimestamp","type":"uint256"}],"name":"diffDays","outputs":[{"name":"_days","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOW_THU","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DOW_FRI","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"isWeekDay","outputs":[{"name":"weekDay","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"timestampToDate","outputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"SECONDS_PER_MINUTE","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"timestampToDateTime","outputs":[{"name":"year","type":"uint256"},{"name":"month","type":"uint256"},{"name":"day","type":"uint256"},{"name":"hour","type":"uint256"},{"name":"minute","type":"uint256"},{"name":"second","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"},{"name":"_seconds","type":"uint256"}],"name":"subSeconds","outputs":[{"name":"newTimestamp","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"DOW_MON","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"timestamp","type":"uint256"}],"name":"getMinute","outputs":[{"name":"minute","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"fromTimestamp","type":"uint256"},{"name":"toTimestamp","type":"uint256"}],"name":"diffYears","outputs":[{"name":"_years","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]);
13 | var bokkypoobahsdatetimecontract = bokkypoobahsdatetimecontractContract.new(
14 | {
15 | from: web3.eth.accounts[1],
16 | data: '0x608060405234801561001057600080fd5b50611091806100206000396000f30060806040526004361061025a5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041662501553811461025f57806302e98e0d1461028c57806310848ddf146102a7578063126702a0146102bf5780631e0582e9146102d45780631f4f77b2146102f257806322f8a2b81461031057806329441674146103285780632af123b81461033d5780633e239e1a146103585780633f9e0eb7146103705780634355644d1461038b5780634371c465146103a6578063442b8c79146103d2578063444fda82146103ed5780634b321502146104085780634df86126146104235780635e05bd6d1461043857806362fb96971461045f57806365c728401461047a5780637217523c1461049257806374f0314f146104ad5780637be34109146104c257806389a3a00d146104dd5780638aa001fc146104f85780638bbf51b7146105105780638d4a2d391461052557806390059aed146105405780639220d4261461057657806392d66313146105be5780639e524caa146105d6578063a324ad24146105f1578063a3f144ae14610609578063ad203bd41461061e578063b05eb08d14610639578063b3bb8cd414610651578063b8d16dbc14610666578063c7b6fd6a1461067e578063c7edf88c14610699578063c9d34622146106ae578063cfbb9f37146106c9578063d2b50743146106de578063d6582d0d146106f3578063de5101af1461070b578063e955643014610723578063ea1c169014610738578063f615ed5414610750578063f9fd52501461076b578063fa93f88314610780578063ff2258cb14610798575b600080fd5b34801561026b57600080fd5b5061027a6004356024356107b3565b60408051918252519081900360200190f35b34801561029857600080fd5b5061027a6004356024356107c6565b3480156102b357600080fd5b5061027a6004356107d2565b3480156102cb57600080fd5b5061027a6107e3565b3480156102e057600080fd5b5061027a6004356024356044356107e8565b3480156102fe57600080fd5b5061027a6004356024356044356107fd565b34801561031c57600080fd5b5061027a60043561080a565b34801561033457600080fd5b5061027a610815565b34801561034957600080fd5b5061027a60043560243561081a565b34801561036457600080fd5b5061027a600435610826565b34801561037c57600080fd5b5061027a600435602435610831565b34801561039757600080fd5b5061027a60043560243561083d565b3480156103b257600080fd5b506103be600435610849565b604080519115158252519081900360200190f35b3480156103de57600080fd5b5061027a600435602435610854565b3480156103f957600080fd5b5061027a600435602435610860565b34801561041457600080fd5b5061027a60043560243561086c565b34801561042f57600080fd5b5061027a610878565b34801561044457600080fd5b5061027a60043560243560443560643560843560a43561087e565b34801561046b57600080fd5b5061027a600435602435610899565b34801561048657600080fd5b5061027a6004356108a5565b34801561049e57600080fd5b5061027a6004356024356108b0565b3480156104b957600080fd5b5061027a6108bc565b3480156104ce57600080fd5b5061027a6004356024356108c3565b3480156104e957600080fd5b5061027a6004356024356108cf565b34801561050457600080fd5b5061027a6004356108db565b34801561051c57600080fd5b5061027a6108e6565b34801561053157600080fd5b5061027a6004356024356108eb565b34801561054c57600080fd5b506105586004356108f7565b60408051938452602084019290925282820152519081900360600190f35b34801561058257600080fd5b5061058b610912565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b3480156105ca57600080fd5b5061027a600435610937565b3480156105e257600080fd5b5061027a600435602435610942565b3480156105fd57600080fd5b5061027a60043561094e565b34801561061557600080fd5b5061027a610959565b34801561062a57600080fd5b5061027a600435602435610960565b34801561064557600080fd5b506103be60043561096c565b34801561065d57600080fd5b5061027a610977565b34801561067257600080fd5b506103be60043561097b565b34801561068a57600080fd5b5061027a600435602435610986565b3480156106a557600080fd5b5061027a610992565b3480156106ba57600080fd5b5061027a600435602435610997565b3480156106d557600080fd5b5061027a6109a3565b3480156106ea57600080fd5b5061027a6109a8565b3480156106ff57600080fd5b506103be6004356109ad565b34801561071757600080fd5b506105586004356109b8565b34801561072f57600080fd5b5061027a6109d3565b34801561074457600080fd5b5061058b6004356109d8565b34801561075c57600080fd5b5061027a6004356024356109fe565b34801561077757600080fd5b5061027a610a0a565b34801561078c57600080fd5b5061027a600435610a0f565b3480156107a457600080fd5b5061027a600435602435610a1a565b60006107bf8383610a26565b9392505050565b60006107bf8383610a3a565b60006107dd82610a57565b92915050565b600281565b60006107f5848484610a85565b949350505050565b60006107f5848484610ad9565b60006107dd82610af3565b600781565b60006107bf8383610b06565b60006107dd82610b20565b60006107bf8383610b2e565b60006107bf8383610bb4565b60006107dd82610c2a565b60006107bf8383610c3f565b60006107bf8383610c65565b60006107bf8383610cc0565b610e1081565b600061088e878787878787610cd4565b979650505050505050565b60006107bf8383610cfe565b60006107dd82610d12565b60006107bf8383610d2d565b6201518081565b60006107bf8383610d42565b60006107bf8383610d96565b60006107dd82610da9565b600381565b60006107bf8383610db0565b600080600061090584610dc0565b9250925092509193909250565b60008060008060008061092442610e55565b949b939a50919850965094509092509050565b60006107dd82610e96565b60006107bf8383610eb2565b60006107dd82610ec5565b62253d8c81565b60006107bf8383610ee0565b60006107dd82610f61565b4290565b60006107dd82610f86565b60006107bf8383610fa8565b600681565b60006107bf8383610fbd565b600481565b600581565b60006107dd82610fd8565b60008060006109c684610fed565b9196909550909350915050565b603c81565b6000806000806000806109ea87610e55565b949c939b5091995097509550909350915050565b60006107bf8383610ffe565b600181565b60006107dd8261100e565b60006107bf838361101d565b610e1081028203828111156107dd57600080fd5b600081831115610a4957600080fd5b603c8383035b049392505050565b6000808080610a6b62015180865b04610dc0565b91945092509050610a7c8383610b2e565b95945050505050565b6225bad61960046064600c600d1986018190059687016113248101929092056003028390056112c09092016105b502929092059093016001199582029094039490940161016f029390930591909101030190565b600062015180610aea858585610a85565b02949350505050565b6007620151809091046003010660010190565b600081831115610b1557600080fd5b610e10838303610a4f565b610e10620151809091060490565b60008160011480610b3f5750816003145b80610b4a5750816005145b80610b555750816007145b80610b605750816008145b80610b6b575081600a145b80610b76575081600c145b15610b835750601f6107dd565b60028214610b935750601e6107dd565b610b9c83610f61565b610ba757601c610baa565b601d5b60ff169392505050565b600080808080610bc76201518088610a65565b600c91890160001901828104939093019650910660010193509150610bec8484610b2e565b905080821115610bfa578091505b62015180870662015180610c0f868686610a85565b0201945086851015610c2057600080fd5b5050505092915050565b60006006610c3783610af3565b101592915050565b600080808080610c526201518088610a65565b918801955093509150610bec8484610b2e565b600080808080610c786201518088610a65565b91889003955093509150610c8c8484610b2e565b905080821115610c9a578091505b62015180870662015180610caf868686610a85565b0201945086851115610c2057600080fd5b610e1081028201828110156107dd57600080fd5b600081603c8402610e10860262015180610cef8b8b8b610a85565b02010101979650505050505050565b600081831115610d0d57600080fd5b500390565b60008080610d236201518085610a65565b9695505050505050565b6201518081028201828110156107dd57600080fd5b600080808080808087891115610d5757600080fd5b610d64620151808a610a65565b91975095509350610d786201518089610a65565b50600c97880297909102019590950393909303979650505050505050565b603c81028201828110156107dd57600080fd5b603c900690565b818101828110156107dd57600080fd5b60008080836226496581018280808062023ab1600486020593506004600362023ab1860201059094039362164b09610fa0600187010205925060046105b58402058503601f01945061098f85605002811515610e1857fe5b059150605061098f83020585039050600b820560301994909401606402929092018301996002600c90940290910392909201975095509350505050565b6000808080808080610e6a6201518089610a65565b919a9099919850610e10620151809092068281049850603c929006828104975091909106945092505050565b60008080610ea76201518085610a65565b509095945050505050565b603c81028203828111156107dd57600080fd5b60008080610ed66201518085610a65565b5095945050505050565b60008080808080610ef46201518089610a65565b91965094509250600c808602850188900360001901925082049450600c82066001019350610f228585610b2e565b905080831115610f30578092505b62015180880662015180610f45878787610a85565b0201955087861115610f5657600080fd5b505050505092915050565b600060048206158015610f7657506064820615155b806107dd57505061019090061590565b6000808080610f986201518086610a65565b91945092509050610a7c83610f61565b6201518081028203828111156107dd57600080fd5b600081831115610fcc57600080fd5b62015180838303610a4f565b60006005610fe583610af3565b111592915050565b600080806109c66201518085610a65565b808203828111156107dd57600080fd5b6000610e108206603c81610a4f565b60008080808080808789111561103257600080fd5b61103f620151808a610a65565b919750955093506110536201518089610a65565b505095909503989750505050505050505600a165627a7a72305820d4f1389ffe027f893a43a30bb50d36944b44ec9d5e69c6327987a6ef9e41a1d60029',
17 | gas: '4700000'
18 | }, function (e, contract){
19 | console.log(e, contract);
20 | if (typeof contract.address !== 'undefined') {
21 | console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
22 | }
23 | })
24 | ```
25 |
26 | ```
27 | INFO [06-04|17:10:54] Submitted contract creation fullhash=0xf1cfcf58e4f9428da80d8c79e299668fb93959177ca400ed8ae18ed46c9fbae2 contract=0x07239Bb079094481bfAAc91cA842426860021Aaa
28 | ```
29 |
30 | Deployment transaction https://ropsten.etherscan.io/tx/0xf1cfcf58e4f9428da80d8c79e299668fb93959177ca400ed8ae18ed46c9fbae2 with 1,181,383 gas used.
31 |
32 | Deployed contract to https://ropsten.etherscan.io/address/0x07239bb079094481bfaac91ca842426860021aaa#code
--------------------------------------------------------------------------------
/docs/ConvertingBetweenJulianDatesAndGregorianCalendarDates.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/1dc26f977c57a6ba3ed6d7c53cafdb191e7e59ae/docs/ConvertingBetweenJulianDatesAndGregorianCalendarDates.pdf
--------------------------------------------------------------------------------
/docs/timestampFromDateTime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/1dc26f977c57a6ba3ed6d7c53cafdb191e7e59ae/docs/timestampFromDateTime.png
--------------------------------------------------------------------------------
/docs/timestampToDateTime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/1dc26f977c57a6ba3ed6d7c53cafdb191e7e59ae/docs/timestampToDateTime.png
--------------------------------------------------------------------------------
/flattened/TestDateTime_flattened.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.6.0;
2 |
3 |
4 | // ----------------------------------------------------------------------------
5 | // BokkyPooBah's DateTime Library v1.01
6 | //
7 | // A gas-efficient Solidity date and time library
8 | //
9 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
10 | //
11 | // Tested date range 1970/01/01 to 2345/12/31
12 | //
13 | // Conventions:
14 | // Unit | Range | Notes
15 | // :-------- |:-------------:|:-----
16 | // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
17 | // year | 1970 ... 2345 |
18 | // month | 1 ... 12 |
19 | // day | 1 ... 31 |
20 | // hour | 0 ... 23 |
21 | // minute | 0 ... 59 |
22 | // second | 0 ... 59 |
23 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
24 | //
25 | //
26 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
27 | // ----------------------------------------------------------------------------
28 |
29 | library BokkyPooBahsDateTimeLibrary {
30 |
31 | uint constant SECONDS_PER_DAY = 24 * 60 * 60;
32 | uint constant SECONDS_PER_HOUR = 60 * 60;
33 | uint constant SECONDS_PER_MINUTE = 60;
34 | int constant OFFSET19700101 = 2440588;
35 |
36 | uint constant DOW_MON = 1;
37 | uint constant DOW_TUE = 2;
38 | uint constant DOW_WED = 3;
39 | uint constant DOW_THU = 4;
40 | uint constant DOW_FRI = 5;
41 | uint constant DOW_SAT = 6;
42 | uint constant DOW_SUN = 7;
43 |
44 | // ------------------------------------------------------------------------
45 | // Calculate the number of days from 1970/01/01 to year/month/day using
46 | // the date conversion algorithm from
47 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
48 | // and subtracting the offset 2440588 so that 1970/01/01 is day 0
49 | //
50 | // days = day
51 | // - 32075
52 | // + 1461 * (year + 4800 + (month - 14) / 12) / 4
53 | // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
54 | // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
55 | // - offset
56 | // ------------------------------------------------------------------------
57 | function _daysFromDate(uint year, uint month, uint day) internal pure returns (uint _days) {
58 | require(year >= 1970);
59 | int _year = int(year);
60 | int _month = int(month);
61 | int _day = int(day);
62 |
63 | int __days = _day
64 | - 32075
65 | + 1461 * (_year + 4800 + (_month - 14) / 12) / 4
66 | + 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
67 | - 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
68 | - OFFSET19700101;
69 |
70 | _days = uint(__days);
71 | }
72 |
73 | // ------------------------------------------------------------------------
74 | // Calculate year/month/day from the number of days since 1970/01/01 using
75 | // the date conversion algorithm from
76 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
77 | // and adding the offset 2440588 so that 1970/01/01 is day 0
78 | //
79 | // int L = days + 68569 + offset
80 | // int N = 4 * L / 146097
81 | // L = L - (146097 * N + 3) / 4
82 | // year = 4000 * (L + 1) / 1461001
83 | // L = L - 1461 * year / 4 + 31
84 | // month = 80 * L / 2447
85 | // dd = L - 2447 * month / 80
86 | // L = month / 11
87 | // month = month + 2 - 12 * L
88 | // year = 100 * (N - 49) + year + L
89 | // ------------------------------------------------------------------------
90 | function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) {
91 | int __days = int(_days);
92 |
93 | int L = __days + 68569 + OFFSET19700101;
94 | int N = 4 * L / 146097;
95 | L = L - (146097 * N + 3) / 4;
96 | int _year = 4000 * (L + 1) / 1461001;
97 | L = L - 1461 * _year / 4 + 31;
98 | int _month = 80 * L / 2447;
99 | int _day = L - 2447 * _month / 80;
100 | L = _month / 11;
101 | _month = _month + 2 - 12 * L;
102 | _year = 100 * (N - 49) + _year + L;
103 |
104 | year = uint(_year);
105 | month = uint(_month);
106 | day = uint(_day);
107 | }
108 |
109 | function timestampFromDate(uint year, uint month, uint day) internal pure returns (uint timestamp) {
110 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
111 | }
112 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (uint timestamp) {
113 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
114 | }
115 | function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) {
116 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
117 | }
118 | function timestampToDateTime(uint timestamp) internal pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
119 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
120 | uint secs = timestamp % SECONDS_PER_DAY;
121 | hour = secs / SECONDS_PER_HOUR;
122 | secs = secs % SECONDS_PER_HOUR;
123 | minute = secs / SECONDS_PER_MINUTE;
124 | second = secs % SECONDS_PER_MINUTE;
125 | }
126 |
127 | function isValidDate(uint year, uint month, uint day) internal pure returns (bool valid) {
128 | if (year >= 1970 && month > 0 && month <= 12) {
129 | uint daysInMonth = _getDaysInMonth(year, month);
130 | if (day > 0 && day <= daysInMonth) {
131 | valid = true;
132 | }
133 | }
134 | }
135 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (bool valid) {
136 | if (isValidDate(year, month, day)) {
137 | if (hour < 24 && minute < 60 && second < 60) {
138 | valid = true;
139 | }
140 | }
141 | }
142 | function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
143 | (uint year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
144 | leapYear = _isLeapYear(year);
145 | }
146 | function _isLeapYear(uint year) internal pure returns (bool leapYear) {
147 | leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
148 | }
149 | function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
150 | weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
151 | }
152 | function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
153 | weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
154 | }
155 | function getDaysInMonth(uint timestamp) internal pure returns (uint daysInMonth) {
156 | (uint year, uint month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
157 | daysInMonth = _getDaysInMonth(year, month);
158 | }
159 | function _getDaysInMonth(uint year, uint month) internal pure returns (uint daysInMonth) {
160 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
161 | daysInMonth = 31;
162 | } else if (month != 2) {
163 | daysInMonth = 30;
164 | } else {
165 | daysInMonth = _isLeapYear(year) ? 29 : 28;
166 | }
167 | }
168 | // 1 = Monday, 7 = Sunday
169 | function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
170 | uint _days = timestamp / SECONDS_PER_DAY;
171 | dayOfWeek = (_days + 3) % 7 + 1;
172 | }
173 |
174 | function getYear(uint timestamp) internal pure returns (uint year) {
175 | (year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
176 | }
177 | function getMonth(uint timestamp) internal pure returns (uint month) {
178 | (,month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
179 | }
180 | function getDay(uint timestamp) internal pure returns (uint day) {
181 | (,,day) = _daysToDate(timestamp / SECONDS_PER_DAY);
182 | }
183 | function getHour(uint timestamp) internal pure returns (uint hour) {
184 | uint secs = timestamp % SECONDS_PER_DAY;
185 | hour = secs / SECONDS_PER_HOUR;
186 | }
187 | function getMinute(uint timestamp) internal pure returns (uint minute) {
188 | uint secs = timestamp % SECONDS_PER_HOUR;
189 | minute = secs / SECONDS_PER_MINUTE;
190 | }
191 | function getSecond(uint timestamp) internal pure returns (uint second) {
192 | second = timestamp % SECONDS_PER_MINUTE;
193 | }
194 |
195 | function addYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
196 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
197 | year += _years;
198 | uint daysInMonth = _getDaysInMonth(year, month);
199 | if (day > daysInMonth) {
200 | day = daysInMonth;
201 | }
202 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
203 | require(newTimestamp >= timestamp);
204 | }
205 | function addMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
206 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
207 | month += _months;
208 | year += (month - 1) / 12;
209 | month = (month - 1) % 12 + 1;
210 | uint daysInMonth = _getDaysInMonth(year, month);
211 | if (day > daysInMonth) {
212 | day = daysInMonth;
213 | }
214 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
215 | require(newTimestamp >= timestamp);
216 | }
217 | function addDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
218 | newTimestamp = timestamp + _days * SECONDS_PER_DAY;
219 | require(newTimestamp >= timestamp);
220 | }
221 | function addHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
222 | newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
223 | require(newTimestamp >= timestamp);
224 | }
225 | function addMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
226 | newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
227 | require(newTimestamp >= timestamp);
228 | }
229 | function addSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
230 | newTimestamp = timestamp + _seconds;
231 | require(newTimestamp >= timestamp);
232 | }
233 |
234 | function subYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
235 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
236 | year -= _years;
237 | uint daysInMonth = _getDaysInMonth(year, month);
238 | if (day > daysInMonth) {
239 | day = daysInMonth;
240 | }
241 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
242 | require(newTimestamp <= timestamp);
243 | }
244 | function subMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
245 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
246 | uint yearMonth = year * 12 + (month - 1) - _months;
247 | year = yearMonth / 12;
248 | month = yearMonth % 12 + 1;
249 | uint daysInMonth = _getDaysInMonth(year, month);
250 | if (day > daysInMonth) {
251 | day = daysInMonth;
252 | }
253 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
254 | require(newTimestamp <= timestamp);
255 | }
256 | function subDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
257 | newTimestamp = timestamp - _days * SECONDS_PER_DAY;
258 | require(newTimestamp <= timestamp);
259 | }
260 | function subHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
261 | newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
262 | require(newTimestamp <= timestamp);
263 | }
264 | function subMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
265 | newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
266 | require(newTimestamp <= timestamp);
267 | }
268 | function subSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
269 | newTimestamp = timestamp - _seconds;
270 | require(newTimestamp <= timestamp);
271 | }
272 |
273 | function diffYears(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _years) {
274 | require(fromTimestamp <= toTimestamp);
275 | (uint fromYear,,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
276 | (uint toYear,,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
277 | _years = toYear - fromYear;
278 | }
279 | function diffMonths(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _months) {
280 | require(fromTimestamp <= toTimestamp);
281 | (uint fromYear, uint fromMonth,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
282 | (uint toYear, uint toMonth,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
283 | _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
284 | }
285 | function diffDays(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _days) {
286 | require(fromTimestamp <= toTimestamp);
287 | _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
288 | }
289 | function diffHours(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _hours) {
290 | require(fromTimestamp <= toTimestamp);
291 | _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
292 | }
293 | function diffMinutes(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _minutes) {
294 | require(fromTimestamp <= toTimestamp);
295 | _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
296 | }
297 | function diffSeconds(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _seconds) {
298 | require(fromTimestamp <= toTimestamp);
299 | _seconds = toTimestamp - fromTimestamp;
300 | }
301 | }
302 |
303 | // ----------------------------------------------------------------------------
304 | // Testing BokkyPooBah's DateTime Library
305 | //
306 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
307 | //
308 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
309 | // ----------------------------------------------------------------------------
310 |
311 | contract TestDateTime {
312 | using BokkyPooBahsDateTimeLibrary for uint;
313 |
314 | uint public nextYear;
315 |
316 | function test() public {
317 | uint today = now;
318 | nextYear = today.addYears(1);
319 | }
320 |
321 | function timestampFromDate(uint year, uint month, uint day) public pure returns (uint timestamp) {
322 | return BokkyPooBahsDateTimeLibrary.timestampFromDate(year, month, day);
323 | }
324 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (uint timestamp) {
325 | return BokkyPooBahsDateTimeLibrary.timestampFromDateTime(year, month, day, hour, minute, second);
326 | }
327 | function timestampToDate(uint timestamp) public pure returns (uint year, uint month, uint day) {
328 | (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
329 | }
330 | function timestampToDateTime(uint timestamp) public pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
331 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(timestamp);
332 | }
333 |
334 | function isLeapYear(uint timestamp) public pure returns (bool leapYear) {
335 | leapYear = BokkyPooBahsDateTimeLibrary.isLeapYear(timestamp);
336 | }
337 | function _isLeapYear(uint year) public pure returns (bool leapYear) {
338 | leapYear = BokkyPooBahsDateTimeLibrary._isLeapYear(year);
339 | }
340 | function isWeekDay(uint timestamp) public pure returns (bool weekDay) {
341 | weekDay = BokkyPooBahsDateTimeLibrary.isWeekDay(timestamp);
342 | }
343 | function isWeekEnd(uint timestamp) public pure returns (bool weekEnd) {
344 | weekEnd = BokkyPooBahsDateTimeLibrary.isWeekEnd(timestamp);
345 | }
346 |
347 | function getDaysInMonth(uint timestamp) public pure returns (uint daysInMonth) {
348 | daysInMonth = BokkyPooBahsDateTimeLibrary.getDaysInMonth(timestamp);
349 | }
350 | function _getDaysInMonth(uint year, uint month) public pure returns (uint daysInMonth) {
351 | daysInMonth = BokkyPooBahsDateTimeLibrary._getDaysInMonth(year, month);
352 | }
353 | function getDayOfWeek(uint timestamp) public pure returns (uint dayOfWeek) {
354 | dayOfWeek = BokkyPooBahsDateTimeLibrary.getDayOfWeek(timestamp);
355 | }
356 |
357 | function isValidDate(uint year, uint month, uint day) public pure returns (bool valid) {
358 | valid = BokkyPooBahsDateTimeLibrary.isValidDate(year, month, day);
359 | }
360 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (bool valid) {
361 | valid = BokkyPooBahsDateTimeLibrary.isValidDateTime(year, month, day, hour, minute, second);
362 | }
363 |
364 | function getYear(uint timestamp) public pure returns (uint year) {
365 | year = BokkyPooBahsDateTimeLibrary.getYear(timestamp);
366 | }
367 | function getMonth(uint timestamp) public pure returns (uint month) {
368 | month = BokkyPooBahsDateTimeLibrary.getMonth(timestamp);
369 | }
370 | function getDay(uint timestamp) public pure returns (uint day) {
371 | day = BokkyPooBahsDateTimeLibrary.getDay(timestamp);
372 | }
373 | function getHour(uint timestamp) public pure returns (uint hour) {
374 | hour = BokkyPooBahsDateTimeLibrary.getHour(timestamp);
375 | }
376 | function getMinute(uint timestamp) public pure returns (uint minute) {
377 | minute = BokkyPooBahsDateTimeLibrary.getMinute(timestamp);
378 | }
379 | function getSecond(uint timestamp) public pure returns (uint second) {
380 | second = BokkyPooBahsDateTimeLibrary.getSecond(timestamp);
381 | }
382 |
383 | function addYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
384 | newTimestamp = BokkyPooBahsDateTimeLibrary.addYears(timestamp, _years);
385 | }
386 | function addMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
387 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMonths(timestamp, _months);
388 | }
389 | function addDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
390 | newTimestamp = BokkyPooBahsDateTimeLibrary.addDays(timestamp, _days);
391 | }
392 | function addHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
393 | newTimestamp = BokkyPooBahsDateTimeLibrary.addHours(timestamp, _hours);
394 | }
395 | function addMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
396 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMinutes(timestamp, _minutes);
397 | }
398 | function addSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
399 | newTimestamp = BokkyPooBahsDateTimeLibrary.addSeconds(timestamp, _seconds);
400 | }
401 |
402 | function subYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
403 | newTimestamp = BokkyPooBahsDateTimeLibrary.subYears(timestamp, _years);
404 | }
405 | function subMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
406 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMonths(timestamp, _months);
407 | }
408 | function subDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
409 | newTimestamp = BokkyPooBahsDateTimeLibrary.subDays(timestamp, _days);
410 | }
411 | function subHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
412 | newTimestamp = BokkyPooBahsDateTimeLibrary.subHours(timestamp, _hours);
413 | }
414 | function subMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
415 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMinutes(timestamp, _minutes);
416 | }
417 | function subSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
418 | newTimestamp = BokkyPooBahsDateTimeLibrary.subSeconds(timestamp, _seconds);
419 | }
420 |
421 | function diffYears(uint fromTimestamp, uint toTimestamp) public pure returns (uint _years) {
422 | _years = BokkyPooBahsDateTimeLibrary.diffYears(fromTimestamp, toTimestamp);
423 | }
424 | function diffMonths(uint fromTimestamp, uint toTimestamp) public pure returns (uint _months) {
425 | _months = BokkyPooBahsDateTimeLibrary.diffMonths(fromTimestamp, toTimestamp);
426 | }
427 | function diffDays(uint fromTimestamp, uint toTimestamp) public pure returns (uint _days) {
428 | _days = BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, toTimestamp);
429 | }
430 | function diffHours(uint fromTimestamp, uint toTimestamp) public pure returns (uint _hours) {
431 | _hours = BokkyPooBahsDateTimeLibrary.diffHours(fromTimestamp, toTimestamp);
432 | }
433 | function diffMinutes(uint fromTimestamp, uint toTimestamp) public pure returns (uint _minutes) {
434 | _minutes = BokkyPooBahsDateTimeLibrary.diffMinutes(fromTimestamp, toTimestamp);
435 | }
436 | function diffSeconds(uint fromTimestamp, uint toTimestamp) public pure returns (uint _seconds) {
437 | _seconds = BokkyPooBahsDateTimeLibrary.diffSeconds(fromTimestamp, toTimestamp);
438 | }
439 | }
440 |
--------------------------------------------------------------------------------
/images/clocks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bokkypoobah/BokkyPooBahsDateTimeLibrary/1dc26f977c57a6ba3ed6d7c53cafdb191e7e59ae/images/clocks.png
--------------------------------------------------------------------------------
/scripts/solidityFlattener.pl:
--------------------------------------------------------------------------------
1 | #!/usr/bin/perl -W
2 | # ----------------------------------------------------------------------------------------------
3 | # Solidity Flattener v1.0.2
4 | #
5 | # https://github.com/bokkypoobah/SolidityFlattener
6 | #
7 | # Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018. The MIT Licence.
8 | # ----------------------------------------------------------------------------------------------
9 |
10 | use strict;
11 | use Getopt::Long qw(:config no_auto_abbrev);
12 | use File::Basename;
13 | use File::Spec::Functions;
14 |
15 | my $DEFAULTCONTRACTSDIR = "./contracts";
16 | my $VERSION = "v1.0.3";
17 |
18 | my $helptext = qq\
19 | Solidity Flattener $VERSION
20 |
21 | Usage: $0 {options}
22 |
23 | Where options are:
24 | --contractsdir Source directory for original contracts. Default '$DEFAULTCONTRACTSDIR'
25 | --remapdir Remap import directories. Optional. Example "contracts/openzeppelin-solidity=node_modules/openzeppelin-solidity"
26 | --mainsol Main source Solidity file. Mandatory
27 | --outputsol Output flattened Solidity file. Default is mainsol with `_flattened` appended to the file name
28 | --verbose Show details. Optional
29 | --help Display help. Optional
30 |
31 | Example usage:
32 | $0 --contractsdir=contracts --mainsol=MyContract.sol --outputsol=flattened/MyContracts_flattened.sol --verbose
33 |
34 | Installation:
35 | Download solidityFlattener.pl from https://github.com/bokkypoobah/SolidityFlattener into /usr/local/bin
36 | chmod 755 /usr/local/bin/solidityFlattener.pl
37 |
38 | Works on OS/X, Linux and Linux on Windows.
39 |
40 | Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018. The MIT Licence.
41 |
42 | Stopped\;
43 |
44 | my ($contractsdir, $remapdir, $mainsol, $outputsol, $help, $verbose);
45 | my %seen = ();
46 |
47 | GetOptions(
48 | "contractsdir:s" => \$contractsdir,
49 | "remapdir:s" => \$remapdir,
50 | "mainsol:s" => \$mainsol,
51 | "outputsol:s" => \$outputsol,
52 | "verbose" => \$verbose,
53 | "help" => \$help)
54 | or die $helptext;
55 |
56 | die $helptext
57 | if defined $help;
58 |
59 | die $helptext
60 | unless defined $mainsol;
61 |
62 | $contractsdir = $DEFAULTCONTRACTSDIR
63 | unless defined $contractsdir;
64 |
65 | if (!defined $outputsol) {
66 | $outputsol = $mainsol;
67 | $outputsol =~ s/\.sol/_flattened\.sol/g;
68 | }
69 |
70 | if (defined $verbose) {
71 | printf "contractsdir: %s\n", $contractsdir;
72 | printf "remapdir : %s\n", defined $remapdir ? $remapdir : "(no remapping)";
73 | printf "mainsol : %s\n", $mainsol;
74 | printf "outputsol : %s\n", $outputsol
75 | }
76 |
77 | open OUTPUT, ">$outputsol"
78 | or die "Cannot open $outputsol for writing. Stopped";
79 |
80 | processSol(catfile($contractsdir, $mainsol), 0);
81 |
82 | close OUTPUT
83 | or die "Cannot close $outputsol. Stopped";
84 |
85 | exit;
86 |
87 |
88 | # ------------------------------------------------------------------------------
89 | # Process Solidity file
90 | # ------------------------------------------------------------------------------
91 | sub processSol {
92 | my ($sol, $level) = @_;
93 | if (defined $remapdir) {
94 | my ($splitfrom, $splitto) = split /=/, $remapdir;
95 | # printf "%sSplit %s: %s => %s\n", " " x $level, $remapdir, $splitfrom, $splitto
96 | # if defined $verbose;
97 | if ($sol =~ /$splitfrom/) {
98 | printf "%sRemapping %s\n", " " x $level, $sol
99 | if defined $verbose;
100 | $sol =~ s!$splitfrom!$splitto!;
101 | printf "%s to %s\n", " " x $level, $sol
102 | if defined $verbose;
103 | }
104 | }
105 | my $dir = dirname($sol);
106 | my $file = basename($sol);
107 | $seen{$file} = 1;
108 | printf "%sProcessing %s\n", " " x $level, $sol
109 | if defined $verbose;
110 |
111 | open INPUT, "<$sol"
112 | or die "Cannot open $sol for reading. Stopped";
113 | my @lines = ;
114 | close INPUT
115 | or die "Cannot close $sol. Stopped";
116 |
117 | for my $line (@lines) {
118 | chomp $line;
119 | if ($line =~ /^import/) {
120 | my $importfile = $line;
121 | $importfile =~ s/import [\"\']//;
122 | $importfile =~ s/[\"\'];.*$//;
123 | $file = basename($importfile);
124 | if ($seen{$file}) {
125 | printf "%s Already Imported %s\n", " " x $level, catfile($dir, $importfile)
126 | if defined $verbose;
127 | } else {
128 | printf "%s Importing %s\n", " " x $level, catfile($dir, $importfile)
129 | if defined $verbose;
130 | processSol(catfile($dir, $importfile), $level + 1)
131 | }
132 | } else {
133 | if ($level == 0 || !($line =~ /^pragma/)) {
134 | printf OUTPUT "%s\n", $line;
135 | }
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/test/00_runGeth.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -f ./testchain/geth/chaindata/*
4 |
5 | # geth --datadir ./testchain init genesis.json
6 |
7 | # geth --datadir ./testchain --unlock 0 --password ./testpassword --rpc --rpccorsdomain '*' --rpcport 8646 --rpcapi "eth,net,web3,debug" --port 32323 --mine --minerthreads 1 --maxpeers 0 --targetgaslimit 994712388 console
8 | geth --allow-insecure-unlock --dev --dev.period 1 --datadir ./testchain --rpc --rpccorsdomain '*' --rpcport 8646 --rpcapi "eth,net,web3,debug" --port 32323 --maxpeers 0 --targetgaslimit 994712388 console
9 |
--------------------------------------------------------------------------------
/test/02_attachGeth.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 |
4 | echo "Execute the following command to load the latest deployed contracts";
5 | echo ""
6 | echo "loadScript(\"deploymentData.js\");"
7 | echo ""
8 |
9 | geth attach ipc:./testchain/geth.ipc
10 |
--------------------------------------------------------------------------------
/test/BokkyPooBahsDateTimeLibrary.js:
--------------------------------------------------------------------------------
1 | var dateTimeLibOutput={
2 | "contracts":
3 | {
4 | "BokkyPooBahsDateTimeLibrary.sol:BokkyPooBahsDateTimeLibrary":
5 | {
6 | "abi": "[]",
7 | "bin": "60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122075d49f0ac9a443fac8bb202f0adb9e02ed12cbbf6d4d258fcb57548a1e88719064736f6c63430006000033"
8 | }
9 | },
10 | "version": "0.6.0+commit.26b70077.Darwin.appleclang"
11 | };
12 |
--------------------------------------------------------------------------------
/test/BokkyPooBahsDateTimeLibrary.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.6.0;
2 |
3 | // ----------------------------------------------------------------------------
4 | // BokkyPooBah's DateTime Library v1.01
5 | //
6 | // A gas-efficient Solidity date and time library
7 | //
8 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
9 | //
10 | // Tested date range 1970/01/01 to 2345/12/31
11 | //
12 | // Conventions:
13 | // Unit | Range | Notes
14 | // :-------- |:-------------:|:-----
15 | // timestamp | >= 0 | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
16 | // year | 1970 ... 2345 |
17 | // month | 1 ... 12 |
18 | // day | 1 ... 31 |
19 | // hour | 0 ... 23 |
20 | // minute | 0 ... 59 |
21 | // second | 0 ... 59 |
22 | // dayOfWeek | 1 ... 7 | 1 = Monday, ..., 7 = Sunday
23 | //
24 | //
25 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
26 | // ----------------------------------------------------------------------------
27 |
28 | library BokkyPooBahsDateTimeLibrary {
29 |
30 | uint constant SECONDS_PER_DAY = 24 * 60 * 60;
31 | uint constant SECONDS_PER_HOUR = 60 * 60;
32 | uint constant SECONDS_PER_MINUTE = 60;
33 | int constant OFFSET19700101 = 2440588;
34 |
35 | uint constant DOW_MON = 1;
36 | uint constant DOW_TUE = 2;
37 | uint constant DOW_WED = 3;
38 | uint constant DOW_THU = 4;
39 | uint constant DOW_FRI = 5;
40 | uint constant DOW_SAT = 6;
41 | uint constant DOW_SUN = 7;
42 |
43 | // ------------------------------------------------------------------------
44 | // Calculate the number of days from 1970/01/01 to year/month/day using
45 | // the date conversion algorithm from
46 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
47 | // and subtracting the offset 2440588 so that 1970/01/01 is day 0
48 | //
49 | // days = day
50 | // - 32075
51 | // + 1461 * (year + 4800 + (month - 14) / 12) / 4
52 | // + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
53 | // - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
54 | // - offset
55 | // ------------------------------------------------------------------------
56 | function _daysFromDate(uint year, uint month, uint day) internal pure returns (uint _days) {
57 | require(year >= 1970);
58 | int _year = int(year);
59 | int _month = int(month);
60 | int _day = int(day);
61 |
62 | int __days = _day
63 | - 32075
64 | + 1461 * (_year + 4800 + (_month - 14) / 12) / 4
65 | + 367 * (_month - 2 - (_month - 14) / 12 * 12) / 12
66 | - 3 * ((_year + 4900 + (_month - 14) / 12) / 100) / 4
67 | - OFFSET19700101;
68 |
69 | _days = uint(__days);
70 | }
71 |
72 | // ------------------------------------------------------------------------
73 | // Calculate year/month/day from the number of days since 1970/01/01 using
74 | // the date conversion algorithm from
75 | // http://aa.usno.navy.mil/faq/docs/JD_Formula.php
76 | // and adding the offset 2440588 so that 1970/01/01 is day 0
77 | //
78 | // int L = days + 68569 + offset
79 | // int N = 4 * L / 146097
80 | // L = L - (146097 * N + 3) / 4
81 | // year = 4000 * (L + 1) / 1461001
82 | // L = L - 1461 * year / 4 + 31
83 | // month = 80 * L / 2447
84 | // dd = L - 2447 * month / 80
85 | // L = month / 11
86 | // month = month + 2 - 12 * L
87 | // year = 100 * (N - 49) + year + L
88 | // ------------------------------------------------------------------------
89 | function _daysToDate(uint _days) internal pure returns (uint year, uint month, uint day) {
90 | int __days = int(_days);
91 |
92 | int L = __days + 68569 + OFFSET19700101;
93 | int N = 4 * L / 146097;
94 | L = L - (146097 * N + 3) / 4;
95 | int _year = 4000 * (L + 1) / 1461001;
96 | L = L - 1461 * _year / 4 + 31;
97 | int _month = 80 * L / 2447;
98 | int _day = L - 2447 * _month / 80;
99 | L = _month / 11;
100 | _month = _month + 2 - 12 * L;
101 | _year = 100 * (N - 49) + _year + L;
102 |
103 | year = uint(_year);
104 | month = uint(_month);
105 | day = uint(_day);
106 | }
107 |
108 | function timestampFromDate(uint year, uint month, uint day) internal pure returns (uint timestamp) {
109 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
110 | }
111 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (uint timestamp) {
112 | timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + hour * SECONDS_PER_HOUR + minute * SECONDS_PER_MINUTE + second;
113 | }
114 | function timestampToDate(uint timestamp) internal pure returns (uint year, uint month, uint day) {
115 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
116 | }
117 | function timestampToDateTime(uint timestamp) internal pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
118 | (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
119 | uint secs = timestamp % SECONDS_PER_DAY;
120 | hour = secs / SECONDS_PER_HOUR;
121 | secs = secs % SECONDS_PER_HOUR;
122 | minute = secs / SECONDS_PER_MINUTE;
123 | second = secs % SECONDS_PER_MINUTE;
124 | }
125 |
126 | function isValidDate(uint year, uint month, uint day) internal pure returns (bool valid) {
127 | if (year >= 1970 && month > 0 && month <= 12) {
128 | uint daysInMonth = _getDaysInMonth(year, month);
129 | if (day > 0 && day <= daysInMonth) {
130 | valid = true;
131 | }
132 | }
133 | }
134 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) internal pure returns (bool valid) {
135 | if (isValidDate(year, month, day)) {
136 | if (hour < 24 && minute < 60 && second < 60) {
137 | valid = true;
138 | }
139 | }
140 | }
141 | function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
142 | (uint year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
143 | leapYear = _isLeapYear(year);
144 | }
145 | function _isLeapYear(uint year) internal pure returns (bool leapYear) {
146 | leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
147 | }
148 | function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
149 | weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
150 | }
151 | function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
152 | weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
153 | }
154 | function getDaysInMonth(uint timestamp) internal pure returns (uint daysInMonth) {
155 | (uint year, uint month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
156 | daysInMonth = _getDaysInMonth(year, month);
157 | }
158 | function _getDaysInMonth(uint year, uint month) internal pure returns (uint daysInMonth) {
159 | if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
160 | daysInMonth = 31;
161 | } else if (month != 2) {
162 | daysInMonth = 30;
163 | } else {
164 | daysInMonth = _isLeapYear(year) ? 29 : 28;
165 | }
166 | }
167 | // 1 = Monday, 7 = Sunday
168 | function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
169 | uint _days = timestamp / SECONDS_PER_DAY;
170 | dayOfWeek = (_days + 3) % 7 + 1;
171 | }
172 |
173 | function getYear(uint timestamp) internal pure returns (uint year) {
174 | (year,,) = _daysToDate(timestamp / SECONDS_PER_DAY);
175 | }
176 | function getMonth(uint timestamp) internal pure returns (uint month) {
177 | (,month,) = _daysToDate(timestamp / SECONDS_PER_DAY);
178 | }
179 | function getDay(uint timestamp) internal pure returns (uint day) {
180 | (,,day) = _daysToDate(timestamp / SECONDS_PER_DAY);
181 | }
182 | function getHour(uint timestamp) internal pure returns (uint hour) {
183 | uint secs = timestamp % SECONDS_PER_DAY;
184 | hour = secs / SECONDS_PER_HOUR;
185 | }
186 | function getMinute(uint timestamp) internal pure returns (uint minute) {
187 | uint secs = timestamp % SECONDS_PER_HOUR;
188 | minute = secs / SECONDS_PER_MINUTE;
189 | }
190 | function getSecond(uint timestamp) internal pure returns (uint second) {
191 | second = timestamp % SECONDS_PER_MINUTE;
192 | }
193 |
194 | function addYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
195 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
196 | year += _years;
197 | uint daysInMonth = _getDaysInMonth(year, month);
198 | if (day > daysInMonth) {
199 | day = daysInMonth;
200 | }
201 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
202 | require(newTimestamp >= timestamp);
203 | }
204 | function addMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
205 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
206 | month += _months;
207 | year += (month - 1) / 12;
208 | month = (month - 1) % 12 + 1;
209 | uint daysInMonth = _getDaysInMonth(year, month);
210 | if (day > daysInMonth) {
211 | day = daysInMonth;
212 | }
213 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
214 | require(newTimestamp >= timestamp);
215 | }
216 | function addDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
217 | newTimestamp = timestamp + _days * SECONDS_PER_DAY;
218 | require(newTimestamp >= timestamp);
219 | }
220 | function addHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
221 | newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
222 | require(newTimestamp >= timestamp);
223 | }
224 | function addMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
225 | newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
226 | require(newTimestamp >= timestamp);
227 | }
228 | function addSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
229 | newTimestamp = timestamp + _seconds;
230 | require(newTimestamp >= timestamp);
231 | }
232 |
233 | function subYears(uint timestamp, uint _years) internal pure returns (uint newTimestamp) {
234 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
235 | year -= _years;
236 | uint daysInMonth = _getDaysInMonth(year, month);
237 | if (day > daysInMonth) {
238 | day = daysInMonth;
239 | }
240 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
241 | require(newTimestamp <= timestamp);
242 | }
243 | function subMonths(uint timestamp, uint _months) internal pure returns (uint newTimestamp) {
244 | (uint year, uint month, uint day) = _daysToDate(timestamp / SECONDS_PER_DAY);
245 | uint yearMonth = year * 12 + (month - 1) - _months;
246 | year = yearMonth / 12;
247 | month = yearMonth % 12 + 1;
248 | uint daysInMonth = _getDaysInMonth(year, month);
249 | if (day > daysInMonth) {
250 | day = daysInMonth;
251 | }
252 | newTimestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY + timestamp % SECONDS_PER_DAY;
253 | require(newTimestamp <= timestamp);
254 | }
255 | function subDays(uint timestamp, uint _days) internal pure returns (uint newTimestamp) {
256 | newTimestamp = timestamp - _days * SECONDS_PER_DAY;
257 | require(newTimestamp <= timestamp);
258 | }
259 | function subHours(uint timestamp, uint _hours) internal pure returns (uint newTimestamp) {
260 | newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
261 | require(newTimestamp <= timestamp);
262 | }
263 | function subMinutes(uint timestamp, uint _minutes) internal pure returns (uint newTimestamp) {
264 | newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
265 | require(newTimestamp <= timestamp);
266 | }
267 | function subSeconds(uint timestamp, uint _seconds) internal pure returns (uint newTimestamp) {
268 | newTimestamp = timestamp - _seconds;
269 | require(newTimestamp <= timestamp);
270 | }
271 |
272 | function diffYears(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _years) {
273 | require(fromTimestamp <= toTimestamp);
274 | (uint fromYear,,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
275 | (uint toYear,,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
276 | _years = toYear - fromYear;
277 | }
278 | function diffMonths(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _months) {
279 | require(fromTimestamp <= toTimestamp);
280 | (uint fromYear, uint fromMonth,) = _daysToDate(fromTimestamp / SECONDS_PER_DAY);
281 | (uint toYear, uint toMonth,) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
282 | _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
283 | }
284 | function diffDays(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _days) {
285 | require(fromTimestamp <= toTimestamp);
286 | _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
287 | }
288 | function diffHours(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _hours) {
289 | require(fromTimestamp <= toTimestamp);
290 | _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
291 | }
292 | function diffMinutes(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _minutes) {
293 | require(fromTimestamp <= toTimestamp);
294 | _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
295 | }
296 | function diffSeconds(uint fromTimestamp, uint toTimestamp) internal pure returns (uint _seconds) {
297 | require(fromTimestamp <= toTimestamp);
298 | _seconds = toTimestamp - fromTimestamp;
299 | }
300 | }
301 |
--------------------------------------------------------------------------------
/test/README.md:
--------------------------------------------------------------------------------
1 | # Contract - Testing
2 |
3 |
4 |
5 |
6 |
7 | # Table of contents
8 |
9 | * [Requirements](#requirements)
10 | * [Executing The Tests](#executing-the-tests)
11 | * [Notes](#notes)
12 |
13 |
14 |
15 |
16 |
17 | # Requirements
18 |
19 | * The tests works on OS/X. Should work in Linux. May work in Windows with Cygwin
20 | * Geth/v1.9.9-stable-01744997/darwin-amd64/go1.13.5 running with the Byzantium fork switched on
21 | * Solc 0.6.0+commit.26b70077.Darwin.appleclang
22 |
23 |
24 |
25 |
26 |
27 | # Executing The Tests
28 |
29 | * Run `geth` in dev mode
30 |
31 | ./00_runGeth.sh
32 |
33 | * Run the test in [01_test1.sh](01_test1.sh)
34 |
35 | ./01_test1.sh
36 |
37 | * See [test1results.txt](test1results.txt) for the results and [test1output.txt](test1output.txt) for the full output.
38 |
39 |
40 |
41 |
42 |
43 | # Notes
44 |
45 | * The tests were conducted using bash shell scripts running Geth/v1.9.9-stable-01744997/darwin-amd64/go1.13.5 JavaScript commands
46 | * The smart contracts were compiled using Solidity 0.6.0+commit.26b70077.Darwin.appleclang
47 | * The test script can be found in [01_test1.sh](01_test1.sh)
48 | * The test results can be found in [test1results.txt](test1results.txt) with details in [test1output.txt](test1output.txt)
49 | * The test can be run on OS/X, should run on Linux and may run on Windows with Cygwin
50 | * The [genesis.json](genesis.json) allocates ethers to the test accounts, and specifies a high block gas limit to accommodate many transactions in the same block
51 | * The [00_runGeth.sh](00_runGeth.sh) scripts starts `geth` with the parameter `--targetgaslimit 994712388` to keep the high block gas limit
52 | * The reasons for using the test environment as listed above, instead of truffles/testrpc are:
53 | * The test are conducted using the actual blockchain client software as is running on Mainnet and not just a mock environment like testrpc
54 | * It is easy to change parameters like dates, addresses or blocknumbers using the Unix search/replace tools
55 | * There have been issues in the part with version incompatibility between testrpc and solidity, i.e., version mismatches
56 | * The intermediate and key results are all saved to later viewing
57 |
--------------------------------------------------------------------------------
/test/TestDateTime.js:
--------------------------------------------------------------------------------
1 | var testDateTimeOutput={
2 | "contracts":
3 | {
4 | "BokkyPooBahsDateTimeLibrary.sol:BokkyPooBahsDateTimeLibrary":
5 | {
6 | "abi": "[]",
7 | "bin": "60566023600b82828239805160001a607314601657fe5b30600052607381538281f3fe73000000000000000000000000000000000000000030146080604052600080fdfea264697066735822122075d49f0ac9a443fac8bb202f0adb9e02ed12cbbf6d4d258fcb57548a1e88719064736f6c63430006000033"
8 | },
9 | "TestDateTime.sol:TestDateTime":
10 | {
11 | "abi": "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"}],\"name\":\"_getDaysInMonth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"daysInMonth\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"}],\"name\":\"_isLeapYear\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"leapYear\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_days\",\"type\":\"uint256\"}],\"name\":\"addDays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_hours\",\"type\":\"uint256\"}],\"name\":\"addHours\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minutes\",\"type\":\"uint256\"}],\"name\":\"addMinutes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_months\",\"type\":\"uint256\"}],\"name\":\"addMonths\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_seconds\",\"type\":\"uint256\"}],\"name\":\"addSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_years\",\"type\":\"uint256\"}],\"name\":\"addYears\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fromTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"toTimestamp\",\"type\":\"uint256\"}],\"name\":\"diffDays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_days\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fromTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"toTimestamp\",\"type\":\"uint256\"}],\"name\":\"diffHours\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_hours\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fromTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"toTimestamp\",\"type\":\"uint256\"}],\"name\":\"diffMinutes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_minutes\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fromTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"toTimestamp\",\"type\":\"uint256\"}],\"name\":\"diffMonths\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_months\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fromTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"toTimestamp\",\"type\":\"uint256\"}],\"name\":\"diffSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_seconds\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"fromTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"toTimestamp\",\"type\":\"uint256\"}],\"name\":\"diffYears\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"_years\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getDay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getDayOfWeek\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"dayOfWeek\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getDaysInMonth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"daysInMonth\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getHour\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hour\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getMinute\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"minute\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getMonth\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getSecond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"second\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"getYear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"isLeapYear\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"leapYear\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"}],\"name\":\"isValidDate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hour\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minute\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"second\",\"type\":\"uint256\"}],\"name\":\"isValidDateTime\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"valid\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"isWeekDay\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"weekDay\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"isWeekEnd\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"weekEnd\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextYear\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_days\",\"type\":\"uint256\"}],\"name\":\"subDays\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_hours\",\"type\":\"uint256\"}],\"name\":\"subHours\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_minutes\",\"type\":\"uint256\"}],\"name\":\"subMinutes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_months\",\"type\":\"uint256\"}],\"name\":\"subMonths\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_seconds\",\"type\":\"uint256\"}],\"name\":\"subSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_years\",\"type\":\"uint256\"}],\"name\":\"subYears\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"newTimestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"test\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"}],\"name\":\"timestampFromDate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hour\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minute\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"second\",\"type\":\"uint256\"}],\"name\":\"timestampFromDateTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"timestampToDate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"timestampToDateTime\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"year\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"month\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"day\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"hour\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minute\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"second\",\"type\":\"uint256\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]",
12 | "bin": "608060405234801561001057600080fd5b506110ed806100206000396000f3fe608060405234801561001057600080fd5b506004361061023c5760003560e01c80637217523c1161013b578063b8d16dbc116100b8578063ea1c16901161007c578063ea1c169014610704578063f615ed5414610754578063f8a8fd6d14610777578063fa93f88314610781578063ff2258cb1461079e5761023c565b8063b8d16dbc14610649578063c7b6fd6a14610666578063c9d3462214610689578063d6582d0d146106ac578063de5101af146106c95761023c565b806392d66313116100ff57806392d66313146105ac5780639e524caa146105c9578063a324ad24146105ec578063ad203bd414610609578063b05eb08d1461062c5761023c565b80637217523c146105035780637be341091461052657806389a3a00d146105495780638aa001fc1461056c5780638d4a2d39146105895761023c565b80633e239e1a116101c9578063444fda821161018d578063444fda82146104425780634b321502146104655780635e05bd6d1461048857806362fb9697146104c357806365c72840146104e65761023c565b80633e239e1a1461039f5780633f9e0eb7146103bc5780634355644d146103df5780634371c46514610402578063442b8c791461041f5761023c565b806314b2d6dc1161021057806314b2d6dc146102be5780631f4f77b2146102fb57806322f8a2b8146103245780632af123b8146103415780633293d007146103645761023c565b80625015531461024157806302e98e0d1461027657806310848ddf14610299578063146bea7b146102b6575b600080fd5b6102646004803603604081101561025757600080fd5b50803590602001356107c1565b60408051918252519081900360200190f35b6102646004803603604081101561028c57600080fd5b50803590602001356107d4565b610264600480360360208110156102af57600080fd5b50356107e0565b6102646107f1565b6102e7600480360360608110156102d457600080fd5b50803590602081013590604001356107f7565b604080519115158252519081900360200190f35b6102646004803603606081101561031157600080fd5b508035906020810135906040013561080c565b6102646004803603602081101561033a57600080fd5b5035610819565b6102646004803603604081101561035757600080fd5b5080359060200135610824565b6102e7600480360360c081101561037a57600080fd5b5080359060208101359060408101359060608101359060808101359060a00135610830565b610264600480360360208110156103b557600080fd5b503561084b565b610264600480360360408110156103d257600080fd5b5080359060200135610856565b610264600480360360408110156103f557600080fd5b5080359060200135610862565b6102e76004803603602081101561041857600080fd5b503561086e565b6102646004803603604081101561043557600080fd5b5080359060200135610879565b6102646004803603604081101561045857600080fd5b5080359060200135610885565b6102646004803603604081101561047b57600080fd5b5080359060200135610891565b610264600480360360c081101561049e57600080fd5b5080359060208101359060408101359060608101359060808101359060a0013561089d565b610264600480360360408110156104d957600080fd5b50803590602001356108b7565b610264600480360360208110156104fc57600080fd5b50356108c3565b6102646004803603604081101561051957600080fd5b50803590602001356108ce565b6102646004803603604081101561053c57600080fd5b50803590602001356108da565b6102646004803603604081101561055f57600080fd5b50803590602001356108e6565b6102646004803603602081101561058257600080fd5b50356108f2565b6102646004803603604081101561059f57600080fd5b50803590602001356108fd565b610264600480360360208110156105c257600080fd5b5035610909565b610264600480360360408110156105df57600080fd5b5080359060200135610914565b6102646004803603602081101561060257600080fd5b5035610920565b6102646004803603604081101561061f57600080fd5b508035906020013561092b565b6102e76004803603602081101561064257600080fd5b5035610937565b6102e76004803603602081101561065f57600080fd5b5035610942565b6102646004803603604081101561067c57600080fd5b508035906020013561094d565b6102646004803603604081101561069f57600080fd5b5080359060200135610959565b6102e7600480360360208110156106c257600080fd5b5035610965565b6106e6600480360360208110156106df57600080fd5b5035610970565b60408051938452602084019290925282820152519081900360600190f35b6107216004803603602081101561071a57600080fd5b503561098b565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b6102646004803603604081101561076a57600080fd5b50803590602001356109b1565b61077f6109bd565b005b6102646004803603602081101561079757600080fd5b50356109d5565b610264600480360360408110156107b457600080fd5b50803590602001356109e0565b60006107cd83836109ec565b9392505050565b60006107cd8383610a00565b60006107eb82610a1d565b92915050565b60005481565b6000610804848484610a3f565b949350505050565b6000610804848484610a95565b60006107eb82610aaf565b60006107cd8383610ac2565b6000610840878787878787610adc565b979650505050505050565b60006107eb82610b1c565b60006107cd8383610b2a565b60006107cd8383610bb0565b60006107eb82610c2a565b60006107cd8383610c3f565b60006107cd8383610c66565b60006107cd8383610cc2565b6000610840878787878787610cd6565b9695505050505050565b60006107cd8383610d00565b60006107eb82610d14565b60006107cd8383610d23565b60006107cd8383610d38565b60006107cd8383610d8a565b60006107eb82610d9d565b60006107cd8383610da4565b60006107eb82610db4565b60006107cd8383610dcc565b60006107eb82610ddf565b60006107cd8383610dee565b60006107eb82610e6e565b60006107eb82610e93565b60006107cd8383610eb0565b60006107cd8383610ec5565b60006107eb82610ee0565b600080600061097e84610ef5565b9196909550909350915050565b60008060008060008061099d87610f06565b949c939b5091995097509550909350915050565b60006107cd8383610f45565b426109cf81600163ffffffff610c3f16565b60005550565b60006107eb82610f55565b60006107cd8383610f64565b610e1081028203828111156107eb57600080fd5b600081831115610a0f57600080fd5b603c8383035b049392505050565b60008080610a3062015180855b04610fa5565b50915091506108048282610b2a565b60006107b28410158015610a535750600083115b8015610a605750600c8311155b156107cd576000610a718585610b2a565b9050600083118015610a835750808311155b15610a8d57600191505b509392505050565b600062015180610aa685858561103b565b02949350505050565b6007620151809091046003010660010190565b600081831115610ad157600080fd5b610e10838303610a15565b6000610ae9878787610a3f565b156108ad57601884108015610afe5750603c83105b8015610b0a5750603c82105b156108ad575060019695505050505050565b610e10620151809091060490565b60008160011480610b3b5750816003145b80610b465750816005145b80610b515750816007145b80610b5c5750816008145b80610b67575081600a145b80610b72575081600c145b15610b7f5750601f6107eb565b81600214610b8f5750601e6107eb565b610b9883610e6e565b610ba357601c610ba6565b601d5b60ff169392505050565b6000808080610bc26201518087610a2a565b600c918801600019810183810494909401965094509250900660010191506000610bec8484610b2a565b905080821115610bfa578091505b62015180870662015180610c0f86868661103b565b0201945086851015610c2057600080fd5b5050505092915050565b60006006610c3783610aaf565b101592915050565b6000808080610c516201518087610a2a565b9187019450925090506000610bec8484610b2a565b6000808080610c786201518087610a2a565b918790039450925090506000610c8e8484610b2a565b905080821115610c9c578091505b62015180870662015180610cb186868661103b565b0201945086851115610c2057600080fd5b610e1081028201828110156107eb57600080fd5b600081603c8402610e10860262015180610cf18b8b8b61103b565b02010101979650505050505050565b600081831115610d0f57600080fd5b500390565b60006108046201518083610a2a565b6201518081028201828110156107eb57600080fd5b600081831115610d4757600080fd5b600080610d576201518086610a2a565b5091509150600080610d6e620151808781610a2a57fe5b50600c9586029590910201939093039190910395945050505050565b603c81028201828110156107eb57600080fd5b603c900690565b818101828110156107eb57600080fd5b6000610dc36201518083610a2a565b50909392505050565b603c81028203828111156107eb57600080fd5b6000610a8d6201518083610a2a565b6000808080610e006201518087610a2a565b91945092509050600c8084028301869003600019019081049350600c810660010192506000610e2f8585610b2a565b905080831115610e3d578092505b62015180880662015180610e5287878761103b565b0201955087861115610e6357600080fd5b505050505092915050565b600060048206158015610e8357506064820615155b806107eb57505061019090061590565b600080610ea36201518084610a2a565b505090506107cd81610e6e565b6201518081028203828111156107eb57600080fd5b600081831115610ed457600080fd5b62015180838303610a15565b60006005610eed83610aaf565b111592915050565b6000808061097e6201518085610a2a565b60008080808080610f1a6201518088610a2a565b91999098919750610e10620151809092068281049750603c9290068281049650919091069350915050565b808203828111156107eb57600080fd5b6000610e108206603c81610a15565b600081831115610f7357600080fd5b6000610f826201518085610a2a565b505090506000610f97620151808581610a2a57fe5b505091909103949350505050565b60008080836226496581018262023ab1600483020590506004600362023ab18302010590910390600062164b09610fa0600185010205905060046105b58202058303601f019250600061098f8460500281610ffc57fe5b0590506000605061098f83020585039050600b820560301994909401606402929092018301996002600c90940290910392909201975095509350505050565b60006107b284101561104c57600080fd5b838383600062253d8c600460036064611324600c600d19890105890101050205600c80600d19870105600c02600287030361016f028161108857fe5b0560046105b5600c600d1989010589016112c0010205617d4b860301010303905080945050505050939250505056fea2646970667358221220144bfa7ff851a685f881e93c3b88c3dce21cc7d3c01423e087bdfba5b17d290964736f6c63430006000033"
13 | }
14 | },
15 | "version": "0.6.0+commit.26b70077.Darwin.appleclang"
16 | };
17 |
--------------------------------------------------------------------------------
/test/TestDateTime.sol:
--------------------------------------------------------------------------------
1 | pragma solidity ^0.6.0;
2 |
3 | import "BokkyPooBahsDateTimeLibrary.sol";
4 |
5 | // ----------------------------------------------------------------------------
6 | // Testing BokkyPooBah's DateTime Library
7 | //
8 | // https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
9 | //
10 | // Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018-2019. The MIT Licence.
11 | // ----------------------------------------------------------------------------
12 |
13 | contract TestDateTime {
14 | using BokkyPooBahsDateTimeLibrary for uint;
15 |
16 | uint public nextYear;
17 |
18 | function test() public {
19 | uint today = now;
20 | nextYear = today.addYears(1);
21 | }
22 |
23 | function timestampFromDate(uint year, uint month, uint day) public pure returns (uint timestamp) {
24 | return BokkyPooBahsDateTimeLibrary.timestampFromDate(year, month, day);
25 | }
26 | function timestampFromDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (uint timestamp) {
27 | return BokkyPooBahsDateTimeLibrary.timestampFromDateTime(year, month, day, hour, minute, second);
28 | }
29 | function timestampToDate(uint timestamp) public pure returns (uint year, uint month, uint day) {
30 | (year, month, day) = BokkyPooBahsDateTimeLibrary.timestampToDate(timestamp);
31 | }
32 | function timestampToDateTime(uint timestamp) public pure returns (uint year, uint month, uint day, uint hour, uint minute, uint second) {
33 | (year, month, day, hour, minute, second) = BokkyPooBahsDateTimeLibrary.timestampToDateTime(timestamp);
34 | }
35 |
36 | function isLeapYear(uint timestamp) public pure returns (bool leapYear) {
37 | leapYear = BokkyPooBahsDateTimeLibrary.isLeapYear(timestamp);
38 | }
39 | function _isLeapYear(uint year) public pure returns (bool leapYear) {
40 | leapYear = BokkyPooBahsDateTimeLibrary._isLeapYear(year);
41 | }
42 | function isWeekDay(uint timestamp) public pure returns (bool weekDay) {
43 | weekDay = BokkyPooBahsDateTimeLibrary.isWeekDay(timestamp);
44 | }
45 | function isWeekEnd(uint timestamp) public pure returns (bool weekEnd) {
46 | weekEnd = BokkyPooBahsDateTimeLibrary.isWeekEnd(timestamp);
47 | }
48 |
49 | function getDaysInMonth(uint timestamp) public pure returns (uint daysInMonth) {
50 | daysInMonth = BokkyPooBahsDateTimeLibrary.getDaysInMonth(timestamp);
51 | }
52 | function _getDaysInMonth(uint year, uint month) public pure returns (uint daysInMonth) {
53 | daysInMonth = BokkyPooBahsDateTimeLibrary._getDaysInMonth(year, month);
54 | }
55 | function getDayOfWeek(uint timestamp) public pure returns (uint dayOfWeek) {
56 | dayOfWeek = BokkyPooBahsDateTimeLibrary.getDayOfWeek(timestamp);
57 | }
58 |
59 | function isValidDate(uint year, uint month, uint day) public pure returns (bool valid) {
60 | valid = BokkyPooBahsDateTimeLibrary.isValidDate(year, month, day);
61 | }
62 | function isValidDateTime(uint year, uint month, uint day, uint hour, uint minute, uint second) public pure returns (bool valid) {
63 | valid = BokkyPooBahsDateTimeLibrary.isValidDateTime(year, month, day, hour, minute, second);
64 | }
65 |
66 | function getYear(uint timestamp) public pure returns (uint year) {
67 | year = BokkyPooBahsDateTimeLibrary.getYear(timestamp);
68 | }
69 | function getMonth(uint timestamp) public pure returns (uint month) {
70 | month = BokkyPooBahsDateTimeLibrary.getMonth(timestamp);
71 | }
72 | function getDay(uint timestamp) public pure returns (uint day) {
73 | day = BokkyPooBahsDateTimeLibrary.getDay(timestamp);
74 | }
75 | function getHour(uint timestamp) public pure returns (uint hour) {
76 | hour = BokkyPooBahsDateTimeLibrary.getHour(timestamp);
77 | }
78 | function getMinute(uint timestamp) public pure returns (uint minute) {
79 | minute = BokkyPooBahsDateTimeLibrary.getMinute(timestamp);
80 | }
81 | function getSecond(uint timestamp) public pure returns (uint second) {
82 | second = BokkyPooBahsDateTimeLibrary.getSecond(timestamp);
83 | }
84 |
85 | function addYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
86 | newTimestamp = BokkyPooBahsDateTimeLibrary.addYears(timestamp, _years);
87 | }
88 | function addMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
89 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMonths(timestamp, _months);
90 | }
91 | function addDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
92 | newTimestamp = BokkyPooBahsDateTimeLibrary.addDays(timestamp, _days);
93 | }
94 | function addHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
95 | newTimestamp = BokkyPooBahsDateTimeLibrary.addHours(timestamp, _hours);
96 | }
97 | function addMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
98 | newTimestamp = BokkyPooBahsDateTimeLibrary.addMinutes(timestamp, _minutes);
99 | }
100 | function addSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
101 | newTimestamp = BokkyPooBahsDateTimeLibrary.addSeconds(timestamp, _seconds);
102 | }
103 |
104 | function subYears(uint timestamp, uint _years) public pure returns (uint newTimestamp) {
105 | newTimestamp = BokkyPooBahsDateTimeLibrary.subYears(timestamp, _years);
106 | }
107 | function subMonths(uint timestamp, uint _months) public pure returns (uint newTimestamp) {
108 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMonths(timestamp, _months);
109 | }
110 | function subDays(uint timestamp, uint _days) public pure returns (uint newTimestamp) {
111 | newTimestamp = BokkyPooBahsDateTimeLibrary.subDays(timestamp, _days);
112 | }
113 | function subHours(uint timestamp, uint _hours) public pure returns (uint newTimestamp) {
114 | newTimestamp = BokkyPooBahsDateTimeLibrary.subHours(timestamp, _hours);
115 | }
116 | function subMinutes(uint timestamp, uint _minutes) public pure returns (uint newTimestamp) {
117 | newTimestamp = BokkyPooBahsDateTimeLibrary.subMinutes(timestamp, _minutes);
118 | }
119 | function subSeconds(uint timestamp, uint _seconds) public pure returns (uint newTimestamp) {
120 | newTimestamp = BokkyPooBahsDateTimeLibrary.subSeconds(timestamp, _seconds);
121 | }
122 |
123 | function diffYears(uint fromTimestamp, uint toTimestamp) public pure returns (uint _years) {
124 | _years = BokkyPooBahsDateTimeLibrary.diffYears(fromTimestamp, toTimestamp);
125 | }
126 | function diffMonths(uint fromTimestamp, uint toTimestamp) public pure returns (uint _months) {
127 | _months = BokkyPooBahsDateTimeLibrary.diffMonths(fromTimestamp, toTimestamp);
128 | }
129 | function diffDays(uint fromTimestamp, uint toTimestamp) public pure returns (uint _days) {
130 | _days = BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, toTimestamp);
131 | }
132 | function diffHours(uint fromTimestamp, uint toTimestamp) public pure returns (uint _hours) {
133 | _hours = BokkyPooBahsDateTimeLibrary.diffHours(fromTimestamp, toTimestamp);
134 | }
135 | function diffMinutes(uint fromTimestamp, uint toTimestamp) public pure returns (uint _minutes) {
136 | _minutes = BokkyPooBahsDateTimeLibrary.diffMinutes(fromTimestamp, toTimestamp);
137 | }
138 | function diffSeconds(uint fromTimestamp, uint toTimestamp) public pure returns (uint _seconds) {
139 | _seconds = BokkyPooBahsDateTimeLibrary.diffSeconds(fromTimestamp, toTimestamp);
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/test/functions.js:
--------------------------------------------------------------------------------
1 | // ETH/USD 19 May 2018 00:14 AEDT from CMC and ethgasstation.info
2 | var ethPriceUSD = 675.71;
3 | var defaultGasPrice = web3.toWei(16, "gwei");
4 |
5 | // -----------------------------------------------------------------------------
6 | // Accounts
7 | // -----------------------------------------------------------------------------
8 | var accounts = [];
9 | var accountNames = {};
10 |
11 | addAccount(eth.accounts[0], "Account #0 - Miner");
12 | addAccount(eth.accounts[1], "Account #1 - Contract Owner");
13 | addAccount(eth.accounts[2], "Account #2 - Alice");
14 | addAccount(eth.accounts[3], "Account #3 - Bob");
15 | addAccount(eth.accounts[4], "Account #4 - Carol");
16 | addAccount(eth.accounts[5], "Account #5 - Dave");
17 | addAccount(eth.accounts[6], "Account #6");
18 | addAccount(eth.accounts[7], "Account #7");
19 | addAccount(eth.accounts[8], "Account #8");
20 | addAccount(eth.accounts[9], "Account #9");
21 | addAccount(eth.accounts[10], "Account #10");
22 | addAccount(eth.accounts[11], "Account #11");
23 |
24 | var minerAccount = eth.accounts[0];
25 | var contractOwnerAccount = eth.accounts[1];
26 | var aliceAccount = eth.accounts[2];
27 | var bobAccount = eth.accounts[3];
28 | var carolAccount = eth.accounts[4];
29 | var daveAccount = eth.accounts[5];
30 | var account6 = eth.accounts[6];
31 | var account7 = eth.accounts[7];
32 | var account8 = eth.accounts[8];
33 | var account9 = eth.accounts[9];
34 | var account10 = eth.accounts[10];
35 | var account11 = eth.accounts[11];
36 |
37 | var baseBlock = eth.blockNumber;
38 |
39 | function unlockAccounts(password) {
40 | for (var i = 0; i < eth.accounts.length && i < accounts.length; i++) {
41 | personal.unlockAccount(eth.accounts[i], password, 100000);
42 | if (i > 0 && eth.getBalance(eth.accounts[i]) == 0) {
43 | personal.sendTransaction({from: eth.accounts[0], to: eth.accounts[i], value: web3.toWei(1000000, "ether")});
44 | }
45 | }
46 | while (txpool.status.pending > 0) {
47 | }
48 | baseBlock = eth.blockNumber;
49 | }
50 |
51 | function addAccount(account, accountName) {
52 | accounts.push(account);
53 | accountNames[account] = accountName;
54 | }
55 |
56 |
57 | // -----------------------------------------------------------------------------
58 | // Token Contract
59 | // -----------------------------------------------------------------------------
60 | var tokenContractAddress = null;
61 | var tokenContractAbi = null;
62 |
63 | function addTokenContractAddressAndAbi(address, tokenAbi) {
64 | tokenContractAddress = address;
65 | tokenContractAbi = tokenAbi;
66 | }
67 |
68 |
69 | // -----------------------------------------------------------------------------
70 | // Account ETH and token balances
71 | // -----------------------------------------------------------------------------
72 | function printBalances() {
73 | var token = tokenContractAddress == null || tokenContractAbi == null ? null : web3.eth.contract(tokenContractAbi).at(tokenContractAddress);
74 | var decimals = token == null ? 18 : token.decimals();
75 | var i = 0;
76 | var totalTokenBalance = new BigNumber(0);
77 | console.log("RESULT: # Account EtherBalanceChange Token Name");
78 | console.log("RESULT: -- ------------------------------------------ --------------------------- ------------------------------ ---------------------------");
79 | accounts.forEach(function(e) {
80 | var etherBalanceBaseBlock = eth.getBalance(e, baseBlock);
81 | var etherBalance = web3.fromWei(eth.getBalance(e).minus(etherBalanceBaseBlock), "ether");
82 | var tokenBalance = token == null ? new BigNumber(0) : token.balanceOf.call(e).shift(-decimals);
83 | totalTokenBalance = totalTokenBalance.add(tokenBalance);
84 | console.log("RESULT: " + pad2(i) + " " + e + " " + pad(etherBalance) + " " + padToken(tokenBalance, decimals) + " " + accountNames[e]);
85 | i++;
86 | });
87 | console.log("RESULT: -- ------------------------------------------ --------------------------- ------------------------------ ---------------------------");
88 | console.log("RESULT: " + padToken(totalTokenBalance, decimals) + " Total Token Balances");
89 | console.log("RESULT: -- ------------------------------------------ --------------------------- ------------------------------ ---------------------------");
90 | console.log("RESULT: ");
91 | }
92 |
93 | function pad2(s) {
94 | var o = s.toFixed(0);
95 | while (o.length < 2) {
96 | o = " " + o;
97 | }
98 | return o;
99 | }
100 |
101 | function pad(s) {
102 | var o = s.toFixed(18);
103 | while (o.length < 27) {
104 | o = " " + o;
105 | }
106 | return o;
107 | }
108 |
109 | function padToken(s, decimals) {
110 | var o = s.toFixed(decimals);
111 | var l = parseInt(decimals)+12;
112 | while (o.length < l) {
113 | o = " " + o;
114 | }
115 | return o;
116 | }
117 |
118 |
119 | // -----------------------------------------------------------------------------
120 | // Transaction status
121 | // -----------------------------------------------------------------------------
122 | function printTxData(name, txId) {
123 | var tx = eth.getTransaction(txId);
124 | var txReceipt = eth.getTransactionReceipt(txId);
125 | var gasPrice = tx.gasPrice;
126 | var gasCostETH = tx.gasPrice.mul(txReceipt.gasUsed).div(1e18);
127 | var gasCostUSD = gasCostETH.mul(ethPriceUSD);
128 | var block = eth.getBlock(txReceipt.blockNumber);
129 | console.log("RESULT: " + name + " status=" + txReceipt.status + (txReceipt.status == 0 ? " Failure" : " Success") + " gas=" + tx.gas +
130 | " gasUsed=" + txReceipt.gasUsed + " costETH=" + gasCostETH + " costUSD=" + gasCostUSD +
131 | " @ ETH/USD=" + ethPriceUSD + " gasPrice=" + web3.fromWei(gasPrice, "gwei") + " gwei block=" +
132 | txReceipt.blockNumber + " txIx=" + tx.transactionIndex + " txId=" + txId +
133 | " @ " + block.timestamp + " " + new Date(block.timestamp * 1000).toUTCString());
134 | }
135 |
136 | function assert(condition, message) {
137 | if (condition) {
138 | console.log("RESULT: PASS " + message);
139 | } else {
140 | console.log("RESULT: FAIL " + message);
141 | }
142 | return condition;
143 | }
144 |
145 | function assertIntEquals(result, expected, message) {
146 | if (parseInt(result) == parseInt(expected)) {
147 | console.log("RESULT: PASS " + message);
148 | return true;
149 | } else {
150 | console.log("RESULT: FAIL " + message);
151 | return false;
152 | }
153 | }
154 |
155 | function assertEtherBalance(account, expectedBalance) {
156 | var etherBalance = web3.fromWei(eth.getBalance(account), "ether");
157 | if (etherBalance == expectedBalance) {
158 | console.log("RESULT: OK " + account + " has expected balance " + expectedBalance);
159 | } else {
160 | console.log("RESULT: FAILURE " + account + " has balance " + etherBalance + " <> expected " + expectedBalance);
161 | }
162 | }
163 |
164 | function failIfTxStatusError(tx, msg) {
165 | var status = eth.getTransactionReceipt(tx).status;
166 | if (status == 0) {
167 | console.log("RESULT: FAIL " + msg);
168 | return 0;
169 | } else {
170 | console.log("RESULT: PASS " + msg);
171 | return 1;
172 | }
173 | }
174 |
175 | function passIfTxStatusError(tx, msg) {
176 | var status = eth.getTransactionReceipt(tx).status;
177 | if (status == 1) {
178 | console.log("RESULT: FAIL " + msg);
179 | return 0;
180 | } else {
181 | console.log("RESULT: PASS " + msg);
182 | return 1;
183 | }
184 | }
185 |
186 | function gasEqualsGasUsed(tx) {
187 | var gas = eth.getTransaction(tx).gas;
188 | var gasUsed = eth.getTransactionReceipt(tx).gasUsed;
189 | return (gas == gasUsed);
190 | }
191 |
192 | function failIfGasEqualsGasUsed(tx, msg) {
193 | var gas = eth.getTransaction(tx).gas;
194 | var gasUsed = eth.getTransactionReceipt(tx).gasUsed;
195 | if (gas == gasUsed) {
196 | console.log("RESULT: FAIL " + msg);
197 | return 0;
198 | } else {
199 | console.log("RESULT: PASS " + msg);
200 | return 1;
201 | }
202 | }
203 |
204 | function passIfGasEqualsGasUsed(tx, msg) {
205 | var gas = eth.getTransaction(tx).gas;
206 | var gasUsed = eth.getTransactionReceipt(tx).gasUsed;
207 | if (gas == gasUsed) {
208 | console.log("RESULT: PASS " + msg);
209 | return 1;
210 | } else {
211 | console.log("RESULT: FAIL " + msg);
212 | return 0;
213 | }
214 | }
215 |
216 | function failIfGasEqualsGasUsedOrContractAddressNull(contractAddress, tx, msg) {
217 | if (contractAddress == null) {
218 | console.log("RESULT: FAIL " + msg);
219 | return 0;
220 | } else {
221 | var gas = eth.getTransaction(tx).gas;
222 | var gasUsed = eth.getTransactionReceipt(tx).gasUsed;
223 | if (gas == gasUsed) {
224 | console.log("RESULT: FAIL " + msg);
225 | return 0;
226 | } else {
227 | console.log("RESULT: PASS " + msg);
228 | return 1;
229 | }
230 | }
231 | }
232 |
233 |
234 | //-----------------------------------------------------------------------------
235 | // Wait one block
236 | //-----------------------------------------------------------------------------
237 | function waitOneBlock(oldCurrentBlock) {
238 | while (eth.blockNumber <= oldCurrentBlock) {
239 | }
240 | console.log("RESULT: Waited one block");
241 | console.log("RESULT: ");
242 | return eth.blockNumber;
243 | }
244 |
245 |
246 | //-----------------------------------------------------------------------------
247 | // Pause for {x} seconds
248 | //-----------------------------------------------------------------------------
249 | function pause(message, addSeconds) {
250 | var time = new Date((parseInt(new Date().getTime()/1000) + addSeconds) * 1000);
251 | console.log("RESULT: Pausing '" + message + "' for " + addSeconds + "s=" + time + " now=" + new Date());
252 | while ((new Date()).getTime() <= time.getTime()) {
253 | }
254 | console.log("RESULT: Paused '" + message + "' for " + addSeconds + "s=" + time + " now=" + new Date());
255 | console.log("RESULT: ");
256 | }
257 |
258 |
259 | //-----------------------------------------------------------------------------
260 | //Wait until some unixTime + additional seconds
261 | //-----------------------------------------------------------------------------
262 | function waitUntil(message, unixTime, addSeconds) {
263 | var t = parseInt(unixTime) + parseInt(addSeconds) + parseInt(1);
264 | var time = new Date(t * 1000);
265 | console.log("RESULT: Waiting until '" + message + "' at " + unixTime + "+" + addSeconds + "s=" + time + " now=" + new Date());
266 | while ((new Date()).getTime() <= time.getTime()) {
267 | }
268 | console.log("RESULT: Waited until '" + message + "' at at " + unixTime + "+" + addSeconds + "s=" + time + " now=" + new Date());
269 | console.log("RESULT: ");
270 | }
271 |
272 |
273 | //-----------------------------------------------------------------------------
274 | //Wait until some block
275 | //-----------------------------------------------------------------------------
276 | function waitUntilBlock(message, block, addBlocks) {
277 | var b = parseInt(block) + parseInt(addBlocks);
278 | console.log("RESULT: Waiting until '" + message + "' #" + block + "+" + addBlocks + "=#" + b + " currentBlock=" + eth.blockNumber);
279 | while (eth.blockNumber <= b) {
280 | }
281 | console.log("RESULT: Waited until '" + message + "' #" + block + "+" + addBlocks + "=#" + b + " currentBlock=" + eth.blockNumber);
282 | console.log("RESULT: ");
283 | }
284 |
285 |
286 | //-----------------------------------------------------------------------------
287 | // Token Contract
288 | //-----------------------------------------------------------------------------
289 | var tokenFromBlock = 0;
290 | function printTokenContractDetails() {
291 | console.log("RESULT: tokenContractAddress=" + tokenContractAddress);
292 | if (tokenContractAddress != null && tokenContractAbi != null) {
293 | var contract = eth.contract(tokenContractAbi).at(tokenContractAddress);
294 | var decimals = contract.decimals();
295 | console.log("RESULT: token.owner=" + contract.owner());
296 | console.log("RESULT: token.newOwner=" + contract.newOwner());
297 | console.log("RESULT: token.symbol=" + contract.symbol());
298 | console.log("RESULT: token.name=" + contract.name());
299 | console.log("RESULT: token.decimals=" + decimals);
300 | console.log("RESULT: token.totalSupply=" + contract.totalSupply().shift(-decimals));
301 | // console.log("RESULT: token.transferable=" + contract.transferable());
302 | // console.log("RESULT: token.mintable=" + contract.mintable());
303 | // console.log("RESULT: token.minter=" + contract.minter());
304 |
305 | var latestBlock = eth.blockNumber;
306 | var i;
307 |
308 | var approvalEvents = contract.Approval({}, { fromBlock: tokenFromBlock, toBlock: latestBlock });
309 | i = 0;
310 | approvalEvents.watch(function (error, result) {
311 | console.log("RESULT: Approval " + i++ + " #" + result.blockNumber + " owner=" + result.args.owner +
312 | " spender=" + result.args.spender + " tokens=" + result.args.tokens.shift(-decimals));
313 | });
314 | approvalEvents.stopWatching();
315 |
316 | var transferEvents = contract.Transfer({}, { fromBlock: tokenFromBlock, toBlock: latestBlock });
317 | i = 0;
318 | transferEvents.watch(function (error, result) {
319 | console.log("RESULT: Transfer " + i++ + " #" + result.blockNumber + ": from=" + result.args.from + " to=" + result.args.to +
320 | " tokens=" + result.args.tokens.shift(-decimals));
321 | });
322 | transferEvents.stopWatching();
323 |
324 | tokenFromBlock = latestBlock + 1;
325 | }
326 | }
327 |
328 |
329 | // -----------------------------------------------------------------------------
330 | // Club Contract
331 | // -----------------------------------------------------------------------------
332 | var clubContractAddress = null;
333 | var clubContractAbi = null;
334 |
335 | function addClubContractAddressAndAbi(address, clubAbi) {
336 | clubContractAddress = address;
337 | clubContractAbi = clubAbi;
338 | }
339 |
340 | function displaySplit(data) {
341 | var eth1 = data[0];
342 | var eth2 = data[1];
343 | var eth3 = data[2];
344 | var refund = data[3];
345 | var total = eth1.add(eth2).add(eth3).add(refund);
346 | return "[eth1=" + eth1.shift(-18) + "; eth2=" + eth2.shift(-18) + "; eth3=" + eth3.shift(-18) + "; refund=" + refund.shift(-18) + "; total=" + total.shift(-18) + "]";
347 | }
348 |
349 | var clubFromBlock = 0;
350 | function printClubContractDetails() {
351 | console.log("RESULT: clubContractAddress=" + clubContractAddress);
352 | if (clubContractAddress != null && clubContractAbi != null) {
353 | var contract = eth.contract(clubContractAbi).at(clubContractAddress);
354 | console.log("RESULT: club.token=" + contract.token());
355 | console.log("RESULT: club.initialised=" + contract.initialised());
356 | console.log("RESULT: club.numberOfMembers=" + contract.numberOfMembers());
357 | console.log("RESULT: club.getMembers=" + JSON.stringify(contract.getMembers()));
358 | var i;
359 | for (i = 0; i < contract.numberOfMembers(); i++) {
360 | var member = contract.getMemberByIndex(i);
361 | var data = contract.getMemberData(member);
362 | console.log("RESULT: club.member[" + i + "]=" + member + " [" + data[0] + ", " + data[1] + ", '" + data[2] + "']");
363 | }
364 | console.log("RESULT: club.numberOfProposals=" + contract.numberOfProposals());
365 | for (i = 0; i < contract.numberOfProposals(); i++) {
366 | console.log("RESULT: club.getProposal[" + i + "]=" + JSON.stringify(contract.getProposal(i)));
367 | }
368 | console.log("RESULT: club.quorum=" + contract.quorum() + "%");
369 | console.log("RESULT: club.quorumDecayPerWeek=" + contract.quorumDecayPerWeek() + "%");
370 | console.log("RESULT: club.requiredMajority=" + contract.requiredMajority() + "%");
371 |
372 | var now = new Date()/1000;
373 | var line = "";
374 | for (i = 0; i < 10; i++) {
375 | var date = parseInt(now) + 60 * 60 * 24 * 7 * i;
376 | line = line + i + "w=" + contract.getQuorum(now, date) + "% ";
377 | }
378 | console.log("RESULT: club.getQuorum(now, * weeks)=" + line);
379 |
380 | var latestBlock = eth.blockNumber;
381 |
382 | var newProposalEvents = contract.NewProposal({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
383 | i = 0;
384 | newProposalEvents.watch(function (error, result) {
385 | console.log("RESULT: NewProposal " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
386 | var proposal = contract.getProposal(result.args.proposalId);
387 | console.log("RESULT: - proposal=" + JSON.stringify(proposal));
388 | });
389 | newProposalEvents.stopWatching();
390 |
391 | var votedEvents = contract.Voted({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
392 | i = 0;
393 | votedEvents.watch(function (error, result) {
394 | console.log("RESULT: Voted " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
395 | });
396 | votedEvents.stopWatching();
397 |
398 | var voteResultEvents = contract.VoteResult({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
399 | i = 0;
400 | voteResultEvents.watch(function (error, result) {
401 | console.log("RESULT: VoteResult " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
402 | });
403 | voteResultEvents.stopWatching();
404 |
405 | var memberAddedEvents = contract.MemberAdded({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
406 | i = 0;
407 | memberAddedEvents.watch(function (error, result) {
408 | console.log("RESULT: MemberAdded " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
409 | });
410 | memberAddedEvents.stopWatching();
411 |
412 | var memberRemovedEvents = contract.MemberRemoved({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
413 | i = 0;
414 | memberRemovedEvents.watch(function (error, result) {
415 | console.log("RESULT: MemberRemoved " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
416 | });
417 | memberRemovedEvents.stopWatching();
418 |
419 | var memberNameUpdatedEvents = contract.MemberNameUpdated({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
420 | i = 0;
421 | memberNameUpdatedEvents.watch(function (error, result) {
422 | console.log("RESULT: MemberNameUpdated " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
423 | });
424 | memberNameUpdatedEvents.stopWatching();
425 |
426 | var tokenUpdatedEvents = contract.TokenUpdated({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
427 | i = 0;
428 | tokenUpdatedEvents.watch(function (error, result) {
429 | console.log("RESULT: TokenUpdated " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
430 | });
431 | tokenUpdatedEvents.stopWatching();
432 |
433 | var tokensForNewMembersUpdatedEvents = contract.TokensForNewMembersUpdated({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
434 | i = 0;
435 | tokensForNewMembersUpdatedEvents.watch(function (error, result) {
436 | console.log("RESULT: TokensForNewMembersUpdated " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
437 | });
438 | tokensForNewMembersUpdatedEvents.stopWatching();
439 |
440 | var etherDepositedEvents = contract.EtherDeposited({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
441 | i = 0;
442 | etherDepositedEvents.watch(function (error, result) {
443 | console.log("RESULT: EtherDeposited " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
444 | });
445 | etherDepositedEvents.stopWatching();
446 |
447 | var etherTransferredEvents = contract.EtherTransferred({}, { fromBlock: clubFromBlock, toBlock: latestBlock });
448 | i = 0;
449 | etherTransferredEvents.watch(function (error, result) {
450 | console.log("RESULT: EtherTransferred " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
451 | });
452 | etherTransferredEvents.stopWatching();
453 |
454 | clubFromBlock = latestBlock + 1;
455 | }
456 | }
457 |
458 |
459 | // -----------------------------------------------------------------------------
460 | // ClubFactory Contract
461 | // -----------------------------------------------------------------------------
462 | var clubFactoryContractAddress = null;
463 | var clubFactoryContractAbi = null;
464 |
465 | function addClubFactoryContractAddressAndAbi(address, clubFactoryAbi) {
466 | clubFactoryContractAddress = address;
467 | clubFactoryContractAbi = clubFactoryAbi;
468 | }
469 |
470 | var clubFactoryFromBlock = 0;
471 |
472 | function getClubAndTokenListing() {
473 | var clubs = [];
474 | var tokens = [];
475 | console.log("RESULT: clubFactoryContractAddress=" + clubFactoryContractAddress);
476 | if (clubFactoryContractAddress != null && clubFactoryContractAbi != null) {
477 | var contract = eth.contract(clubFactoryContractAbi).at(clubFactoryContractAddress);
478 |
479 | var latestBlock = eth.blockNumber;
480 | var i;
481 |
482 | var clubListingEvents = contract.ClubEthListing({}, { fromBlock: clubFactoryFromBlock, toBlock: latestBlock });
483 | i = 0;
484 | clubListingEvents.watch(function (error, result) {
485 | console.log("RESULT: get ClubEthListing " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
486 | clubs.push(result.args.clubAddress);
487 | tokens.push(result.args.tokenAddress);
488 | });
489 | clubListingEvents.stopWatching();
490 | }
491 | return [clubs, tokens];
492 | }
493 |
494 | function printClubFactoryContractDetails() {
495 | console.log("RESULT: clubFactoryContractAddress=" + clubFactoryContractAddress);
496 | if (clubFactoryContractAddress != null && clubFactoryContractAbi != null) {
497 | var contract = eth.contract(clubFactoryContractAbi).at(clubFactoryContractAddress);
498 | console.log("RESULT: clubFactory.owner=" + contract.owner());
499 | console.log("RESULT: clubFactory.newOwner=" + contract.newOwner());
500 |
501 | var latestBlock = eth.blockNumber;
502 | var i;
503 |
504 | var ownershipTransferredEvents = contract.OwnershipTransferred({}, { fromBlock: clubFactoryFromBlock, toBlock: latestBlock });
505 | i = 0;
506 | ownershipTransferredEvents.watch(function (error, result) {
507 | console.log("RESULT: OwnershipTransferred " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
508 | });
509 | ownershipTransferredEvents.stopWatching();
510 |
511 | var clubEthListingEvents = contract.ClubEthListing({}, { fromBlock: clubFactoryFromBlock, toBlock: latestBlock });
512 | i = 0;
513 | clubEthListingEvents.watch(function (error, result) {
514 | console.log("RESULT: ClubEthListing " + i++ + " #" + result.blockNumber + " " + JSON.stringify(result.args));
515 | });
516 | clubEthListingEvents.stopWatching();
517 |
518 | clubFactoryFromBlock = latestBlock + 1;
519 | }
520 | }
521 |
522 |
523 | // -----------------------------------------------------------------------------
524 | // Generate Summary JSON
525 | // -----------------------------------------------------------------------------
526 | function generateSummaryJSON() {
527 | console.log("JSONSUMMARY: {");
528 | if (crowdsaleContractAddress != null && crowdsaleContractAbi != null) {
529 | var contract = eth.contract(crowdsaleContractAbi).at(crowdsaleContractAddress);
530 | var blockNumber = eth.blockNumber;
531 | var timestamp = eth.getBlock(blockNumber).timestamp;
532 | console.log("JSONSUMMARY: \"blockNumber\": " + blockNumber + ",");
533 | console.log("JSONSUMMARY: \"blockTimestamp\": " + timestamp + ",");
534 | console.log("JSONSUMMARY: \"blockTimestampString\": \"" + new Date(timestamp * 1000).toUTCString() + "\",");
535 | console.log("JSONSUMMARY: \"crowdsaleContractAddress\": \"" + crowdsaleContractAddress + "\",");
536 | console.log("JSONSUMMARY: \"crowdsaleContractOwnerAddress\": \"" + contract.owner() + "\",");
537 | console.log("JSONSUMMARY: \"tokenContractAddress\": \"" + contract.bttsToken() + "\",");
538 | console.log("JSONSUMMARY: \"tokenContractDecimals\": " + contract.TOKEN_DECIMALS() + ",");
539 | console.log("JSONSUMMARY: \"crowdsaleWalletAddress\": \"" + contract.wallet() + "\",");
540 | console.log("JSONSUMMARY: \"crowdsaleTeamWalletAddress\": \"" + contract.teamWallet() + "\",");
541 | console.log("JSONSUMMARY: \"crowdsaleTeamPercent\": " + contract.TEAM_PERCENT_GZE() + ",");
542 | console.log("JSONSUMMARY: \"bonusListContractAddress\": \"" + contract.bonusList() + "\",");
543 | console.log("JSONSUMMARY: \"tier1Bonus\": " + contract.TIER1_BONUS() + ",");
544 | console.log("JSONSUMMARY: \"tier2Bonus\": " + contract.TIER2_BONUS() + ",");
545 | console.log("JSONSUMMARY: \"tier3Bonus\": " + contract.TIER3_BONUS() + ",");
546 | var startDate = contract.START_DATE();
547 | // BK TODO - Remove for production
548 | startDate = 1512921600;
549 | var endDate = contract.endDate();
550 | // BK TODO - Remove for production
551 | endDate = 1513872000;
552 | console.log("JSONSUMMARY: \"crowdsaleStart\": " + startDate + ",");
553 | console.log("JSONSUMMARY: \"crowdsaleStartString\": \"" + new Date(startDate * 1000).toUTCString() + "\",");
554 | console.log("JSONSUMMARY: \"crowdsaleEnd\": " + endDate + ",");
555 | console.log("JSONSUMMARY: \"crowdsaleEndString\": \"" + new Date(endDate * 1000).toUTCString() + "\",");
556 | console.log("JSONSUMMARY: \"usdPerEther\": " + contract.usdPerKEther().shift(-3) + ",");
557 | console.log("JSONSUMMARY: \"usdPerGze\": " + contract.USD_CENT_PER_GZE().shift(-2) + ",");
558 | console.log("JSONSUMMARY: \"gzePerEth\": " + contract.gzePerEth().shift(-18) + ",");
559 | console.log("JSONSUMMARY: \"capInUsd\": " + contract.CAP_USD() + ",");
560 | console.log("JSONSUMMARY: \"capInEth\": " + contract.capEth().shift(-18) + ",");
561 | console.log("JSONSUMMARY: \"minimumContributionEth\": " + contract.MIN_CONTRIBUTION_ETH().shift(-18) + ",");
562 | console.log("JSONSUMMARY: \"contributedEth\": " + contract.contributedEth().shift(-18) + ",");
563 | console.log("JSONSUMMARY: \"contributedUsd\": " + contract.contributedUsd() + ",");
564 | console.log("JSONSUMMARY: \"generatedGze\": " + contract.generatedGze().shift(-18) + ",");
565 | console.log("JSONSUMMARY: \"lockedAccountThresholdUsd\": " + contract.lockedAccountThresholdUsd() + ",");
566 | console.log("JSONSUMMARY: \"lockedAccountThresholdEth\": " + contract.lockedAccountThresholdEth().shift(-18) + ",");
567 | console.log("JSONSUMMARY: \"precommitmentAdjusted\": " + contract.precommitmentAdjusted() + ",");
568 | console.log("JSONSUMMARY: \"finalised\": " + contract.finalised());
569 | }
570 | console.log("JSONSUMMARY: }");
571 | }
572 |
--------------------------------------------------------------------------------
/test/genesis.json:
--------------------------------------------------------------------------------
1 | {
2 | "config": {
3 | "homesteadBlock": 1,
4 | "byzantiumBlock": 2
5 | },
6 | "nonce": "0",
7 | "difficulty": "0x400",
8 | "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
9 | "coinbase": "0x0000000000000000000000000000000000000000",
10 | "timestamp": "0x00",
11 | "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
12 | "extraData": "0x",
13 | "gasLimit": "0x3B4A1B44",
14 | "alloc": {
15 | "0xa00Af22D07c87d96EeeB0Ed583f8F6AC7812827E": {
16 | "balance": "10000000000000000000000000"
17 | },
18 | "0xa11AAE29840fBb5c86E6fd4cF809EBA183AEf433": {
19 | "balance": "10000000000000000000000000"
20 | },
21 | "0xa22AB8A9D641CE77e06D98b7D7065d324D3d6976": {
22 | "balance": "10000000000000000000000000"
23 | },
24 | "0xa33a6c312D9aD0E0F2E95541BeED0Cc081621fd0": {
25 | "balance": "10000000000000000000000000"
26 | },
27 | "0xa44a08d3F6933c69212114bb66E2Df1813651844": {
28 | "balance": "10000000000000000000000000"
29 | },
30 | "0xa55A151Eb00fded1634D27D1127b4bE4627079EA": {
31 | "balance": "10000000000000000000000000"
32 | },
33 | "0xa66a85ede0CBE03694AA9d9dE0BB19c99ff55bD9": {
34 | "balance": "10000000000000000000000000"
35 | },
36 | "0xa77A2b9D4B1c010A22A7c565Dc418cef683DbceC": {
37 | "balance": "10000000000000000000000000"
38 | },
39 | "0xA88A05d2b88283ce84C8325760B72a64591279a2": {
40 | "balance": "10000000000000000000000000"
41 | },
42 | "0xa99A0Ae3354c06B1459fd441a32a3F71005D7Da0": {
43 | "balance": "10000000000000000000000000"
44 | },
45 | "0xAAAA9De1E6C564446EBCA0fd102D8Bd92093c756": {
46 | "balance": "10000000000000000000000000"
47 | },
48 | "0xaBBa43E7594E3B76afB157989e93c6621497FD4b": {
49 | "balance": "10000000000000000000000000"
50 | },
51 | "0xacCa534c9f62Ab495bd986e002DdF0f054caAE4f": {
52 | "balance": "10000000000000000000000000"
53 | },
54 | "0xAddA9B762A00FF12711113bfDc36958B73d7F915": {
55 | "balance": "10000000000000000000000000"
56 | },
57 | "0xaeEa63B5479B50F79583ec49DACdcf86DDEff392": {
58 | "balance": "10000000000000000000000000"
59 | },
60 | "0xaFfa4D3A80Add8CE4018540e056DACb649589394": {
61 | "balance": "10000000000000000000000000"
62 | },
63 | "0xB00bfdE102270687324F9205b693859df64F8923": {
64 | "balance": "10000000000000000000000000"
65 | },
66 | "0xB11Be1D4EF8E94d01cB2695092A79d139A8DAD98": {
67 | "balance": "10000000000000000000000000"
68 | },
69 | "0xB22BE2D9eEF0d7E260CF96A64FEEa0B95ED3E74f": {
70 | "balance": "10000000000000000000000000"
71 | },
72 | "0xB33B7ecf5E47BE3981c74d989d3Af8b665b4B649": {
73 | "balance": "10000000000000000000000000"
74 | },
75 | "0xB44B43d59b738B088b690aE276C1E979aBa8268D": {
76 | "balance": "10000000000000000000000000"
77 | },
78 | "0xb55B57D113b45481E31AaF03D6F4e5Ad4ef325F8": {
79 | "balance": "10000000000000000000000000"
80 | },
81 | "0xb66BCB4e473De80E2C8A47CED10c22c705A5e602": {
82 | "balance": "10000000000000000000000000"
83 | },
84 | "0xB77BbBaa7c1649547Ae61de4B80B91568c28351A": {
85 | "balance": "10000000000000000000000000"
86 | },
87 | "0xB88B728490B417E29b0784Db30535dB343830dba": {
88 | "balance": "10000000000000000000000000"
89 | },
90 | "0xB99B3d1f72eDb05a0321dB58eddcF83FD73C4aDe": {
91 | "balance": "10000000000000000000000000"
92 | },
93 | "0xBaAb56DA883EDBe5314b8005BE410022c510cCae": {
94 | "balance": "10000000000000000000000000"
95 | },
96 | "0xbbbB9809DE0456Ce0E0Cd660E6E4CeabEf3F521c": {
97 | "balance": "10000000000000000000000000"
98 | },
99 | "0xBccB68DD0Ac87EF290aeF49870d155F076C87868": {
100 | "balance": "10000000000000000000000000"
101 | },
102 | "0xbDDB726ee06906e104DB210E6d0506F2B062e477": {
103 | "balance": "10000000000000000000000000"
104 | },
105 | "0xbeEB24ff18203658D0a1d4682ee3f36ad663eC87": {
106 | "balance": "10000000000000000000000000"
107 | },
108 | "0xbFfBd8F029EF0BD81cF754b53E8b3a5684F8b3fF": {
109 | "balance": "10000000000000000000000000"
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/test/settings:
--------------------------------------------------------------------------------
1 | GETHATTACHPOINT=ipc:./testchain/geth.ipc
2 | PASSWORD=
3 |
4 | SOURCEDIR=../contracts
5 |
6 | DATETIMELIBSOL=BokkyPooBahsDateTimeLibrary.sol
7 | DATETIMELIBJS=BokkyPooBahsDateTimeLibrary.js
8 | TESTDATETIMESOL=TestDateTime.sol
9 | TESTDATETIMEJS=TestDateTime.js
10 | TESTDATETIMEFLATTENED=../flattened/TestDateTime_flattened.sol
11 |
12 | DEPLOYMENTDATA=deploymentData.js
13 |
14 | TEST1OUTPUT=test1output.txt
15 | TEST1RESULTS=test1results.txt
16 | TEST2OUTPUT=test2output.txt
17 | TEST2RESULTS=test2results.txt
18 | TEST3OUTPUT=test3output.txt
19 | TEST3RESULTS=test3results.txt
20 | TEST4OUTPUT=test4output.txt
21 | TEST4RESULTS=test4results.txt
22 |
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-37-30.360937280Z--a00af22d07c87d96eeeb0ed583f8f6ac7812827e:
--------------------------------------------------------------------------------
1 | {"address":"a00af22d07c87d96eeeb0ed583f8f6ac7812827e","crypto":{"cipher":"aes-128-ctr","ciphertext":"7746ca0958bde0c8404f27e102f2fbb74eae623786ec344362e3434934a55b7d","cipherparams":{"iv":"5fc7dce773e69818a2d08f293657dbad"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f3675b3f9a1f414e429249eecc41c3ea20c6023012362fe8bf9e4ea231fc3801"},"mac":"c1fc366ec058c62c29e0e1668f997e20d08a9e57c7335dcf0d6d38e9faddfca5"},"id":"e3f0faf2-6ec2-4f29-a14e-c48d2d751b94","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-37-58.104082316Z--a11aae29840fbb5c86e6fd4cf809eba183aef433:
--------------------------------------------------------------------------------
1 | {"address":"a11aae29840fbb5c86e6fd4cf809eba183aef433","crypto":{"cipher":"aes-128-ctr","ciphertext":"a025e7b46192578ac826200c281e6d7d83ba31c93c33c8d575dbe8fc1a75b1b9","cipherparams":{"iv":"b1e35272e6823a857e11627cfa20ffd6"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0943b2a690f33601eba2a545435a3463d7d9b7ce96d15b544a0db14377ab5202"},"mac":"d2afc76e4fb19d01920e2822fd0cc760824b10e710ce565bdd1369d52fcdc741"},"id":"f1b73a4b-8229-4c3b-8844-f59f398087b0","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-38-21.169063367Z--a22ab8a9d641ce77e06d98b7d7065d324d3d6976:
--------------------------------------------------------------------------------
1 | {"address":"a22ab8a9d641ce77e06d98b7d7065d324d3d6976","crypto":{"cipher":"aes-128-ctr","ciphertext":"8a5a891ef2a10dc0d7faaa3bc01cd48d2bb38aca285f9acd73889f54e03ad017","cipherparams":{"iv":"17401904119a8f70861dfe9a9b02a463"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e1e7f968847eaaf620f3c5e3541b6a3f0d8e00df9a9d470952eb6bf31cbb398b"},"mac":"de7767918e49ce2ec36b0dd8c85f8853f2b2db39da70f8b8a52d7d8c6856a6de"},"id":"baa6c875-74cf-4c02-ace7-c8c6aa32765f","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-38-41.707647638Z--a33a6c312d9ad0e0f2e95541beed0cc081621fd0:
--------------------------------------------------------------------------------
1 | {"address":"a33a6c312d9ad0e0f2e95541beed0cc081621fd0","crypto":{"cipher":"aes-128-ctr","ciphertext":"6291be87d8beb1a5a9833946c0727a93f531c341316d3ca32a97e36513b829bf","cipherparams":{"iv":"37e0e2897ff5de0a2b34ddbc7f67a7bd"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"2633c529cb47901bba6f3cf8acb8aa3f27d218e3120b1f0832f5acac7e12830a"},"mac":"b1ace4451045b2cb06507a719e7e9edb97b7c9ce38e42014472cbb4f52ed4d5f"},"id":"7ab0d4a9-c6b5-426f-9445-1604929628c2","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-39-04.584040707Z--a44a08d3f6933c69212114bb66e2df1813651844:
--------------------------------------------------------------------------------
1 | {"address":"a44a08d3f6933c69212114bb66e2df1813651844","crypto":{"cipher":"aes-128-ctr","ciphertext":"0334a6431e1278ef00ec18262d71325fb6cbec744708bdd306757d23bf9665b2","cipherparams":{"iv":"707c645f21c317d506b7f0d3073d85a1"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"7bc76dc778baef6878f043da5461f40faa700d029b8dbde5a10a7899129e329a"},"mac":"ffb6282494f01133507fc97bf57d8a7644205e0dab33dc977bf809e541c8f41e"},"id":"356880ad-1c9d-4bd1-92ce-48de1a668c8f","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-42-01.013666678Z--a55a151eb00fded1634d27d1127b4be4627079ea:
--------------------------------------------------------------------------------
1 | {"address":"a55a151eb00fded1634d27d1127b4be4627079ea","crypto":{"cipher":"aes-128-ctr","ciphertext":"ee8985250e7b89990b8614f9ceec5f96f11e66ef147e2a689ac29bcdbab5142c","cipherparams":{"iv":"594d35ce8d73e0efb89ddc882f13d912"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e9635fc62fb0b9db5c0ffa6cd415f7b58c3dc4b5d9af700aac347a568792dc82"},"mac":"6b035510432179623cbaa5d3306106d5c608695fde89d7ec2d3aff5f484a6376"},"id":"47bfbb81-5b55-4cf4-9289-80e2fe0fbd9c","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-42-37.426191216Z--a66a85ede0cbe03694aa9d9de0bb19c99ff55bd9:
--------------------------------------------------------------------------------
1 | {"address":"a66a85ede0cbe03694aa9d9de0bb19c99ff55bd9","crypto":{"cipher":"aes-128-ctr","ciphertext":"f1b8dfabcdc9da96c9ee44a0ee7005b17bcdeda702e7fb17624a35bd51252d28","cipherparams":{"iv":"c762e2bd794022892e1d99c7494b7a41"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d92954d1c8073978d17c5943b72aa826108c8cc927b1097a7ea3ef71b02d15cc"},"mac":"dd118288bb676dca7a7607ff86ed02eccfa4dfac2ebef69bf52dc0304e1af465"},"id":"396c5807-24e8-4a78-a76e-5dfcd0e2dfe4","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-42-58.899396047Z--a77a2b9d4b1c010a22a7c565dc418cef683dbcec:
--------------------------------------------------------------------------------
1 | {"address":"a77a2b9d4b1c010a22a7c565dc418cef683dbcec","crypto":{"cipher":"aes-128-ctr","ciphertext":"6f4262c172be2e9053e556380e5ea842959e0ffa51c17fc270259832f3cfe91a","cipherparams":{"iv":"b056c35ee783e7bcdf58e70b717c8bf8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"35a93f01a9cc1dcb323305b15cdd22ad899796f620783fab8512b0100eb478da"},"mac":"20088a8203dc6e2a8ff5288799700aaf969424912cdfd5b1e9262fd703ea2da8"},"id":"46a2e757-d4e9-40ba-aec4-6640d7b74347","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-47-09.150580614Z--a88a05d2b88283ce84c8325760b72a64591279a2:
--------------------------------------------------------------------------------
1 | {"address":"a88a05d2b88283ce84c8325760b72a64591279a2","crypto":{"cipher":"aes-128-ctr","ciphertext":"3d3331aeb08de887031a50ec00c4385dc2f3ee28b3f720b788964b45a77321c7","cipherparams":{"iv":"c5024557ef11f71d86209aa5cb9c90bd"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"130cd49e03cbf0eccba0d430c7c545be2dd9ed78120b42a128974b63e644c283"},"mac":"e98487a07e49dcde74e890d1dd9ea51d07aa62ecf19d96c782599c265c5a90c7"},"id":"5083b6d1-3059-457f-bdae-6a413a222428","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-47-34.770098207Z--a99a0ae3354c06b1459fd441a32a3f71005d7da0:
--------------------------------------------------------------------------------
1 | {"address":"a99a0ae3354c06b1459fd441a32a3f71005d7da0","crypto":{"cipher":"aes-128-ctr","ciphertext":"92983913294e4fac0d23b2aa87371c63538e3735fc99c9212f4b3db8301ecccf","cipherparams":{"iv":"cab44152a75c5abccdb1f90a849c84ca"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"29ac10474ba160267a637197d12e938ee313daa501f6b0883ae96da4c19f6155"},"mac":"224930b5688b9e0cc77d321610e440c32af3372fe4b17d8e451bf2c3c89ddf25"},"id":"47cc9299-fea0-46c6-88e8-452fb714ca4c","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-58-17.400859858Z--aaaa9de1e6c564446ebca0fd102d8bd92093c756:
--------------------------------------------------------------------------------
1 | {"address":"aaaa9de1e6c564446ebca0fd102d8bd92093c756","crypto":{"cipher":"aes-128-ctr","ciphertext":"525cb018c05b12bb038b9802c8d28dda40bdd8027a5a94efdfe5f06d13428020","cipherparams":{"iv":"31b96dade192e677db9d03ca2da3dd4b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"aaf8e556d62452fb946046397c8c58545cbb1e118a3f3e3b8cc2995a2e9020a7"},"mac":"bbc30ecbf1ca76ee507c08db2dc07611b29a69a5f3de3bb2b0c92a1b8e0cb6b3"},"id":"9ae73070-0b07-472c-bfe5-e07cbe66f289","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-58-35.122799190Z--abba43e7594e3b76afb157989e93c6621497fd4b:
--------------------------------------------------------------------------------
1 | {"address":"abba43e7594e3b76afb157989e93c6621497fd4b","crypto":{"cipher":"aes-128-ctr","ciphertext":"9d93b2417788589c2bbc56d829189ee7014a131cde75ff222ed95765760e33e9","cipherparams":{"iv":"72adceb8556da2df85337eb7e3857e91"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f81be6c897007703d414b4849894395cecb982380791ff29b9742ee7ab1b9437"},"mac":"ed0dbee8cbde6219c7c15c501ca31146705c0d310301aa73311c0bf943712127"},"id":"be47d6a6-f747-4741-bdfd-33182d2f674d","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-58-51.178332229Z--acca534c9f62ab495bd986e002ddf0f054caae4f:
--------------------------------------------------------------------------------
1 | {"address":"acca534c9f62ab495bd986e002ddf0f054caae4f","crypto":{"cipher":"aes-128-ctr","ciphertext":"95204bfd49fad4e3ef709e55857b0fa9f0e9d03c1e2219a44408bddafd45ba72","cipherparams":{"iv":"9ae7d4de6b7d7d78fd0c6499dda0f35d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"2be91d7a047ae89c934f2b09b541887ac8a7dfb99df658e05f9ee05f2c5ef478"},"mac":"d9abc981e0b3d7ca60d3138dce58e5529bb12fee092cdd77a0a93b453e22dd3b"},"id":"3cae58b4-bdd3-43ee-929c-b1eff57e10ad","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-59-14.034178720Z--adda9b762a00ff12711113bfdc36958b73d7f915:
--------------------------------------------------------------------------------
1 | {"address":"adda9b762a00ff12711113bfdc36958b73d7f915","crypto":{"cipher":"aes-128-ctr","ciphertext":"0bacd07a24fee23bcb01e05f7f75ba8fc862500a8c76274dcdb85c6f46886623","cipherparams":{"iv":"e7ec110f1ff5d8bfc45f7d73e19dbd9f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"b774e6680f20cafce454fc994ad2ba33afd3556feeea7f5338bcaadeb3559de3"},"mac":"fec0ec38202864975845c5602150c62b8ade0538cfdb9b6a0cdbaf48a916d18c"},"id":"b6b3a3ab-35fe-48aa-a74a-681a08cfea36","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-59-33.471449656Z--aeea63b5479b50f79583ec49dacdcf86ddeff392:
--------------------------------------------------------------------------------
1 | {"address":"aeea63b5479b50f79583ec49dacdcf86ddeff392","crypto":{"cipher":"aes-128-ctr","ciphertext":"88e5fd79e85032bb427b082f9875de72b21aca1acb0370b59fe301306510f68f","cipherparams":{"iv":"da6522bfd41e2676def953ee017f5f23"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"a8770326e860c28a45d1aff231560bc00a69622dad0f50d9ff395ec1f6f1b453"},"mac":"128e84afe94656cc89e96180676607cfaae0c4b220eec2e11642b7cd38146226"},"id":"b6dcecff-9bbb-40c5-bcea-501e3d610c7b","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-05-20T02-59-51.697690594Z--affa4d3a80add8ce4018540e056dacb649589394:
--------------------------------------------------------------------------------
1 | {"address":"affa4d3a80add8ce4018540e056dacb649589394","crypto":{"cipher":"aes-128-ctr","ciphertext":"575889b5c78941e143e3af18ab2fd614d6a36846dbc424bda006f40a8ccdd4ef","cipherparams":{"iv":"1a6fb0f7f7bbf9692568853037786fa2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"4ec7f5ad42e5c55fd8eac0f0553a1e6a5c363d8e835fc048673560f9e36bfcfc"},"mac":"6373ec14230362fc815c2929b8058a83b9a2f3e6d3e92b35c2d2696a0ba4cf8d"},"id":"8af80842-e108-4256-b33f-9fa5fb5f6de5","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-46-38.500831000Z--b00bfde102270687324f9205b693859df64f8923:
--------------------------------------------------------------------------------
1 | {"address":"b00bfde102270687324f9205b693859df64f8923","crypto":{"cipher":"aes-128-ctr","ciphertext":"35a15a36140fe96dd1eca2b68fbbfd950e892edd5cb1885c99f0ef67ad83d93a","cipherparams":{"iv":"f1fe0fa1b348fb133087f82eb01780b8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f152543f3b3ec82d834273256aff02ea0776323c31b3f1b5f2717e5bd428e9a3"},"mac":"851663b1e882a5443e64f886ae38aed51544f7603a73433d587272871316f5b8"},"id":"cb1bb6d8-9c68-46ce-93cb-36e33ffd19c6","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-47-13.633282000Z--b11be1d4ef8e94d01cb2695092a79d139a8dad98:
--------------------------------------------------------------------------------
1 | {"address":"b11be1d4ef8e94d01cb2695092a79d139a8dad98","crypto":{"cipher":"aes-128-ctr","ciphertext":"4fcea88902f73ca1b8436f901116dd708e4f5523b377fd0712856f1aea29eb90","cipherparams":{"iv":"eb7e8d31dc6a2cfc97e246736d36e915"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"3b5af400423f21363f700cc06f83f59d5391812520572c76bcdab0f257f01651"},"mac":"1664521b7de10c689094f73b90f724ac864d56cbac4b84e7efd0730f70dba747"},"id":"f88012ab-cbc8-43b0-bd2f-0b7d2a3edc95","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-47-34.792913000Z--b22be2d9eef0d7e260cf96a64feea0b95ed3e74f:
--------------------------------------------------------------------------------
1 | {"address":"b22be2d9eef0d7e260cf96a64feea0b95ed3e74f","crypto":{"cipher":"aes-128-ctr","ciphertext":"832a92865948d045dd35a0f2bce83bc6de81549b9d42dbd65c7a7fcd85dd3bf6","cipherparams":{"iv":"05e0d8e5a40ea28f19d4b6476fc00c9b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"3b62430be26cdee906d5478258e0bb3161c71c285ea7cda7086679d83a81ac9f"},"mac":"d201c1b1b483b0f35e6cd3c683aee09825fc99c4eb696ae3095a857a23cade03"},"id":"bc0436d0-09ff-4445-8ac7-9908950ff795","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-50-14.030093000Z--b33b7ecf5e47be3981c74d989d3af8b665b4b649:
--------------------------------------------------------------------------------
1 | {"address":"b33b7ecf5e47be3981c74d989d3af8b665b4b649","crypto":{"cipher":"aes-128-ctr","ciphertext":"3a3b04be39786bf87a9f4b4b2690379b4eca20b8ad4d0da2006411f05c07efe3","cipherparams":{"iv":"c815748114f2d09d6d15d3a00b3a483d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d89f0c41bed67c651bfe912ea7ead8cb413b1ee0a69143a1260bd0bcae40ac84"},"mac":"89230f76ec55390f350b5382ac5d37e13e77d2d161d7de04b8610df7b55a7581"},"id":"2dab1c9d-f601-4650-b48e-dcdff71f507e","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-51-02.743266000Z--b44b43d59b738b088b690ae276c1e979aba8268d:
--------------------------------------------------------------------------------
1 | {"address":"b44b43d59b738b088b690ae276c1e979aba8268d","crypto":{"cipher":"aes-128-ctr","ciphertext":"e6bbab4c2bfcfaa33bbafacae6cc571b5db9857f3a7fdab78e876476635e3a00","cipherparams":{"iv":"f093dbbc316014d016b2bc32bd32780b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0080c34c2d31eecb545ebea48d24ee707d9e553fcc99f5c552def09806fba6f8"},"mac":"3eef10bc5656f54f38f4948af7e17ad970e739647487a9d1ecc797caecf2c06d"},"id":"a6c44866-ec89-4c2d-94a9-750a4150f24a","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-53-16.250696000Z--b55b57d113b45481e31aaf03d6f4e5ad4ef325f8:
--------------------------------------------------------------------------------
1 | {"address":"b55b57d113b45481e31aaf03d6f4e5ad4ef325f8","crypto":{"cipher":"aes-128-ctr","ciphertext":"2fce0fe5d7e583df0cef51e29bcc38dd0c398ae726875681e6d58cd82f462636","cipherparams":{"iv":"64d3586f82f429a940cb76913a3e5de0"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"6236c42555711facadffd9756963240c109fdf7a5b47fc2c136d4f597393c97e"},"mac":"3a523b8196c671c21e93d29c51dc5f44fb73aae24e79a8a22193d08241acb6de"},"id":"64956427-5805-4c06-bfaf-0ea4c2d22093","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-53-56.678333000Z--b66bcb4e473de80e2c8a47ced10c22c705a5e602:
--------------------------------------------------------------------------------
1 | {"address":"b66bcb4e473de80e2c8a47ced10c22c705a5e602","crypto":{"cipher":"aes-128-ctr","ciphertext":"fc80becce2d16f01c117c298bb24436e9eebfc43d07b76760ae62825a12569cc","cipherparams":{"iv":"42e5d0f5a5ea7b0e3e433edda6a4147b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"ab72efd6bdf0c9f07b272bc1a030db8918007b9b9faf3c8096e80db016c6dbe4"},"mac":"2b45bd7c8167b76c9c95c77747ac933318acaea2aade500f5394c5321f9a41c7"},"id":"45c4cf16-2bf0-46f3-bc41-1b582ba794fa","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-55-56.546405000Z--b77bbbaa7c1649547ae61de4b80b91568c28351a:
--------------------------------------------------------------------------------
1 | {"address":"b77bbbaa7c1649547ae61de4b80b91568c28351a","crypto":{"cipher":"aes-128-ctr","ciphertext":"767d6658fb2fe43c47de4b40a9fc2ce7bddd2f518566276da20f9f389d38e142","cipherparams":{"iv":"85d12a9dea777bf7537261405af7a3ff"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"b72744837e610dd9384af2ccaac73cd90fb41c543427e18bf706ec53f2270502"},"mac":"fa6fe6e6996ec6683bbba4851c6544f2484f898f3a1b247612b8fb811612fd94"},"id":"e18c9c63-ce88-4b96-8085-88549589cccf","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-58-22.605806000Z--b88b728490b417e29b0784db30535db343830dba:
--------------------------------------------------------------------------------
1 | {"address":"b88b728490b417e29b0784db30535db343830dba","crypto":{"cipher":"aes-128-ctr","ciphertext":"31e956f9396b0d179c1136a03cfa7fc3c8f0f980b48537836aacec7f61bc8886","cipherparams":{"iv":"5d2778c9221aab3c0525f562b2f87ef5"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"d9f0731deef314e2772397e838b65410fa26d282d927c8254b839a4eac42e1fe"},"mac":"8c1e4c56aba715e04f0f8ce48460f47f194c10d7a18ca501ba6d019fa85f1768"},"id":"a0038920-3917-43eb-b308-80f7e660f77b","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T03-59-11.614985000Z--b99b3d1f72edb05a0321db58eddcf83fd73c4ade:
--------------------------------------------------------------------------------
1 | {"address":"b99b3d1f72edb05a0321db58eddcf83fd73c4ade","crypto":{"cipher":"aes-128-ctr","ciphertext":"05fd0fbb32d77fe2b2bc8f263b9537a55344c1c7548e523a4fb8c55d11994613","cipherparams":{"iv":"c111f6674336e452981b474d770d28e7"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"449f356632539f47beaff2a41cb55d28b00755aef0aaadf60ac1fed6a6fd94de"},"mac":"de231546e4b1b03da76dfab1f77b2658109234eddcd7e3c15da92d0931f5664f"},"id":"5bba5e7f-db58-45f4-adb4-c6d8a285b018","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T04-00-06.765694000Z--baab56da883edbe5314b8005be410022c510ccae:
--------------------------------------------------------------------------------
1 | {"address":"baab56da883edbe5314b8005be410022c510ccae","crypto":{"cipher":"aes-128-ctr","ciphertext":"2776d97b30f53bfda59941dc62a5e5267a383160e94e60c79877ad337b0d237f","cipherparams":{"iv":"c1d4d608e272f4fc02d8a9436161cae2"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"23244e4fd4394d6effe0c05af91af1db41b8e7ba7b953bf2bd8df10d549297a3"},"mac":"e3b0a4bc3cb9912247bc1285f2b5a2e4cd772872a1519efbd347c9fd3e1bde24"},"id":"c53d37a2-0791-4915-89d0-15beee16f8a2","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T04-00-29.951106000Z--bbbb9809de0456ce0e0cd660e6e4ceabef3f521c:
--------------------------------------------------------------------------------
1 | {"address":"bbbb9809de0456ce0e0cd660e6e4ceabef3f521c","crypto":{"cipher":"aes-128-ctr","ciphertext":"60f89b1ca820a34e0d2c25321f338836ab3873efcc3ccefa99403bb8ef7d34ac","cipherparams":{"iv":"0ffce5b666507c9e1c910cdadd2b6661"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"facd3a865fc9d97ad636a1bd3e8ef540f2036ee4765468843a6786e6cb727aa7"},"mac":"dcbca27db50cd3ac35b75d28a17a50242d699b285ce822b9d409e1e927fa1913"},"id":"77d9c9bd-be5f-46de-861c-949cdf437610","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T04-02-29.293263000Z--bccb68dd0ac87ef290aef49870d155f076c87868:
--------------------------------------------------------------------------------
1 | {"address":"bccb68dd0ac87ef290aef49870d155f076c87868","crypto":{"cipher":"aes-128-ctr","ciphertext":"e2f82512052dc1e7ed9a435f08876b241f42332dfdfc96f6ee197310b2d50468","cipherparams":{"iv":"a12c55d704f3e2aa8b18eee04cbbddc0"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"91bbbf4f3301d395ebfffb741ffa1764ff198f7688f2211cd77f5b9b99d419d0"},"mac":"202a5b0fd250f90a786d01e9f17cd7eb431f5093abc74a96c6c0fd493844d56e"},"id":"f6728945-50eb-40d7-b74f-225210bdb27d","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T04-02-54.216243000Z--bddb726ee06906e104db210e6d0506f2b062e477:
--------------------------------------------------------------------------------
1 | {"address":"bddb726ee06906e104db210e6d0506f2b062e477","crypto":{"cipher":"aes-128-ctr","ciphertext":"fc86d192ff984371fe9a307a94622f52b83d243df1c1e2c87c95cfe404cab9d0","cipherparams":{"iv":"abac565370e5ef73b3a300b993eef903"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"0e17376f4214ed015ec12f9531eb7087293a792a27cfc799a718a34b4a9f006f"},"mac":"37e419d92fe7afe29dce9facd3be51929a0121f6579040fca8b7a7eaeb4f8360"},"id":"cdbc98f8-59c3-4823-9f6f-f02e652315fb","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T04-08-54.756436000Z--beeb24ff18203658d0a1d4682ee3f36ad663ec87:
--------------------------------------------------------------------------------
1 | {"address":"beeb24ff18203658d0a1d4682ee3f36ad663ec87","crypto":{"cipher":"aes-128-ctr","ciphertext":"867f7f20c9bc0cc77e33f5ffe654ec64d700cbfe8b95a9cd35a035c669a4f7df","cipherparams":{"iv":"2ded8c674918626a2f8b0b2442f63b5e"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"9e48eb9d0e9d138512251dde8ccbed433616704bc88dc17d688199d24bfb504e"},"mac":"ea4a9704c4974fce6b85f3f95b31a1e64ed294c69ea2e5110f837ea73b85d595"},"id":"7af67eed-c600-4622-a939-6700bbd25c75","version":3}
--------------------------------------------------------------------------------
/test/testchain/keystore/UTC--2017-11-23T04-09-53.679255000Z--bffbd8f029ef0bd81cf754b53e8b3a5684f8b3ff:
--------------------------------------------------------------------------------
1 | {"address":"bffbd8f029ef0bd81cf754b53e8b3a5684f8b3ff","crypto":{"cipher":"aes-128-ctr","ciphertext":"74d1fbc0f815262e20f6dc089c7370c64678a56cc2ebf8bd54f0e8cff854e61f","cipherparams":{"iv":"46f9abced6bb053168b1cc1ed1c759a3"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"ca6928880f930bc6ab285ccc798dc25de1540b059b885306825f7b98a8ffceb8"},"mac":"ec1dd0e7454ad21e9a22173e1209ea0355e96d583eb8fc4d4ff603de9155875b"},"id":"42466d6f-39e7-4b07-bafb-5409d60fc2bc","version":3}
--------------------------------------------------------------------------------