Let’s Play — Capture the Ether : Warmup

Forest Fang
Coinmonks
8 min readApr 14, 2018

--

This is a series of stories on my journey of Capture the Ether, a game where we hack Ethereum Solidity code for fun and learn about smart contract security.

Table of Contents

  • Lotteries: random number in smart contract. Part I, Part II
  • Math: how to do math safely in Solidity.
  • Accounts: account ownership and security.
  • Miscellaneous: everything else.

What is Capture the Ether?

In Capture the Ether, we win points by completing challenges. Each challenge comes with a smart contract to deploy and objectives can be completed by exploiting the contract into a specific state. Challenges are grouped into categories that focus on specific areas of security vulnerabilities in smart contracts.

Why this Series?

I have learnt my Solidity skill first through CryptoZombies, and written some smart contracts with Truffle framework in a few hackathons. As of this writing, I am halfway through the Lottery section and have found it to be an engaging educational resource.

I have not yet had trouble coming up with ideas how to tackle the challenge, but I had plenty painful moments figuring out the tools I need to implement my approach and debugging my smart contract.

In this series of articles, I will focus on practical smart contract programming and my hard learnt mistakes. I will lay out the tools and IDE/CLI setup, explain the key security insight of each problem, and show you how to implement them in practice. It will assume you have basic understanding of how Ethereum works and I highly recommend you go through CryptoZombies first to learn the basics of Solidity. In the interests of space, I will not explain concepts in details but will provide links as necessary.

Before we start, I should mention that Capture the Ether already provides an excellent resources to get you started. The Warmup challenges are also meant to prepare you with the tools you need. I will focus on the missing details that gave me troubles in my experience.

Deploy a Contract

As instructed, you first need Metamask, an in-browser Ethereum wallet. Once installed, you can follow the prompt to finish setup. Now we need to Switch to Ropsten Test Network. I will demo using beta version of Metamask in a Brave browser.

Metamask Chrome Extension Standalone Page — Select a network

The network can be chosen by clicking on the network selector on top right. Main Ethereum Network is the production network where Ethers and (ERC20) tokens have real value and can be traded and used to operate smart contract.

The other test networks are used to develop and test smart contracts. They run the identical EVM as in the main network but some use more efficient (and less secure) consensus algorithm such as PoA. Ethers on test network can be similarly mined but faucets are also available to acquire free Ethers for testing. In Capture the Ether, you need a little more than two Ethers to play the game (you need two Ethers to complete smart contract interaction and then some more to pay the gas.)

Here are some faucets:

  1. https://faucet.metamask.io 1 Ether per account per day
  2. https://faucet.bitfwd.xyz/ 1 Ether per account per day
  3. https://faucet.kyber.network/ 1 Ether per account
  4. http://faucet.ropsten.be:3001/ 1 Ether every drip (queue based)

I recommend you get 3 Ethers first and come back for more only if you need them when you make mistakes in the challenges.

Ether in testnet does not have real value so be sure you are on test network when you play the game. You private key and all Ethereum addresses work just the same in miannet and testnet. Don’t send your mainnet Ether to a testnet account or you will lose them. To be foolproof, don’t share private key/seed/account between mainnet and testnet.

Metamask Dropdown — Confirm a transaction

With that, click Begin Challenge, and confirm. Your own copy of the below smart contract will be deployed. Click check solution again to complete the challenge.

pragma solidity ^0.4.21;contract DeployChallenge {       
// This tells the CaptureTheFlag contract that the challenge is complete.
function isComplete()
public
pure
returns (bool) {
return true;
}
}

Notice that Capture the Ether relies on calling isCompelete function to determine if you have achieved the objective. Furthermore, because you deployed a copy of this smart contract code with your Ethereum account, Capture the Ether can trustlessly link the accomplishment to your Ethereum address.

Call me

This question asks us to call a function on a deployed contract, i.e. send a transaction to a smart contract address with payload that contains function interface and arguments. You can refer to interacting with smart contract to learn the details of what happens under the hood.

The hard core way would be us figuring out the payload data, running this through CLI and communicating with a local node directly. Here I will demonstrate two easiest ways that interfaces with Metamask directly.

Javascript Console with web3.js

Web3.js is a Javascript library that communicate with Ethereum node through JSON-RPC interface. You can read more and find API documentation on its Github website.

Metmask injects web3.js to every running web page in your browser. This has the awesome effect that you can interact with Ethereum directly without worrying managing private keys and node connection. In fact, let’s give it a try by opening the Console via Command/Ctrl+Option+J and running the following lines:

🎉 You should see your default Metamask address and its balance. You may find the syntax to be rather clunky as everything is asynchronous and callback based. The good news is that web3.js 1.x will return promises for async function so you can chain promise or use async/await syntax. (We will cover this in the next article when we write web3.js code in Truffle.) You can track Metamask progress of web3.js 1.x support at Github.

To interact with a contract, web3.js relies on ABI (application binary interface), which specifies what functions are available and what arguments are accepted for each function.

The easiest way to get ABI from source code is by using a solidity compiler. Feel free to jump to the next subsection, which introduces an online IDE Remix, if you don’t care about the details of solidity compiler and web3.js.

We will use solc from the binary Solidity package on Mac and you can find many other compilers in the documentation.

Compile Solidity Contract with solc

We can load this ABI with web3.js in JS console and issue a transaction to call callme function in the contract:

Get instance of deployed smart contract and send transaction to `callme`

Metamask should pop up asking you to authorize a transaction that is triggered by the last line. With that one confirmed, you can go ahead check your solution. 🎉+100 points.

Remix

Remix is an in-browser IDE for Solidity. You can write, compile, and interact with smart contract with a friendly-ish GUI.

Let us create a new file by clicking the + button on the top left and name it CallMeChallenge.sol . We will then put the contract code in the editor:

Remix in-browser Solidity IDE
  1. Create File
  2. Copy and paste solidity code
  3. Check Auto Compile which will compile your code whenever it is changed
  4. The green box celebrates your code compiles with detected contract name: CallMeChallenge

Now we can interact with the contract on Ethereum blockchain:

  1. Click Run tab
  2. Choose Injected Web3 and verify you are on Ropsten test network on the right. There are a few other environments available. Simply these are possible blockchain (providers) you can interact with. Injected Web3 means web3.js is injected into browser page, in this case, by Metamask.
  3. Verify you are on the intended account and your balance is correctly reflected. If you created multiple accounts in Metamask, you will have those to choose from.
  4. A list of Contract defined in the current file will be listed here. In this case, we only have CallMeChallenge
  5. You can either Create a new contract or Load an existing contract that has been deployed. In this case, we enter the address of our deployed contract in the challenge.
  6. An instance of contract should show up below. This is akin to what happened when we ran CallMeChallenge.at('<address>') above.
  7. There are two buttons callme and isComplete which are the two public functions of the contract. Notice the different color because callme is a state modifying function that can only be called with a transaction where you will pay gas. On the other hand, isComplete is a read only function can be called without paying any gas. (Note you will still pay gas if calling a read only function within a transaction.)

Go click isComplete , you should immediately see 0: bool: false on the right if you have yet completed the challenge. Now click callme and Metamask should ask to authorize a transaction. Transaction status will be updated in the console below. Once the transaction has been mined, you can click isComplete again, and now it should show 0: bool: true instead. Congratulation +100 points!

Choose a nickname

This one should be easy for you now that you know how to use Remix. The only tricky part is that now we need to call function with an argument.

Go ahead copy and paste the code into a new file. Load the contract from the address 0x71c46Ed333C35e4E6c62D32dc7C8F00D125b4fee. Fill in your preferred nick name to the right of setNickname function.

You need to wrap string/bytes argument with double quotes. Remix uses space to delimit arguments.

Easiest 200 points in my life! 😬

For completeness, you can interact with this contract with web3.js as shown above:

Get instance of deployed smart contract and send transaction to `setNickname`

Conclusion

In this post, you have learnt to create your own Ethereum account on Ropsten test network with Metamask, use web3.js in Javascript console injected by Metamask, and call contracts using web3.js using code or Remix via GUI.

Next time, we will dive into the Lotteries section where we will discover common and interesting security vulnerabilities in smart contract. We will also look at how to use EthFiddle to write and test Solidity code in browser without paying any gas.

Capture the Ether is brought to you by @smarx, who blogs about smart contract development at Program the Blockchain.

I am not affiliated with the game itself and the awesome company behind it. Views expressed are solely my own and do not express the views or opinions of any entity with which I have been, am now, and will be affiliated.

--

--

Forest Fang
Coinmonks

functional programming advocate; visualization addict; blockchain enthusiast;