-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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-5388: Token-Gated HTTP Endpoints #5388
Changes from all commits
a073021
361a52e
1319b46
d1e861f
e89bf56
ec9eda7
7dabc74
176745d
2ae203a
edcab14
f307c7c
c9aa177
cf43827
fb81ca6
d591104
fdc0af5
a955a2f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,151 @@ | ||||||
--- | ||||||
eip: 5388 | ||||||
title: Token-Gated HTTP Endpoints | ||||||
description: Composable RESTful and Solidity interface to implement token-gated HTTP endpoints using data tokens. | ||||||
author: Tim Daubenschütz (@TimDaub) | ||||||
discussions-to: https://ethereum-magicians.org/t/token-gated-https-endpoints/10205 | ||||||
status: Draft | ||||||
type: Standards Track | ||||||
category: ERC | ||||||
lightclient marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
created: 2022-08-01 | ||||||
requires: 712 | ||||||
TimDaub marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
--- | ||||||
|
||||||
## Abstract | ||||||
|
||||||
This standard introduces composable RESTful HTTP and Solidity interfaces that enable paying to access HTTP endpoints using [EIP-20](./eip-20.md) tokens. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure it is about REST? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
|
||||||
## Motivation | ||||||
|
||||||
According to RFC 7231, HTTP status code `402 Payment Required` is reserved for future use. But the future is now as Ethereum enables users to verify their identity with a server using public key infrastructure. | ||||||
|
||||||
The Ethereum community has expressed the need for a composable method of token-gating HTTP endpoints. In this document, we outline a protocol implementable by HTTP servers to accept [EIP-20](./eip-20.md) payments prior to allowing access to an authorized endpoint. | ||||||
|
||||||
## Specification | ||||||
|
||||||
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. | ||||||
|
||||||
Upon the user's initial request, an HTTP server implementing token-gating via this EIP responds with a `402 Payment Required` status code: | ||||||
|
||||||
- Its body must include a valid JSON string that complies with the Solidity Contract ABI Specification for calling contracts. | ||||||
- It must include a custom header `X-EIP-5388-CONTRACT-ADDRESS` that suggests the contract's address a call must be directed to. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The use of the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is important to make sure this address is compatible beyond Ethereum mainnet by adding the chain id. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can u please add a reference that explains why the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Makes sense, will add it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is a standard. You can (and should) drop the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There is a good SO thread there and my good friend Peter wrote an RFC a while back https://www.rfc-editor.org/rfc/rfc6648 https://stackoverflow.com/questions/3561381/custom-http-headers-naming-conventions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
- It must include a custom header `X-EIP-5388-ABI-ENCODED-INPUT` that suggests the call signature the user must invoke at `X-EIP-5388-CONTRACT-ADDRESS` to gain access to the endpoint. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel the spec also lacks a part in solidity interface for what smart contract it will be to respond to a end point request There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure I understand what you mean, would you mind elaborating? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think what @xinbenlv is asking is probably which are these contracts that these endpoints might be dependent on, as suggested in his changes. Is that it? |
||||||
|
||||||
### Example Response | ||||||
|
||||||
``` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
HTTP requests have syntax highlighting available |
||||||
HTTP/2.0 402 Payment Required | ||||||
Date: Mon, 01 Aug 2022 13:37:00 GMT | ||||||
Content-Type: application/json | ||||||
X-EIP-5388-CONTRACT-ADDRESS: 0x005241438cAF3eaCb05bB6543151f7AF894C5B58 | ||||||
X-EIP-5388-ABI-ENCODED-INPUT: 23b872dd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b | ||||||
|
||||||
"{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"type\":\"function\"}" | ||||||
``` | ||||||
|
||||||
### Authorization via [EIP-712](./eip-712) Signature | ||||||
|
||||||
After successfully calling the suggested Ethereum contract with the appropriate inputs, for a user request that containing a validly signed message for endpoint authorization, the server must allow access to the bespoke endpoint. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about |
||||||
|
||||||
The signature is complaint with [EIP-712](./eip-712.md): | ||||||
|
||||||
```js | ||||||
keccak256(abi.encodePacked( | ||||||
hex"1901", | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @TimDaub , The code snippet declares it to be "js" in line 52. Is |
||||||
DOMAIN_SEPARATOR, | ||||||
keccak256(abi.encode( | ||||||
keccak256("Invocation(address contract,string input"), | ||||||
contract, | ||||||
keccak256(bytes(input)), | ||||||
)) | ||||||
)) | ||||||
``` | ||||||
|
||||||
where `DOMAIN_SEPARATOR` must be unique to the chain to prevent replay attacks from other domains, and satisfy the requirements of [EIP-712](./eip-712.md): | ||||||
|
||||||
```js | ||||||
DOMAIN_SEPARATOR = keccak256( | ||||||
abi.encode( | ||||||
keccak256( | ||||||
"EIP712Domain(string version,uint256 chainId,string endpoint,string method)" | ||||||
), | ||||||
keccak256(bytes(version)), | ||||||
chainid, | ||||||
keccak256(bytes(endpoint)), | ||||||
keccak256(bytes(method)) | ||||||
) | ||||||
); | ||||||
``` | ||||||
|
||||||
where `endpoint` must represent the full URL, e.g. `https://ethereum.org/api/v1/cutedoge` and `method` an existing HTTP method. | ||||||
|
||||||
```js | ||||||
{ | ||||||
"types": { | ||||||
"EIP712Domain": [ | ||||||
{ | ||||||
"name": "version", | ||||||
"type": "string" | ||||||
}, | ||||||
{ | ||||||
"name": "chainId", | ||||||
"type": "uint256" | ||||||
}, | ||||||
{ | ||||||
"name": "endpoint", | ||||||
"type": "string" | ||||||
}, | ||||||
{ | ||||||
"name": "method", | ||||||
"type": "string" | ||||||
} | ||||||
], | ||||||
"Invocation": [ | ||||||
{ | ||||||
"name": "contract", | ||||||
"type": "address" | ||||||
}, | ||||||
{ | ||||||
"name": "input", | ||||||
"type": "string" | ||||||
} | ||||||
], | ||||||
"primaryType": "Invocation", | ||||||
"domain": { | ||||||
"version": version, | ||||||
"chainId": chainid, | ||||||
"endpoint": endpoint, | ||||||
"method": method | ||||||
}, | ||||||
"message": { | ||||||
"contract": contract, | ||||||
"input": input | ||||||
} | ||||||
} | ||||||
} | ||||||
``` | ||||||
|
||||||
The resulting hexadecimal-encoded signature must be included in a user's request to the endpoint as the `Bearer` value of the `Authorization` header. An example: | ||||||
|
||||||
```http | ||||||
GET /index.html | ||||||
Authorization: Bearer 0xabc... | ||||||
``` | ||||||
|
||||||
Upon validating the signature and cross-checking it with the mandated on-chain interaction, a server must allow access to the appointed endpoint's resource. | ||||||
|
||||||
## Rationale | ||||||
|
||||||
There is no rationale related this standard. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
## Backwards Compatibility | ||||||
|
||||||
No backward compatibility issues were found. | ||||||
|
||||||
## Security Considerations | ||||||
|
||||||
Needs discussion. | ||||||
|
||||||
## Copyright | ||||||
|
||||||
Copyright and related rights waived via [CC0](../LICENSE.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think HTTP and RESTful can be decoupled. If this EIP mandates RESTful API, the title shall reflect it. If it only mandates HTTP, then I think we can drop the
RESTful
in the description and just keep it about HTTP endpoint?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I am not sure REST is required/useful?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
I kind of like to also have a RESTFul standard, but it can be one level above HTTP, hence that it self could have an separate EIP.