Mastering Ethereum — Ethereum Basics [Chapter 2]

MrCatalyst
14 min readJun 21, 2022

--

In this chapter we will start exploring Ethereum, learning how to use wallets, how to create transactions, and also how to run a basic smart contract.

Topics covered in this chapter :

  1. Ether Currency Units
  2. Choosing an Ethereum Wallet
  3. Control and Responsibility
  4. Getting Started with MetaMask
  5. Introducing the World Computer
  6. Externally Owned Accounts (EOAs) and Contracts
  7. A Simple Contract: A Test Ether Faucet
  8. Compiling the Faucet Contract
  9. Creating the Contract on the Blockchain
  10. Interacting with the Contract
  11. Conclusions

Ether Currency Units

Ethereum’s currency unit is called ether, identified also as “ETH” or with the symbols Ξ or, less often, ♦: for example, 1 ether, or 1 ETH, or Ξ1, or ♦1.
Ether is subdivided into smaller units, down to the smallest unit possible, which is named wei. One ether is 1 quintillion wei (1 * 1018 or 1,000,000,000,000,000,000). You may hear people refer to the currency “Ethereum” too, but this is a common beginner’s mistake. Ethereum is the system, ether is the currency.

Choosing an Ethereum Wallet

We will use the term “wallet” to mean a software application that helps you manage your Ethereum account.In short, an Ethereum wallet is your gateway to the Ethereum system. It holds your keys and can create and broadcast transactions on your behalf.The Ethereum platform itself is still being improved, and the “best” wallets are often the ones that adapt to the changes that come with the platform upgrades.

Remember that for a wallet application to work, it must have access to your private keys, so it is vital that you only download and use wallet applications from sources you trust. Nevertheless, it is good practice to avoid “putting all your eggs in one basket” and have your Ethereum accounts spread across a couple of wallets.

The following are some good starter wallets:

  • MetaMask : MetaMask is a browser extension wallet that runs in your browser.It is a web-based wallet.
  • Jaxx : Jaxx is a multiplatform and multicurrency wallet that runs on a variety of operating systems, including Android, iOS, Windows, macOS, and Linux. Jaxx is either a mobile or a desktop wallet, depending on where you install it.
  • MyEtherWallet (MEW) : MyEtherWallet is a web-based wallet that runs in any browser. MyEtherWallet is a web-based wallet.
  • Emerald Wallet : Emerald Wallet is designed to work with the Ethereum Classic blockchain, but is compatible with other Ethereum-based blockchains. It also has a companion tool to do all operations from the command line.

We’ll start by installing MetaMask on a desktop — but first, we’ll briefly discuss controlling and managing keys.

Control and Responsibility

Open blockchains like Ethereum are important because they operate as a decentralized system. That means lots of things, but one crucial aspect is that each user of Ethereum can — and should — control their own private keys, which are the things that control access to funds and smart contracts. We sometimes call the combination of access to funds and smart contracts an “account” or “wallet.”
Some users choose to give up control over their private keys by using a third-party custodian, such as an online exchange. In this book, you will learn how to take control and manage your own private keys.
With control comes a big responsibility. If you lose your private keys, you lose access to your funds and contracts. No one can help you regain access — your funds will be locked forever. Here are a few tips to help you manage this responsibility:

  • Do not improvise security. Use tried-and-tested standard approaches.
  • The more important the account, the higher security measures should be taken.
  • The highest security is gained from an air-gapped device, but this level is not required for every account.
  • Never store your private key in plain form, especially digitally.
  • Private keys can be stored in an encrypted form, as a digital “keystore” file. Being encrypted, they need a password to unlock. When you are prompted to choose a password, make it strong (i.e., long and random), back it up, and don’t share it.
  • Do not store any passwords in digital documents, digital photos, screenshots, online drives, encrypted PDFs, etc. Again, do not improvise security. Use a pass‐ word manager or pen and paper.
  • Before transferring any large amounts (especially to new addresses), first do a small test transaction (e.g., less than $1 value) and wait for confirmation of receipt.

Getting Started with MetaMask

This section is covered in a separate article: here

Introducing the World Computer

You’ve now created a wallet and sent and received ether. So far, we’ve treated Ethereum as a cryptocurrency. But Ethereum is much, much more. Ether is meant to be used to pay for running smart contracts, which are computer programs that run on an emulated computer called the Ethereum Virtual Machine (EVM).

Each node on the Ethereum network runs a local copy of the EVM to validate contract execution, while the Ethereum blockchain records the changing state of this world computer as it processes transactions and smart contracts.

Externally Owned Accounts (EOAs) and Contracts

The type of account you created in the MetaMask wallet is called an externally owned account (EOA). Externally owned accounts are those that have a private key; having the private key means control over access to funds or contracts.

And there is a contract account has smart contract code, which a simple EOA can’t have.Furthermore, a contract account does not have a private key. Instead, it is owned (and controlled) by the logic of its smart contract code: the software program recorded on the Ethereum blockchain at the contract account’s creation and executed by the EVM.

Contracts have addresses, just like EOAs. Contracts can also send and receive ether, just like EOAs. However, when a transaction destination is a contract address, it causes that contract to run in the EVM, using the transaction, and the transaction’s data, as its input. In addition to ether, transactions can contain data indicating which specific function in the contract to run and what parameters to pass to that function. In this way, transactions can call functions within contracts.

In addition to ether, transactions can contain data indicating which specific function in the contract to run and what parameters to pass to that function. In this way, transactions can call functions within contracts.

In the next few sections, we will write our first contract.

A Simple Contract: A Test Ether Faucet

Ethereum has many different high-level languages, all of which can be used to write a contract and produce EVM bytecode. One high-level language is by far the dominant choice for smart contract programming: Solidity. Solidity was created by Dr. Gavin Wood, the coauthor of the Book “Mastering Ethereum” (essentially this book’s Author). We’ll use Solidity to write our first contract.

For our first example, we will write a contract that controls a faucet. You’ve already used a faucet to get test ether on the Ropsten test network. A faucet is a relatively simple thing: it gives out ether to any address that asks, and can be refilled periodically. You can implement a faucet as a wallet controlled by a human or a web server.

You will find all the code samples for this book in the code subdirectory of the book’s GitHub repository(https://github.com/ethereumbook/ethereumbook/). Specifically, our Faucet.sol contract is in: code/Solidity/Faucet.sol

This is a very simple contract, about as simple as we can make it. Let’s look at what this contract does and how it works, line by line. You will quickly notice that many elements of Solidity are similar to existing programming languages, such as Java‐ Script, Java, or C++.

The first line is a comment: // Our first contract is a faucet!

The next line is where our actual contract starts: contract Faucet {

This line declares a contract object, similar to a class declaration in other object oriented languages. The contract definition includes all the lines between the curly braces ({}), which define a scope.

Next, we declare the first function of the Faucet contract: function withdraw(uint withdraw_amount) public {

The function is named withdraw, and it takes one unsigned integer (uint) argument named withdraw_amount. It is declared as a public function, meaning it can be called by other contracts. The function definition follows, between curly braces. The first part of the withdraw function sets a limit on withdrawals:require(withdraw_amount <= 100000000000000000);

It uses the built-in Solidity function require to test a precondition, that the with draw_amount is less than or equal to 100,000,000,000,000,000 wei, which is the base unit of ether (see Table 2–1) and equivalent to 0.1 ether. If the withdraw function is called with a withdraw_amount greater than that amount, you know what will happen, execution of the contract breaks with an exception also ; is needed after every line termination

Next comes the actual withdrawal:msg.sender.transfer(withdraw_amount);

A couple of interesting things are happening here.The msg object is one of the inputs that all contracts can access. It represents the transaction that triggered the execution of this contract.The attribute sender is the sender address of the transaction. The function transfer is a built-in function that transfers ether from the current contract to the address of the sender.The transfer function takes an amount as its only argument. We pass the withdraw_amount value that was the parameter to the withdraw function declared a few lines earlier.

The very next line is the closing curly brace, indicating the end of the definition of our withdraw function.

Next, we we declare one more function: function () public payable {}

This function is a so-called fallback or default function, which is called if the transac‐ tion that triggered the contract didn’t name any of the declared functions in the con‐ tract, or any function at all, or didn’t contain data. Contracts can have one such default function (without a name) and it is usually the one that receives ether. That’s why it is defined as a public and payable function, which means it can accept ether into the contract. It doesn’t do anything, other than accept the ether, as indicated by the empty definition in the curly braces ({}). If we make a transaction that sends ether to the contract address, as if it were a wallet, this function will handle it.

Right below our default function is the final closing curly brace, which closes the definition of the contract Faucet. That’s it!

Compiling the Faucet Contract

Now that we have our first example contract, we need to use a Solidity compiler to convert the Solidity code into EVM bytecode so it can be executed by the EVM on the blockchain itself.

To keep things simple, we will use one of the more popular IDEs, called Remix. Use your Chrome browser (with the MetaMask wallet you installed earlier) to navigate to the Remix IDE at https://remix.ethereum.org.

When you first load Remix,you’ll see a contracts folder. right click and select new file option.

Name the new file Faucet.sol.Once you have the new tab open, copy and paste the code from our example

Once you have loaded the Faucet.sol contract into the Remix IDE, go to compile tab and click “Compile Faucet.sol” and if all goes well you will see a green tick mark.

If anything goes wrong, it will be most probably due the solidity version and compiler version. Just change the compiler version to match the pragma statement from the Faucet.sol file it would work.The Solidity compiler has now compiled our Faucet.sol into EVM bytecode. If you are curious, Click on the Bytecode.

Creating the Contract on the Blockchain

So, we have a contract. We’ve compiled it into bytecode. Now, we need to “register” the contract on the Ethereum blockchain. We will be using the Ropsten testnet to test our contract, so that’s the blockchain we want to submit it to.

Registering a contract on the blockchain involves creating a special transaction whose destination is the address 0x0000000000000000000000000000000000000000, also known as the zero address. The zero address is a special address that tells the Ether‐ eum blockchain that you want to register a contract. Fortunately, the Remix IDE will handle all of that for you and send the transaction to MetaMask.

First, switch to the Run tab and select Injected Web3 in the Environment drop-down selection box. This connects the Remix IDE to the MetaMask wallet, and through MetaMask to the Ropsten test network. Once you do that, you can see Ropsten under Environment. Also, in the Account selection box it shows the address of your wallet

Right below the Run settings you just confirmed is the Faucet contract, ready to be created. Click on the Deploy button.

Remix will construct the special “creation” transaction and MetaMask will ask you to approve it,

You’ll notice the contract deployment transaction has no ether in it, but it has 258 bytes of data (the compiled contract) and will con‐ sum 26 gwei in gas. Click Confirm to approve it.

Now you have to wait. It will take about 15 to 30 seconds for the contract to be mined on Ropsten. Remix won’t appear to be doing much, but be patient. Once the contract is created, it appears at the bottom of the ‘Deploy’ button.

Notice that the Faucet contract now has an address of its own: Remix shows it as “Faucet at 0x322……..A40ED (0x32295D311b3B0edaFb34d985C8B7228A37eA40ED)” (although your address, the random letters and numbers, will be different). The small clipboard symbol to the right allows you to copy the contract address to your clipboard. We will use that in the next section.

Interacting with the Contract

Let’s recap what we’ve learned so far: Ethereum contracts are programs that control money, which run inside a virtual machine called the EVM. They are created by a special transaction that submits their bytecode to be recorded on the blockchain. Once they are created on the blockchain, they have an Ethereum address, just like wallets. Anytime someone sends a transaction to a contract address it causes the contract to run in the EVM, with the transaction as its input. Transactions sent to contract addresses may have ether or data or both. If they contain ether, it is “deposited” to the contract balance. If they contain data, the data can specify a named function in the contract and call it, passing arguments to the function.

Viewing the Contract Address in a Block Explorer
We now have a contract recorded on the blockchain, and we can see it has an Ether‐ eum address. Let’s check it out in the ropsten.etherscan.io block explorer and see what a contract looks like.The address you copied from the remix IDE in the section “Creating the Contract on the Blockchain

Keep Remix open; we’ll come back to it again later. Now, navigate your browser to ropsten.etherscan.io and paste the address into the search box. You should see the contract’s Ethereum address history,

Funding the Contract
For now, the contract only has one transaction in its history: the contract creation transaction.
Our faucet needs funds! Our first project will be to use MetaMask to send ether to the contract. You should still have the address of the contract in your clipboard (if not, copy it again from Remix). Open MetaMask, and send 1 ether to it, exactly as you would to any other Ethereum address.

In a minute, if you reload the Etherscan block explorer, it will show another transac‐ tion to the contract address and an updated balance of 1 ether.
Remember the unnamed default public payable function in our Faucet.sol code? It looked like this:
function () public payable {}
When you sent a transaction to the contract address, with no data specifying which function to call, it called this default function. Because we declared it as payable, it accepted and deposited the 1 ether into the contract’s account balance. Your transaction caused the contract to run in the EVM, updating its balance. You have funded your faucet!

Withdrawing from Our Contract
Next, let’s withdraw some funds from the faucet. To withdraw, we have to construct a transaction that calls the withdraw function and passes a withdraw_amount argument to it. To keep things simple for now, Remix will construct that transaction for us and MetaMask will present it for our approval.
Return to the Remix tab and look at the contract on the Run tab. You should see a orange box labeled withdraw with a field entry labeled uint256 withdraw_amount

This is the Remix interface to the contract. It allows us to construct transactions that call the functions defined in the contract. We will enter a withdraw_amount and click the withdraw button to generate the transaction.
First, let’s figure out the withdraw_amount. We want to try and withdraw 0.1 ether, which is the maximum amount allowed by our contract. Remember that all currency values in Ethereum are denominated in wei internally, and our withdraw function expects the withdraw_amount to be denominated in wei too. The amount we want is 0.1 ether, which is 100,000,000,000,000,000 wei (a 1 followed by 17 zeros).
Type “100000000000000000” into the withdraw_amount box and click on the withdraw button.
MetaMask will pop up a transaction window for you to approve. Click Submit to send your withdrawal call to the contract

Wait a minute and then reload the Etherscan block explorer to see the transaction reflected in the Faucet contract address history.

We now see a new transaction with the contract address as the destination and a value of 0 ether. The contract balance has changed and is now 0.9 ether because it sent us 0.1 ether as requested. But we don’t see an “OUT” transaction in the contract address history.
Where’s the outgoing withdrawal? A new tab has appeared on the contract’s address history page, named Internal Transactions. Because the 0.1 ether transfer originated from the contract code, it is an internal transaction (also called a message). Click on that tab to see it.
This “internal transaction” was sent by the contract in this line of code (from the withdraw function in Faucet.sol):
msg.sender.transfer(withdraw_amount);
To recap: you sent a transaction from your MetaMask wallet that contained data instructions to call the withdraw function with a withdraw_amount argument of 0.1 ether. That transaction caused the contract to run inside the EVM. As the EVM ran the Faucet contract’s withdraw function, first it called the require function and vali‐ dated that the requested amount was less than or equal to the maximum allowed withdrawal of 0.1 ether. Then it called the transfer function to send you the ether. Running the transfer function generated an internal transaction that deposited 0.1 ether into your wallet address, from the contract’s balance. That’s the one shown on the Internal Transactions tab in Etherscan.

Conclusions

In this chapter, you set up a wallet using MetaMask and funded it using a faucet on the Ropsten test network. You received ether into your wallet’s Ethereum address, then you sent ether to the faucet’s Ethereum address.
Next, you wrote a faucet contract in Solidity. You used the Remix IDE to compile the contract into EVM bytecode, then used Remix to form a transaction and created the Faucet contract on the Ropsten blockchain. Once created, the Faucet contract had an Ethereum address, and you sent it some ether. Finally, you constructed a transaction to call the withdraw function and successfully asked for 0.1 ether. The contract checked the request and sent you 0.1 ether with an internal transaction.

It may not seem like much, but you’ve just successfully interacted with software that controls money on a decentralized world computer.
We will do a lot more smart contract programming in Chapter 7 and learn about best practices and security considerations in Chapter 9.

--

--