I’ve recently started researching how Ethereum works and decided to write a simple Smart Contract with a web interface. At a high-level the process is fairly straightforward, but I found it surprisingly hard to find information for completing some basic tasks. After finally completing my starter project, cryptobragging.com, I decided to write this tutorial so other people could get started building their own and avoid some of the pain points.

Disclaimer: I’m still very new to this, so apologies for any mistakes in here!

Background

I’m assuming you have basic knowledge about how cryptocurrencies work, the blockchain, and what Smart Contracts are. Unfortunately I do not explain these concepts in detail here, but these resources below were very helpful when I was learning:

Where do I start?

Head to https://remix.ethereum.org and you’ll find a mini IDE environment for writing Smart Contracts.

Remix is a great tool which lets you write contracts, test them in a fake network, deploy them, and also call contract functions. Let’s take a look at my contract as an example.

I’ve called my contract a “Bragging Contract” because it allows people to brag about their ETH payments publicly. There is a message on my website which can only be changed if someone pays more than the highest payment accepted so far. Let’s take a look at the contract code:

pragma solidity ^0.4.11; // Brag about how much Ethereum you've paid

// Visit cryptobragging.com to learn more

contract BraggerContract {

// The address that paid the most

address public richest;



// The string that will be displayed on cryptobragging.com

string public displayString;



// The highest payment so far

uint public highestBalance;



address owner; function BraggerContract() public {

owner = msg.sender;

highestBalance = 0;

} function becomeRichest(string newString) public payable {

// Ensure the sender is paying more than the highest so far.

require(msg.value > highestBalance);



// Cap the string length for the website.

require(bytes(newString).length < 500);



highestBalance = msg.value;

richest = msg.sender;

displayString = newString;

}



function withdrawBalance() public {

owner.transfer(this.balance);

}

}

The contract keeps track of the richest “address”, how much they paid, and their string. If someone calls becomeRichest(), they can replace the displayString if they pay more than highestBalance. Let’s break this down piece by piece.

function BraggerContract() public {

owner = msg.sender;

highestBalance = 0;

}

This is the constructor which needs to have the same name as the contract. The public modifier means it can be called externally. msg is a variable supplied to the function which gives you information about the function caller. msg.sender is the address of the person that called the function. Think of the address as a user account which stores ETH. I keep track of the owner (me) so I can transfer the contract balance to myself later.

function becomeRichest(string newString) public payable {

// Ensure the sender is paying more than the highest so far.

require(msg.value > highestBalance);



// Cap the string length for the website.

require(bytes(newString).length < 500);



highestBalance = msg.value;

richest = msg.sender;

displayString = newString;

}

becomeRichest() is the main function of the contract. You’ll notice a new modifier for the function called payable. This modifier allows the caller to “attach” ETH to the function call. If the function is successfully called, the ETH will be stored in the contract itself (unless the code specifies to send it elsewhere). To access the amount of attached ETH, you can check msg.value. Note: msg.value is actually in units of wei. 10¹⁸ wei = 1 ETH.

require() lets you enforce that certain conditions are met, otherwise the transaction will be reverted. I required that the supplied ETH is larger than the highest seen so far, and that the string length is smaller than 500 bytes (so the website won’t look wonky with long strings). If the requirements are met, the appropriate variables are updated.

function withdrawBalance() public {

owner.transfer(this.balance);

}

The last function lets me withdraw the ETH stored in the contract. this.balance is the amount stored, and owner.transfer() transfers the ETH to my address. If anyone ends up actually paying into this contract, I plan on donating the proceeds to charity.

Testing the contract

Ok, so hopefully by this point the contract code makes sense. Now let’s test this out in Remix to make sure that everything works as expected. If you’d like to follow along, you can copy and paste the code above. Click on the Run tab and select Javascript VM to load the test environment.

You will see there are 5 test addresses with 100 ETH each. First, let’s create an instance of this contract by clicking Create.

Alright, it’s time to become the richest! Since we have plenty of (fake) ETH to spare, let’s start this off with 50 ETH.

Put 50 in the Value field, which corresponds to how much ETH you are sending to a function call.

Now write some text and click on the red box which says becomeRichest. This will call the function with 50 ETH and the string “I am rich!” from the address you selected. Since the highestBalance starts at 0, this will be successful and the variables will be updated. Click on the boxes for each variable to see the new values:

If you look back at the accounts, you will also notice that 50 ETH has been withdrawn from the corresponding address. Play around with different values, accounts, and strings to make sure the contract is behaving properly. If you don’t supply enough value, then the function will fail as expected. In the console, you can see the error state:

Deploying the contract

Alright, looks like the contract is working. Now it’s time to deploy it on the blockchain! I personally used a Chrome extension called MetaMask which allows you to use Ethereum wallets on the web and access blockchain data. After you set up MetaMask, you get an address to which you can transfer ETH.

Personally, I already had ETH on Coinbase so I used their website to transfer ETH to the address MetaMask provided, but there are tons of other ways to do this. I transferred a relatively small amount of money for testing and I would recommend the same.

Disclaimer: Please be careful when creating accounts like this, transferring ETH, building contracts, etc. Spend ETH only if you know what you’re doing. There are a lot of security considerations to take into account. Smart Contracts have been hacked before. Real money is involved here so keep your private keys and passwords safe!

Ok, after you’ve set up MetaMask you can switch to the main network to start deploying contracts and calling functions. First, change the environment to injected Web3. This allows Remix to communicate to MetaMask. Be careful, you are now able to spend real ETH, this is not a test environment!

If you click the red “Create” button now, MetaMask will pop up a window asking you to confirm a transaction:

To understand Gas Limit and Gas Price, I’d recommend reading this article and doing some more research. At a basic level, gas is related to how complex your contract is. You can set a gas price which represents how much you will pay, per gas, to create a contract or execute a function.

Clicking submit will create a transaction, and you will spend up to the Max Total ETH listed. If all goes well, and you’ve figured out the Gas stuff, you should have a completed contract! Here is my contract on Etherscan, a site which lets you explore the blockchain and contracts.

Building the web app (dApp)

Sweet, so the contract is written and deployed now! But how do people interact with it? There are a lot of ways — such as using Remix like we did earlier — and there other similar tools like Mist and Parity. However, I think it would be more fun if we could build our own web interface. Let’s take a look at the beautiful interface I built:

You might notice that the website looks exactly like the Firebase Hello World page for hosting. This is because I am lazy and didn’t want to design a web page 😁. Anyway, the interface is fairly minimal. I’ve displayed the variables from the contract at the top of the page, and provided a few fields which are basically the arguments for the becomeRichest() function call. Let’s break down these components.

Reading the contract state

At the top of the page, I am displaying 3 variables: the message, the author’s address, and the amount they paid. The tool I’m using is called web3 which is a javascript library that lets you perform many Ethereum functions. Here is the setup:



web3 = new Web3(web3.currentProvider);

} else {

// set the provider you want from Web3.providers

web3 = new Web3(new Web3.providers.HttpProvider("

} if (typeof web3 !== 'undefined') {web3 = new Web3(web3.currentProvider);} else {// set the provider you want from Web3.providersweb3 = new Web3(new Web3.providers.HttpProvider(" https://mainnet.infura.io / "));

I’m using Infura as my fallback “provider” and as far as I understand, they are providing the infrastructure required to connect with the blockchain, read/modify it, etc. The fallback provider allows people who don’t have tools like MetaMask to at least read the contract state. The next step is to connect to the contract:

var contract = web3.eth.contract(abiArray).at("0x47078E95D238108b5ee30D4806025B5AAb6dac83");

0x47078e… is the address of my contract, which you can see here on Etherscan. abiArray is the Contract Application Binary Interface (ABI) which is basically a description of the function methods and variables. If you go to the code tab on Etherscan, you can find the ABI.

In javascript, I have:

var abiArray = JSON.parse("[{\"constant\":true,\"inputs\":[]...

Ok, we’ve connected to the contract. Now let’s read some variables:

contract.displayString(function(error, result) {

console.log(result);

});

As you can see, it’s pretty straightforward to find the displayString. Here is more info for other ways to call functions. Please keep in mind that this approach is vulnerable to a stored XSS attack, where someone could put javascript in a variable which would then be displayed and executed on your page. Sanitize your input!

Calling a contract function

We’re almost done! The last thing is to call becomeRichest() function, which is actually not very different from reading variables. The key differences are that this function takes arguments and needs a transaction info object.

// Call the smart contract to become the richest.

function becomeRichest() {

var ethValueString = $('#ethValue').val();

var displayString = $('#txtDisplayString').val(); var ethNumber = new BigNumber(ethValueString);

var weiValue = web3.toWei(ethNumber, 'ether'); var transactionObject = {

"value": weiValue,

}

contract.becomeRichest(displayString, transactionObject, function(error, result) {});

}

There are probably a few things that are confusing here, such as “wei” and BigNumber. As I mentioned earlier, 10¹⁸ wei = 1 ETH. Smart contracts always transact with wei, and wei is the smallest possible unit of ETH. Since these numbers are huge, we need the BigNumber library to handle them properly. First, I converted the user provided ETH number into wei. Then, I created a transactionObject which contains the value parameter. Finally, I called becomeRichest with the supplied string and transaction info. That’s it! (well you still have to check error states, edge cases, improve the UI, etc but that’s an exercise for the reader 😉).

Closing thoughts

I hope this tutorial was helpful in your quest to build Smart Contracts. I’m pretty sure I didn’t do a lot of things the “proper way” so please leave a comment if you see areas where I could improve! Personally, I see a lot of potential with Smart Contracts and dApps and I’ve had a blast building them so far. Good luck!