├── .gitignore ├── LICENSE.txt ├── README.md ├── app.js ├── index.html └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 Chen, Yi-Cyuan 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Solidity optimize name 2 | Find a optimized name for method. 3 | Please go to [here](http://emn178.github.io/solidity-optimize-name/). 4 | 5 | ## License 6 | The project is released under the [MIT license](http://www.opensource.org/licenses/MIT). 7 | 8 | ## Contact 9 | The project's website is located at https://github.com/emn178/solidity-optimize-name 10 | Author: Chen, Yi-Cyuan (emn178@gmail.com) 11 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | var CHARS = '0123456789abcdefghijklmnopqrstuvwxysABCDEFGHIJKLMNOPQRSTUVWXYS$_'.split(''); 3 | var CHAR_MAP = {}; 4 | CHARS.forEach(function (c, index) { 5 | CHAR_MAP[c] = index; 6 | }); 7 | 8 | var CHAR_CODES = CHARS.map(function (c) { 9 | return c.charCodeAt(0); 10 | }); 11 | 12 | var CHAR_CODE_MAP = {}; 13 | CHARS.forEach(function (c, index) { 14 | CHAR_CODE_MAP[index] = c.charCodeAt(0); 15 | }); 16 | 17 | var data = { blocks: [], s: [] }; 18 | function save(hash) { 19 | data.reset = hash.reset; 20 | data.block = hash.block; 21 | data.start = hash.start; 22 | data.finalized = hash.finalized; 23 | data.lastByteIndex = hash.lastByteIndex; 24 | for (var i = 0; i < hash.blocks.length; ++i) { 25 | data.blocks[i] = hash.blocks[i]; 26 | } 27 | for (var i = 0; i < hash.s.length; ++i) { 28 | data.s[i] = hash.s[i]; 29 | } 30 | } 31 | 32 | function restore(hash) { 33 | hash.reset = data.reset; 34 | hash.block = data.block; 35 | hash.start = data.start; 36 | hash.finalized = data.finalized; 37 | hash.lastByteIndex = data.lastByteIndex; 38 | for (var i = 0; i < data.blocks.length; ++i) { 39 | hash.blocks[i] = data.blocks[i]; 40 | } 41 | for (var i = 0; i < data.s.length; ++i) { 42 | hash.s[i] = data.s[i]; 43 | } 44 | } 45 | 46 | function toBytes(str) { 47 | var bytes = []; 48 | for (var i = 0; i < str.length; ++i) { 49 | bytes.push(str.charCodeAt(i)); 50 | } 51 | return bytes; 52 | } 53 | 54 | function parseSignature(signature) { 55 | if (signature.charAt(signature.length - 1) != ')' || signature.indexOf(' ') !== -1) { 56 | return false; 57 | } 58 | var parts = signature.split('('); 59 | if (parts.length == 2) { 60 | return { 61 | name: parts[0], 62 | args: '(' + parts[1] 63 | }; 64 | } else { 65 | return false; 66 | } 67 | } 68 | 69 | function increase(bytes) { 70 | bytes[0] += 1; 71 | for (var i = 0; i < bytes.length; ++i) { 72 | if (bytes[i] === 64) { 73 | bytes[i] = 0; 74 | if (i == bytes.length - 1) { 75 | bytes[i + 1] = 1; 76 | } else { 77 | bytes[i + 1] += 1; 78 | } 79 | } else { 80 | break; 81 | } 82 | } 83 | return bytes; 84 | } 85 | 86 | function toChars(bytes) { 87 | var str = ''; 88 | for (var i = 0; i < bytes.length; ++i) { 89 | str += CHARS[bytes[i]]; 90 | } 91 | return str; 92 | } 93 | 94 | function toCharCodes(bytes) { 95 | var codes = []; 96 | for (var i = 0; i < bytes.length; ++i) { 97 | codes.push(CHAR_CODE_MAP[bytes[i]]); 98 | } 99 | return codes; 100 | } 101 | 102 | function find(obj) { 103 | var sig = obj.name + obj.args; 104 | var args = toBytes(obj.args); 105 | var bytes = [0]; 106 | var index = 0; 107 | var prefix = toBytes(obj.name + '_'); 108 | var hash = keccak256.create(); 109 | hash.update(prefix); 110 | save(hash); 111 | var char, methodId = keccak256.array(sig); 112 | while (methodId[0] || methodId[1]) { 113 | if (index >= CHARS.length) { 114 | increase(bytes); 115 | hash = keccak256.create(); 116 | hash.update(prefix); 117 | hash.update(toCharCodes(bytes)); 118 | save(hash); 119 | index = 0; 120 | } 121 | char = CHARS[index]; 122 | hash.update(char); 123 | hash.update(args); 124 | methodId = hash.array(); 125 | restore(hash); 126 | ++index; 127 | } 128 | if (index) { 129 | sig = obj.name + '_' + toChars(bytes) + char + obj.args; 130 | } 131 | return [sig, keccak256(sig).substr(0, 8)]; 132 | } 133 | 134 | $(document).ready(function () { 135 | $('#optimize').click(function () { 136 | var input = $('#input').val(); 137 | $('#error').hide();; 138 | var data = parseSignature(input); 139 | if (!data) { 140 | $('#error').show();; 141 | return; 142 | } 143 | console.time('a'); 144 | var result = find(data); 145 | console.timeEnd('a') 146 | $('#output').append('

' + result[0] + ': 0x' + result[1] + '

') 147 | }); 148 | }); 149 | })(jQuery); 150 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Solidity Optimize Name 6 | 7 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | 28 |
29 |
30 | 31 | 32 |
33 |
incorrect input
34 |
35 |
36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body, html, h1, h2 { 2 | margin: 0; 3 | padding: 0; 4 | font-family: 'Roboto Slab', serif; 5 | } 6 | 7 | #header { 8 | background-color: #2d2d2d; 9 | color: white; 10 | text-align: center; 11 | } 12 | 13 | #container { 14 | text-align: center; 15 | margin: 20px; 16 | } 17 | 18 | #error { 19 | text-align: center; 20 | display: none; 21 | color: red; 22 | } 23 | 24 | #output { 25 | width: 400px; 26 | margin: 0 auto; 27 | } 28 | 29 | #footer { 30 | margin-top: 40px; 31 | padding-top: 40px; 32 | padding-bottom: 40px; 33 | font-size: 12px; 34 | line-height: 1.5; 35 | color: #777; 36 | border-top: 1px solid #eee; 37 | text-align: center; 38 | } 39 | 40 | input { 41 | outline: none; 42 | padding: 10px; 43 | font-size: 16px; 44 | height: 11px; 45 | width: 300px; 46 | vertical-align: middle; 47 | } 48 | 49 | .btn { 50 | display: inline-block; 51 | padding: 6px 12px; 52 | margin-bottom: 0; 53 | font-size: 14px; 54 | font-weight: normal; 55 | line-height: 1.42857143; 56 | text-align: center; 57 | white-space: nowrap; 58 | vertical-align: middle; 59 | -ms-touch-action: manipulation; 60 | touch-action: manipulation; 61 | cursor: pointer; 62 | -webkit-user-select: none; 63 | -moz-user-select: none; 64 | -ms-user-select: none; 65 | user-select: none; 66 | background-image: none; 67 | border: 1px solid transparent; 68 | border-radius: 4px; 69 | } 70 | .btn:focus, 71 | .btn:active:focus, 72 | .btn.active:focus, 73 | .btn.focus, 74 | .btn:active.focus, 75 | .btn.active.focus { 76 | outline: thin dotted; 77 | outline: 5px auto -webkit-focus-ring-color; 78 | outline-offset: -2px; 79 | } 80 | .btn:hover, 81 | .btn:focus, 82 | .btn.focus { 83 | color: #333; 84 | text-decoration: none; 85 | } 86 | .btn:active, 87 | .btn.active { 88 | background-image: none; 89 | outline: 0; 90 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 91 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); 92 | } 93 | .btn.disabled, 94 | .btn[disabled], 95 | fieldset[disabled] .btn { 96 | pointer-events: none; 97 | cursor: not-allowed; 98 | filter: alpha(opacity=65); 99 | -webkit-box-shadow: none; 100 | box-shadow: none; 101 | opacity: .65; 102 | } 103 | .btn-default { 104 | color: #333; 105 | background-color: #fff; 106 | border-color: #ccc; 107 | } 108 | .btn-default:hover, 109 | .btn-default:focus, 110 | .btn-default.focus, 111 | .btn-default:active, 112 | .btn-default.active, 113 | .open > .dropdown-toggle.btn-default { 114 | color: #333; 115 | background-color: #e6e6e6; 116 | border-color: #adadad; 117 | } 118 | .btn-default:active, 119 | .btn-default.active, 120 | .open > .dropdown-toggle.btn-default { 121 | background-image: none; 122 | } 123 | .btn-default.disabled, 124 | .btn-default[disabled], 125 | fieldset[disabled] .btn-default, 126 | .btn-default.disabled:hover, 127 | .btn-default[disabled]:hover, 128 | fieldset[disabled] .btn-default:hover, 129 | .btn-default.disabled:focus, 130 | .btn-default[disabled]:focus, 131 | fieldset[disabled] .btn-default:focus, 132 | .btn-default.disabled.focus, 133 | .btn-default[disabled].focus, 134 | fieldset[disabled] .btn-default.focus, 135 | .btn-default.disabled:active, 136 | .btn-default[disabled]:active, 137 | fieldset[disabled] .btn-default:active, 138 | .btn-default.disabled.active, 139 | .btn-default[disabled].active, 140 | fieldset[disabled] .btn-default.active { 141 | background-color: #fff; 142 | border-color: #ccc; 143 | } 144 | .btn-default .badge { 145 | color: #fff; 146 | background-color: #333; 147 | } 148 | --------------------------------------------------------------------------------