Building Decentralised Link Shortner on Ethereum blockchain using Truffle

Anil Kumar Maurya
Jul 17 · 4 min read
https://anilmaurya.github.io/link-shortner/

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 or here 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.

What is Truffle ?

Truffle is a framework for blockchain development, it streamlined smart contract creation, compilation, testing, and deployment onto Ethereum. Read more about truffle here

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.

Getting Started:

A) Install npm, node & Truffle

Follow 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 box

$ 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

C) Install Ganache for blockchain setup on local machine 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
Ganache Screenshot after contract deployment

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 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>
// 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 = Ethereum::HttpClient.new("https://ropsten.infura.io/v3/<API-KEY>")
contract_json = JSON.parse(File.read('LinkShortner.json'))
@contract_abi = contract_json['abi']
@address = contract_json["networks"]["3"]["address"]
@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, abi: @contract_abi,
client: @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
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 plugin is required.


Anil Kumar Maurya

Written by

Principal Engineer @joshsoftware

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade