├── .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} --------------------------------------------------------------------------------