
Ethereum, tokens & smart contracts.
Notes on getting started Part 9. Dapps & MetaMask
Previous notes in case you are just joining us:Part 1. Setting up.
Part 2. Web3.js/node.
Part 3. Solidity.
Part 4. Smart Contracts.
Part 5. Smarter Contracts.
Part 6. Tokens & Inheritance.
Part 7. ERC20 Token Standard.
Part 8. Crowdfunding and ICOs.
Dapps ( or ÐApps) stand for Decentralized Applications, this begs the question what is a centralized application ? Well, most of the web and software services today are in some form or another centralized. Typically there is a single database that stores your information, there is a monolithic code base that has no external input, it was funded by a small group, it is controlled by a single entity and on and on.
Dapps are a new architecture in which parts if not all of the product or service exists in a decentralized fashion,as mentioned this could also extend to both ownership,code base,funding etc.
Ethereum Dapps ( These are early days ) :
So far we have covered contracts that live in the Ethereum blockchain and use the Ethereum vm, what we have seen so far is a mix of a programming language and a cryptocurrency.
Unfortunately you can’t make a software service out of these parts, at least not a very complex one and not today.The reason is that it is both cumbersome and impractical…
- It is cumbersome because as you will see connecting and interacting with a blockchain and using it as a backend is far from being a resolved matter ( we will explore some current options though). The Ethereum foundation and other parties are actively developing new tools to make this easier.
- The impractical part is a bit more daunting; the average webpage is around 2–3 mb and growing; that same webpage in ethereums VM would cost around $15,000 (and growing), to deal with this issue an add on of sorts is being developed: Swarm. which will deal with storage in a distributed and cost effective way.
- It should be mentioned that other types of tooling (to make dapp development easier/possible) are currently in active development, check for instance: https://github.com/ethereum for current and future projects.
As mentioned these are early days and Ethereum is still an experiment ( a successful one so far) ,it is in active development and will probably change radically in the near future, so does that mean we can’t yet write Dapps ?
Not at all, what that means is that the Dapps we can currently write will be hybrid or assisted in some way until and if Ethereum provides equivalent tooling to what we have elsewhere, let’s now take a look at how to make such a hybrid Dapp.
Enter MetaMask

Perhaps the easiest way to build and consume a Dapp today is via MetaMask which in a nutshell is a light client/wallet (like parity) that runs on chrome browsers. We’ll now take a look at what that means and see if we can code a minimal Dapp for our blips token.

Installing Meta mask is a breeze,just add it as a plugin from the chrome store and create an account,a little wallet/client window then appears in your browser when clicking the plugins icon; ( notice I am connecting to the Kovan Test Net and I sent some ether from parity to have a balance).
Note: As of this writing adding tokens on metamask is not supported, but it might be in the future. I would recommend parity or mist for now for token management via UI.
If you’ve done any web development via javascript the next part will probably look familiar, to connect to the blockchain (Kovan in this case), simply start a web3 provider and meta mask connects you in the background, here’s an example :
window.addEventListener("load", function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== "undefined") {
// Use Mist/MetaMask's provider
window.web3 = new Web3(web3.currentProvider);
} else {
console.log("No web3? You should consider trying MetaMask!");
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 = new Web3(
new Web3.providers.HttpProvider("https://localhost:8545")
);
}// APP >web3.eth.getAccounts(function(error, accounts) {
if (!error) {
web3.eth.getBalance(accounts[0], function(error, balance) {
if (!error) {
console.log(
"Your account: " +
accounts[0] +
" has a balance of: " +
balance.toNumber() / 1000000000000000000 +
"Ether"
);
} else {
console.error(error);
}
});
} else {
console.error(error);
}
});
});// "MetaMask - injected web3"
// "Your account: 0xbfca6ecdcb1a21d99befea4fd8cde79bc81e2c57 has a balance of: 0.799386868Ether"
ETHJS
It should be noted that web3 ( which is included in metamask for now) is not the only way to interact with ethereums blockchain, at the base there is a JSON-RPC API and web3 is but one wrapper, there are other like eth.js which is also popular in Dapp development:
The same example above can be rewriten like this:
window.addEventListener("load", function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== "undefined") {
// Use Mist/MetaMask's provider
window.web3 = new Web3(web3.currentProvider);
} else {
console.log("No web3? You should consider trying MetaMask!");
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 = new Web3(
new Web3.providers.HttpProvider("https://localhost:8545")
);
}// APPconst eth = new Eth(window.web3.currentProvider);
eth.accounts(function(error, accounts) {
if (!error) {
eth.getBalance(accounts[0], function(error, balance) {
if (!error) {
console.log(
"Your account: " +
accounts[0] +
" has a balance of: " +
Eth.fromWei(balance, "ether") +
"Ether"
);
} else {
console.log(error);
}
});
} else {
console.log(error);
}
});
});// "MetaMask - injected web3"// "Your account: 0xbfca6ecdcb1a21d99befea4fd8cde79bc81e2c57 has a balance of: 0.799386868Ether"Note that unlike the first example, we have to include the ethjs library.
Note: Calling the blockchain via meta Mask and other libraries is an Asynchronous affair (query the blockchain, wait for a response, do something with the result).In our examples we dealt with this with callbacks, but depending on your library and programming tastes you could deal with the async part with promises,here's an example chaining promises ( and using fat arrows ) in ethjs:const eth = new Eth(window.web3.currentProvider);
eth
.coinbase()
.then(coinbase => eth.getBalance(coinbase))
.then(balance =>
console.log(
"Your coinbase has a balance of: " + Eth.fromWei(balance, "ether")
)
)
.catch(error => {});// "Your coinbase has a balance of: 0.799386868"Codepen hosted sample: https://codepen.io/k3no/pen/mBvvzO
This should give you an idea of how to interact with the blockchain from a browser via Javascript, let’s now look at slightly more complex examples:
Call a contract :
We’ll be using our beloved BLIPS crowdfunding token from previous notes as a target for calling a contract.
Note: As a reminder, here's the BLIPS Token address on the Kovan network: 0xCCeEF52Df5Ff1B80e63E3f211021bd0bAe5323D6
window.addEventListener("load", function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== "undefined") {
// Use Mist/MetaMask's provider
window.web3 = new Web3(web3.currentProvider);
} else {
console.log("No web3? You should consider trying MetaMask!");
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 = new Web3(
new Web3.providers.HttpProvider("https://localhost:8545")
);
}const tokenABI = [...]; // See Codepen for full ABI.
const eth = new Eth(window.web3.currentProvider);
const token = eth
.contract(tokenABI)
.at("0xCCeEF52Df5Ff1B80e63E3f211021bd0bAe5323D6");token.symbol().then(function(tokenSymbol) {
console.log("Token Symbol :" + tokenSymbol[0]);
});
token.name().then(function(tokenName) {
console.log("Token Name :" + tokenName[0]);
});
token.totalSupply().then(function(supply) {
console.log("Total Supply :" + supply[0]);
});eth
.coinbase()
.then(coinbase => token.balanceOf(coinbase))
.then(balance =>
console.log("Your coinbase has a balance of: " + balance[0] + " tokens")
)
.catch(error => {});
});
// Console :// "MetaMask - injected web3"// "Token Symbol :BLIPS"// "Token Name :Blips Token"// "Total Supply :5200"// "Your coinbase has a balance of: 2000 tokens"
Most likely you will want to interact with a token via state changing transactions, let’s see how meta mask handles this:
window.addEventListener("load", function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== "undefined") {
// Use Mist/MetaMask's provider
window.web3 = new Web3(web3.currentProvider);
} else {
console.log("No web3? You should consider trying MetaMask!");
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 = new Web3(
new Web3.providers.HttpProvider("https://localhost:8545")
);
}
const coinbase = '0xbfca6ECdcB1a21d99bEfeA4Fd8CDE79Bc81e2c57';
const tokenAccount = '0xCCeEF52Df5Ff1B80e63E3f211021bd0bAe5323D6';
const eth = new Eth(window.web3.currentProvider);// not meant for production since it would fire every time you load the page... eth
.sendTransaction({
from: coinbase,
to: tokenAccount,
value: Eth.toWei(0.05, 'ether'),
gas: '3000000',
data: '0x',
})
.then(result => {
console.log("Tx:" + result);
})
.catch(error => {});
});
The first thing that happens when you run this example, is that metamask asks you to confirm the transaction:

And then you get a transaction receipt:
"Tx:0x23fa03376136f7f23048b87affc0f28a1ea167ccce81833bf9417af2275c6896"
The effects are as expected: less ether in the account and more Blips Tokens in circulation as well as the sending account :

BLIPS DAPP
So now that we have a basic understanding of how to bridge the browser and the blockchain via metaMask and web3 or ethjs, we need to package it all for consumption into a Dapp, our Dapp will be a simple front for our BLIPS Token campaign that will pull total supply and allow you to contribute and get tokens in exchange for ether, all from the comfort of your browser.
The Code:
let tokenABI = [...]; // check the source code for the full ABI
let tokenAddress = "0xCCeEF52Df5Ff1B80e63E3f211021bd0bAe5323D6";
let token;$("#mmAlert").hide();
$("#txSuccess").hide();// Connect to MetaMask :
window.addEventListener("load", function() {
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (typeof web3 !== "undefined") {
// Use Mist/MetaMask's provider
window.web3 = new Web3(web3.currentProvider);
} else {
console.log("No web3? You should consider trying MetaMask!");
// fallback - use your fallback strategy (local node / hosted node + in-dapp id mgmt / fail)
window.web3 = new Web3(
new Web3.providers.HttpProvider("https://localhost:8545")
);
}
Dapp();
});function Dapp() {
// Init eth:
const eth = new Eth(window.web3.currentProvider);
const token = eth.contract(tokenABI).at(tokenAddress);
// Are we logged into MetaMask :
window.web3.eth.getAccounts(function(err, accounts) {
if (err != null) console.error("An error occurred: " + err);
else if (accounts.length == 0) {
$("#mmAlert").show();
// Prompting for reload, but ideally you should check for account changes
} else {
console.log("User is logged in to MetaMask");
$("#mmAlert").hide();
}
});// Coinbase Account balance:
eth
.coinbase()
.then(coinbase => eth.getBalance(coinbase))
.then(
balance =>
(document.getElementById("accountBalance").innerHTML = Eth.fromWei(
balance,
"ether"
))
)
.catch(error => {});// BLIPS supply:token.totalSupply().then(function(supply) {
document.getElementById("supply").innerHTML = supply[0];
});// BLIPS Balance:
eth
.coinbase()
.then(coinbase => token.balanceOf(coinbase))
.then(
balance =>
(document.getElementById("blipsBalance").innerHTML = balance[0])
)
.catch(error => {});
}// Get Some BLIPS ! // vanilla JS...
document.getElementById("buy").onclick = function(e) {
e.preventDefault();
var eth = document.getElementById("amount").value; // Note: Offloading balance validation to metaMask,
// but ideally you should also validate here
// Against Balance.
// Some basic number validation...if ($.isNumeric(eth) && eth > 0) {
$("#amount").removeClass("is-invalid");
getBlips(eth);
} else {
$("#amount").addClass("is-invalid");
}
};
// Jquery ...
$("#reload").click(function() {
Dapp();
});function getBlips(amount) {
console.log("Will try to exchange" + amount + "for Blips");
const eth = new Eth(window.web3.currentProvider);
eth
.coinbase()
.then(function(coinbase) {
eth
.sendTransaction({
from: coinbase,
to: tokenAddress,
value: Eth.toWei(amount, "ether"),
gas: "3000000",
data: "0x"
})
.then(result => {
console.log("Tx:" + result);
$("#receipt").html(
'<a href="https://kovan.etherscan.io/tx/' +
result +
'" target="_blank">' +
result +
"</a>"
);
$();
$("#txSuccess").show();
});
})
.catch(error => {});
}
Live BLIPS Dapp on Codepen: https://codepen.io/k3no/pen/jGJQvd
Dependencies:- MetaMask Chrome Plugin.
- CSS: bootstrap 4, font-awesome
- JS: (Babel); Jquery-min, ethjs(from their repo), bootstrap 4
So how does it work ?
The first thing our BLIPS Dapp does is check to see if you are logged into MetaMask, if not, it prompts you to log in/ Unlock MetaMask and reload the Dapp.

Once you have unlocked MetaMask and reloaded the Dapp, you are presented with your Balance in Ether and BLIPS if you have any (notice it’s the same from MetaMask ). No Blips, no problem you can buy BLIPS from the Dapp, that’s it’s only function.

Upon clicking the buy button, you are presented with MetaMasks confirm transaction screen, if you submit it you get a transaction receipt and upon reloading your Dapp, you get your BLIPS ! (notice that totalSupply Increases and your ether balance decreases)
Disclaimer: This is a minimal Dapp for educational purposes, it could be improved in a number of ways( modularity,security,UI,UX,features).
Dapp Developing Considerations :
- The above Dapp code is basically an integration of the previous examples gently hammered into a front end UI, so there is almost no new code except for some validation and interfacing (talking) to the Front End.
- Most of the initial difficulty is due to the asynchronous nature of interacting with the blockchain via MetaMask and conveying such flow to the user; in the example I opted to offload checking balances to the user via a note that asks for a refresh or reload of the Dapp ( for simplicity ), but you could also add a listener for account changes like MetaMask suggests:
https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#ear-listening-for-selected-account-changesvar accountInterval = setInterval(function() {
if (web3.eth.accounts[0] !== account) {
account = web3.eth.accounts[0];
updateInterface();
}
}, 100);
- I also skipped the initial check for MetaMask ( although it’s logged ) and you should also probably listen for disconnects.
- Validation is also a recurring theme, while MetaMask checks transactions before sending them, depending on your Dapp you could need more validation.
- One last thing that I didn't check but that might be important are gas costs which we already covered in previous notes, that is if your transactions incur in different gas costs that’s something you will need to bake into your Dapp.
Better DAPPs
You might be thinking this Dapp is too much trouble for what it does, or maybe you are thinking wait a minute, this is nothing but a very complex donate button. You are partially right.
But think about it, this Dapp if released into the mainnet ( not the testnet) would allow anybody to donate to your cause in a secure anonymous way and receive tokens, the Dapp is also descentralized, it lives in the blockchain with no one controlling it, and it would cost a few dollars to deploy and use.
Like many other new and amazing fields in tech ( A.I. or I.O.T for instance ), the challenge is coming up with new uses that build on top of the basic behavior, in A.I. that’s prediction or behavior based on heaps of data and biological models, in I.O.T. uses of physical things connected through the internet. And so in our case the challenge is extending smart contracts like our BLIPS token and finding new uses for them.
Note: The future might be brighter, the biggest pain point with MetaMask is that it is a chrome plugin, so it requires your users to use chrome and download a plugin, a new library: Mascara , is in the works. This library or others like it would allow you to simply include a light Ethereum client you could interact via javascript, making integration with the blockcahin dramatically easier.
SERVER SIDE DAPPS :
These are but a few ways to start writing a Dapp, for more complex projects where you would want users to not interact with your contracts via meta mask or their own clients, you would need a few extra steps :
- Run geth plus a client /node on a server, keep everything in sync, and archival node for instance would comsume GB’s of storage and take a few days to sync initially.
- Manage your users keys or provide a way for them to do so and interact with your application backend.
- Manage storage while swarm reaches maturity.
These steps are beyond these introductory notes, and frankly if you are looking at a server Dapp you will most likely need a team and a budget, so rather than go in that direction my next couple of notes will go into exploring other development tools and some intermediate smart contract patterns to set you up for more complex projects…
Friendly Recap:
- Notes Part 1 : Setting up : Getting a wallet/client , connecting to a test Ethereum blockchain and getting some test ether.
- Notes Part 2: web3.js/node : Interacting with the blockchain through web3.js and node for more convenience and ease of development.
- Notes Part 3: Solidity : Installing solidity (Ethereums contract writing language ) , Creating a very basic contract, compiling it, deploying it to the blockchain ( the test one) and interacting with it.
- Notes Part 4: Smart Contracts: We modified our simple contract so we could store and retrieve information (making it smart), in the process we also covered how to watch the blockchain and contracts and finally we took a look at gas and how to estimate it.
- Notes Part 5: Smarter Contracts: In order to allow contracts more complex behavior (make them smarter) , we need to delve a bit deeper into contract creation via constructors and a few more complex types which we will use in making a token contract.
- Notes Part 6: Tokens & Inheritance: We made our first Token and interacted with it by transfering some of it from one account to another, we also briefly covered inheritance which is used in more complex contracts.
- Notes Part 7: ERC20 Token Standard: We made and deployed an erc20 token which can be considered the parting standard for working sub currencies. We examined the code and talked about transfers in between tokens.
- Notes Part 8: Crowdfunding and ICOs: We explored the subject of crowdfunding via smart contracts in the form of ICOs and the exchange of ether for tokens, we made contracts that can receive ether, collect ether and can be used for exchanging ether and creating an unlimited supply of tokens.
- Notes Part 9: Dapps & MetaMask (This post): We looked into what is a Dapp and where we are in terms of development ( very early), we then introduced MetaMask which helps make Dapps accessible in the browser , we looked at various ways to interact with MetaMask via javascript and we integrated them into a fully fledged test Dapp that uses our previously made token smart contract, we also touched on the future of Dapps and server implementations.

✨✨ Now a Book ! ✨✨If you are looking for an introduction to Ethereum, Solidity and Smart Contracts these notes were edited and revised into a convenient book !
Available in ebook and paperback:
https://www.amazon.com/dp/B078CQ8L7V
Cheers !
Keno
About the Author :
Born Eugenio Noyola Leon (Keno) I am a Designer,Web Developer/programmer, Artist and Inventor, currently living in Mexico City, you can find me at www.k3no.com