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 contract

tx = 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

EthersJS doe not support batch listening of events so I had to use web3js’s allEvents() function call

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 😁