As of today, I don’t think this proposal makes sense to me, but I have some questions as to my understanding.
I think the only way to add human-readable transactions will be to:
- Decode the calldata (as nested and far down as possible)
- Have a local AI/LLM transcribe the calldata to the human operator
At this time, I think embedding such a description directly into the application is:
- Redundant
- Because it is redundant, it is needlessly gas-inefficient
- Potentially even misleading
Redundant and needlessly gas-inefficient
It is redundant because the calldata already has all the information required, which means a user would essentially be signing the same thing twice (basically in 2 different “languages” one being the “calldata language” and another being the “human language”). It is potentially misleading because language is constantly evolving and often very confusing.
Potentially misleading
Let’s say I want to do the following:
- Approve my ERC20 token to be deposited into Aave with the
approvefunction - Deposit my ERC20 into Aave using the
supplyfunction - Using a batch transaction with my Safe{Wallet} smart contract wallet
Typically, this would require an EIP-712 message to a user’s wallet for signing. How would you suggest this works? I’ll lay out what I think it looks like based on your outline of the technique here: (Please correct me if I’m wrong here)
UI queries the application’s canonical decoder and populates the description field
Is the application’s canonical decoder the smart contract? So would the Safe{Wallet} contract need a new function called “decoder”, which would do… what exactly? Would every smart contract need to decode calldata → a string? This seems like a MASSIVE amount of gas.
Then, since the Safe{Wallet} is just part of the transaction, it would then need to call the description function of the Aave contract, assuming one such exists, otherwise it would fail? And by convention, we’d have to tell users that they should not interact with any contract that has not correctly implemented this?
Then, on the topic of language, for the Aave contract, let’s say the calldata is decoded to:
this transaction will supply USDC to the Aave contract to gain yield on behalf of you
One could argue this is not specific enough, so we may need to change this to:
this transaction will supply the USDC token at address XXX to the Aave contract at address YY to gain ZZ yield on behalf of you at address AAA
But even this is misleading… What if you get front run and the interest is different? Would it then need to be:
this transaction will supply the USDC token at address XXX to the Aave smart contract at address YY to gain ZZ yield on behalf of you at address AAA, unless you get front run in which case you will get BBB interest...
And then, there are many cases where language evolves, and maybe in 10 years we have changed the name smart contract to mean something else, does someone need to upgrade the contract because of this?
And this is just the Aave contract, this isn’t even including the description from the Safe{Wallet} contract. I expect these “human-readable” descriptions people need to sign would turn into massive apple iOS terms of service that people ignore and sign - and we are back to the original problem of people not verifying what they are signing.
If the intent is to hash the description for people to sign to save gas, then yes, it wouldn’t be as gas horrendous as I thought, but it would still cost extra gas (as the OP pointed out), but without the security guarantees intended.
More thoughts
I think the intent of this is to enshrine a human-readable description into the smart contracts. I feel like what might be nicer, would be to have external solidity functions return a string description for all functions, but then we are back to the gas issue, which we could probably mitigate by pushing developers to make these concise, and then have some supporting documentation to explain what they mean? But it feels like we are probably still being quite redundant here…
Instead
Going through @MicahZoltu’s github I came across theintercepter, which looks more appropriate to what I think we should do.
Calldata already has all the information we need to understand the transaction. It might be more interesting to upload a documentation contract to the blockchain with just straight text than an LLM can read and use to help explain calldata. Then, all contracts can have a getDocs function which returns the documentation. Or, we could do something similar to an NFT like getDocsURI, which returns a URI to the robot-enabled documentation.
Thinking through this out loud, I sort of like this idea more. From a security perspective, this has issues - “what if the LLM does something stupid?” but I think if we are already nervous about people not being able to understand decoded calldata, then I think it’s reasonable to assume we could standardize an LLM to be able to decipher the data, and those who are extra security conscious can still verify the data themselves…