On Ethereum, every transaction that changes the state of a smart contract costs a small fee: this is called gas. Most commonly, end users pay gas while interacting with a smart contract. However, when you’re making a profit on your product by charging some transaction fee or just want to gain many users quickly, you may think about covering the Ethereum gas costs yourself. Well, good news — it’s achievable! In this article, I’ll describe how to do this from both the business side and technical side.
To calculate the precice amount of gas you need to know two factors: Ethereum gas price and the complexity of the operation you want to execute. The current average gas price of Ethereum depends on the current demand on the Ethereum network. Now, let’s see how you can offload the gas costs from the transaction creator to the platform itself.
Blockchain use case: P2P options exchange
The need for offloading the transaction fee in order to achieve cheaper prices is real! We’ve recently faced the problem of moving as much Ethereum gas cost as we can from the end user to the contract creator. The project in question was a blockchain peer-to-peer options exchange, which got a percentage of profit from every successful option settlement. The goal was to encourage people to use the product by waiving any additional cost, just like in non-blockchain solutions.
One of the functions that needed to be free for the users was a standard ERC20 functionality – approve(). User A can allow user B to transfer a certain amount of tokens from user A’s wallet. This method, like any other, normally costs Ethereum gas to execute, but we want to achieve this with no cost to the user. Let’s call the target solution zero-fee allowance. The following requirements must be met for a trusted and secure solution:
- The transaction has to be executed by the contract owner, not the end user.
- It has to be clear which action is performed by the contract owner on behalf of which end user.
- The transaction can be invoked only once.
- Two transactions containing two intents by the same end user have to be executed in the order of creation.
Dealing with the Ethereum gas cost challenge
We began by searching through Ethereum Improvement Proposals for problems similar to ours and maybe some solutions. Jackpot! Issue 662 addressed our problem.
After a detailed analysis we were ready to develop our own solution based on what we learned.
We divided the process into 3 parts:
- Arbitrary data (the intent) is signed offline using the end user’s private key. The data contains the approve method signature, all parameters and contract address on which the request should be executed. The resulting data signature is sent along with rest of data to the server. Within this step, the user doesn’t make any state changing transactions, so there’s no transaction fee.
- The server gets the data from the end user and pushes it to the network using the smart contract owner’s key. The smart contract owner pays the transaction fee.
- The contract verifies if the sent data is really the end user’s intent by validating the signature. Then it checks for replay attacks and user intent’s execution order. Lastly, it executes the actual approve function.
This part describes the technical solution. So, if you’re not interested in the guts of implementation details, then just skip to the next section, where I’ll discuss the financial aspect of the zero-fee allowance approach.
We based our solution on StandardToken from OpenZeppelin framework. It gave us base methods like the aforementioned approve(). Next, we moved to validating the end user’s intent in the getSigner() function. Firstly, the end user address is recovered from the data signature. Then, the signature is checked against the signature calculated for the arbitrary data passed by the end user. In this step, the intents order is checked by incrementing the nonce value. Lastly, the intent is checked for any previous executions.
After all these checks pass, the flow continues like the standard approve method with the spender address being replaced with the one belonging to the user who signed the message. For readability, the code is split into three methods – checkProvableApprove and provable_approve. The first one is constant and can be used for checking intent correctness, while the second changes the state.
Business calculation of the Ethereum ETH price
Let’s take a look on price per unit that user has to spend per transaction with zero-fee allowance in comparison with the traditional approach.
The gas price and ETH/USD ratio given at the time of writing:
|Gas price (Gwei)
The conclusion is quite clear. The zero-fee allowance approach costs over 2 times more than when the approve() function is executed directly by the user. In our use-case, that move was worth it, but it should be an individual decision. After all, as the popular song goes, “it’s all about the money”.
If you liked this article, then give it a share. We’ve got more great stuff on our blog (e.g. a guide on how to start an ICO), so make sure you subscribe to our newsletter to be up to date!