Capture The Ether Lottery Solutions

In this post, I will share my explanations for the Lottery section of the Capture The Ether challenges. There are plenty of solutions around the web - my goal was to solve the challenges locally, avoiding Etherscan when possible, and writing code locally.

You can find the code here.

Let’s begin.

Guess The Number

This is very similar to the warmup challenges. In the code, you will find the script guessTheNumber.js. The code has comments explaining what each line does. Still, here is what we need to do:

  1. Looking at the constructor you will notice that you need to have 1 Ropsten ETH in your account before pressing the Begin Challenge button, otherwise the transaction will fail;

  2. After deploying the contract we can now solve the challenge locally. Again, we need to get the contract abi and address. Then, we need to connect to it using our account.

  3. As you must have already noticed, the answer is in the code. The number is 42. However, look at the guess() function. Where have you seen that require statement before? Exactly, you need to send 1 ETH to the function in order to solve it.

Guess The Secret Number

This is almost equal to the previous challenge. In the code, you will find the script guessTheSecretNumber.js. The code has comments explaining what each line does. Still, here is what we need to do:

  1. Do steps 1 and 2 from the previous challenge;

  2. This time we only have the hash of the number we need to send to the guess() function. We need to figure out the number by running a loop, hashing the current loop counter value, and then checking if the hash matches. You probably saw that the guess() function takes an uint8 as a parameter. This tells us that the number is less than 256 because the uint8 max value is 2⁸-1 = 255;

  3. When we have the correct number, we just need to call the guess() function and send 1 ETH to it again.

Guess The Random Number

This challenge requires a bit more work. There are at least three ways to solve this:

  1. Check the Etherscan contract creation transaction, and look for state changes. You will find the solution there. This is not the goal of this solution;

  2. Get the value in position 0 of the contract storage;

  3. Compute the solution using the same formula that the challenge uses.

These last two options allow us to interact with the contract. Option 2 is the easiest, but both can be found in the guessTheRandomNumber.js script. As always, the code has comments explaining what each line does. Still, here is what's needed for each solution:

For both possible solutions, we need to do steps 1 and 2 from the previous challenge, and then:

Solution 2:

  1. Get the value from position 0 of the contract storage and convert it to uint8;

  2. When we have the correct number, we just need to call the guess() function and send 1 ETH to it again.

Solution 3:

  1. We need the hash of the contract creation transaction, which we can get from Etherscan.

  2. Get the contract creation transaction itself using the hash;

  3. Get the block in which the transaction was included;

  4. Get the block parent hash and block timestamp. If you look at the code, you'll notice that block.blockhash(block.number - 1) - that's why we get the parent hash of the block the transaction was included in;

  5. Compute the hash using the above values;

  6. Get the last byte of the hash, because the solution is an uint8, and convert it to a number.

  7. When we have the correct number, we just need to call the guess() function and send 1 ETH to it again.

Guess The New Number

This challenge gets a little bit trickier because the answer is calculated when we call the guess function.

One approach to solve this challenge is to create a contract that computes the answer and calls the challenge guess() function in the same block. This way, our answer is always correct.

You will find the contract in contracts/GuessTheNewNumberSolver.sol. Once again, the code is explained. Still, here are the steps needed:

  1. Look at the contract and understand what it is doing. The contract has comments explaining everything.

  2. We need to deploy the contract. User your account so you can get your ETH back later, after solving the challenge;

  3. Call the guess() function of the contract you just deployed. As a parameter, we need to send it the challenge address;

  4. Call the withdraw function to get your ETH back;

Predict The Future

This challenge gets even trickier because you have to lock in your guess before an answer is calculated.

Luckily for us, we know the answer is between 0 and 9 because we mod the calculated uint8 by 10. However, knowing this isn't enough.

The key to solving this challenge is settling in the correct block. So, one approach to solve this challenge is to create a contract that locks a guess between 0 and 9. Then, we repeatedly call the predict() function of our contract until it determines that settling on the current block will produce the result that matches our locked guess.

You will find the contract in contracts/PredictTheFutureSolver.sol. Once again, the code is explained. Still, here are the steps needed:

  1. Look at the contract and understand what it is doing. The contract has comments explaining everything.

  2. We need to deploy the contract. User your account so you can get your ETH back later, after solving the challenge;

  3. Call the lockGuess() function of the contract you just deployed. As a parameter, we need to send our guess;

  4. Call the predict function until it determines that settling will produce the result we guessed;

  5. Call the withdraw function to get your ETH back;

Predict The Future Block Hash

At first, this challenge may seem like a more complicated version of the previous one. However, it is not.

Looking at the contract, you'll see that the solution is determined by calculating the blockhash of the block you locked your guess in + 1. It may seem that this will require a tremendous amount of luck to guess correctly. However, what you should do first is to go to the solidity documentation and read about the blockhash function. Do it.

You'll hopefully see that it returns the hash of the last 256 blocks. For earlier blocks it will return 0 - this is how we solve the challenge! We simply lock our guess that the hash will be 0, then we get the block number our transaction was included in, wait for 257 blocks, and settle. It will return 0 and we will solve the challenge.

Once again, the code is explained. Still, here are the steps needed:

  1. Get the contract abi and address;

  2. Get the private key of the ropsten account you are using to interact with Capture The Ether. Otherwise, you can't pass the challenge as CTE doesn't know who you are;

  3. Get the contract and connect with it using your account;

  4. Lock your guess. Remember, guess 0.

  5. Wait for 257 blocks. This will take some time. Go rest a little bit :)

  6. Settle and get your ETH back;

Subscribe to kyrers
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.