├── .gitignore ├── LICENSE ├── README.md ├── images ├── favicon.ico ├── spinner.gif └── sponsor.png ├── index.html ├── now.json ├── s └── index.html └── scripts └── app.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Saurav Tomar 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ethereum URL Shortener 2 | 3 | Made using [EthersJS library](https://ethers.io) 4 | 5 | [How it works](https://medium.com/coinmonks/making-a-url-shortener-on-ethereum-blockchain-5947e52fd3a3) 6 | 7 | [smart contract source code](https://ethfiddle.com/xR5sZrU10t) 8 | -------------------------------------------------------------------------------- /images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravtom/ethereum-url-shortener/4a1c410660f3b9594cfaa6edace8cfb12f164321/images/favicon.ico -------------------------------------------------------------------------------- /images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravtom/ethereum-url-shortener/4a1c410660f3b9594cfaa6edace8cfb12f164321/images/spinner.gif -------------------------------------------------------------------------------- /images/sponsor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sauravtom/ethereum-url-shortener/4a1c410660f3b9594cfaa6edace8cfb12f164321/images/sponsor.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Ethereum URL Shortener 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 37 | 38 | 39 | 40 | 41 |
42 |
43 | 85 |
86 | 87 | 101 | 102 | 115 | 116 | 141 | 142 |
143 |
144 |

145 |
146 |

147 | URL Shortener 148 |

149 |

150 | Powered by Ethereum Blockchain 151 |


152 |
153 |
154 |

155 | 156 |

157 |

158 | 159 | Go 160 | 161 |

162 |
163 |
164 | 165 |

166 |
167 |
168 |
169 |
170 |
171 | 172 |
173 | 174 | 175 | 177 | 178 | 179 | 180 | 181 | 182 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /now.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ethereum-url-shortner", 3 | "alias": "0x.now.sh" 4 | } 5 | -------------------------------------------------------------------------------- /s/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 9 | 10 | 11 | 12 | 19 | 20 | 159 |
160 | 161 | -------------------------------------------------------------------------------- /scripts/app.js: -------------------------------------------------------------------------------- 1 | var contract; 2 | var address; 3 | var abi; 4 | 5 | String.prototype.format = String.prototype.f = function() { 6 | var s = this, 7 | i = arguments.length; 8 | 9 | while (i--) { 10 | s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]); 11 | } 12 | return s; 13 | }; 14 | 15 | $(document).ready(function() { 16 | $("#spinner").hide(); 17 | detectWeb3(); 18 | initContract(); 19 | checkNetwork(); 20 | batchEvents(abi, address); 21 | }) 22 | 23 | $(".close").click(function() { 24 | $(".modal").removeClass("is-active"); 25 | }); 26 | 27 | $(".recent-btn").click(function() { 28 | $(".transactions-modal").addClass("is-active"); 29 | }); 30 | 31 | function detectWeb3(){ 32 | window.ethereum.enable(); 33 | if (typeof web3 !== 'undefined') { 34 | // Use Mist/MetaMask's provider 35 | web3 = new Web3(web3.currentProvider); 36 | } else { 37 | $(".metamask-modal").addClass("is-active"); 38 | console.log('METAMASK NOT DETECTED'); 39 | } 40 | } 41 | 42 | function checkNetwork(){ 43 | console.log('CHECKING NETWORK'); 44 | 45 | contract.getLink(1) 46 | .then((output) => { 47 | console.log('OUTPUT',output); 48 | }) 49 | .catch((err) => { 50 | console.log('ERROR',err); 51 | $(".metamask-network-modal").addClass("is-active"); 52 | }); 53 | 54 | } 55 | 56 | const isValidUrl = (string) => { 57 | try { 58 | new URL(string); 59 | return true; 60 | } catch (_) { 61 | return false; 62 | } 63 | } 64 | 65 | function initContract() { 66 | let provider = new ethers.providers.Web3Provider(web3.currentProvider); 67 | address = "0x4b8241f24537d2539d0b310bc074fd68a782e182"; 68 | abi = [ 69 | { 70 | "constant": false, 71 | "inputs": [ 72 | { 73 | "name": "url", 74 | "type": "string" 75 | } 76 | ], 77 | "name": "createNewLink", 78 | "outputs": [ 79 | { 80 | "name": "", 81 | "type": "uint256" 82 | } 83 | ], 84 | "payable": false, 85 | "stateMutability": "nonpayable", 86 | "type": "function" 87 | }, 88 | { 89 | "inputs": [], 90 | "payable": false, 91 | "stateMutability": "nonpayable", 92 | "type": "constructor" 93 | }, 94 | { 95 | "anonymous": false, 96 | "inputs": [ 97 | { 98 | "indexed": false, 99 | "name": "message", 100 | "type": "string" 101 | } 102 | ], 103 | "name": "Log", 104 | "type": "event" 105 | }, 106 | { 107 | "anonymous": false, 108 | "inputs": [ 109 | { 110 | "indexed": false, 111 | "name": "linkId", 112 | "type": "uint256" 113 | }, 114 | { 115 | "indexed": false, 116 | "name": "url", 117 | "type": "string" 118 | } 119 | ], 120 | "name": "LinkAdded", 121 | "type": "event" 122 | }, 123 | { 124 | "constant": true, 125 | "inputs": [ 126 | { 127 | "name": "linkId", 128 | "type": "uint256" 129 | } 130 | ], 131 | "name": "getLink", 132 | "outputs": [ 133 | { 134 | "name": "", 135 | "type": "address" 136 | }, 137 | { 138 | "name": "", 139 | "type": "string" 140 | } 141 | ], 142 | "payable": false, 143 | "stateMutability": "view", 144 | "type": "function" 145 | }, 146 | { 147 | "constant": true, 148 | "inputs": [ 149 | { 150 | "name": "", 151 | "type": "uint256" 152 | } 153 | ], 154 | "name": "linkMapping", 155 | "outputs": [ 156 | { 157 | "name": "userAddress", 158 | "type": "address" 159 | }, 160 | { 161 | "name": "url", 162 | "type": "string" 163 | } 164 | ], 165 | "payable": false, 166 | "stateMutability": "view", 167 | "type": "function" 168 | } 169 | ] 170 | contract = new ethers.Contract(address, abi, provider.getSigner()); 171 | console.log('e0x Contract Initiated'); 172 | } 173 | 174 | function batchEvents(abi, address) { 175 | //batch listening of events 176 | MyContract = web3.eth.contract(abi); 177 | myContractInstance = MyContract.at(address); 178 | events = myContractInstance.allEvents({event: 'LinkAdded', fromBlock: 0, toBlock: 'latest'}); 179 | 180 | events.watch(function(error, result){ 181 | console.log(result); 182 | //console.log(result.args.url, result.args.linkId.toNumber(), result.blockNumber, result.transactionHash); 183 | 184 | var shortUrl = '{0}/s?id={1}'.f(window.location.origin, result.args.linkId.toNumber()); 185 | var shorterUrl = shortUrl.replace('https://',''); 186 | var shorterUrl = shorterUrl.replace('http://',''); 187 | var row = "\ 188 | \ 189 |

{0}

\ 190 | {2}\ 191 | {3}\ 192 | link\ 193 | ".f(result.args.url,shortUrl,shorterUrl,result.blockNumber,result.transactionHash); 194 | //console.log(row); 195 | $("#tx-table").prepend(row); 196 | }); 197 | } 198 | 199 | async function shorten() { 200 | detectWeb3(); 201 | url = document.getElementById("url").value; 202 | if(!url){ 203 | return window.alert("URL VALUE IS EMPTY"); 204 | } 205 | if(!isValidUrl(url)){ 206 | return window.alert("INVALID URL"); 207 | } 208 | $("#info").html(""); 209 | $("#spinner").show(); 210 | $('#generate').prop('disabled', true); 211 | tx = await contract.createNewLink(url); 212 | console.log(tx.hash); 213 | 214 | $("#info").prepend( "

waiting for transaction to be mined


" ); 215 | 216 | contract.on("LinkAdded", (linkId, linkUrl) => { 217 | if(linkUrl !== url){ 218 | console.log('NOT MY EVENT'); 219 | return 220 | } 221 | $("#info").html( "

transaction confirmed

view tx on blockchain
".f(tx.hash) ); 222 | var shortUrl = '{0}/s?id={1}'.f(window.location.origin, linkId.toNumber()); 223 | $("#info").prepend( "Short URL: {0}
".f(shortUrl) ); 224 | console.log("EVENT LISTENER", shortUrl, linkId.toNumber(), linkUrl); 225 | $("#spinner").hide(); 226 | $('#generate').prop('disabled', false); 227 | }); 228 | } 229 | --------------------------------------------------------------------------------