Relayers
Since shielder
is just a smart contract, each transaction in shielder must be submitted by some AccountId
. However, if this was done just by the user itself, then it would lead to privacy loss. For this reason we introduce relayers: parties that post shielder transactions to chain, on behalf of normal users.
To support relayers we enrich Operation
s for which it makes sense with two new fields: relayer_address
and relayer_fee
. Consider the example of the WithdrawETH
operation
struct WithdrawETH {
relayer_address: AccountId,
relayer_fee: u128,
withdraw_address: AccountId,
amount_eth: u128,
}
Now the corresponding methods would be implemented as follows:
fn update(acc: Account, op: WithdrawETH) -> Account {
decrease balance of AZERO in acc by op.relayer_fee
decrease balance of ETH in acc by op.amount_eth
return acc;
}
The corresponding implementation of public_exec
is
fn public_exec(op: WithdrawETH) {
transfer op.relayer_fee AZERO from shielder to op.relayer_address
transfer op.amount_eth ETH from shielder to op.withdraw_address
}
The typical flow of sending a transaction by the user would be then:
Contact a relayer and negotiate fee.
Create a transaction placing the relayer's address in
relayer_address
field and the negotiated fee inrelayer_fee
(in AZERO). Generate the corresponding snark proof. Note thatwithdraw_address
should be a fresh account with no history, for max privacy.Pass all the data to the relayer.
The relayer validates that the
relayer_address
andrelayer_fee
is correct, and simulates the transaction to make sure it passes (the proof is correct etc.).The relayer sends the transaction, bears it's gas fee, but gains
relayer_fee
which should be larger than gas cost.
Last updated
Was this helpful?