Open kamescg opened 4 years ago
Very happy to see these methods evolving. Even just getting more prior art in the ecosystem for this kind of thing is great.
Very curious at which points these different feature-specific message types can start to standardize around common formats. Happy to watch the gradual evolution, but it's no secret that I think these should and will tend towards becoming a generalized object capability framework.
I can mostly only commit to times that are in the evening PST or on Fridays during the PST daytime.
Very interested in discussing these things as well. Thanks for starting the thread. Things that we think could be interesting:
approve
the transfer (replaced by permit
) and then another transaction to actually purchase
the item (which will withdraw my DAI). Ideally, I'd want that to be in a single transaction/signed message so that I only have 1 step to purchase something with DAI.permit and pay gas
. Ideally, a mechanism where someone can sign a permit
a transfer for a given recipient, AND the ability to let a 3rd party execute that and take some DAI to cover the gas costs: X permits Y to get some of their DAI and lets Z actually perform the transaction by letting Z take some DAI to cover gas.We might want to start a multi-thesis kialo poll to find what our top priority target feature/requirements for a next iteration/standard might be. I like all those features, and I even have ways I'd like to extend them long term, and so the hardest decision (for me? for the community?) tends to be "what's the next valuable iteration?"
A couple ways I can see for extending @julien51's ideas in a more general direction:
permitAndRun
, any contract could implement a processBatch()
method, which could take a series of signed messages, each of which is routed to its appropriate permit()
(sig-verifying, gasless) equivalent. (Very actor-model messaging)permit
to pay gas
, given that there are already lots of use cases that require serial, atomic transactions to be executed, it might be nice to extend the processBatch()
method to support some basic boolean logic. AND[messageArray]
would require all messages succeed otherwise they would all be reverted. OR[messageArray]
could run them in series, and stop on the first success.If we allow Message
to refer to any method on the contract being called, then a metatx-relayer could be repaid in any state change that contract can offer via the message sender, in the form of an AND clause where one message is a payment to the relayer.
A quick shot at defining Message
, I have very low solidity chops, consider this pseudo-code:
struct InvokingMessage {
4byte method;
bytes[] arguments;
InvocationSignature signature;
}
struct InvocationSignature {
uint8 v;
bytes32 r;
bytes32 s;
}
If you wanted to embed these in an AND
or OR
message (which itself could be merely a type of method to call), you would not sign the invocations, but the and/or
, to avoid unwrapping attacks.
Yes! I love these topics :)
Rather than batch-send AND permitAndRun, any contract could implement a processBatch() method, which could take a series of signed messages, each of which is routed to its appropriate permit() (sig-verifying, gasless) equivalent. (Very actor-model messaging)
I want to break this down a little bit.
any contract could implement a processBatch() method
Are you imagining a Proxy
contract i.e. GnoisSafe
that implements the processBatch()
interface and could be a message signing hub for individuals or entire decentralized application user base? Does a unique benefit exist in implementing a smart wallet (similar to instadapp) to automate protocol coordination at a contract layer, as opposed to the user experience/interface level?
which could take a series of signed messages
Is there an agreed upon standard for encoding signed messages that can be interpreted and ran by a smart contract? It sounds like you are describing a "mini on-chain interpreter" that uses encoded/minified signed messages to handle smart contract logic at run-time?
I would like to see this approach more readily available in the ecosystem, because when we start to use signed messages as smart contract logic gateways, it opens interesting opportunities (I think) for possibly introducing verifiable credentials as another method for adding real world state to on-chain logic i.e. another oracle method. If messaging signing Proxies can also get authority from an on-chain PKI protocol (with @SilentCicero weighted signatures experiment too), this in short grants users permissions to specific smart contracts functionality via delegated signed messages, via on-chain trust anchors
.
This could unlocks token mechanics (and other permissions) at an organizational level and NOT just the user key or on-chain wallet. Maybe?
We recently experimented with a very simple condensing method. Condensing signatures and batch processing them. @joeb000 can speak more to it, since he implemented the contracts. However, it is very specific to our forked ERC20, which we call ERC20Certificates that basically allows us to issue IOU's and have the user redeem the token, without us transferring and incurring gas costs. The approach wouldn't apply to existing tokens and would need to be backported in a "wrapper" smart contract, which we call lockbox
.
https://github.com/rapid-eth/erc20-certificates/blob/master/contracts/ERC20Certificate.sol#L94
Rather than bind permit to pay gas, given that there are already lots of use cases that require serial, atomic transactions to be executed, it might be nice to extend the processBatch() method to support some basic boolean logic. AND[messageArray] would require all messages succeed otherwise they would all be reverted. OR[messageArray] could run them in series, and stop on the first success.
That makes a ton of sense! And I think we're starting to see this hardened business requirement around DeFi applications that need those predictable transactions for coordinating across the many new composable finance protocols.
succeed otherwise they would all be reverted
Can we discuss a little further on how we want to implement this? I know serial, atomic transactions can be executed, but I think that's my least familiarity in this current scope, especially when doing it via signed messages and not relying on the EVM to coordinate tx stuff more natively. Is there something we can utilize now? Or do we need to fork and abstract an existing smart contract?
Also I wan to add @SilentCicero to the conversation, because he recently was explaining to me how he wants to do a SmartWallet
with weighted
signature inputs, using a module system, and it could be relevant to this conversation.
A little bit on a side topic as per the direction is currently going in- the same way there is a standard for MetaData for TokenURI's, we should create a standard for the data about counterfactual tokens. IE when I create a counterfactual token series and store the root on-chain, I should then also be able to store the JSON object that represents the tree of counterfactual tokens so that services like OpenSea can index counterfactual tokens the same as "minted" tokens, with the exception of course they need to be minted to become tradable.
@crazyrabbitltc interesting. I would have assumed a standard of some sort was already underway.
Counter factual assets make a lot of sense for user experience I think too. I like how Pepo is incorporating optimistic UI in there app when it comes to tokens. Worth checking out.
I think if we use counterfactual assets in a smart way we can include more optimistic interface improvements too. Let's experiment :)
Dan is right though we need to take a poll of some sort so we can identify the multiple optimizations that we are all talking about in this thread.
There is meta transactions, counterfactual assets, signature authentication methods and perhaps whatever else we come up with. What do you guys think? Does it make sense to discuss all of those topics on this ticket or should we make new tickets or do we create a keybase chat group to discuss these more in real time?
Are you imagining a Proxy contract i.e. GnoisSafe that implements the processBatch() interface and could be a message signing hub for individuals or entire decentralized application user base?
No, contract accounts like Gnosis safe already have support for batched transactions, and it results in improved gas performance, among achieving batched atomicity, and probably other benefits. In the spirit of permit()
, I was instead exploring protocols that could be added to smart contracts (like tokens) meant to store and manage "shared" state.
Like I said in tweet with you, add metaTx to contract accounts, and those users can use metaTx on all contracts. Add metaTx to contracts, and all their users can use metaTx. There are benefits to both cases.
Is there an agreed upon standard for encoding signed messages that can be interpreted and ran by a smart contract? It sounds like you are describing a "mini on-chain interpreter" that uses encoded/minified signed messages to handle smart contract logic at run-time?
I don't believe there currently is a standard for signed messages intended to be run by a smart contract, and this would be a wonderful target for anyone involved in MetaTransactions, because once there is one, wallets could interpret the signing of these messages with the same interpretation they render transactions with.
Combined with batching, and several messages could be authorized with a single signature, which could reduce gas costs, and be used to compose metaTx paybacks quite naturally (you can include a gas-paying message in the queue).
This could unlocks token mechanics (and other permissions) at an organizational level and NOT just the user key or on-chain wallet. Maybe?
I strongly believe delegation is a pattern that works at basically every scale, from the individual, to the organization, all the way down to the nanoprocess.
The approach wouldn't apply to existing tokens and would need to be backported in a "wrapper" smart contract, which we call lockbox.
Same for permit()
. I think it's good for us to think beyond erc-20 here. We don't need to break those, but how can we take off-chain messages, and propose a standard for new tokens?
Also, I don't think you need to "wrap"/lock a token to allow its delegation: You could use the allowance()
method instead to create on-chain delegation to an off-chain delegation contract.
Can we discuss a little further on how we want to implement this? I know serial, atomic transactions can be executed, but I think that's my least familiarity in this current scope, especially when doing it via signed messages and not relying on the EVM to coordinate tx stuff more natively. Is there something we can utilize now?
Since any solidity can call revert
, I think it would be fairly simple to run through an array of messages in a loop, checking that each one succeeds, and if any one fails, to call revert()
. But I'm not a solidity expert. I would want to get input from someone who deals with EVM more.
There is meta transactions, counterfactual assets, signature authentication methods and perhaps whatever else we come up with. What do you guys think? Does it make sense to discuss all of those topics on this ticket or should we make new tickets or do we create a keybase chat group to discuss these more in real time?
I think we've already begun to stretch what a single-threaded github issue can gracefully manage, there are a lot of incrementally deliverable specs of value here (like a standard signed invocation message standard) that could be built into the other things we've discussed.
Keybase teams seem pretty neat because you can make sub-teams, and sub-teams of sub-teams, so it could grow to suit our needs. I would also think ethereum-magicians
could be a good place for this, might catch some otherwise-absent eyes.
No, contract accounts like Gnosis safe already have support for batched transactions, and it results in improved gas performance, among achieving batched atomicity, and probably other benefits. In the spirit of permit(), I was instead exploring protocols that could be added to smart contracts (like tokens) meant to store and manage "shared" state.
Sorry. I should have been more explicit. Sooo many ideas rattling around :)
To clarify I totally agree with you, that a "exploring protocols that could be added to smart contracts " should be a top priority. That being said, I think for me at-least it's interesting to think about how to use existing audited contracts to get an MVP for some optimizations today.
I know GnosisSafe
has batch signing, but what I think is also useful in this situation is the smart contract module
strategy for a couple of reasons. I see a world where a decentralized application might set up a DAppHUB thing via a GnosisSafe
. And when we finalize our message signing standard they might want to install a module into their dapp authentication hubb
that will help them more easily use whatever we dream up here in these threads.
Like @julien51 pointed out certain token distribution systems can be optimized due to the shared contract factory. Maybe I'm wrong but a SmartContract interface that utilizes the existing multi-sig features +++ these new signatures standard in a module, seems like the most optimal way to help achieve that prototype. Happy to be proven wrong, because I know there are probably sooo many ways to skin that cat? Perhaps we need to separate technical and product level discussions, for clarity sake, but ensure we think of both, so we move into the future, but also help others upgrade existing systems.
I really want Nick to hop in here, because he was explaining something close to what I think we're grasping at here, which was using weighted signatures to "brute force" a `multi-sig' module system.
I don't believe there currently is a standard for signed messages intended to be run by a smart contract, and this would be a wonderful target for anyone involved in MetaTransactions, because once there is one, wallets could interpret the signing of these messages with the same interpretation they render transactions with.
This should definitely be a bigger ecosystem conversation. I like your idea of Ethereum Magicians.
Since any solidity can call revert, I think it would be fairly simple to run through an array of messages in a loop, checking that each one succeeds, and if any one fails, to call revert(). But I'm not a solidity expert. I would want to get input from someone who deals with EVM more.
Again I agree with you that atomic transactions should be first priority 😊 In addition though I would also like to see procedural approach too. Where transactions can be coordinated across multiple blocks and... this is where my head starts to spin... transactions in ETH 2.0 in multiple shards 🤯🤯🤯
I think that optimization will be interesting for DeFi protocols that need atomic swaps, but ALSO wan't procedural contracts for better user experience with smart wallets.
Have to go hop on train to NY, but will continue to think about next steps.
I think Keybase and Ethereum Magicians sounds like the way to go. Should we just pull trigger on those?
I think is also useful in this situation is the smart contract module strategy for a couple of reasons. I see a world where a decentralized application might set up a DAppHUB thing via a GnosisSafe. And when we finalize our message signing standard they might want to install a module into their dapp authentication hubb that will help them more easily use whatever we dream up here in these threads.
I think that's an interesting idea, and it might be worth breaking the whole gnosis-safe module system into an extensibility pattern that can be added to any contract, so that modules like this can be added to them.
It's worth highlighting that this kind of extensibility requires explicit governance of that contract, so I'm sure it won't appeal to all contract authors, but for groups that have a well-defined upgrade path already, I don't see why they wouldn't, and so packaging any of these proposals as a module
could be a neat way of letting anyone (contract account or more public contract) to benefit from the same code! Cool!
this is where my head starts to spin... transactions in ETH 2.0 in multiple shards 🤯🤯🤯
I think my view of multi-shard atomicity found clarity in this talk, which basically suggests for atomicity you need the operation to take place in a single process, and you can achieve this effect by moving transfer rights from multiple shards/chains into a single permitted environment which then performs the atomic interaction.
For the sake of simplicity, I think we can constrain the batch processing to interactions that are atomic within the current synchronous context.
The only thing holding me back on the keybase team is a catchy name. "Token user experience working group" is a mouthful, and a bit more specific than I'm thinking ;)... Not a huge rush, though. Happy to stew on that before doing it.
A proposed bounty for the upcoming Gitcoin hackathon: https://medium.com/@danfinlay/announcing-a-the-generalized-metatransaction-contest-abd4f321470b
(Draft, soliciting feedback)
We're making a bounty of this in Gitcoin's virtual hackathon starting tomorrow morning: https://github.com/MetaMask/Hackathons/issues/2
@danfinlay That's awesome! I have let my team know. We definitely want to contribute to this effort and will start discussing immediately ways we can help bring this to life.
Thanks for this initiative @danfinlay Excited to be contributing towards this generalized standard for meta transactions.
@KamesCG Hey! Wanted to add to your list of resources a free course on Meta-Transactions from Academy with help from Austin Griffith, Alex van de Sande, OpenZeppelin and Simona Pop:
Wrote this last week https://medium.com/bloxis/generalised-ethereum-meta-transactions-our-take-cb9f027866e9 - just want to be a part of the conversation and build something great. Is the group already having meetings??
Token User Experience Working Group
Objective: Optimize user experience for ERC20 and ERC721.
User experience includes minimal transactions/signing and also lower gas costs.
Meeting Schedule
To be determined.
Overview
Transferring tokens from accounts (funded and unfunded) should be easier for all users.
The new
permit
function included inSAI
is a great demonstration of the added benefit of using signatures, in addition to transaction to unlock smart contract functionality. Minimizing user friction.In addition to the current upgrade in the DAI contract we can also backport that functionality to existing ERC20 contracts. A number of solutions can be proposed and utilized. It would be great to define and prototype a few really good working examples.
@joeb000 has been experimenting with similar signing token transfer setups.
https://github.com/rapid-eth/erc20-lockbox
Meta Transactions
Ref1: https://twitter.com/austingriffith/status/1196470765350113281 Ref2: https://twitter.com/UnlockProtocol/status/1196886794094219265 Ref3: https://twitter.com/KamesCG/status/1194853820326653952
Merkle Trees
Ref1: https://twitter.com/DennisonBertram/status/1196898372365488128