Your resource for web content, online publishing
and the distribution of digital products.



Create an ERC20 token payment splitting smart contract

DATE POSTED:September 16, 2021

How do you ensure that the Non-Fungible Token (NFT) that you just bought will definitely be delivered?

Let’s take this question further.

Imagine that you are purchasing a used luxury watch that comes with an ERC-721 based NFT certificate (like the one that I discussed in the article NFT-based Luxury Watch Certificate). How do both the buyer and seller ensure payment and delivery without a middleman?

Photo by Nicolas Cool on Unsplash

In this series, I propose how an NFT Escrow Service Smart Contract may make peer-to-peer trading of NFTs or physical goods such as luxury watches safe and secure.

The source codes for this project can be found in its Github repository here.

Getting Started

In the scenario that I am demonstrating, John purchases a watch and receives an NFT-based certificate from BreitLex, the watch manufacturer. He gets bored with his watch after a while (yes, this happens to watch flippers all the time) and sells the watch to Mary.

To execute this scenario, create 3 accounts on your Ethereum Wallet. Here, I use MetaMask.

Imagine that we are now BreitLex. Deploy the BreitLex NFT Smart Contract so that you may start minting a token for the new watch that you are about to manufacture. Deploying the BreitLex NFT Smart Contract only needs to be done once when you first begin to make watches. Thereafter, you can continue minting as many tokens as the watch you are manufacturing.

BreitLex now mints a new BNFT token for the watch that it has just made. Enter the watch model, manufactured date, serial number, and a picture of the watch. Click [Go].


Now John comes by to buy the watch. BreitLex performs a [Transfer] of this watch’s NFT certificate to John.

BreitLex enters John’s wallet address and clicks [Go].

John checks if he has received his watch’s NFT certificate by entering BreitLex’s NFT Smart Contract address and the token ID that represents his watch. Yes, it says in the screenshot below that the NFT certificate belongs inside John’s wallet.

John Sells His Watch

Here’s where the fun begins.

John has gotten bored of his watch and decides to sell it online. Traditionally, John would have sold it through one of the popular watch-trading websites like Chrono24. Since this is a BreitLex watch that comes with an NFT-based certificate, John can sell the watch himself without a middleman.

Here’s how he will do it with the NFT Escrow Service Smart Contract.

An NFT Escrow Service Smart Contract goes through 5 states in a successful trade (and 2 exceptions).

Here’s a demonstration of how it works.

John launches the NFT Escrow Service Smart Contract.

To run the NFT Escrow Service Smart Contract, John copies and paste nftescrow.sol into the Remix IDE. He compiles and deploys it by executing the deploy() function.

Of course, if John isn’t a geek, he will be executing this process through a Decentralized App (DApp) with a slick user interface! But we will leave the discussion of this DApp for the next part of this series of articles.

John Deposits the NFT Certificate in the NFT Escrow Smart Contract

John then deposits his watch’s NFT Certificate in the NFT Escrow Smart Contract that he has just deployed.

This process involves 2 steps. First, John must authorize the Escrow Service Smart Contract to hold custody of the NFT Certificate on his behalf. To do so, John goes back to the BreitLex Smart Contract, retrieves his token ID, the click [Authorize Escrow].

To do this, John enters the Escrow Service Smart Contract’s address and clicks [Go]. Now the NFT Escrow Service Smart Contract is authorized to hold on to John’s NFT Certificate.

Finally, John executes the depositNFT() function by providing the address of the BreitLex NFT Smart Contract as well as his token ID.

John’s NFT token has been removed from his wallet and transferred to the NFT Escrow Service Smart Contract.

In fact, John, or anyone else who knows the address of the NFT Escrow Smart Contract can see John’s NFT Token right there if they visit the NFT Escrow Service Smart Contract on Etherscan.

Mary Buys John’s Watch

Mary comes along and decides that she wishes to purchase John’s watch. Negotiations are made between John and Mary and it was decided that Mary will buy the watch for 1 ETH.

She asked John for the address of John’s NFT Escrow Service Smart Contract, keys in 1 ETH, and run depositETH().

To ensure that both parties are truthful, they can visit the NFT Escrow Service Smart Contract on Etherscan. Here, they see that the Escrow Service Smart Contract is holding custody of 1 BNFT Token (from John) and 1 ETH (from Mary).


John is satisfied that Mary has transferred 1 ETH to the Escrow Service Smart Contract.

He initiates a delivery by executing initiateDelivery(). He packs his watch up and ships it to Mary.

Mary receives the watch. She checks it and is satisfied that it was delivered in the condition as John has promised.

Mary executes confirmDelivery() at the NFT Escrow Service Smart Contract.

This sets off a process where the Escrow Service Smart Contract does 2 steps:

  1. Transfers the 1 ETH that it has held in custody to John.
  2. Transfers the watch’s NFT token to Mary.

If you view the NFT Smart Contract on Etherscan at this point, you realize that it no longer holds custody of any ETH, nor NFT token. They have all been transferred to their new owners.

John is now 1 ETH richer, but no longer owns his watch, nor its NFT certificate. Mary is 1 ETH poorer but is now the proud owner of a watch and its NFT certificate.

Canceling A Sale

Here’s an exception. Imagine that John has deployed the Escrow Service Smart Contract and deposited his NFT certificate. But he can’t find a buyer for his watch. He will have to cancel the transaction to get his NFT certificate back.

Here’s how. John executes cancelAtNFT().

The Escrow Service Smart Contract returns his NFT certificate back into his wallet. This is straightforward since no buyers have committed to making the purchase at this point.

Now let’s imagine that the situation is a little stickier than that. John has deposited his NFT certificate into the Escrow Service Smart Contract, negotiated the trade with Mary. They both have agreed to the trade and Mary had deposited 1 ETH into the NFT Escrow Service Smart Contract.

Somehow, Mary decided not to proceed with the trade. Perhaps she encountered buyer’s remorse and decided that she wanted her 1 ETH back.

At this stage, the cancellation cannot be made unilaterally. Some discussions would have ensured offline between Mary and John and they both must have agreed to call off the deal.

Mary then runs cancelAtNFT() to confirm that she no longer wishes to proceed with the trade.

John does the same. He executes cancelAtNFT() too. The Escrow Service Smart Contract checks to ensure that both John and Mary have executed cancelAtNFT(). It then returns John's NFT certificate to him and Mary's 1 ETH to her.

In the details of this transaction on Etherscan, we see 2 processes taking place:

  1. Mary’s 1 ETH is returned to Mary’s wallet.
  2. John’s NFT Token is returned to John’s wallet.

And the cancellation process completes!


What if Mary doesn’t confirm that she has received the watch although she did?

Then Mary will not receive the NFT certificate for her new watch. And John will not receive the 1 ETH that Mary has deposited into the NFT Escrow Service Smart Contract.

There’s really no good motivation on Mary’s part to sabotage the process by not executing the confirmDelivery() function since John could lodge a complaint with BreitLex to blacklist this watch based on its serial number.

Also, anyone who checks the NFT certificate for the watch at BrietLex’s DApp will notice that Mary doesn’t actually “own” the watch although she has the watch physically. This will make it really difficult for Mary to sell the watch since there’s no way she can transfer the watch’s NFT certificate (which she doesn’t own) to a potential new owner.

But Mary could have refused to confirm delivery because the watch wasn’t delivered in the condition as promised!

Then John and Mary should negotiate offline, come to a consensus so that Mary is happy to execute confirmDelivery() to conclude the transaction. Both parties are worst off should they not be able to come to an agreement so they really should talk.

What if John doesn’t deliver the watch to Mary?

Then Mary wouldn’t confirm that she has received the watch.

And as a result, the NFT Escrow Service Smart Contract wouldn’t release 1 ETH to John nor the NFT certificate to Mary.

John wouldn’t want this to happen. If his intention was to cheat, he would need the watch’s NFT certificate in order to sell it to someone else. There’s really no good motivation for John to sabotage the process by not delivering the watch to Mary as promised because he doesn’t get paid, and he loses his NFT certificate to the Escrow Smart Contract forever.

Also, nobody will buy his watch since they could go to the BreitLex DApp, read the watch’s NFT certificate and realize that it has been held in custody by an NFT Escrow Service Smart Contract.

What if Mary makes a request to cancel but John ignores her? Or vice versa.

Then the Escrow Service Smart Contract continues to hold custody of both Mary’s ETH and John’s NFT Certificate until both parties come to an agreement. There’s really no reason why both parties wouldn’t want to come to an agreement quickly because:

  • Mary’s 1 ETH will forever be locked up in the Escrow Service Smart Contract.
  • John’s NFT will forever be locked up in the Escrow Service Smart Contract.

Does the Escrow Service Smart Contract work only for watches?

It works for any physical asset where proof-of-ownership matters, for example, NFT-based title deeds for real estate — you can sue the other party using the transaction records on the Escrow Service Smart Contract as evidence of non-compliance.

It works for jewelry, expensive Birkin bags, and diamonds too!

Does the Escrow Service Smart Contract work for, say, digital art?

Yes, since there’s no delivery, parties in the Escrow Service Smart Contract can assume instant delivery.

This is out of topic, but does it really matter to a watch owner that your watch doesn’t come with a certificate?

Today, paper-based certificates get misplaced all the time. Watches without certificates lose tremendous value when sold in the second-hand marketplace for a few reasons. Firstly, watch collectors want their watches to come in a full set including boxes, certificates, and even instruction manuals. Another reason is that the fear that you are buying a replica is alleviated when the serial number on the certificate matches the one etched on the watch itself.

Should NFT-based watch certificates be implemented across the luxury watch industry, the value proposition becomes even more compelling because anyone can check if the serial number on the NFT cert matches that on the watch and see its model, manufactured date, or any other metadata that the watch manufacturer wishes to write into its NFT certificate.

A large part of luxury watches ownership comes from knowing that you own the real thing. So yes, if owning an authentic watch matters to you, then owning the watch physically, but knowing that its NFT cert says that the watch belongs to someone else should bother you greatly.

So both John and Mary must run… codes to do this?

Of course not. That’s where the Decentralized App (DApp) comes in. Keep reading.

What’s Next?

In the 2nd part of this series, I will demonstrate how a Decentralized App (DApp) that I have built will make it easy for laymen to execute the escrow business logic described here.

  1. NFT Escrow Service: Business Logic
  2. NFT Escrow Service: Decentralized App Demo
  3. NFT Escrow Service: Smart Contract

Stay tuned!

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

Icons made by Vitaly Gorbachev from
Photo by Jaelynn Castillo from Unsplash

Join Coinmonks Telegram Channel and learn about crypto trading and investing

NFT-Based Escrow Service: Business Logic was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.