Events

There's a special type of function called an event; it's a way for us to use the EVM or Ethereum virtual machine logging facilities. This is important to us, because, if you remember, when our player takes an action in the game, it's not in real time; it goes to the Ethereum Network where it waits to be confirmed by miners and then and only then is it written to the blockchain. When that happens, any events associated with that transaction are fired off. We can use those to call JavaScript callbacks in our application and update the UI for the player. Events are inheritable members of the contract, which means any events written into a contract are available to any contracts inherited from it. And, finally, the event arguments themselves are stored in the transactions log; that's a special data structure of the blockchain where we can see which events fired as part of the transaction.

Let's take a look at a real event to get a better idea of what I mean. Inside our contract, we define an event using the event keyword, give it a name—and notice here that the name starts with a capital letter: PlayerWon then add parameters for the data points we want to index:

event PlayerWon(address player, unit amount);

Inside of our winOrLose function, once we determine the player has won, we can omit the player one event that writes the player's address and the amount they won to the transaction log. In the JavaScript for our application, we can listen for this event and when we receive it let the player know the good news:

function winOrLose(unit display, bool guess, unit wager) external payable returns (bool) {
/* Use true for a higher guess, false for a lower guess */
require(online == true);
require(msg.sender.balance > msg.value, "Insufficient funds");
unit mysteryNumber_ = mysteryNumber();
bool isWinner = determineWinner(mysteryNumber_, display, guess);
if (isWinner == true) {
/* Player won */
emit PlayerWon(msg.sender, msg.value);
msg.sender.transfer(wager * 2);
return true;
} else if (isWinner == false) {
/* Player lost */
return false;
}
}