Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add EIP: Web3 URL to EVM Call Message Translation #6860

Merged
merged 24 commits into from
Oct 18, 2023
Merged
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6b62f1e
Add more details for the examples
qizhou Apr 10, 2023
9cd2315
Update eip-4804.md
qizhou Apr 11, 2023
e609666
Update EIPS/eip-4804.md
qizhou Apr 19, 2023
8073a0f
Update eip-4804.md
qizhou Apr 19, 2023
6a64db6
Revert EIP-4804 to original, copy it to EIP-6860 prior to modifications.
nand2 Oct 10, 2023
e689e74
ERC-6860: Changes vs ERC-4804
nand2 Oct 10, 2023
740de6e
ERC-6860: Fix lint warnings.
nand2 Oct 10, 2023
d347289
ERC-6860: Fix lint warnings.
nand2 Oct 10, 2023
066b331
ERC-6860: More clarifications on URI-percent-encoding.
nand2 Oct 10, 2023
3924322
ERC-6860: Add in the modification section information about the chang…
nand2 Oct 10, 2023
9c57f98
ERC-6860: Auto mode: bytes<X> type: Clarify the length of the argumen…
nand2 Oct 10, 2023
74e02e0
Update EIPS/eip-6860.md
nand2 Oct 12, 2023
01f3d2d
Update EIPS/eip-6860.md
nand2 Oct 12, 2023
2457b06
Update EIPS/eip-6860.md
nand2 Oct 12, 2023
e4eb876
Update EIPS/eip-6860.md
nand2 Oct 12, 2023
5572ee8
Update EIPS/eip-6860.md
nand2 Oct 12, 2023
cec1561
ERC-6860: Formalize the percent-encoding rules.
nand2 Oct 12, 2023
7b0f0ac
ERC-6860: Renaming of "ERC" to "EIP" inside.
nand2 Oct 12, 2023
f6a0978
Revert "ERC-6860: Renaming of "ERC" to "EIP" inside."
nand2 Oct 12, 2023
c688f05
ERC-6860: Fix a markdown lint warning.
nand2 Oct 12, 2023
0a40258
ERC-6860: percent-encoding: Add clarification of encoding of "!".
nand2 Oct 13, 2023
fc14e1f
ERC-6860: percent-encoding: Removing the "!" exception for path.
nand2 Oct 15, 2023
2a3e4e2
ERC-6860: Add full ABNF definition.
nand2 Oct 18, 2023
aeda4ee
ERC-6860: Fix markdown linter
nand2 Oct 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
241 changes: 241 additions & 0 deletions EIPS/eip-6860.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
---
eip: 6860
title: Web3 URL to EVM Call Message Translation
description: A translation of an HTTP-style Web3 URL to an EVM call message
author: Qi Zhou (@qizhou), Chao Pi (@pichaoqkc), Sam Wilson (@SamWilsn)
discussions-to: https://ethereum-magicians.org/t/eip-4804-web3-url-to-evm-call-message-translation/8300
status: Draft
type: Standards Track
category: ERC
created: 2023-09-29
requires: 137
---

## Abstract

This standard translates an RFC 2396 URI like `web3://uniswap.eth/` to an EVM message such as:

```
EVMMessage {
To: 0xaabbccddee.... // where uniswap.eth's address registered at ENS
Calldata: 0x
...
}
```

⚠️ This proposal updates [ERC-4804](./eip-4804.md) with minor corrections, clarifications and modifications.

## Motivation

Currently, reading data from Web3 generally relies on a translation done by a Web2 proxy to Web3 blockchain. The translation is mostly done by the proxies such as dApp websites/node service provider/etherscan, which are out of the control of users. The standard here aims to provide a simple way for Web2 users to directly access the content of Web3, especially on-chain Web contents such as SVG/HTML. Moreover, this standard enables interoperability with other standards already compatible with URIs, like SVG/HTML.

## Specification

This specification only defines read-only (i.e. Solidity's `view` functions) semantics. State modifying functions may be defined as a future extension.

A Web3 URL is an ASCII string in the following form

```
web3URL = web3Schema [userinfo "@"] contractName [":" chainid] path ["?" query]
web3Schema = [ "w3://" | "web3://" ]
contractName = address | [name "." [ subDomain0 "." ... ]] nsProviderSuffix
path = ["/" method ["/" argument_0 ["/" argument_1 ... ]]]
argument = [type "!"] value
query = "attribute_1=value_1 [ "&" attribute_2=value_2 ... ]
attribute = "returns" | "returnTypes" | other_attribute
```

where

- **web3Schema** indicates the schema of the URL, which is `web3://` or `w3://` for short.
- **userinfo** indicates which user is calling the EVM, i.e., "From" field in EVM call message. If not specified, the protocol will use 0x0 as the sender address.
- **contractName** indicates the contract to be called, i.e., "To" field in the EVM call message. If the **contractName** is an **address**, i.e., 0x + 20-byte-data hex, then "To" will be the address. Otherwise, the name is from a name service. In the second case, **nsProviderSuffix** will be the suffix from name service providers such as "eth", etc. The way to translate the name from a name service to an address will be discussed in later EIPs.
- **chainid** indicates which chain to resolve **contractName** and call the message. If not specified, the protocol will use the same chain as the name service provider, e.g., 1 for eth. If no name service provider is available, the default chainid is 1.
- **query** is an optional component containing a sequence of attribute-value pairs separated by "&".

All non-ASCII characters must be encoded with URI percent-encoding (RFC 3986).
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://en.wikipedia.org/wiki/Percent-encoding, only unreserved characters and reserved characters with special purpose need not be percent-encoded, so I feel the statement here can be more accurate.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, and even looking deeper into RFC 3986, I find out that they split the reserved chars into 2 groups:

reserved    = gen-delims / sub-delims
gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
                  / "*" / "+" / "," / ";" / "="

And also that depending of the component, the list of characters that need to be encoded is different:

Path:

path          = path-abempty
...
path-abempty  = *( "/" segment )
segment       = *pchar
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"

Host (in case of hostname):

reg-name    = *( unreserved / pct-encoded / sub-delims )

So here in this example they allow not-encoded ":" and "@" in path but not in host, because they have a special meaning in host.
So they optimize to make encoding mandatory when really necessary. I'll update the text to do it likewise here.

Copy link

@nand2 nand2 Oct 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I have formalized this by adding :

The URL must be encoded with URI percent-encoding (RFC 3968) with rules very similar to the RFC. Per component, the rules are :

  • userinfo : Identical to userinfo as defined in RFC 3986 Appendix A.
  • contractName : Identical to reg-name as defined in RFC 3986 Appendix A.
  • chainid : Identical to port as defined in RFC 3986 Appendix A.
  • path : Identical to path-abempty as defined in RFC 3986 Appendix A, except the character "!" that needs to be percent-encoded when not used as type/value separator in an argument.
  • query : Identical to query as defined in RFC 3986 Appendix A.

Question : I quite like the full formalization of the structure of the URL in RFC 3986 Appendix A, I think it could be good to make a similar full formalization in an Appendix. What do you think?

Copy link

@nand2 nand2 Oct 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about the "!" character in path : If we assume that in the future we will not support domain name services that allows "!" as part of domain names (likely I guess), then we can skip this exception and be identical to the RFC ("!" are not required to be encoded in path).
I guess that's the way to go.

I have edited:

The URL must be encoded with URI percent-encoding (RFC 3968) with rules very similar to the RFC: Component userinfo follows userinfo encoding as defined in RFC 3986 Appendix A, component contractName follows reg-name, chainid follows port, path follows path-abempty, and query follows query.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I have formalized this by adding :

The URL must be encoded with URI percent-encoding (RFC 3968) with rules very similar to the RFC. Per component, the rules are :

  • userinfo : Identical to userinfo as defined in RFC 3986 Appendix A.
  • contractName : Identical to reg-name as defined in RFC 3986 Appendix A.
  • chainid : Identical to port as defined in RFC 3986 Appendix A.
  • path : Identical to path-abempty as defined in RFC 3986 Appendix A, except the character "!" that needs to be percent-encoded when not used as type/value separator in an argument.
  • query : Identical to query as defined in RFC 3986 Appendix A.

Question : I quite like the full formalization of the structure of the URL in RFC 3986 Appendix A, I think it could be good to make a similar full formalization in an Appendix. What do you think?

Yes, I think we can make a similar structure to formalize the details for each component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about the "!" character in path : If we assume that in the future we will not support domain name services that allows "!" as part of domain names (likely I guess), then we can skip this exception and be identical to the RFC ("!" are not required to be encoded in path). I guess that's the way to go.

I have edited:

The URL must be encoded with URI percent-encoding (RFC 3968) with rules very similar to the RFC: Component userinfo follows userinfo encoding as defined in RFC 3986 Appendix A, component contractName follows reg-name, chainid follows port, path follows path-abempty, and query follows query.

I guess if the address contains ! we can still use address!abc%33.eth to support it?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think we can make a similar structure to formalize the details for each component.

Ok I will do that

I guess if the address contains ! we can still use address!abc%33.eth to support it?

Yes; to be more precise (I think I was a bit confusing) :

  • If we choose to be similar to the RFC, that means that the ! type/value delimiter can be either written as ! or %21. The problem is then : we cannot know if this is part of the domain name or not.. For example, if we have address%21abc%21.xyz, then we cannot know if this is the abc!.xyz address (detected with the <type>!<value> syntax), or the address!abc!.xyz address (detected with auto-detection part 5 as an address)
  • The "proper" way to handle that is to require the ! type/value delimiter to always be written as !, not %21. It then makes it a tiny bit of difference with the RFC.

I will do the Appendix with the formal definition, and let's continue from there :)

Copy link
Contributor Author

@qizhou qizhou Oct 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. If we put ! as type/value delimiter defined in ABNF, then we should never use %21%. I am not sure what is the specific difference with the RFC? (Looks like our domainName is stricter than reg-name in RFC 3986? or we may defer reg-name to NS lookup in future EIPs as RFC3986 does?)

That said, we could clarify the address part as below (I use reg-name for domainName, but feel free to comment)

  • address!vitalik.eth is a valid address to lookup vitalik from ENS;
  • address%21vitalik.eth is invalid as it cannot be recognized as any argument;
  • address!%21vitalik.eth is a valid address to lookup !vitalik from ENS;
  • address!vitalik%2Eeth is invalid as it cannot be recognized as a domain name with a TLD;
  • address!vitalik%2E.eth is a valid address to lookup vitalik. from ENS;
  • address!!vitalik.eth is a valid address to lookup !vitalik from ENS.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that domainName stricter than reg-name without reason (we could break with some upcoming domain name services), I have modified it to be identical to RFC 3986 ; and indeed already you have made domain name resolution deferred in upcoming EIPs (such as 6821) ; since 6821 is lower than 6860 I have linked 6821 for ENS and kept the mention "will be discussed in later EIPs for other name services.".

I agree on case 1/ and case 2/ : the ! type/value delimiter is in the ABNF so it's clear %21 is not authorized as a delimiter.
Case 2/ and 6/ : I agree
Case 4/ and 5/ : I would disagree on that; the general workflow would be : 1/ extract <value> from <type>!<value>, 2/ percent-decode <value> and then 3/ give <percent-decoded-value> to the domain name resolver code to do his work -- these would be 2 different layers. (Trying https://google%2Ecom on a browser, it does percent-decode it into google.com before doing resolution). So I would think :

  • address!vitalik%2Eeth is a valid address to lookup vitalik.eth from ENS
  • address!vitalik%2E.eth is invalid as it would lookup vitalik..eth from ENS

What do you think?

My modifications are at :
ethereum/ERCs@master...nand2:ERCs:patch-1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me. I just create the PR with the patch here ethereum/ERCs#84


### Resolve Mode

Once the "To" address and chainid are determined, the protocol will check the resolver mode of contract by calling the `resolveMode` method of the "To" address. The Solidity signature of `resolveMode` is:

```solidity
function resolveMode() external returns (bytes32);
```

The protocol currently supports two resolve modes: auto and manual.

- The manual mode will be used if the `resolveMode` return value is `0x6d616e75616c0000000000000000000000000000000000000000000000000000`, i.e., "manual" in bytes32
- The auto mode will be used if :
- the `resolveMode` return value is `0x6175746f00000000000000000000000000000000000000000000000000000000`, i.e, "auto" in bytes32, or
- the `resolveMode` return value is `0x0000000000000000000000000000000000000000000000000000000000000000`, or
- the call to `resolveMode` throws an error (method not implemented or error thrown from the method)
- Otherwise, the protocol will fail to the request with error "unsupported resolve mode".
nand2 marked this conversation as resolved.
Show resolved Hide resolved

#### Manual Mode

The manual mode will use the raw ``path [ "?" query ]`` as calldata of the message directly (no URI-percent-encoding decoding will be done). Path cannot be empty and must be at least ``/``.

The returned message data will be treated as ABI-encoded bytes and the decoded bytes will be returned to the frontend.

The MIME type returned to the frontend is ``text/html`` by default, but will be overriden if the **path** has a filename extension suffix :

```
path = path_part [ "." filename_extension ]
```

In this case, the MIME type will be deduced from the filename extension.

#### Auto Mode

In the auto mode, if **path** is empty or "/", then the protocol will call the target contract with empty calldata. Otherwise, the calldata of the EVM message will use standard Solidity contract ABI, where

- **method** is a string of the function method to be called
- **argument_i** is the i-th argument of the method. If **type** is specified, the value will be translated to the corresponding type. The protocol currently supports these basic types: bool, int, uint, int&lt;X&gt;, uint&lt;X&gt; (with X ranging from 8 to 256 in steps of 8), address, bytes&lt;X&gt; (with X ranging from 1 to 32), bytes, and string. If **type** is not specified, then the type will be automatically detected using the following rule in a sequential way:
1. **type**="uint256", if **value** is numeric; or
2. **type**="bytes32", if **value** is in the form of 0x+32-byte-data hex; or
3. **type**="address", if **value** is in the form of 0x+20-byte-data hex; or
4. **type**="bytes", if **value** is in the form of 0x followed by any number of bytes besides 20 or 32; or
5. else **type**="address" and parse the argument as a domain name in the form of `[name "." [ subDomain0 "." ... ]] nsProviderSuffix`. In this case, the actual value of the argument will be obtained from **nsProviderSuffix**, e.g., eth. If **nsProviderSuffix** is not supported, an unsupported NS provider error will be returned.

The format of **value** should be :
- If **type** is "string", then **value** is URI-percent-encoded (RFC 3986) for all non-ASCII characters and for the following characters: ``!``, ``/``, ``?``, ``%``.
nand2 marked this conversation as resolved.
Show resolved Hide resolved
- If **type** is "bool", then **value** must be either ``true`` or ``false``.
- If **type** is "bytes&lt;X&gt;" or "bytes", then **value** must be in hexadecimal form prefixed by "0x". If X is specified, then **value** must be made of 2 + 2 * X chars.
- If **type** is "address", then **value** is either in hedadecimal form prefixed by "0x", or a domain name string.

- **returns** attribute in **query** tells the format of the returned data. Its value syntax is :

```
value = ["(" [types] ")"]
types = type_1 [ "," type_2 ... ]
type = basic_type [ "[]" [ "[]" ... ] | "[size]" [ "[size_2]" ... ] ]
```

``basic_type`` can be any of the types listed as supported as argument.
- If the **returns** attribute is undefined or empty, the returned message data will be treated as ABI-encoded bytes and the decoded bytes will be returned to the frontend. The MIME type returned to the frontend will be undefined by default, but will be overriden if the last argument has a filename extension :

```
last_argument = last_argument_part [ "." filename_extension ]
```

- If **returns** is equal to "()", the raw bytes of the returned message data will be returned, encoded as a "0x"-prefixed hex string in an array in JSON format: ``["0xXXXXX"]``
- Otherwise, the returned message data will be ABI-decoded in the data types specified in the **returns** value and encoded in JSON format. The encoding of the data will follow the Ethereum JSON-RPC format:
- Unformatted data (bytes, address) will be encoded as hex, prefixed with "0x", two hex digits per byte
- Quantities (integers) will be encoded as hex, prefix with "0x", the most compact representation (slight exception: zero should be represented as "0x0")
- Boolean and strings will be native JSON boolean and strings

If multiple **returns** attributes are present, the value of the last **returns** attribute will be applied. Note that **returnTypes** is the alias of **returns**, but it is not recommended to use and is mainly for [ERC-4804](./eip-4804.md) backward-compatible purpose.

### Examples

#### Example 1a

```
web3://w3url.eth/
```

where the contract of **w3url.eth** is in manual mode.

The protocol will find the address of **w3url.eth** from ENS in chainid 1 (Mainnet). Then the protocol will call the address with "Calldata" = `keccak("resolveMode()")[0:4]` = "0xDD473FAE", which returns "manual" in ABI-type "(bytes32)". After determining the manual mode of the contract, the protocol will call the address with "To" = **contractAddress** and "Calldata" = "0x2F". The returned data will be treated as ABI-type "(bytes)", and the decoded bytes will be returned to the frontend, with the information that the MIME type is ``text/html``.

#### Example 1b

```
web3://w3url.eth/
```

where the contract of **w3url.eth** is in auto mode.

The protocol will find the address of **w3url.eth** from ENS in chainid 1 (Mainnet). Then the protocol will call the address with "Calldata" = `keccak("resolveMode()")[0:4]` = "0xDD473FAE", which returns "", i.e., the contract is in auto mode. After determining the auto mode of the contract, the protocol will call the address with "To" = **contractAddress** and "Calldata" = "". The returned data will be treated as ABI-type "(bytes)", and the decoded bytes will be returned to the frontend, with the information that the MIME type is undefined.

#### Example 2

```
web3://cyberbrokers-meta.eth/renderBroker/9999
```

where the contract of **cyberbrokers-meta.eth** is in auto mode.

The protocol will find the address of **cyberbrokers-meta.eth** from ENS on chainid 1 (Mainnet). Then the protocol will call the address with "Calldata" = `keccak("resolveMode()")[0:4]` = "0xDD473FAE", which returns "", i.e., the contract is in auto mode. After determining the auto mode of the contract, the protocol will call the address with "To" = **contractAddress** and "Calldata" = "0x" + `keccak("renderBroker(uint256)")[0:4] + abi.encode(uint256(9999))`. The returned data will be treated as ABI-type "(bytes)", and the decoded bytes will be returned to the frontend, with the information that the MIME type is undefined.

#### Example 3

```
web3://vitalikblog.eth:5/
```

where the contract of **vitalikblog.eth:5** is in manual mode.

The protocol will find the address of **vitalikblog.eth** from ENS on chainid 5 (Goerli). Then after determing the contract is in manual mode, the protocol will call the address with "To" = **contractAddress** and "Calldata" = "0x2F" with chainid = 5. The returned data will be treated as ABI-type "(bytes)", and the decoded bytes will be returned to the frontend, with the information that the MIME type is ``text/html``.

#### Example 4

```
web3://0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170/
```

where the contract "0xe4ba0e245436b737468c206ab5c8f4950597ab7f:42170" is in manual mode.

After determing the contract is in manual mode, the protocol will call the address with "To" = "0xe4ba0e245436b737468c206ab5c8f4950597ab7f" and "Calldata" = "0x2F" with chainid = 42170 (Arbitrum Nova). The returned data will be treated as ABI-type "(bytes)", and the decoded bytes will be returned to the frontend, with the information that the MIME type is ``text/html``.

#### Example 5

```
web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=(uint256)
```

where the contract "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" is in auto mode.

The protocol will find the addresses of **vitalik.eth** from ENS on chainid 1 (Mainnet) and then call the method "balanceOf(address)" of the contract with the **vitalik.eth**'s address. The returned data from the call of the contract will be treated as ABI-type "(uint256)", and the decoded data will be returned to the frontend in JSON format like `[ "0x9184e72a000" ]`, with the information that the MIME type is ``application/json``.

#### Example 6

```
web3://0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48/balanceOf/vitalik.eth?returns=()
```

where the contract ”0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48“ is in auto mode.

The protocol will find the address of **vitalik.eth** from ENS on chainid 1 (Mainnet) and then call the method "balanceOf(address)" of the address. The returned data from the call of the contract will be treated as raw bytes and will be encoded in JSON format like `["0x000000000000000000000000000000000000000000000000000009184e72a000"]` and returned to the frontend, with the information that the MIME type is ``application/json``.

### Changes versus [ERC-4804](./eip-4804.md)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use EIP-4804 (also EIP over ERC) in the whole document.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, if I do so, I get errors from the EIP Walidator, which then prevents merging :

error[markdown-refs]: references to proposals with a `category` of `ERC` must use a prefix of `ERC`


#### Corrections

- Manual mode : [ERC-4804](./eip-4804.md) stipulates that there is no interpretation of the path [ "?" query ]. This ERC indicates that there is in fact an interpretation of the path, for MIME type determination purpose.
- Auto mode : If there is no **returns** attribute in **query**, [ERC-4804](./eip-4804.md) stipulates that the returned data is treated as ABI-encoded bytes32. This ERC indicates that in fact the returned data is treated as ABI-encoded bytes.

#### Clarifications

- URL format: This ERC indicates that the URL should be in ASCII format.
- Resolve mode: This ERC indicates more details on how the resolve mode is determined.
- Manual mode : This ERC indicates how to deal with URI-percent-encoding, the return data, and how the MIME type is determined.
- Auto mode : This ERC indicates in more details the encoding of the argument values, as well as the format and handling of the **returns** value.
- Examples : This ERC add more details to the examples.

#### Modifications

- Protocol name: [ERC-4804](./eip-4804.md) mentionned ``ethereum-web3://`` and ``eth-web3://``, these are removed.
- Auto mode: Supported types: [ERC-4804](./eip-4804.md) supported only uint256, bytes32, address, bytes, and string. This ERC add more types.
- Auto mode: Encoding of returned integers when a **returns** attribute is specified: [ERC-4804](./eip-4804.md) suggested in example 5 to encode integers as strings. This ERC indicates to follow the ethereum JSON RPC spec and encode integers as a hex string, prefix with "0x".
nand2 marked this conversation as resolved.
Show resolved Hide resolved

## Rationale

The purpose of the proposal is to add a decentralized presentation layer for Ethereum. With the layer, we are able to render any web content (including HTML/CSS/JPG/PNG/SVG, etc) on-chain using human-readable URLs, and thus EVM can be served as decentralized Backend. The design of the standard is based on the following principles:
nand2 marked this conversation as resolved.
Show resolved Hide resolved

- **Human-readable**. The Web3 URL should be easily recognized by human similar to Web2 URL (`http://`). As a result, we support names from name services to replace address for better readability. In addition, instead of using calldata in hex, we use human-readable method + arguments and translate them to calldata for better readability.

- **Maximum-Compatible with HTTP-URL standard**. The Web3 URL should be compatible with HTTP-URL standard including relative pathing, query, fragment, etc so that the support of existing HTTP-URL (e.g., by browser) can be easily extended to Web3 URL with minimal modification. This also means that existing Web2 users can easily migrate to Web3 with minimal extra knowledge of this standard.
nand2 marked this conversation as resolved.
Show resolved Hide resolved

- **Simple**. Instead of providing explicit types in arguments, we use a "maximum likelihood" principle of auto-detecting the types of the arguments such as address, bytes32, and uint256. This could greatly minimize the length of URL, while avoiding confusion. In addition, explicit types are also supported to clear the confusion if necessary.

- **Flexible**. The contract is able to override the encoding rule so that the contract has fine-control of understanding the actual Web resources that the users want to locate.

## Security Considerations

No security considerations were found.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).