Ropsten Ethereum Faucet: Smart Contract

Motivation

This series of tutorial documents my process of building an Ethereum faucet on the Ropsten Testnet. This is the 2nd article of the series and it explains how the Faucet Smart Contract works.

  1. Ropsten Ethereum Faucet: How it works
  2. Ropsten Ethereum Faucet: Smart Contract
  3. Ropsten Ethereum Faucet: JSON Web Service
  4. Ropsten Ethereum Faucet: Web App

The source codes for this project are in the project’s Github repository and the faucet smart contract is accessible here.

Setting up the Faucet Smart Contract

To compile the faucet smart contract, visit the Remix Ethereum IDE. Create a new smart contract file and name it faucet.sol.

Paste the faucet source code into faucet.sol.

If this is your first time running the Remix IDE, add the following plug-ins so that you can compile and run the Faucet smart contract that you have just created.

  1. Deploy & run transactions
  2. Solidity compiler.

The Faucet smart contract is developed in Solidity 0.5.0. At the Solidity compiler section, select Solidity 0.5.0. Then click [Compile faucet.sol].

After faucet.sol is compiled, it is ready to be tested and run. Switch to the “Deploy & Run Transactions” plug-in. Enter 2 ether as value, then click [Deploy]. Here, you are deploying the Faucet Smart Contract and giving the Faucet 2 ETHs to start with. Of course you may provide as much new ETHs to your faucet as you wish.

You can view the Faucet Smart Contract in Etherscan once it’s been deployed. Notice that the Faucet has 2 ETH in it.

The [receive] function allows you to send ETHs from the faucet to another address. To do this, enter the wallet address of the recipient and the amount of ETH to send to it.

When the faucet runs out of ETHs, you will need to top up. To do so, enter the amount of ETHs to send to the faucet, then click [receive] to confirm that you are sending the ETHs to the faucet.

The faucet keeps a record of everyone who has requested ETHs in an array. To view it, enter the array’s position, say 0 for the first person who has made a request. Then click [requesters]. This shows you the wallet address of the first requester and the amount of ETH that he had requested from the faucet.

How It Works

address public me;

struct requester {
   address requesteraddress;
   uint amount;
}

requester[] public requesters;

me stores the address of the faucet. Every requester is saved as a struct that contains the address of the requester of ETH and the amount of ETH that he has requested.

requester[] is an array that stores the requester struct.

constructor() public payable {
	me = msg.sender;
}

When the faucet is first deployed, the address of the new faucet is store in me. Notice that the constructor is payable. This allows the person who deploys this faucet to add ETHs to it. This was how we were able to add ETH to the faucet when we first deploy it with Remix.

event sent(uint _amountsent);
event received();

The sent event is triggered when the function call to send ETH to a requester is successful. The received event is triggered when the function call for the receiver to receive ETH is successful. We will see how when these events are triggered in a moment.

Events allow the DApps that makes call to these function know that the functions have competed their execution. We will revisit this when we discuss the Faucet DApp in the next article.

function receive()
	public
	payable
{
	emit received();
}

The receive function lets the faucet receive ETH from a contributor. This is the function that you will call when you need to add new ETH to the faucet. Notice that this function is payable and it triggers the received() event to emit when called.

function send(address payable _requester, uint _request)
    public
    payable
{
    uint amountsent = 0;
    _request = _request * 1e18;
        
    if (address(this).balance > _request){
        amountsent = _request/1e18;
        _requester.transfer(_request);   
    }
    else{
        amountsent = (address(this).balance)/1e18;
        _requester.transfer(address(this).balance);
    }
       
    requester memory r;
    r.requesteraddress = _requester;
    r.amount = amountsent;
    requesters.push(r);
    emit sent(amountsent);
}

The send() function is called to transfer ETH from the faucet to an ETH requester. It requires 2 parameters – the wallet address of the requester _requester and the amount of ETH _request that he is requesting.

It multiplies _request by 1e18 (that is 1, followed by 18 zeros). This is because 1 ETH = 1,000,000,000,000,000,000 wei and wei , the smallest denomination of ETH, is the unit of measurement used in Solidity.

The function then checks if the requester is asking for more ETH than the faucet owns. If the faucet has enough to fulfill the request, this transfer is made by executing  _requester.transfer(_request). The amount requested is copied to the amountsent variable. If the requester is asking for more than the ETH that the faucet has, the faucet transfers everything it has to the requester.

Next, the requester’s wallet address as well as the amount transferred to it is pushed to the requesters array. Finally, the sent() event is triggered. 

What’s Next?

The source codes for this projects can be found in my Github repository.

In the next part of this tutorial, I will explain the codes behind the Faucet Smart Contract’s JSON Web Service. Stay tuned!

If you enjoyed this tutorial, perhaps you may also wish to read:

Photo by Zbysiu Rodak on Unsplash