ERC-5219 Contract Resource Requests

Final · Other · created 2022-07-10

Defines an interface for requesting resources from a smart contract, much like requesting a web page, and receiving an HTTP-like response with a status code, body and headers. It lets a decentralized app's front end be served on chain without a central server.

Why it is needed

Ethereum is the most widely used blockchain for building decentralized apps (DApps), yet to use such an app you must first visit a website hosted on a central server and download its front-end code. Even if the back-end contract is on chain, the front end depends on one company's server. The original text points out four risks here. The number of parties that must be trusted grows unnecessarily, and a central website cannot resist censorship. There is no mechanism to preserve front-end code permanently, and smart contracts cannot interact directly with other apps' front ends. This standard defines the shape of requests and responses so that a contract itself can return the resources a front end needs, opening a path to serving even the app's front end on chain.

In depth

What the standard specifies

This standard defines an interface for requesting a resource from a smart contract and receiving an HTTP-like response. A DApp contract MUST implement the interface in the attached file IDecentralizedApp.sol. The body of the original text does not include the function declarations directly and instead points to the attached file, so implementers should treat that file as the reference. The shape of the response can be seen in the example in Note to Implementers. It consists of statusCode, body, and a headers list of key and value pairs. Words such as MUST, SHOULD and MAY from RFC 2119 indicate the requirement levels of the original text.

Name resolution and backwards compatibility

Name resolution itself (how to find which contract a name points to) is not defined by this standard. An EIP that proposes a name resolution mechanism MAY reference this standard, and MAY recommend that clients support its own mechanism. Clients MAY also support regular DNS as defined in RFC 1034 and RFC 1035. The Backwards Compatibility section states that this standard is backwards compatible with the standards listed in the Name Resolution section. In other words, whichever naming scheme is used, the request and response format that follows can be unified by this standard.

Separation of concerns: front-end contract and back-end contract

Separating application logic from front-end logic is RECOMMENDED. Here, front-end logic means a contract that implements the interface above. The Rationale explains why. Storing complex front-end logic in a contract makes deployment expensive, and such logic is better run on the end user's device. The roles are also split so that the front-end contract does not need to care about interacting with the back-end contract.

request is read-only

The request method is defined as read-only, on the idea that all data should be sent to the contract from the resolved DApp side. Submitting a transaction to send a request costs money and requires waiting until the transaction is mined, which makes for a poor user experience. When an action that changes state is needed, it can be requested using another EIP together with the 307 Temporary Redirect status code. In other words, the path for fetching the front end is separated from the path for changing state.

Why it does not mimic HTTP exactly

Instead of mimicking a full HTTP request, the standard takes a greatly reduced form. The original text gives three reasons. The only HTTP method that is meaningful in practice is GET. Query parameters can be encoded in the resource. Request headers are generally not needed for GET requests. As a result, the request is simple and focused on specifying the resource, and the response conveys the core of HTTP with just statusCode, body and headers. A client can interpret this response like an ordinary web response.

Saving gas: message/external-body

The Note to Implementers section recommends using the message/external-body MIME type to reduce gas costs. With this type, a contract can point to data that it may not be able to access directly. The example in the original text sets statusCode to 200, uses the placeholder string THIS IS NOT REALLY THE BODY! as the body, and sets the Content-type header value to message/external-body; access-type=URL; URL="ipfs://11148a173fd3e32c0fa78b90fe42d305f202244e2739". The client reads this header and fetches the actual data from IPFS instead of using the body. This way, large front-end code does not need to be stored on chain.

Things to watch out for

Original ERC · ← ERCs