To relay your transactions we use the concept of meta-transactions. Meta-transactions are based on the principle of off-chain message signing for on-chain use. A user signs a message representing its transaction intent. The message is then sent to Rockside. There it gets wrapped in a new transaction to be sent and executed on chain by a smart contract.
The parameters to be included on the signed message are:
signer: address of the account who signed the message. The user who want to interact with the destination contract.
to: if the destination contract has to interact with another account (contract or EOA), this field can be used (for example to transfer tokens).
value: can be used to allow user owning ether/token to perform transactions.
data: bytes to be executed.
nonce: nonce value used by the signer. It's a 2 dimensional nonce represented as a 256 bit integer split in two. See replay protection page
At Rockside we follow EIP-712 to structure the relay message.
When the message is created and signed, it's sent to Rockside with a chosen speed of inclusion in the blockchain.
Accept the transaction: Rockside use EthGasStation as a reference for the gas prices. Depending on your given gas price limit, your requested speed and the current market gas prices, we decide whether or not to relay your transaction. We also verify that the Forwarder has enough ether to refund Rockside for the gas used by the transaction.
Choose the appropriate EOA: Rockside manages different pools of EOA to send transactions. A pool of EOA for each available speed. This way, we guarantee that a "fast" transaction will not be slowed down by a transaction with a "safelow" speed. It's like on the highway, each transaction has its own queue depending on its speed.
The message is included within a transaction: Using the corresponding EOA a transaction containing the signed message of the user is sent to the user's Forwarder. The gas price used by Rockside is in accordance with the speed requested.
The source code of Forwarder contract is available on Github.
Message signature validation: The Forwarder verifies that the signature corresponds to the signer and the parameters of the transaction.
Check and update nonce: To avoid replay attacks, the forwarder verifies that the nonce was not already used. Once done, the current nonce is incremented.
Call the destination contract: When all verifications are done, the destination contract is called with the parameters of the transactions.
Refund Rockside relayer: An amount of ether corresponding to the gas consumed and the gas price used (limited by the gas price limit) is sent from the Forwarder to the Rockside Relayer.
The destination contract has to implement the following method:
relayExecute(signer, to, value, data, gasLimit, gasPrice, nonce)
This method has to be only accessible by the forwarder contract (the forwarder is in charge of validating the signature and the nonce). With the received parameters, the transaction is executed on behalf of the signer.