Checking the Sender in a Smart Contract

December 26, 2017 by Todd Proebsting

This article will demonstrate how to write a simple, but complete, smart contract in Solidity that accepts and distributes ether on behalf of the contract’s owner. It assumes that you are comfortable with the ether-handling concepts introduced in our
last Solidity example blog post.

The obvious (and unrealistic!) shortcoming of this contract is that anybody can withdraw ether from the contract, so it is of no real use. The contract needs the notion of an owner account that will be the only account that can withdraw ether.

Fortunately, every account has a unique address, and it is possible to store addresses persistently and to test for address equality. Here’s the changed code to do that, renamed “TipJar” because anybody can deposit, but only the owner can withdraw:

The TipJar contract has a global, persistent value, owner, that stores the current owner.

The TipJar contract’s constructor sets the initial value of owner to msg.sender, which in the case of a constructor is the address of the account that is deploying the contract.

The withdraw() function now requires that the account requesting the withdraw transaction (msg.sender) be the current owner.

The key things to note above are that address of a transaction’s sender’s account is available to the smart contract (as msg.sender), and that addresses can be stored and compared just like other scalar values.

Changing the Owner

An important pattern to enable in smart contracts is making them transferable. In the case of the TipJar example, that would mean allowing the current owner to transfer ownership to another account:

The require statement aborts the transaction if any account other than the current owner attempts to change the owner.

The persistent state variable owner is updated with the value held in the newOwner parameter.

Creating New Modifiers

Solidity has a powerful mechanism for creating custom function “modifiers”. Up until now, we’ve only used the built-in modifiers public and view. Modifiers allow programmers to summarize boilerplate prologue (and epilogue) code that may appear in many functions. In the example above, the require(owner == msg.sender) code is a simple example of such prologue code. The code below will eliminate that by creating a new ownerOnly modifier: