Building Decentralised Link Shortner on Ethereum blockchain using Truffle
Anil Kumar Maurya
Posted on August 6, 2020
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
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 _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 plugin is required.
Code is hosted on github
Application is hosted at http://anilmaurya.github.io/link-shortner
References:
https://medium.com/@nhancv/deploy-smart-contract-with-truffle-79d2bf218332
https://hackernoon.com/making-a-decentralized-url-shortener-using-ethereum-4fdfccf712a6
Posted on August 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.