Again, we see that it starts off with a contract declaration (this time with no other contracts it inherits from). Immediately after that we see the line

address public owner;

This creates a “state” variable for the contract. State variables are stored inside of Ethereum’s internal key-value store so they will remain permanently stored in the blockchain. State variables are like the database for your long-lived contracts. In this case, we’re adding a permanent field to the contract specifying the address of the wallet (or contract) that currently owns this contract. This section of the Solidity documentation has a good explanation of the different types of storage in Solidity.

The function

function Ownable() Public {

owner = msg.sender;

}

is the constructor function for the contract (notice how it has the same name as the contract itself) and is marked public because otherwise the solidity compiler will warn you that its visibility is not explicitly set, but this function is called once, and only once, when the contract is created and can never be called again. Thus, by setting the owner field to msg.sender on creation of the contract, any contract that inherits from this contract will automatically have its owner set to the person who initiated the transaction that created the contract (AKA msg.sender ). Also note that we are able to reference the state variable owner directly, there is no need to do something like self.owner or this.owner as you would in Python and JavaScript respectively.

Interestingly, msg is not a parameter of the function, yet we’re still able to reference it. That’s because it’s one of the three Solidity “global” variables that are always available during contract execution: msg , tx , and block . For now, all you need to know is that msg contains information about the transaction that initiated contract execution.

The only other function in the contract is

1 function transferOwnership(address newOwner) public onlyOwner {

2 require(newOwner != address(0));

3 OwnershipTransferred(owner, newOwner);

4 owner = newOwner;

5 }

Unlike our previous function, this one accepts a single parameter newOwner of type address which is one of Solidity’s primitive types and is a 256-bit number that represents the address of a contract or wallet. The function is marked public, because the owner of the contract will need to be able to call this function if he/she ever wants to change the contracts owner. There is also a function modifier onlyOwner , but we’ll come back to that in a minute.

Line 2 require(newOwner != address(0)); is a sanity check that prevents ownership being transferred to a nil value. The require function is built-in, and is an acceptable way of ending execution if something is not as expected. Note that require statements with no additional information are the primary form of error handling in solidity, so prepare yourself for a frustrating debugging experience when things go wrong :)

Line 3 owner = newOwner; is simple, it simply overrides the permanent state value we talked about earlier with the address of the new owner.

But what about line 3, OwnershipTransferred(owner, newOwner); ? If you look back at the original contract code you’ll note that the OwnershipTransferred event is declared right after the owner state variable

event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

Defining an event is kind of like defining a function, except you don’t get to write the body of it. You simply specify the signature, and then when you call the event, the value of all the arguments you passed to it are emitted as an “event”.

Events are stored in the blockchain, but they are NOT accessible to contracts. They are, however, accessible to Ethereum clients and can be used as a cheap form of storage, as well as a way to update frontends / UI.s. Read this post for more information if you’re curious.

Note that when we say an operation is “cheap” in Solidity terms that means the operation does not consume much “gas” which is the “currency” of execution in the Ethereum VM. Every time someone sends a message / transaction to your contract, they will specify a “gas limit” which is the maximum amount of gas that your contract can consume trying to process their request. If your contract uses more gas than they are willing to pay, the operation will fail. An important consequence of this is that while we pay a one-time fee to deploy your contract, its ultimately our user’s who pay for our code to run.

The final piece of the isOwnable contract that we haven’t discussed yet is the onlyOwner portion of the function declaration. This is called a function modifier, and its similar to a decorator in other languages in that it allows us to modify the behavior of a function with another function. In this case, its behavior is obvious from the name, it makes sure that the function can only be called by the owner. That makes sense because this is a public function so we wouldn’t want anyone to be able to take over your contract just by calling it.

We can understand how the modifier works by looking at its declaration

modifier onlyOwner() {

require(msg.sender == owner);

_;

}

In this case, the onlyOwner modifier code will run BEFORE the function its modifying is run, and it will verify that the transaction was sent by the owner of the contract. The code for the function that is being modified will run where the _; is. That means if we wanted to check if the send was the owner AFTER the modified function was run, we could rewrite the modifier like this

modifier onlyOwner() {

_;

require(msg.sender == owner);

}

That’s the entire IsOwnable contract! Note that I didn’t write that particular contract, its a commonly used helper contract from the zeppelin-solidity library which is a great source of pre-written, audited Solidity code (with a particular emphasis on ICOs).

Lets get back to our main contract