Building Decentralised Link Shortner on Ethereum blockchain using Truffle

Original post available here.

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 contractcreationcompilationtesting, 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_URLmodule.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]
  enddef 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.

Code is hosted on github

Application is hosted at http://anilmaurya.github.io/link-shortner

Demo of Link Shortner

References:


https://medium.com/@nhancv/deploy-smart-contract-with-truffle-79d2bf218332

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

This entry was posted in Blockchain, Tutorials and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s