Atomic Ethereum Blockchain Operations

Andrea f Speziale
5 min readDec 19, 2019

In my latest article I promised 🤞 to share how to enable blockchain fee payments in ERC20 tokens for ether-less accounts, even if the smart contract or token you are interacting with doesn’t support meta-transactions natively.

I will go through it really quickly because it is straightforward.
What is really interesting is the smart contract designed while working on the feature described above.

In order to achieve this feature, you can create a system which at least:

  • Exposes a list of supported ERC20 tokens;
  • Accepts ether-less account transaction intention;
  • Estimates the GAS, then the ETH and the ERC20 cost of the ether-less account transaction intention;
  • Prepares a payload to be signed by the ether-less account which describes how many ETH it will receive in exchange for the estimated ERC20 cost;
  • Prepares the payload of the ether-less account transaction intention;
  • Sends the payload and returns it signed by the ether-less account;
  • Checks some pre-conditions and broadcasts the exchange transaction to the proper smart contract which contains the exchange payload as input;
  • As soon as the exchange transaction is mined, the very first transaction intention of the ether-less account is broadcasted.

The ether-less account has accepted:

  • The ERC20 cost of its transaction intention;
  • To receive ETH in exchange for some ERC20 tokens to be spent on its behalf.

“Yes… I know there are many issues in the described flow.”

But most of them can be addressed one by one and this is why I still want to focus on the mentioned smart contract.
I like to call it: Atomic Proxy Smart Contract.

The Atomic Proxy Smart Contract

You will probably ask yourself why I refer to the smart contract as
Atomic and Proxy.

The reason is

it handles a sequence of well-defined transactions on behalf of multiple signers.

The idea was to have a smart contract which uses the meta-transaction concepts and gets a “destructured” chain of transactions (with its signers) as input. The chain is an agreement between two or more actors.
If one of the chained transactions fails, the chain is broken and the agreement fails as well.
The recipient of each transaction must be a smart contract and it will be able to check the transaction signer and to respond consequently. The only requirement is that the signer must be the first parameter of the recipient smart contract function call.

The Entry Point

The forward function is the Atomic Proxy smart contract entry point:

As you can see, the function inputs are the components of the chained transactions to be forwarded.
For each transaction we can easily identify the recipient contained in the recipients param. and the value field contained in the txsValueField param.

What about the data field of each transaction?

We need to treat each transaction data field, hexadecimals of different lengths, as a dynamic array of bytes.
Unfortunately, it is still impossible to pass an array of bytes as input of a smart contract public function.
The approach was to pack each transaction data field in a single bytes input (packedTxsDataField) with an array of integers describing the length of each data field (txsDataSizes) in order to unpack the data later.

“Ok… you have the to, data and value field of each transaction.
Where are the senders?”

As mentioned above, the chain of transactions represents the agreement among the parties. Each party must sign the forward function payload as agreement proof and each data field must have the transaction signer as first parameter. After unpacking the packedSignature and the packedTxsDataField input, we can compare the extracted signers and be sure each transaction has the right one.

What about the other inputs?

The expiration and salt parameters provide a lifecycle to the chained transactions.

The Flow

At the end of the day we are:

  • Building an array of transactions data field from a packed data;
  • Building an array of signatures from a packed data;
  • Doing some checks;
  • Forwarding a chain of transactions which acts as an agreement.

Expiration is one of the most important pre-conditions.
If you are dealing with some automated exchange value system, you definitely want to avoid being victim of market fluctuation.

The unpack of the transactions data field was an interesting challenge:

Using the slice method provided by the BytesLib.sol library it was possible to create the txsDataField array by looping the packedTxsDataField parameter and selecting the actual transaction data field with its size. The same thing needs to be done for the packedSignature array. The difference between the packedTxsDataField and packedSignature arrays is that the latter doesn’t need any extra array to describe the length of each element. This is because Ethereum signatures have a fixed length of 65 bytes.

After checking the getHash function result and ensuring we are not in the middle of a replay attack, we get from each transaction data field the first function call parameter which represents the sender of the transaction:

In order to check if the signers are a subset of senders and every party of the agreement accepted the terms represented by the chained transactions, we can obtain the signers using the well-known Solidity ecrecover method.

Now each transaction is ready to be processed and forwarded borrowing the uPort project executeCall function.

The Recipient smart contract

In the exchange value scenario, one of the chained transactions recipients can be a smart contract which owns some ETH and transfers it to someone else.

As you can see from the example above, the sendETH function gets the signer as first parameter.

The possible ETHSender smart contract, verifying the passed signer, can execute the transaction or make it fail. As a consequence, the execution of chained transactions continues or is interrupted and the agreement it represents is respected or not ❤️.

Check the Atomic Proxy and ETHSender SC and a use case scenario.
If you liked this post, it would be amazing if you’d hit the
Recommend button below, which will mean more people see it. You can also find me over on Twitter. Thanks!

--

--

Andrea f Speziale
Andrea f Speziale

Written by Andrea f Speziale

Occasional writer and impostor coder. Randomly traversing the software engineering black hole 🕳️ #typescript and #nodejs enthusiast @Musixmatch

Responses (1)