Many thanks for the information. The assignment information is very helpful. I just send a request for assigning web3:// schema of URI for EIP-4804 to iana and wait for their response I will update the info if I get any response.
Thanks for the comment. EIP-4804 natively supports multiple EVM chains (i.e., rinkeby/kovan/arbi/optim/bsc by replacing port to chain id) so I feel using eth:// may be too narrow. Further, one major application of EIP-4804 is to provide a web3 resource locator that can be dynamically generated on-chain, especially web resources such as SVG/HTML, therefore I feel that web3:// may better serve the purpose.
Many thanks for the invitation. I am very glad to explore the applications of web3:// for non-EVM blockchains, and I am open to collaborating on the generalization and improving EIP-4804 accordingly. For the next step, one thing I would like to do is to give a presentation of the motivation, design thoughts, and applications of EIP-4804 at the next CASA meeting? Then we could collect some consensus and move to future steps. What do you think?
what I would suggest is to encode the entire signature at once like so: web3://.../balanceOf(address)/...
since the entire canonical signature is used to encode the function selector. an error in parsing arguments (e.g. confusing bytes32/uint256, or bool/uint8/uint256 or bytes/strings, etc.) could lead to incorrect function called.
if there’s a fallback that behaves differently it would be unintuitive to debug.
by specifying the exact function signature then you don’t have ambiguities with params and can leave params out as defaults. (e.g. balanceOf(address) with no param would be balanceOf(0x0))
once you have the function 4bytes selector you can fetch the return type from a db such as 4bytes.directory.
edit: if I may suggest it can be useful to pass an optional block number too, eg. in case you want to fetch balance in a previous block.
Generally, to avoid lying to the users, the browser needs to
become a light client of the blockchain (in the Ethereum PoW chain case, that means all headers, which need some time to download.)
show the proof of data visited. This is mostly the Merkle proof of the data in the state trie.
Note that asking the gateway to return these data for each web3:// request (especially all headers) may be over-burdened.
To achieve a fully trustless web, one direction is to have a browser extension that
becomes a light client of the blockchain, which downloads the headers in the background (can from the gateway or p2p network); and
ask the gateway to respond with the proof (or the extension itself can directly access p2p network). With the light client data, we can tell whether the gateway lies or not.
There are a lot of interesting things that need to be done, but I think the web3 URL will serve as a good starting point to enable a fully-decentralized web3!
We have a regular URI/URL meeting every two weeks. In the last meeting, we reached the agreement to use returnTypes attribute to specify the return types. I could include the topic of where to specify the input types in the next meeting (see here for more info URL/URI standard working group - HackMD)
This seems to introduce the dependency on 3rd party db. I think we should avoid this because the standard is a decentralized resource locator that should not depend on any 3rd component.
This can be done by setting an optional block attribute in the attribute-value list. However, we may not expect the gateway or browser to fully support it because calling a contract on a historical block requires running an archive node.
Just discovered this EIP, nice!
I’ve been developping a electron-based proof-of-concept browser implementing a evm:// protocol I made up (&& refined with frolic), so I am happy to migrate to this EIP.
I have several questions :
Auto mode: If I have a method that returns 3 strings, and I want the second one returned as string, not JSON, how do I do it? For example, a method that return a token representation in HTML, SVG, TXT(ascii art) that I put in . For tuples and non-bytes/string results, I feel there should be a way to say that we want the result either as raw or as json?
Auto mode: If I have a method that returns a string and I want to return this string cast as a specific MIME type (e.g. image/svg+xml), how do I do it?
Auto mode: If I have a mathod that returns returns 2 variables, and I want the second one cast as image/svg+xml ?
Auto mode: Autodetection of the type of argument : I can see an issue with the autodetection of bytes : if the contract expect bytes, and we put bytes in the URL and don’t explicitely set the type, and by bad luck it has 20 or 32 length, then autodetection switch to bytes32/address type and the call signature changes, and it breaks the call. So maybe, for the bytes type, the type must always be explicitely present, it should not be autodetectable, like string?
Manual mode: how do you specify the return data types and MIME type, since the full path?query is sent to the smartcontract?
If my understanding is correct, you can put returns=(string, string, string) in the query, and the standard will return the JSON like [s0, s1, s2], and then you can retrieve the second one by getting s1 in the JSON data. E.g.,
curl web3://contractAddr/method?returns=(string,string,string) | jq '.[1]'
(you may replace web3:// with a gateway)
Then it should return the second string as you need.
Thanks for the comment. The easiest way is to allow the contract to accept the argument as string + “.” + suffix, where the suffix will decide the MIME return type. You can check the description of the standard here:
Thanks for the comment. I don’t think you can do that as MIME can be only applied to one web3:// response (and it should also apply to an HTTP:// response). In such a case, you should separate the returned variables into two different methods.
Thanks for the comment. The reason to support autodetection for address and bytes32 is that they are much more frequently used vs other non-20-or-32 bytes on contracts. I do see a potential problem that a developer/user may put a bytes with auto-detection but it was mistakenly parsed to address or bytes32. One way is that we can remove the auto-detection for non-20-or-32 bytes so that for bytes input, we always ask for explicit bytes type. We can collect more consensus from the community on this part.
Thanks for the comment. It will be determined by the last argument of the full path. See below copied from the standard.
Ok, yes the usecase I had in mind was, what if I want to directly access the value because I am using for example <img src="web3://..." />,…
But yes this usecase should be very very rare, and if it happens, one can always write a method proxying this. So I drop this.
Ok so if I understand correctly, in your example, the actual web3 url would be : web3://0x804a6b66b071e7e6494ae0e03768a536ded64262/compose/string!111.svg
I can see a problem : Let’s take web3://0xxxxxx/method/string!bla.svg
What if I wanted to send the string “bla.svg” as argument to the method? So here I don’t want to cast the result as SVG, I just want to send the string “bla.svg”.
So if a method ask for a string, and by bad luck, there is at the end of the string a dot and some letters, and the browser recognized these letters as a mime type, then the browser would remove the dot and the letters from the argument given to the method, and the browser would wrongly cast the output as something not planned.
Maybe an idea would be to put the (still optional) mime suffix to the method, web3://<contract>/<method>[.<suffix>]/<arg1>... such as web3://0xxxxxx/method.html/string!bla.svg ?
Ok for mime type.
Regarding the return data types, is it mandatory on the manual mode that a method must return only one value, or can it returns multiple values, and we have to declare it with returns=() ?
Thanks for the comments. If the string happens to be the last argument with a suffix, it may return an undesired MIME. However, I would guess such a situation will be rare for auto mode. In the manual mode, since the contract developer already knows EIP-4804, the MIME with the last argument with a suffix should fall into the contract design expectation (i.e., the developer should avoid passing “.svg” as the last argument to a non-svg data).
The key thing is that the auto mode is designed to be compatible with existing contracts, which are not aware of EIP-4804, and thus we should not rely on any assumption on the method name. If the contract uses manual mode, then the contract developer should be aware of EIP-4804, and thus the developer could design the way to work with MIME detection correctly. What do you think?
In the long term, we may add the third mode (or an option to manual mode) to support the MIME return by contracts. That means each contract method in this method will return (bytes32, bytes32), where the first one is the MIME type, and the second one is the data. Or we may even support a mode that each method will return (httpResponseHeader, bytes32). However, this seems to be a rather big change, we need to collect more comments from the community, especially experts from HTTP or browsers.
Thanks for the comment. The manual mode is designed for the contracts designed for the frontend, so it only returns one value (bytes32) and declares it with returns=() will just pass the data to calldata.
In the future, we may add the reserved queries that may be prefixed by __ (double underscore) if we want to pass more other info such as gasLimit, but we may need to collect more consensus from the community to see if it is the best way.
Ok for auto mode : we can say that when we develop a website, and we want to call a external third-party method that could trigger this bug, we can write a wrapper around it.
So I will focus on manual mode :
I think it is too bad that, when I develop an onchain website, I will always need to think that there should be not dots in the last argument of my URLs.
My string arguments would either need to not be the last argument of URLs, or need to not contains dots. If the string is provided by user, I would need to replace dots by another placeholder.
And I just realized that even float numbers have this issue :
(unfortunately “.123” is a valid mime type of application/vnd.lotus-1-2-3)
So if I want to make a method that takes as input only a float, I would need to add a dummy argument at the end, or replace dots by a placeholder, or scale them by 10^n to avoid the dot.
Would it not be better to do it in a way that does not add constraints on the contents of your arguments when you develop a onchain website?
If you think it is not a problem, I will say no more and I will implement the browser using the current EIP-4804 definition.
That’s great to hear I also have some ideas for a third mode, but yeah let’s keep that for later.