Control Structures

With its increasing popularity, your SpaceCookie might become the next big pastry. However, you don't want to face the wrath of the SpaceMuffin. To that end, you are committed to spy on it only once out of ten times.

If else

To write a function telling you if you are allowed to spy or not, you have to use if else pattern. It works as follow

if (1 == 2) {
  return "1 == 2???";
} else {
  return "1 is not equal to 2".
}

if takes a boolean expression. If true, if statement is executed. If false, else statement is.

Exercise
Correct!
False!

Loading...

Write allowed function to know if you are allowed to spy. spy should return 0 if not allowed.
pragma solidity ^0.4.24; contract SpaceMuffin { uint private fans = 1; function getFans() view public returns (uint) { return fans; } } contract SpaceCookie { SpaceMuffin muffin = SpaceMuffin(0xe1A15B265e58B7bE2E8A626AeE8e27b5d288a1B7); // take a look, a new variable is declared uint private attempts = 0; function allowed() view public returns (bool) { attempts += 1; // write your condition here } function spy() view public returns (uint) { // adapt spy function to return 0 if not allowed return muffin.getFans(); } }

Hint

  • Take a look at how the internal counter works
  • Use modulo operation: 20 % 10 = 0 and 21 % 10 = 1 for instance

This pattern is very useful to create distinctive path without blocking the flow like require does.

Return multiple values

In the previous implementation, when spy returns 0, it is impossible to tell if it was forbidden or if SpaceMuffin has no fans. To get around it, it would be great if spy was able to return two values. First is if it was allowed and second the number of fans.

Solidity functions are actually able to do this. For a function returning a position, it would look like

function position() returns (uint, uint) {
  return (1, 2);
}

// returns can be named and are returned automatically at the end of the function
function position() returns (uint x, uint y) {
  x = 1; y = 2;
}

// Or even a more readable solution, where you don't have to worry about x and y being allocated
function position() returns (uint x, uint y) {
  return (1, 2);
}

Exercise
Correct!
False!

Loading...

spy signature has changed and is now able to return 2 results. You should correct its core.
pragma solidity ^0.4.24; contract SpaceMuffin { uint private fans = 1; function getFans() view public returns (uint) { return fans; } } contract SpaceCookie { SpaceMuffin muffin = SpaceMuffin(0xe1A15B265e58B7bE2E8A626AeE8e27b5d288a1B7); uint private attempts = 0; function allowed() view public returns (bool) { attempts += 1; return attempts % 10 == 0; } // function signature has changed function spy() view public returns (bool isAllowed, uint fans) { // you should save allowed result to avoid calling it twice if (allowed()) { return muffin.getFans(); } else { return 0; } } }

Hint

  • Save allowed result otherwise attempts is updated twice
  • You have to return two parameters, first is a bool, second a uint
  • If not allowed, you can set fans to whatever you want

The code now looks better. It notifies the user if no access was granted and returns a meaningful result if it was allowed.

Calling a function having multiple result is done below

(bool allow, uint fans) = cookie.spy();

To only retrieve one result, simply ignore other ones

// only save fans
(, uint fans) = cookie.spy();

For loop

Some users have designed a way to get around your protection. Instead of calling the function once, they call it ten times in a row and save the result. To automate this process, they have done the following

uint fans = 0;
for (uint i = 0; i < 10; i = i + 1) {
  (bool _allow, uint _fans) = cookie.spy();
  if (_allow) {
    fans = _fans;
  }
}

It's a for loop. Formally it works as follow

for (initialisation; condition; incrementation)
for (uint i = 0; i < 10; i += 1)

Initialisation step is run once before the loop. Condition is checked like an if at the beginning of each statement. If valid it execute the statement once, if not it stops the loop. Incrementation is executed at the end of each statement and influence the condition.

That's it. You now know more about control structures in Solidity. Let's move on to the next challenge.

results matching ""

    No results matching ""