Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
🔗 https://t.co/Rte4yKrN1q shutting down is old news. But have you found a replacement? Well, we did! A link shortener that will keep your link stored for a lifetime ... because it's on the blockchain. Check out @sauravtom's Ethereum URL shortener at https://t.co/QhsWph5eOi!
How it works
The web app deployed at 0x.now.sh, interacts with a smart contract deployed on Ethereum Ropsten testnet. Being on testnet means you can interact with it using free ethers. Get your free ethers here.
The Process
- Users make a transaction requesting the blockchain to store a URL string.
- Since it is a transaction that modifies the state of the blockchain, it needs to have some amount of ethers attached to it so that it can be mined to the blockchain by miners.
- The amount of fee (also called gas) is determined by the Metamask chrome extension and displayed in the prompt box.
- There is some waiting time for the transaction to be confirmed (5–10sec) depending on how busy the blockchain is.
- The shortened URL is generated. eg https://0x.now.sh/s?id=23
- When the users clicks on the shortened URL another transaction is made requesting the blockchain which URL string is located at the provided reference (in this case 23)
- Since this transaction is not changing the state of the blockchain, we do not need to pay any ETH this time, the user is seamlessly redirected to the long URL.
dApp
Being a Decentralized application means that this web app does not require any centralized database to function. It only interacts with the smart contract deployed on the blockchain.
The SmartContract 📃
pragma solidity ^0.4.24;
contract e0x { event Log(string message); event LinkAdded(uint linkId, string url); struct LinkTemplate { address userAddress; string url; } uint lastLinkId; mapping (uint => LinkTemplate) public linkMapping; constructor() public { lastLinkId = 0; } function createNewLink(string url) public returns (uint) { lastLinkId++; linkMapping[lastLinkId] = LinkTemplate(msg.sender, url); emit LinkAdded(lastLinkId, url); return lastLinkId; } modifier linkExists(uint linkId) { //link with the given hash does not exist if(linkMapping[linkId].userAddress == 0x0000000000000000000000000000000000000000) { revert(); } _; } function getLink(uint linkId) linkExists(linkId) public constant returns( address, string ) { LinkTemplate memory link = linkMapping[linkId]; return( link.userAddress, link.url ); }
}
Technical Challenges
Interacting with the smart contract
EthersJS library is used to talk to the blockchain
// provider picks up the Metamask injected web3 object from browser let provider = new ethers.providers.Web3Provider(web3.currentProvider);let address = "ADDRESS_OF_DEPLOYED_SMART_CONTRACT";let abi = [...] //defines JSON interface for the smart contract
Storing data on the blockchain
// calling the createNewLink function defined in the smart contracttx = await contract.createNewLink(url);console.log(tx.hash);
Listening to blockchain events
contract.on("LinkAdded", (linkId, linkUrl) => { var shortUrl = '{0}/s?id={1}'.f(window.location.origin, linkId.toNumber()) $("#info").prepend( "Short URL: <a href='{0}'>{0}</a><br>".f(shortUrl) ); });
Generating the list of recently shortened URLs
web3’s allEvents() function call was used to list down all the events recorded in the smart contract whenever a new url was shortened.
MyContract = web3.eth.contract(abi); myContractInstance = MyContract.at(address); events = myContractInstance.allEvents({event: 'LinkAdded', fromBlock: 0, toBlock: 'latest'}); events.watch(function(error, result){ console.log(result.args.url, result.args.linkId.toNumber()); ...});
Making the shortened URLs accessible in all Browsers
This was quite tricky because interacting with blockchain required the browser to be web3 enabled, and have some wallet installed (metamask or similar). Currently web3 and wallet support is only for Chrome and Firefox on Desktop only.
To solve this, I had to create a wallet on the fly as follows
provider = ethers.getDefaultProvider('ropsten');wallet = ethers.Wallet.createRandom();wallet = wallet.connect(provider);
Shout out to the awesome ethersJS library for having support for this.
Counting URL visits
The flexibility for using this one all browsers comes at a cost. Each time user clicks on the shortened URL no change is made to the blockchain state, hence it is not possible to determine how many times each link was clicked. This issues remains unsolved.
The complete source code for this project is on Github.
Pull Requests welcome 😁
Making a decentralized URL shortener using Ethereum⛓ was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.