Title: Lets_discuss_Metamask_s_hackathon_on_generalized_m
Category: Magicians

Author: Amxx
Date: 2020-01-11T17:59:23.345Z

As many amount you may know, Metamask recently published a post and bounty for a new meta-transaction standard.
Unlike previous work that relied on account/proxy smart contracts (see ERC725, UniversalLogin, Gnosis, Authereum …) this targets meta-transactions directly supported by the app. They are quoting Dai’s permit function as an example.
While I think this is a really interresting move from metamask, I also think this should not be a competition but rather a collaboration between members of this community.
Starting a collaboration on twitter is difficult, and Dmitry Palchun made a good point that we should discuss that here, as it will most likelly end up being the cause of multiple ERC proposals.
Anyone interested to contribute to collaborating is welcome to answer here. Reviewer, hackers, protocol designers are more than welcome to give their opinion!
On my side, I’ve been pretty busy in the past few days and I have a working demo that I believe would be a good start:

repo: https://github.com/Amxx/GMTX

GMTXReceier contract: https://github.com/Amxx/GMTX/blob/master/core/contracts/GMTXReceiver.sol

Showcase dapp contract: https://github.com/Amxx/GMTX/blob/master/core/contracts/utils/MessageHub.sol

Showcase dapp frontend: https://gmtx.app.hadriencroubois.com/

Author: Ethernian
Date: 2020-01-11T19:39:06.682Z

Thank you, @Amxx for starting this discussion and for your decision to cooperate instead of to compete.
I had not have a look into your code yet.
I have an implementation idea, may be wrong and not verified yet, that I would just drop here.
a quickly dropped idea:
It was possible to just add any trailing bytes after encoded solidity call. These bytes were just ignored and the call went through without exception.  May be we could add the MetaTx signature to the calldata just to the end and evaluate in receiving contract?
If it already obvious - sorry.

Author: Amxx
Date: 2020-01-11T19:48:45.487Z

Ethernian:

It was possible to just add any trailing bytes after encoded solidity call.


This is how I pass the sender (origin of the meta transaction) after relaying the call (received by a generic receiver).
If you idea is to call the targeted function directly, with extra data being processed only if available … well I don’t see how to process it but it sounds interresting

Author: Ethernian
Date: 2020-01-11T21:46:13.332Z

Amxx:

I don’t see how to process it but it sounds interresting


Solidity call dispatcher could take care about this trailing extra data, verify the signature and make the msg.signer available to the rest of the contract in some predefined variable together with the msg.sender.
I have one question:
what do we mean by generic approach? Do we assume the forward or backward form of it (or both)?

Author: Ethernian
Date: 2020-01-11T22:15:34.420Z

Philosophical:
To be honest, I think we are trying to work around EVM limitations that should be lifted not in this way but in some EVM HardFork Upgrade.
There is a damn old Account Abstraction proposal, that is aimed to solve all problems like this.
If there are still hard problems preventing implementation, probably a smaller upgrade separating the message signer and the gas spender could be possible?
Ethereum gave up the Bitcoin-level immutability for the ability to make breaking protocol upgrades for high speed development - and doesn’t use it. That’s bad!

Author: Amxx
Date: 2020-01-11T22:56:11.760Z

Ethernian:

There is a damn old Account Abstraction proposal, that is aimed to solve all problems like this.
If there are still hard problems preventing implementation, probably a smaller upgrade separating the message signer and the gas spender could be possible?


Thats a really good point. We might be trying to build a dirty ERC that badly solves something that an EIP could do much better.

Author: Amxx
Date: 2020-01-11T23:03:09.625Z

Well, this is really similar to what I do. I have an entry point that receives meta-transaction as struct, which then calls itself with the calldata included in the meta-tx AND appends the sender at the end of the calldata.
From other function you just run as usual, except that if the calls comes from yourself you overwrite the msg.sender with the 20 last bytes of the calldata. If calling yourself is something you do under normal operation then you just use a mirror to distinguish relayed calls from “normal” self calls.

Author: wighawag
Date: 2020-01-12T01:40:11.464Z

Hey @Amxx thanks for bringing the discussion here and focusing on collaboration.
I have actually proposed an EIP for native meta transaction a while ago but for some reason it there was not much attention to it
Have a look here: https://github.com/ethereum/EIPs/issues/1776
It is actualy already live in sandbox.game but we did not enabled our relayer yet.
It solves many of the intricacies of metattx while remaining flexible: it can be used per token or in a general processor.
I am focusing for the Hackathon on the later.
It solves the msg.sender thing in a very simple manner, the first parameter is ensures to be the metattx signer.this make it compatible with many erc that have from function (erc20, erc721, erc1155)
Once I find some time I ll have a look at what you did.
Really looking forward to the outcome of this!

Author: wighawag
Date: 2020-01-20T04:32:47.611Z

Hi all,
I made a new implementation of EIP-1776 for the hackathon and you can play with it on Gorli or Rinkeby) here : https://metatx.eth.link
it is also obviously accessible via metatx.eth but because metamask will try to resolve ENS name on the network it is connected to (and that I did not register the name on Rinkeby or Gorli) it will fails to resolve it unless you go first on the mainnet.
The implementation is a Singleton proxy contract that implement all the meta-tx intricacies, including relayer repayment and forward the call to the destination. It is compatible with EIP-1776 (which I modified slightly for some improvements).
As a result, the requirement for metatx recipient is just kept to a very minimum. They simply need to check msg.sender to be the address of the singleton. No much need for a base class, except maybe for modifiers.
You can find the code here : https://github.com/wighawag/singleton-1776-meta-transaction
@Amxx I had a look at your proposal, I like the fact that it explores another method of implementation, that of the recipient being the meta-tx processor. What you call, a “no-proxy” implementation.
I have thus found at least 4 dimensions on which different meta-tx implementation differentiate themselves.
A) Type of implementation
First of all, It seems we have thus so far the following type of meta-tx implementation


Account-contract Based (a la Gnosis Safe, etc…) where recipient do not need any modification but that require user to get a deployed account contract.

Singleton Proxy where the recipient simply need to check for the singleton address and where all the logic of metatx is implemented in the singleton. It can support charging with tokens and even provide token payments

Token Proxy where the recipient simply need to check for the token address and where all the logic of metatx is implemented in the token. This is the approach originally taken by @austingriffith in “Native Meta Transaction”. It is usually limited to be used for meta-tx to be paid in the specific token. Relayer would then need to trust each token for repayment.

No Proxy where the recipient is the meta-tx processor and where all the logic get implemented. While it can support relayer repayment, relayer would have to somehow trust each recipient implementation.

Create2 based?  I personally did not explore these much but this could be used to provide a mechanism by which user are still using EOA to sign metatx (same like account-contract based) but have an account-contract created on-demand (maybe when the first metatx is executed, in which case the relayer could be paying the cost in ether in exchange of some tokens).

Note that EIP-1776 is agnostic to the type of implementation.
B) Relayer refund
Another differentiation is the ability of relayer to get paid.
In my opinion, It is such an important feature for relayers that we should ensure it is at least possible to implement it on top, if not already present.
In that regard one thing that becomes important as soon as a relayer get paid, is that there is a mechanism to ensure the relayer cannot make the meta-tx fails. hence the need for txGas in EIP-1776.
Another important EIP that would help here is EIP-1930
C) Token Transfer / Approval
While relayer-refund can be on its own, I found that it is trivial to also add the ability for meta-transaction processors to support transfering tokens to recipient.
This is a very powerful feature as it remove the need to pre-approve recipient, if they already support meta-tx.
D) MetaTx Signer Verification
Finally, another differentation possible for non-account based metatx is how the signer is being picked up by the recipient.
In EIP-1776 it assumes that recipient can easily add a from field to their functions as this is already a common practise in many standard.
in @Amxx and GSN version, the signer is appended to the data of the call.
I would be happy to update EIP-1776 to use this method if that is objectively better. For now, I feel the “first param” is simpler and can fulfil the same purpose, While it can in some case, requires recipient contracts to add, otherwise unecessary, extra function, most EIP, like EIP-20, EIP-721 and EIP-1155, have already functions that take the from as first parameter.

Author: 3esmit
Date: 2020-01-20T06:20:59.981Z

I am aiming into an integrated solution for Proof-of-Stake Ethereum.
I’ve proposed a soft fork to enable miners (and in future stakers/validators) to be relayers (just like they do with regular transactions), see https://github.com/ethereum/EIPs/pull/2473
This changes can be done to geth/others, without a consensus change, and then smart contracts can then always forward gas payment to block.coinbase and stop having to deal with a separate ecosystem for relayers, instead the same gas market gets extended for other tokens.
For the use-case of EIP-2473 become more efficient, I proposed EIP-2474, which allows block.coinbase  to make calls, see. https://github.com/ethereum/EIPs/pull/2474
In regards of EIP-2473, it mentions EIP-1077, but we could support multiple standards if needed.
I’ve also updated, and is still WIP into a new EIP-1077 interface which encodes only gas payment stuff, leaving the rest to be evaluated by the wallet/account contract, and considering the gasBase to enable the refund of the gas payment to relayer.

Author: Amxx
Date: 2020-01-20T18:25:55.546Z

wighawag:

You can find the code here : GitHub - wighawag/singleton-1776-meta-transaction: A Singleton MetaTx Processor using EIP-1776 that support all ERC20 tokens


Your ERC712 domain does not include the chainId. I think this is really dangerous has it opens the door to replay between chains if contracts are deployed at the same address.

Author: Amxx
Date: 2020-01-20T18:30:51.831Z

wighawag:

No Proxy where the recipient is the meta-tx processor and where all the logic get implemented. While it can support relayer repayment, relayer would have to somehow trust each recipient implementation.


My idea with the no-proxy model is to separate the meta-transaction validation by the recipient form the relayer repayment. In that sens the recipient should not deal with relayer repayment. Relayer repayment is either perform by an additional on-chain layer (such as GSN) or left to off-chain accounting (including non decentralized payment in fiat).

Author: 3esmit
Date: 2020-01-20T18:40:29.909Z

Your ERC712 domain does not include the chainId. I think this is really dangerous has it opens the door to replay between chains if contracts are deployed at the same address.

This go even far deep. In case of a chain split, the chainID inside the domain separator wont work. See the discussion I opened at GnosisSafe: Add EIP-1344 chainid opcode to signed messages composition · Issue #170 · safe-global/safe-smart-account · GitHub

Author: Amxx
Date: 2020-01-20T22:14:50.030Z

It won’t work if the domain separator is only computed in the constructor, but it’s easy to add an unrestricted public function that recomputes it at any time using the value given by the chainId opcode. I’ve done that in a few contracts were I want to avoid recomputing the domain hash everytime.
function initialize(/* params */)
external onlyOwner()
{
	require(EIP712DOMAIN_SEPARATOR == bytes32(0), "already-configured");
	EIP712DOMAIN_SEPARATOR = _domain().hash();
	// extra stuff
}
function updateDomainSeparator()
external
{
	require(EIP712DOMAIN_SEPARATOR != bytes32(0), "not-configured");
	EIP712DOMAIN_SEPARATOR = _domain().hash();
}
function _chainId()
internal pure returns (uint256 id)
{
	assembly { id := chainid() }
}
function _domain()
internal view returns (IexecODBLibOrders_v4.EIP712Domain memory)
{
	return IexecODBLibOrders_v4.EIP712Domain({
		name:              "iExecODB",
		version:           "3.0-alpha",
		chainId:           _chainId(),
		verifyingContract: address(this)
	});
}

Author: 3esmit
Date: 2020-01-20T22:35:59.849Z

Yeah, I suggested that, if gnosis safe wants to use EIP712, they have to compute the domainhash every transaction…
The best would be to update EIP712, or use EIP191 with EIP1344 in the application data.

Author: wighawag
Date: 2020-01-21T13:44:59.702Z

Amxx:

Your ERC712 domain does not include the chainId. I think this is really dangerous has it opens the door to replay between chains if contracts are deployed at the same address.


I am aware of it  you can find my reasoning about the current chainId opcode in this forum (I proposed an alternative opcode that was safe under minority fork and did not require any caching but unfortunately got rejected, see EIP-1965) and I agree that chainId is important but require more complex handling that simply injecting in the constructor (or even the chainId opcode as it is  currently exposed) hence why I decided to not included it here.
But let’s not focus on that for the discussion here as this is just the domain separator. In that we can deal with that, once we agree on the rest 
Let’s discuss the important potentially incompatible difference between our perspective and figure out the best of each

Author: wighawag
Date: 2020-01-21T13:47:01.893Z

Amxx:

My idea with the no-proxy model is to separate the meta-transaction validation by the recipient form the relayer repayment. In that sens the recipient should not deal with relayer repayment. Relayer repayment is either perform by an additional on-chain layer (such as GSN) or left to off-chain accounting (including non decentralized payment in fiat).


This is not about no-proxy vs proxy. In both case it can be dealt with outside contract.
It is about B) and if a repaymemt is supported, the signer would always need to be in control, hence why I think it is important it is part of the message standard, and not yet another.
That is why one of the goal of EIP-1776 is to be implementation independent so wallet can still process different implementation

Author: Amxx
Date: 2020-01-21T14:14:10.828Z

wighawag:

It is about B) and if a repaymemt is supported, the signer would always need to be in control, hence why I think it is important it is part of the message standard, and not yet another.


This is assuming the message signer will be the repayer.
I believe the original idea with metatransactions was about separating the user and the transaction sender, by moving the gas cost in eth away from the user to the relayer. If you require the user to repay the relayer you are bringing back some of the original issue.
I believe that user, relayer, and repayer should be 3 separate entities. In some case 2 of those might be the same (user and repayer) but I think it would be great if as a project I can repay for some of my user meta-transactions while not being in charge of the relaying infrastructure myself.
My proposal is about allowing the receiver to process the user meta-transaction without any repayment support, and In front of that I would have any relaying mechanism, including some where there is a on-chain repayment mechanism.

Author: wighawag
Date: 2020-01-21T14:43:35.507Z

My proposal do not require the user to pay, it allows the user to pay.
The thing though that is important in all case is that if someone else than a relayer is going to pay, there need to be checks in place (txgas among them) that ensure the relayer can’t get the reward while not ensuring the metatx get submitted as intended

Author: wighawag
Date: 2020-01-21T14:47:45.172Z

As for having a repayer being different than the relayer this can be done by whatever relay system is in place.
This does not remove the need to ensure the signer is in total control of how its metatx get included.

Author: Amxx
Date: 2020-01-21T17:25:13.709Z

IMHO:

A meta-transaction should not be considered as executed (nonce increase, …) unless the included call succeded. There is either enough gas, and the meta-tx succeded or not enough and then it fails and can be replayed
If the meta-tx targets a contract that has try-catch behaviour, it’s up to this contract to check that the try has enough gas and revert otherwize.
The only personne that needs to protect itself against reverted transaction is the relayer. It wants to ensure the repayer pay regardless of the outcome.
It’s up to the relayer to say how much gas he wants the relayer to include in the transaction.

Therefore, I believe gas is an agreement between relayer and repayer and part of the relaying infrastructure. I believe it is not par of the generic meta-tx format.
If the relayer and repayer uses on-chain repayment, then they have to nest meta-tx and include gas settings in the body of the wrapping meta-tx

Author: wighawag
Date: 2020-01-21T19:22:44.318Z

A meta-transaction should not be considered as executed (nonce increase, …) unless the included call succeded. There is either enough gas, and the meta-tx succeded or not enough and then it fails and can be replayed

That’s a valid approach indeed and was what the first metatx implementation did.
I’ll then add that as another dimension where metatx implementation differs, let’s call it
E) meta tx failure responsibility
I am not sure if that is great option to give relayer full responsibility though as this means it harder for them to decide whether to submit the tx or not. They’ll basically be suffering from state changes that are potentially unrelated to their decision.
Imagine a trade tx, why should the relayer suffer from the trade failing because another tx came through first (maybe even in the same block)
In the case where txGas is included and the reward is given even if the metatx fails, the relayer has just to check the balance of the token and can make a more accurate prediction.
The relayer will still suffer in some case but this is less likely and would be more predictable.

The only personne that needs to protect itself against reverted transaction is the relayer. It wants to ensure the repayer pay regardless of the outcome.

Exactly

It’s up to the relayer to say how much gas he wants the relayer to include in the transaction.

Yes obviously, only the relayer will dictate how much gas it given in its own tx, and this is not a problem indeed if we assume that relayer takes all responsibility for meta tx failure. But if we consider (like normal tx) that user take responsibility of their actions, then we need to protect them from a relayer putting not enough gas, hence the need for ‘txGas’ in that case.
To me the only benefit for giving full responsibility to relayers is simplicity and this is indeed a valid reason but relayers’ protection from unpredictable outcome is in my opinion quite important

Author: 3esmit
Date: 2020-01-22T00:30:28.460Z

Why dont use EIP-1344 as application parameter of the signature? Its like in Ethereum then.

Author: 3esmit
Date: 2020-01-22T00:41:38.024Z

I see the problem you are trying to solve, your approach could work but it open the system to unknowns, as the relayer can decide too much on the parameters, and you are trying to make the incentives on the relayer to execute the transaction properly, giving an overhead on the decision making of relayer.



 Amxx:

A meta-transaction should not be considered as executed (nonce increase, …) unless the included call succeded. There is either enough gas, and the meta-tx succeded or not enough and then it fails and can be replayed


I disagree on this, because in ethereum when you dont provide enough gas, the transaction fail and the nonce still incrases, and a new signature is required. Why here it should be different?

If the meta-tx targets a contract that has try-catch behaviour, it’s up to this contract to check that the try has enough gas and revert otherwize.

Why it should care? It should do the agreed and executing the call with the provided gas limit, what happens inside does not matters. Also, there is no way to verify what outcome was intended.

The only personne that needs to protect itself against reverted transaction is the relayer. It wants to ensure the repayer pay regardless of the outcome.

I disagree, both parties should care only about their part of the transaction. The signer need to care how much the transaction they trying to execute cost (gasLimit) and how much they are willing to pay for each unit of gas used (gasPrice) in the offered token (gasToken). Meanwhile the Relayer should only provide enough gas to make the transaction execute + pay the gasToken.

Author: wighawag
Date: 2020-01-22T12:14:30.863Z

Just that I did not want to bother with proper chainId handling in the demo.

Author: wighawag
Date: 2020-01-22T12:17:50.812Z

3esmit:

I see the problem you are trying to solve, your approach could work but it open the system to unknowns, as the relayer can decide too much on the parameters, and you are trying to make the incentives on the relayer to execute the transaction properly, giving an overhead on the decision making of relayer.


To what are you referring to here ?

I disagree, both parties should care only about their part of the transaction. The signer need to care how much the transaction they trying to execute cost (gasLimit) and how much they are willing to pay for each unit of gas used (gasPrice) in the offered token (gasToken). Meanwhile the Relayer should only provide enough gas to make the transaction execute + pay the gasToken.

I agree too but when I replied “exactly” to the same text, I assumed that it was obvious that the signer will indeed take responsibility on the parameter it signs. The point was that given the signed message, it is the relayer that take the risk of the tx (not the metatx) failing.

Author: Amxx
Date: 2020-01-22T13:10:13.070Z

3esmit:

I disagree on this, because in ethereum when you dont provide enough gas, the transaction fail and the nonce still incrases, and a new signature is required. Why here it should be different?


When a eth transaction fails, this includes a cost to the sender (that protect the miners). The nonce gets increased because this behaviour should not be replayed (othewise a miner could include a failling transaction many times and drain your wallet). This is a protection for the “transaction payment” not being duplicated, I don’t thing it has anything to do with the “transaction call” not being duplicated (it reverts and it could be interresting to see it being repeated until it succeeds).
In (my vision of) a metatransaction, the sender doesn’t care about the payment. He just wants a transaction to successed. The economic of this transaction succeeding is a an agreement between the relayer and the repayer, which is to be implemented in the repaying layer at an app level, not into the meta-tx validation protocol. Again, I believe meta-transaction validation and meta-transaction relaying repayment are 2 distinct layers.
I’ve done an actual implementation that build gas repayment economic using my generic meta-transaction (that does not include gas). This can be used as proxy to reparate clearly relayer, repayer and user:
The repayment contract: GMTX/example/solidity/contracts/GasRepayer.sol at master · Amxx/GMTX · GitHub
Example of usage: GMTX/example/solidity/test/GasRepayer.js at master · Amxx/GMTX · GitHub

A metastraction only succeed if the call included does not revert
Repayment is handled by a separate application (powered by meta-transaction)
A repayment meta-transaction succeedes event if the nested call fails, assuming enough gas was provided, and can thus not be replayed
If the repayment meta-transaction did not include enough gas, if is considered a “succesfull faillure” and the included user meta-transaction isn’t consumed → you can try to replay it with more gas in a new repayment meta-transaction.

In this context, relayer only consider relaying metatransaction that target the relayAndRepay function of the GasRepayer contract. This can be done by checking the target and the first 4 bytes of the meta-transaction. If the sender has a sufficient balance, then it is guarantied to be reimbursed.
The repayer just takes any meta-transaction from any user, and just encapsulates it into a meta-transaction that meets this pattern.
→ Relayer is assured to get payed
→ Repayer pays any gas usage
→ Users transaction isn’t consumed unless the Repayer actually included enough gas.

Author: Amxx
Date: 2020-01-22T14:17:43.501Z

3esmit:

The signer need to care how much the transaction they trying to execute cost (gasLimit) and how much they are willing to pay for each unit of gas used (gasPrice) in the offered token (gasToken).


In the Web2 world, when you do an operation you are unlikelly to care about of even be aware of its processing cost. I believe it should be the same for meta-transaction. The end user who signs it doesn’t care.
The relayer does care about the relaying cost! Depending on the situation it’s either going to accept it as a lost, ask for repayment in fiat offchain, or ask for a repayment onchain. In that last case there should be a protocole, including signatures, that ensures relayer and repayer are on the same page. But again, unless the user actually the repayer, it should not care about gas. Only the repayer does. Thus, the repaying protocole shouldn’t be part of the meta-transaction signature/verification/replay-protection/ordering.

Author: Amxx
Date: 2020-01-22T18:50:07.621Z

After re-reading my code, I’ve partially change my mind. I believe you are right for the gasLimit of a meta-tx which should be set by the signer.
My mind didn’t change however regarding the gasPrice (cf my separation of relayer, repayer and user)
I updated my code consequently

Author: 3esmit
Date: 2020-01-23T02:01:31.394Z

Amxx:

In the Web2 world, when you do an operation you are unlikelly to care about of even be aware of its processing cost. I believe it should be the same for meta-transaction. The end user who signs it doesn’t care.


When I say that the signer have to care, it dont mean that any one here is guess gas limits… But that the user wallet (or a service) would do that calculation, and estimate the cost, which user only have to approve. A wallet could be automated to dont even ask for approval and do all in backend, but I wouldnt use something like that because I care about what Im signing as costs money.
I understand your concept, and technically I agree it would work, but I think that whats safer is to enforce the correct parameters from the beginning, not to allow an third party set then for me.
If it was not possible to calculate those parameters in the user wallet, I would agree with your vision, but as is possible to calculate it, then Ill do it.
The only possible advantage would be if I am signing without a blockchain signed (where the prediction is not possible), right now, in ethereum the wallet can only give a very high gasLimit that “will guarantee to work”.

Author: wighawag
Date: 2020-01-23T07:02:39.661Z

Amxx:

Repayment is handled by a separate application (powered by meta-transaction)


IMO it is better for the standard to allow the user to pay if desired instead of having yet another system for it. After all, this is not so much to add and having it, does not preclude using yet another system later if it turns ou to be inadequate.
I would also like to add than having token support allow for more than just paying for the gas. My solution actually also include token transfer in that it can approve the recipient, allowing recipient to receive token without prior approval, a current pain in web3 user experience.
In your system if the user wanted to be the repayer, which in my opinion is an obvious case, (as even if there were a third party repayer, it might want to charge the users tokens, maybe to implement some sort of rate-limit), it would have to make 2 meta-transaction, one inside the other.
By the way, your code  that specify the gas amount for the inner call is not enough. The gas amount specified is just a maximum value and does not error out if there is not enough gas to fulfil it. This also means this does not ensure the gas provided is that amount. So unless you do extra check like my implementation do, you run the risk of the relayer making the inner tx fails even if it was signed with the correct gas amount. If a repayer is involved, this means it can lose money while not fulfilling the signer message.
Another important aspect of gas consumption that will affect the repayer is that you also need to account for the extra gas require to process the meta-tx itlesf in order to be accurate. You do with a hardcoded value FLAT_GAS_USAGE
For that EIP-1776 propose the baseGas parameter that allow the system to remains  independent of opcode pricing. Relayer can simply reject meta-tx that do not provide enough baseGas to ensure they can compute the price of the meta-tx accurately.
By the way EIP-1776 focus on the message format, so that multiple implementation are possible. This means that if the refunding mechansim (gas price) is specified as part of the format, your solution could simply ignore it.
That’s why I believe at this stage we should focus on the message format so that we can experiment with multiple implementation in parallel and not block ourselves in one.
We still need to agree on some other thing though, the thing that will affect the receivers, like how the signer is identified (whether through data appended to the call or through reusing the first parameter of functions)…

Author: Ethernian
Date: 2020-01-23T10:14:51.948Z

@Amxx , @3esmit, @wighawag,
I have proposed msg.signer in the solidity-dev group and it looks like we could get good support there. @chriseth was quite positive about the proposal.
All in all it means we could get some Meta-Tx functionality bootstrapped in Solidity.
msg.signer is the 1st candidate, but probably we need more.
Could you, please, review @chriseth’s answer and his question in gitter? It is about how we see it implemented. As I understood him, we could (should?) progress quite fast here.

Author: chriseth
Date: 2020-01-23T10:49:00.213Z

Sorry, I fear you misunderstood my answer in gitter. By “keeping flexible” I meant I only want to add features to the language that are necessary and which do not include “arbitrary” decisions that might change later.
Is this feature something that can be done without the help of the compiler?

Author: 3esmit
Date: 2020-01-23T11:47:20.653Z

@Ethernian I already asked for this in this issue https://github.com/ethereum/solidity/issues/8160
Join there, lets make some noise xD

Author: Ethernian
Date: 2020-01-23T12:26:28.566Z

@chriseth,
I really beg your pardon, if I forced you to answer here to rewind my optimism. 
Thank you for clarifications.
There are different implementation of general Meta-Tx made by different people. A small discussion should be started to understand if the functionality can be implemented as a function.

Author: Amxx
Date: 2020-01-23T13:45:22.611Z

@3esmit, I aggre to the gas limit being in the metatransaction, and hidden by the wallet (see my code here)



 wighawag:

IMO it is better for the standard to allow the user to pay if desired instead of having yet another system for it. After all, this is not so much to add and having it, does not preclude using yet another system later if it turns ou to be inadequate.


I’m worried that if this is part of the standard, some smartcontract that do not have access to user’s assets would have difficulties implementing the required feature.

Author: Amxx
Date: 2020-01-23T13:54:48.297Z

Usually, in solidity, msg.xxx or tx.xxx are relevant to stuff that is accessible through evm opcodes / in the evm stack. I could make it work … but in the end the best solution would be to have meta-tx nativelly supported by EVM. Similarly to how EIP155 modified the transaction siganture to account for additional data (chainId) we could have a new EIP that propose some signature on top of classic transactions:

If the transaction has the EIP155 format, process it as usual
If the transaction has an additional (relaying) signature on top (EIPxxx format), use the additional signature to retreive the relayer address.

We could then have
→ msg.sender = address of the one paying the gas
→ msg.signer = address of the signer (equal to msg.sender for EIP155, equal to the inner signature for EIPxxx)
or
→ msg.sender = address of the the inner transaction
→ msg.relayer = address of the one paying the gas (different in EIPxxx, equal to msg.sender in EIP155)

Author: wighawag
Date: 2020-01-23T19:46:29.930Z

Amxx:

I’m worried that if this is part of the standard, some smartcontract that do not have access to user’s assets would have difficulties implementing the required feature.


Oh, but in my solution this only need to be implemented by the singleton meta tx processor. receiver do not need to deal with any of that. They just need to trust the singleton contract to do its job.

Author: wighawag
Date: 2020-01-23T19:48:37.308Z

That would be great to have something like that to reduce the code complexity of supporting meta-tx.
I would not call it msg.signer though as this can only be trusted to be the signer if the  msg.sender is a trusted contract that verify the signature.
But having a msg.tailData or something could be useful, though it is not that big improvement I guess.

Author: Ethernian
Date: 2020-01-23T23:03:25.675Z

wighawag:

I would not call it msg.signer though as this can only be trusted to be the signer if the msg.sender is a trusted contract that verify the signature.


unsure we understand each other.
I proposed, that a solidity bootstrap code should check if there is a trailing signature signing the msg.data, then set the msg.sender accordingly and then and the call target function as usual. Who is the msg.sender is not important for this.
How it corresponds to trusted contract you mentioned?

Author: Ethernian
Date: 2020-01-23T23:18:14.423Z

Amxx:

or
→ msg.sender = address of the the inner transaction
→ msg.relayer = address of the one paying the gas (different in EIPxxx, equal to msg.sender in EIP155)


introduced on general solidity level, this would be a breaking change, because it changes the semantic of msg.sender.
In contrast, msg.signer would introduce a new, non-conflicting semantic.
Anyone, who would like to accept both Meta-Tx and Regular-Tx would check msg.sender.
It must be explicit developer’s decision.

Author: wighawag
Date: 2020-01-24T04:45:20.492Z

Oh, sorry did not get the part of the signature.
But in that case, solidity would have to do much more, because it need to reconstruct the sign message from the data passed in as a parameters. Plus as we want to support contract-account via EIP-1271 it needs to support that too.

Author: Amxx
Date: 2020-01-24T17:20:25.770Z

Ethernian:

introduced on general solidity level, this would be a breaking change, because it changes the semantic of msg.sender .


That depends on how the contract is built. Some use msg.sender to say “the personne who paid the gas and did the call”, but most contract use msg.sender to mean “the person that signed”.
If “msg.sender” is the “meta-transaction proxy” and the user is in msg.signer, then already deployed contracts (like ERC20) would not benefit from these meta-transactions.
Also, that is what the GSN tools do: _msgSender() replaces msg.sender and returns the meta-tx signer when the call is a GSN call.

Author: Ethernian
Date: 2020-01-25T14:35:22.031Z

Amxx:

That depends on how the contract is built. Some use msg.sender to say “the personne who paid the gas and did the call”, but most contract use msg.sender to mean “the person that signed”.


This is exactly the breaking change. Currently, the semantic of msg.sender is both - person who paid the gas and signed the tx and independent from “how the contract is built”.
This will create ambiguities for someone who audit the contract - he can be mislead about the conditions including msg.sender. May be differences will not be that huge, but consequences must be understood first before we can claim it is harmless.

Author: Ethernian
Date: 2020-01-25T14:40:57.743Z

Amxx:

If “msg.sender” is the “meta-transaction proxy” and the user is in msg.signer , then already deployed contracts (like ERC20) would not benefit from these meta-transactions.


How it is possible to change an implemnetation of msg.sender for already deployed contracts?



 Amxx:

Also, that is what the GSN tools do: _msgSender() replaces msg.sender and returns the meta-tx signer when the call is a GSN call.


Yes, I understand you. Nevertheless, I would not mix up different implementations in the same msg.sender just because of the desired immutability of the code and its semantic.

Author: Amxx
Date: 2020-01-25T16:20:39.105Z

Then onchain account based meta-transaction (like argent provides) are the only way to combine existing contracts (think of all the ERC20 tokens) and meta-transactions.
Because that is what people will want

Author: wighawag
Date: 2020-04-07T10:43:43.407Z

Hey all, Just published a new EIP : EIP-2585 to solve the msg.sender problem by using a minmal forwarder.
The forwarder will not do any gas repayment or anything extra but has enough capabilities to let extension to be built.
In the demo : https://metatx.eth.link I actually built EIP-1776 on top
So while EIP-1776 support gas repayment, expiry time, etc… EIP-2585 only focus on signature and replay protection.
If we could agree on that minimal forwarder, more complex and capabale solutions like GSN, EIP-1776 or other could be built without needing receiver contract to be changed.
Would love to get your feedback
Thanks