January 29, 2026

Capitalizations Index – B ∞/21M

Using the OpenZeppelin Escrow Library – Will Shahda –

Using the OpenZeppelin Escrow Library – Will Shahda –

Buried in the OpenZeppelin documentation is brief mention of their escrow library. Turns out this library is useful for a variety of payment applications. Even situations where it is not necessary to hold funds for a period of time, the escrow library can protect against security risks by implementing the withdrawal pattern.

Basically, if you call transfer inside another function, an attacker could create a contract that causes the function to fail and potentially wreak havoc on your contract. If you call it in a separate withdrawal function, the attacker cannot abuse any other part of your contract.

In this tutorial, we are going to use the escrow library to implement a simple payment gateway.

Our payment gateway will have a few basic features:

  • It should create an OpenZeppelin escrow contract.
  • It should accept payments and send them to the escrow contract.
  • It should allow the owner of the gateway to withdraw funds from the escrow to a wallet.
  • It should allow the owner of the gateway to view the balance they can withdraw.

If you need help setting up a project before we start coding, read my article Build Smart Contracts with OpenZeppelin and Truffle.

Create the payment gateway contract

This is just an empty contract, nothing surprising here.

pragma solidity ^0.5.2;
/**
* @title Payment gateway using OpenZeppelin Escrow
* @author Will Shahda
*/
contract PaymentGateway

Make the payment gateway ownable

There will be a couple of functions we will want to restrict access to. The easiest way to do this is make our contract “ownable”. Whoever creates an ownable contract becomes its owner, and will be able to call the restricted functions.

Let’s extend our contract to make it “ownable”.

import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';
/**
* @title Payment gateway using OpenZeppelin Escrow
* @author Will Shahda
*/
contract PaymentGateway is Ownable

Create an escrow

The escrow library is meant to be used alongside other contracts. Instead of extending Escrow, we create an instance of it for our payment gateway.

import 'openzeppelin-solidity/contracts/ownership/Ownable.sol';
import 'openzeppelin-solidity/contracts/payment/escrow/Escrow.sol';
contract PaymentGateway is Ownable 
}

Add a wallet

We need an address to receive the funds collected from payments.

Let’s name the variable wallet and pass the address into the contract’s constructor. We do this instead of using msg.sender in case the contract creator wants to use a separate address for receiving funds.

contract PaymentGateway is Ownable 
}

Make sure the wallet variable is also payable.

Create function for sending payments

This is the first function that makes use of the escrow contract. Payers will use it to make payments destined for the wallet address.

/**
* Receives payments from customers
*/
function sendPayment() external payable

Notice we are calling the deposit function with the value of ether sent to our sendPayment function. If we try to use the transfer function on our escrow, the payment would not be accounted for, and the owner would not be able to withdraw it.

Create function for withdrawing funds

All this function has to do is call the escrow’s withdraw function with our wallet variable. The escrow then initiates the transfer of funds.

/**
* Withdraw funds to wallet
*/
function withdraw() external onlyOwner

This function is the reason we made our contract “ownable”. We don’t want just anyone to initiate a withdrawal, even if funds can only be sent to our wallet. Because our contract extends Ownable, all we had to do was add the onlyOwner modifier.

Create function for viewing balance

This is another function we want to restrict to the owner.

To get the balance, we make a call to the escrow that returns all the deposits stored for our wallet.

/**
* Checks balance available to withdraw
* @return the balance
*/
function balance() external view onlyOwner returns (uint256) 

As you can see, we are returning a uint256. It is good practice to use the SafeMath library for uint256 because it throws errors on overflow instead of silently causing problems. Let’s do that as well.

import 'openzeppelin-solidity/contracts/math/SafeMath.sol';
contract PaymentGateway is Ownable ;

Because accounts[0] is used to create contract instances, it will become our payment gateway’s owner, and is therefore a good choice for a wallet address.

Test the payment gateway

Let’s make sure our contract works. After deployment, open the Truffle console and run the following commands:

const accounts = await web3.eth.getAccounts()
const instance = await PaymentGateway.deployed()
instance.sendPayment()

We are calling sendPayment from accounts[1], because as you recall, accounts[0] creates the contract and will be set to our payment gateway wallet.

Now let’s check the balance available for us to withdraw:

instance.balance()

This should output a balance of 1 ether. Keep in mind the balance will be displayed in wei as a hex value.

Because only the owner can view the balance, calling instance.balance() will fail.

Finally let’s withdraw our funds to the wallet:

instance.withdraw()

Again, only accounts[0] can call this function because it is the owner.

After withdrawal, we can check the balance of accounts[0] to see that is has been incremented by ~1 ether (subtracting the ether spent on gas for transactions).

Real world applications

Any dApp that accepts payment could benefit from an escrow. It could be something simple like the payment gateway we just created. It could be something complex like a two sided marketplace with third party arbitration. No matter what the application, you can protect yourself from security issues using the withdrawal pattern implemented by OpenZeppelin’s escrow library.

View the code for this tutorial

https://github.com/opz/EscrowTutorial

Published at Sat, 20 Apr 2019 08:37:56 +0000

Previous Article

TRON Has A New SR Who Has Not Created Any Blocks

Next Article

Will Craig Wright’s newly presented proof hold up in court and prove that he is creator of Bitcoin?

You might be interested in …

Ethereum Price Tear Almost Reached $60

Ethereum Price Tear Almost Reached $60 When Europe woke up this morning and checked eth’s price, they may have seen a small rise from $40 to $46, but America had a very eventful night. Eth’s […]