EIP-4804: Web3 URL to EVM Call Message Translation

A web3:// sandbox is now available, to play and experiment with web3:// URLs!
Temporary URL : https://web3protocol-sandbox.nand.fr/

Also, 2 new ERCs (pending PR) for the ERC-6944 resource request resolve mode :

  • ERC-7617: Add chunk support in ERC-6944 resource request mode: a response can be made of several methods calls (useful with serving large content).
  • ERC-7618: Add Content-encoding handling in ERC-6944 resource request mode : Serving compressed data can now be done.

These 2 features has been added to the web3protocol-js and web3protocol-go libs, and indirectly to web3curl, w3link.io HTTPS gateway and EVM Browser.

1 Like

This is really cool!

With the aim of making creation and edition of a web3:// website easily accessible, I am working on on-chain website NFTs, named OCWebsites : you mint an OCWebsite, then you can access to a graphical interface to upload/manage/delete files, create versions, mark one version live, lock versions, globally lock, manage plugins.

At its core, the “NFT” part is just for handling ownership; and the base OCWebsite is a system handling differents versions, and different plugins. Each version can configure its plugins differently, and is totally independant : the purpose is to handle deployment with preprod/prod, but also to have an historical archive.
Then is packaged by default as plugin :

  • A static frontend plugin: Upload/manage/delete static files. The main one.
  • An admin backend, provided by ocweb.eth and served in /admin, which will make the whole website configurable. Anyone could make another admin backend.
  • A variables injector, served in /variables.json. Useful to boostrap the static frontend with environnment variables.
  • A proxy: Redirect any local path to a remote website path. Probably won’t be included by default.
  • A welcome page, served on /, to welcome you for the first time

I have posted a work in progress on Holesky at web3://0x7216Acab8bcF349C01D9E8f3212C7159eE794629:17000/ , you can try now! The /admin plugin is not there yet, but by using the minter website, you can access to this graphical interface.

The minter website (web3://0x7216Acab8bcF349C01D9E8f3212C7159eE794629:17000/) is also an OCWebsite :

I think I should have it ready for early August!

2 Likes

@qizhou Regarding the ongoing hacked frontend situation, what do you think would be the best state-of-the-art way to certify on-chain websites / on-chain website versions ?

My naive take is, let’s have authorities (like HTTPS certificate authorities) post a public key on-chain (which algo?), then let’s have them review and sign the fact that 1/ the website / website version is immutable (source code review), and 2/ they have taken steps to verify that the application submitter is who they claim they are; then the on-chain website expose the signature via a to-be-decided interface.

Then the web3:// browser comes with 0 embedded certificate authorities (and maybe later with some), and the user can add/remove certificate authorities he trust.

Just as a demonstration purpose, we could hack something quickly, make it work with EVM browser, in a “test” mode, then we can show it, and refine it;
I’m sure after these frontend hacks, people will notice and it will support the case of web3://

Another subject : Regarding the fragment part of URLs (://host/query?args#fragment), we have not specified anything for web3://.
In http, they are not forwarded to the server, and used for anchoring (scrolling to a place in the page), but also for setting state (e.g. some single-page apps use the fragment part as the page, http://xxx/#/mypage)

  • In resource mode, it sounds logical to not forward it to the “server” as well (I need to fix that on the implementations)
  • In manual mode: Same thing.
  • In auto mode: even though it makes no sense to support fragment, I think we should support it because 1/ this is what we expect from URLs, and it would be confusing to not support it on a single case, and 2/ ok extreme case, but we could query an html page which would use the fragment.

So I would go forward adding to erc-6860 the fact that we have the same behavior than HTTP for fragment. (and if we want to send the # char to the server, we url encode it, like HTTP). Any objections?

@qizhou I have a suggestion, although EIP6860 is currently used as a view function, it would be nice to provide some standard execution parameters, such as value, gaslimit, and especially blocknumber(the second argument to eth_call), for easy access to short-term history data.

Great suggestion! I agree that we should add more eth_call parameters in the standard. However, this means that we have to change the semantics of manual mode a bit - in manual mode, all paths and queries will be passed to the contract. This means that we need to have some exceptions to the queries.

One example I am thinking about is introducing a special query prefixed by _, which specifies a parameter for eth_call. E.g.,

web3://usdc.eth/balanceOf/vitalik.eth?returns=(uint256)&_blockNumber=10000

Note that some RPC clients may not support historical state eth_call so web3:// with historical block number may return error.

1 Like

I cannot get the point. To certify web3://, we only need to prove that the content is from the latest EVM (e.g., light client from Helios or succient proof after verklized state). Why we need additional authorities?

Good point! Fragments should be supported as part of goal to be compatible with HTTP.

In addition to EVM verification, I was thinking, for sensitive frontends, for an optional mechanism of external “auditors” which would be required to review and sign any new website change, to be displayed at the browser level. But yeah I am probably over-thinking it, I drop this!

_blockNumber is a good option, but also _value and _from to do some mock calls, I’ll write a pr if I can

I think we can follow the same governance practice for the smart contract: a governance contract will be the admin of the NFT, and only when the token votes exceed a certain threshold can they upgrade the website to a new version.

With the current parsing, many contracts do not have a function that sets the resolvemode. But the call function in these contracts contains some indeterminate long parameters, such as address,uint,tuple, etc. I think we can add some arg to handle these parameters.

What is the value of allowing different resolveMode for existing contracts? Could you please give some examples?

Actually it should be adding more autoparameter types, I was wrong, I will try to change the gateway and add more autoparameter types.

1 Like

Hi @BoxChen

Thanks for your PR on web3protocol-go at Add array and tuple params support by nishuzumi · Pull Request #1 · web3-protocol/web3protocol-go · GitHub , I can see there is quite some work.
You are looking at adding array/tuple as input to auto mode, that’s a good idea!
I think we should review the specification first here:

  • For tuple arg, I see your example /functionName/(bool,uint256,bool,uint256[])!(true,123,false,[456,789]) : reusing the returns= syntax is a good idea. Question for the values: how to handle the ,, (, ), [, ] special chars in string values? For example, let’s say I have /functionName/(string,uint)!... and I want to pass the hello "a,") string as the first parameter, /functionName/(string,uint)!(hello "a,"),1234) won’t work. I believe the solution is : we add optional double-quotes to the string value (with the support of quote escaping \"), so that here we have /functionName/(string,uint)!("hello \"a,\")",1234). Any other idea?

  • For array arg, you propose /functionName/uint64[]![1,3,5]: sound good to me. We should also support multidimensional arrays, such as /functionName/uint64[2][2]![[1,2],[3,4]]. And with the above suggestion of optional double quotes for string values, we would have for example /functionName/string[]![1,abcd,"bla[]"], which will send the array of 3 strings 1, abcd and bla[] to the smart contract.

And of course we should support recursion, with e.g. array of structs such as /funcName/(uint,bool)[]![(1,false),(2,false)], complex mix such as /funcName/((uint,(bool,bool),string[])[],bool)!([(5,(true,true),[boo,baa]),(2,(false,true),[aa,")"])],true), …

Any input/ideas on this rough specification? (If you want, I can do the whole writing on this on the ERC, or you can propose a PR, as you want.)

Thanks for working on this, it is a non-trivial item.

Hi @nand
Thank you very much for your suggestions.
Regarding the first question, yes, my test case doesn’t seem to be as comprehensive as it should be, regarding this case, a stack join for double quotes could be added to the splitTupleElement function. Also you reminded me that all cases of transliteration should be filtered here, including ( [ etc.

The case for multi-dimensional arrays will be relatively complex, but it should be possible to use a regular way to loop through the matches, and the processing here to not complicated.

In the meantime, recursive support should theoretically be supported directly, I’ll try to test this with the test suite.

Thank you very much for the suggested changes, which add a lot of things I’ve overlooked.

In the meantime I I suggest that web3protocal-go does a formatting session using gofmt, at the moment there is no standard formatting procedure for we b3protocal-go’s code, including no use of tab indentation and no omission of the post line semicolon, if that’s possible I can submit a pr to format everything.

1 Like

Hello,

I am currently encountering some new issues. I’m not sure what standard is being used for string parsing. From what we can see, it seems that strings can be parsed without adding double quotes. If this is the case, then the termination symbols should be commas (,), closing parentheses ), and closing square brackets ], correct?

Hi @BoxChen

Sure, thanks, yes please do a PR to format all the code – I admit I never used gofmt there.

Well, right now with the existing format /funcName/string!<value>, <value> do not need any double quotes because there are no special characters that can break the parsing of the URL (besides /, ? and #, which are global delimiters, and for which we expect them to be URI-percent-encoded (%2F, %3F and %23)).

The new feature we are discussing is adding 5 new delimiters : [, ], (, ), ,.
Let’s say we have /funcName/string[2]![<value>,<value2>].
If I want to send the strings 1,2,3 and [ to the smart contract:

  • Without double quote , it will be : /funcName/string[2]![1,2,3,[] : it will break parsing.
  • With double quote, it will be : /funcName/string[2]!["1,2,3","["] : it can be parsed.

Do you agree?

Thanks for working on this :slight_smile:

HI @nand

Using double quotes is indeed a good approach. However, this special implementation might lead to inconsistent parsing across different string contexts. For example, string!1234, string![“1234”,“1234”], (“1234”,[“344”]). The inconsistency might only occur in arrays and tuples.

There’s another approach: requiring all string content to be URI-percent-encoded. According to the wiki, characters like [, ], (, ), and , can all be percent-encoded. This second method has a lower cost and provides a more uniform standard.