ERC1363 Payable Token — How it works
ERC20 tokens are widely known for facilitating basic transfers and approvals, but their limitations become evident when it comes to real-world payments.
In this article we will discuss how they could be used for real life payments and why I built the ERC1363 Payable Token.
Here you can find the ERC1363 Official EIP and implementation.
What are ERC20 tokens?
As EIP 20 says:
ERC20 provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party.
So basically you can use tokens to represent any fungible tradable good: coins, loyalty points, in-game points, etc.
Here the standard ERC20 definition:
Here a basic implementation of thetransfer
function.
And below a basic implementation of the approve
and transferFrom
functions.
Token Balances
So, as you can see, balances
is not more than a mapping between tokens holder address and its amount of tokens.
For example, assume that a token contract has two token holders:
0x111...111
with a balance of 100 units0x222...222
with a balance of 200 units
The token contract’s balances
data structure will contain the following informations:
balances[0x111...111] = 100
balances[0x222...222] = 200
The balanceOf(...)
function will return the following values:
tokenContract.balanceOf(0x111...111); // will return 100
tokenContract.balanceOf(0x222...222); // will return 200
Transfer Token Balance
If 0x111...111
wants to transfer 10 tokens to 0x222...222
, 0x111...111
will execute the function:
tokenContract.transfer(0x222...222, 10);
The token contract’s transfer(...)
function will alter the balances
data structure to contain the following informations:
balances[0x111...111] = 90
balances[0x222...222] = 210
The balanceOf(...)
function will now return the following values:
tokenContract.balanceOf(0x111...111); // will return 90
tokenContract.balanceOf(0x222...222); // will return 210
Approve And TransferFrom Token Balance
approve(...)
and transferFrom(...)
are used when someone wants to authorise another address to spend tokens in its behalf.
Again, allowed
is not more than a mapping between tokens holder address, spender address and the amount of tokens approved.
What’s the issue?
All good but, what if token receiver wants to make an action after token received or after a token approval?
Imagine you’re sending tokens to pay invoice ACME#1, and the contract needs to automatically mark it as paid. But, without notification mechanisms, no one knows that the tokens were received.
Or consider approving tokens for a subscription manager, expecting your subscription to activate automatically. In real life, every transaction typically results in something — a service or product in return. However, token transfers lack that direct, real-time acknowledgment or action, making processes inefficient and disjointed without manual steps or multiple transactions.
Actually, solutions maybe:
- approving the receiver contract and then initiating another transaction to notify the contract that you've allowed it to spend your tokens. This requires action from the user.
or
- the contract’s ecosystem/platform could “listen” for the
Transfer
orApproval
events and trigger another transaction to perform the desired action automatically.
Both solutions involve at least two transactions, resulting in higher fees, longer wait times, and increased complexity.
Paying gas costs twice and experiencing delays during the transaction process, results in a frustrating onboarding experience for users.
This is why I decided to create my own implementation of a Payable Token. I needed a more efficient solution that could trigger actions automatically upon receiving tokens or approvals, eliminating the need for multiple transactions, reducing fees, and simplifying the entire process.
Has anyone already solved this?
I searched extensively, and while many have tackled similar problems, there’s no widely accepted standard yet. Some alternatives include using the approveAndCall
method, ERC677’s transferAndCall
, or ERC223’s integration within the standard transfer. Each of these requires a different callback function on the receiver contract.
The idea for Payable Tokens came from studying ERC721 (Non-Fungible Tokens), which inspired me to extend its approach to enhance functionality for token payments.
What is an ERC1363 Payable Token?
The ERC1363 allows for the implementation of a standard API for tokens interaction with smart contracts after transfer
, transferFrom
or approve
. This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party, and then make a callback on the receiver or spender contract.
The following are functions and callbacks introduced by this EIP:
transferAndCall
andtransferFromAndCall
will call anonTransferReceived
on aERC1363Receiver
contract.approveAndCall
will call anonApprovalReceived
on aERC1363Spender
contract.
Unlike other ERC20 extension proposals, ERC1363 doesn’t override the ERC20 transfer
and transferFrom
methods and defines the interfaces IDs to be implemented maintaining backward compatibility with ERC20.
This proposal aims to make tokens capable of performing actions more easily and working without the use of any off-chain listener. It allows to make a callback on a receiver/spender contract, after a transfer or an approval, in a single transaction.
ERC1363 tokens can be used for specific utilities in all cases that require a callback to be executed after a transfer or an approval received. ERC1363 is also useful for avoiding token loss or token locking in contracts by verifying the recipient contract’s ability to handle tokens.
There are many proposed uses of Ethereum smart contracts that can accept ERC20 callbacks.
Examples could be:
- creating a token payable crowdsale
- selling services for tokens
- paying invoices
- making subscriptions
For these reasons it was originally named “Payable Token”.
Smart contracts implementing the ERC1363 standard MUST implement all of the functions in the ERC1363
interface, as well as the ERC20
and ERC165
interfaces.
A contract that wants to accept ERC1363 tokens via transferAndCall
or transferFromAndCall
MUST implement the ERC1363Receiver
interface:
A contract that wants to accept ERC1363 tokens via approveAndCall
MUST implement the ERC1363Spender
interface:
Here there is the reference implementation of the ERC1363 Token.
You can use it in your project by installing with npm:
npm install erc-payable-token
Follow Vittorio Minacori on GitHub, Twitter or LinkedIn.