Building Decentralised Link Shortner on Ethereum blockchain using Truffle
Tags: blockchain, smartcontracts, truffle, dapps
Published: 2020-08-06 12:40:04

---
title: Building Decentralised Link Shortner on Ethereum blockchain using Truffle
published: true
date: 2019-07-17 10:25:12 UTC
tags: blockchain,smartcontracts,truffle,dapps
canonical_url: 
---

![](https://cdn-images-1.medium.com/max/1024/1*sk-QwadTmfhVunslJvQ6vA.png)<figcaption><a href="https://anilmaurya.github.io/link-shortner/">https://anilmaurya.github.io/link-shortner/</a></figcaption>

Blockchain is emerging technology, it needs no introduction. By any chance if you are left behind and don’t know about blockchain then I recommend reading about blockchain first before reading this article. You can read about blockchain [here](https://blockgeeks.com/guides/what-is-blockchain-technology/) or [here](https://www.investopedia.com/terms/b/blockchain.asp) or search on internet and you will find plenty of article to read from.

**What is Ethereum ?**

Launched in 2015, Ethereum is the world’s leading programmable blockchain. It is a global, open-source platform for decentralized applications. These decentralized applications (or “dapps”) gain the benefits of cryptocurrency and blockchain technology. Read more about ethereum [here](https://www.ethereum.org).

**What is Truffle ?**

[Truffle](https://truffleframework.com/) is a framework for blockchain development, it streamlined **smart contract** _creation_, _compilation_, _testing_, and _deployment_ onto Ethereum. Read more about truffle [here](https://www.trufflesuite.com/docs/truffle/overview)

**What is Decentralised App ?**

Decentralised application does not require centralised server to work (hence no maintenance cost). It interacts with smart contract deployed on blockchain network.

**What is Smart Contract ?**

Smart contracts are programs which govern the behaviour of accounts within the Ethereum state. We will write smart contract in Solidity language, Solidity is an object-oriented, high-level language for implementing smart contracts. Read more about solidity from [here](https://solidity.readthedocs.io/en/v0.5.10/).

**Getting Started:**

A) Install npm, node & Truffle

Follow [https://docs.npmjs.com/downloading-and-installing-node-js-and-npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) for installing npn & node.

Then install truffle

```
npm install -g truffle
```

check if truffle installed successfully or not

```
$ truffle version
Truffle v5.0.21 (core: 5.0.21)
Solidity v0.5.0 (solc-js)
Node v11.0.0
Web3.js v1.0.0-beta.37
```

B) Create Project

Create new folder for project & initialise with truffle. We will use [React Truflle bo](https://www.trufflesuite.com/boxes/react)x

```
$ mkdir link\_shortner
$ cd link\_shortner/
$ truffle unbox react
✔ Preparing to download
✔ Downloading
✔ Cleaning up temporary files
✔ Setting up box

Unbox successful. Sweet!

Commands:

Compile: truffle compile
  Migrate: truffle migrate
  Test contracts: truffle test
```

If you are new to Truffle then read about created directory from [https://www.trufflesuite.com/docs/truffle/getting-started/creating-a-project](https://www.trufflesuite.com/docs/truffle/getting-started/creating-a-project)

C) Install Ganache for blockchain setup on local machine [https://www.trufflesuite.com/docs/ganache/overview](https://www.trufflesuite.com/docs/ganache/overview)

**Link Shortner Smart Contract**

Create LinkShortner.sol file inside _contracts/_ folder and write following content in it.

```
pragma solidity ^0.5.0;

contract LinkShortner {
  event LinkAdded(uint linkId, string url);
  uint lastLinkId;

struct LinkTemplate {
  address userAddress;
  string url;
 }

mapping (uint => LinkTemplate) public linkMapping;

constructor() public {
  lastLinkId = 0;
 }

function createNewLink(string memory url) public returns (uint, string memory) {
   lastLinkId++;
  linkMapping[lastLinkId] = LinkTemplate(msg.sender, url);
    emit LinkAdded(lastLinkId, url);
  return(lastLinkId, url);
 }

function getLink(uint linkId) public view returns(address, string memory) {
  LinkTemplate memory link = linkMapping[linkId];
  return(link.userAddress, link.url);
 }

function getLastLink() public view returns(address, string memory, uint) {
  LinkTemplate memory link = linkMapping[lastLinkId];
  return(link.userAddress, link.url, lastLinkId);
 }

}
```

Now deploy this contract on local blockchain network:

```
$ truffle compile
$ truffle migrate
```

![](https://cdn-images-1.medium.com/max/1024/1*wZ0QsuCLcaaLyTitaoTH8A.png)<figcaption>Ganache Screenshot after contract deployment</figcaption>

**React Application for interaction with Smart Contract**

Open client/src/App.js file

Replace

```
import SimpleStorageContract from "./contracts/SimpleStorage.json";
```

with

```
import SimpleStorageContract from "./contracts/LinkShortner.json";
```

Creating new link

```
contract.methods.createNewLink(this.state.url).send({ from: accounts[0] })
```

Install [Metamask](https://metamask.io) chrome extension

and run React app

```
cd client
npm run start
```

**Deploying contract on Ropsten test network**

```
- Register new account on infura.io
- Create new project
- Get project api and connection link:
ROPSTEN\_URL=https://ropsten.infura.io/v3/<your-api-key>
```

Goto Truffle project, install truffle-hdwallet-provider

```
npm install truffle-hdwallet-provider — save
```

Create `.env` file, put MNEMONIC and <network>\_URL to file

```
MNEMONIC=wallet mnemonic 12 words
ROPSTEN\_URL=https://ropsten.infura.io/v3/<your-api-key>
```

Update truffle-config with following content

```
const path = require("path");
require('dotenv').config()
const HDWalletProvider = require('truffle-hdwallet-provider')
const MNEMONIC = process.env.MNEMONIC
const ROPSTEN\_URL = process.env.ROPSTEN\_URL

module.exports = {
  // See <[http://truffleframework.com/docs/advanced/configuration](http://truffleframework.com/docs/advanced/configuration)>
  // to customize your Truffle configuration!
  contracts\_build\_directory: path.join(\_\_dirname, "client/src/contracts"),
  networks: {
    ropsten: {
      provider: function() {
        return new HDWalletProvider(MNEMONIC, ROPSTEN\_URL);
      },
      network\_id: '3',
    },
    development: {
      host: "127.0.0.1",
      port: 7545,
      network\_id: "\*",
   },
   test: {
     host: "127.0.0.1",
     port: 7545,
     network\_id: "\*",
  }
 }
};
```

Run following command to deploy

```
truffle migrate --network ropsten
```

**Sinatra API for reading Short Link on ethereum network**  
 Create folder backend  
Add following content in backend/app.rb

```
# Require the bundler gem and then call Bundler.require to load in all gems
# listed in Gemfile.
require 'bundler'
Bundler.require

require 'sinatra'
require 'ethereum'

before do
  content\_type 'application/json'
end

class Contract
  def initialize
[@client](http://twitter.com/client) = Ethereum::HttpClient.new("[https://ropsten.infura.io/v3/](https://ropsten.infura.io/v3/ebcc6fb682fd49a589e84d8a2360cbf0)<API-KEY>")
    contract\_json = JSON.parse(File.read('LinkShortner.json'))
[@contract\_abi](http://twitter.com/contract_abi) = contract\_json['abi']
[@address](http://twitter.com/address) = contract\_json["networks"]["3"]["address"]
[@client](http://twitter.com/client).default\_account = "0x3b8B0b23C4850FA8289da815a6abEE4Fc2DF941A"
  end

def result(id)
    return nil unless id
    contract\_instance.call.get\_link(id.to\_i)[1]
  end

def contract\_instance
    Ethereum::Contract.create(name: "LinkShortner", address: [@address](http://twitter.com/address), abi: [@contract\_abi](http://twitter.com/contract_abi),
                              client: [@client](http://twitter.com/client))
  end
end
class App < Sinatra::Base
  get '/url' do
    response.headers["Access-Control-Allow-Origin"] = "\*"
    return {url: Contract.new.result(params[:id])}.to\_json
  end
end
```

Deploy sinatra API on heroku

```
heroku create
heroku buildpacks:set [https://github.com/timanovsky/subdir-heroku-buildpack](https://github.com/timanovsky/subdir-heroku-buildpack)
heroku buildpacks:add heroku/ruby
heroku config:set PROJECT\_PATH=backend
git push heroku master

```

**Now use deployed API for reading short link**

```
fetch("https://<heroku-app-url>/url?id="+id).then((response) => {
  return response.json();
}).then((response) => {
  const url = response.url
  console.log(url)
})
```

That’s it, now you have your link shortner decentralised app deployed on ethereum network. Generated short link can be shared with anyone, irrespective of browser. For creating short link [Metamask](https://metamask.io) plugin is required.

Code is hosted on [**github**](https://github.com/anilmaurya/link-shortner)   
Application is hosted at [http://anilmaurya.github.io/link-shortner](http://anilmaurya.github.io/link-shortner)

{% youtube O0lsTIwUVk8 %}

References:  
[https://medium.com/@nhancv/deploy-smart-contract-with-truffle-79d2bf218332](https://medium.com/@nhancv/deploy-smart-contract-with-truffle-79d2bf218332)

[https://hackernoon.com/making-a-decentralized-url-shortener-using-ethereum-4fdfccf712a6](https://hackernoon.com/making-a-decentralized-url-shortener-using-ethereum-4fdfccf712a6)