URL Format for Transaction Requests
Daniel A. Nagy (@nagydani)
A standard way of representing various transactions, especially payment requests in Ethers and ERC-20 tokens as URLs.
URLs embedded in QR-codes, hyperlinks in web-pages, emails or chat messages provide for robust cross-application signaling between very loosely coupled applications. A standardized URL format for payment requests allows for instant invocation of the user's preferred wallet application (even if it is a webapp or a swarm đapp), with the correct parameterization of the payment transaction only to be confirmed by the (authenticated) user.
The convenience of representing payment requests by standard URLs has been a major factor in the wide adoption of Bitcoin. Bringing a similarly convenient mechanism to Ethereum would speed up its acceptance as a payment platform among end-users. In particular, URLs embedded in broadcast Intents are the preferred way of launching applications on the Android operating system and work across practically all applications. Desktop web browsers have a standardized way of defining protocol handlers for URLs with specific protocol specifications. Other desktop applications typically launch the web browser upon encountering a URL. Thus, payment request URLs could be delivered through a very broad, ever growing selection of channels.
This specification supersedes the defunct ERC-67, which is a URL format for representing arbitrary transactions in a low-level fashion. This ERC focuses specifically on the important special case of payment requests, while allowing for other, ABI-specified transactions.
Payment request URLs contain "ethereum" in their schema (protocol) part and are constructed as follows:
request = schema_prefix target_address [ "@" chain_id ] [ "/" function_name ] [ "?" parameters ] schema_prefix = "ethereum" ":" [ "pay-" ] target_address = ethereum_address chain_id = 1*DIGIT function_name = STRING ethereum_address = ( "0x" 40*40HEXDIG ) / ENS_NAME parameters = parameter *( "&" parameter ) parameter = key "=" value key = "value" / "gas" / "gasLimit" / "gasPrice" / TYPE value = number / ethereum_address / STRING number = [ "-" / "+" ] *DIGIT [ "." 1*DIGIT ] [ ( "e" / "E" ) [ 1*DIGIT ]
TYPE is a standard ABI type name, as defined in Ethereum Contract ABI specification.
STRING is a URL-encoded unicode string of arbitrary length, where delimiters and the
percentage symbol (
%) are mandatorily hex-encoded with a
Note that a
number can be expressed in scientific notation, with a multiplier of a power of 10. Only integer numbers are allowed, so the exponent MUST be greater or equal to the number of decimals after the point.
If key in the parameter list is
gas then value MUST be a
number. Otherwise, it must correspond to the
TYPE string used as key.
For the syntax of ENS_NAME, please consult ERC-137 defining Ethereum Name Service.
target_address is mandatory and denotes either the beneficiary of native token payment (see below) or the contract address with which the user is asked to interact.
chain_id is optional and contains the decimal chain ID, such that transactions on various test- and private networks can be requested. If no
chain_id is present, the client's current network setting remains effective.
function_name is missing, then the URL is requesting payment in the native token of the blockchain, which is ether in our case. The amount is specified in
value parameter, in the atomic unit (i.e. wei). The use of scientific notation is strongly encouraged. For example, requesting 2.014 ETH to address
0xfb6916095ca1df60bb79Ce92ce3ea74c37c5d359 would look as follows:
Requesting payments in ERC-20 tokens involves a request to call the
transfer function of the token contract with an
address and a
uint256 typed parameter, containing the beneficiary address and the amount in atomic units, respectively. For example,
requesting a Unicorn to address
0x8e23ee67d1332ad560396262c48ffbb01f93d052 looks as follows:
If using ENS names instead of hexadecimal addresses, the resolution is up to the payer, at any time between receiving the URL and sending the transaction. Hexadecimal addresses always take precedence over ENS names, i. e. even if there exists a matching ENS name consisting of
0x followed by 40 hexadecimal digits, it should never be resolved. Instead, the hexadecimal address should be used directly.
Note that the indicated amount is only a suggestion (as are all the supplied arguments) which the user is free to change. With no indicated amount, the user should be prompted to enter the amount to be paid.
gasPrice are suggested user-editable values for gas limit and gas price, respectively, for the requested transaction. It is acceptable to abbreviate
gas, the two are treated synonymously.
The proposed format is chosen to resemble
bitcoin: URLs as closely as possible, as both users and application programmers are already familiar with that format. In particular, this motivated the omission of the unit, which is often used in Ethereum ecosystem. Handling different orders of magnitude is facilitated by the exponent so that amount values can be expressed in their nominal units, just like in the case of
bitcoin:. The use of scientific notation is strongly encouraged when expressing monetary value in ether or ERC-20 tokens. For better human readability, the exponent should be the decimal value of the nominal unit: 18 for ether or the value returned by
decimals() of the token contract for ERC-20 tokens. Additional parameters may be added, if popular use cases requiring them emerge in practice.
0x prefix before ethereum addresses specified as hexadecimal numbers is following established practice and also unambiguously distinguishes hexadecimal addresses from ENS names consisting of 40 alphanumeric characters.
Future upgrades that are partially or fully incompatible with this proposal must use a prefix other than
pay- that is separated by a dash (
-) character from whatever follows it.
In the fairly common case of only indicating the recipient address in a request for payment in ether, this specification is compatible with the superseded ERC-67.
Since irreversible transactions can be initiated with parameters from such URLs, the integrity and authenticity of these URLs are of great importance. In particular, changing either the recipient address or the amount transferred can be a profitable attack. Users should only use URLs received from authenticated sources with adequate integrity protection.
To prevent malicious redirection of payments using ENS, hexadecimal interpretation of Ethereum addresses must have precedence over ENS lookups. Client software may alert the user if an ENS address is visually similar to a hexadecimal address or even outright reject such addresses as likely phishing attacks.
In order to make sure that the amount transacted is the same as the amount intended, the amount communicated to the human user should be easily verifiable by inspection, including the order of magnitude. In case of ERC-20 token payments, if the payer client has access to the blockchain or some other trusted source of information about the token contract, the interface should display the amount in the units specified in the token contract. Otherwise, it should be displayed as expressed in the URL, possibly alerting the user to the uncertainty of the nominal unit. To facilitate human inspection of the amount, the use of scientific notation with an exponent corresponding to the nominal unit of the transacted token (e.g. 18 in case of ether) is advisable.
Copyright and related rights waived via CC0