Draft EIPs
This directory contains implementations of EIPs that are still in Draft status.
Due to their nature as drafts, the details of these contracts may change and we cannot guarantee their stability. Minor releases of OpenZeppelin Contracts may contain breaking changes for the contracts in this directory, which will be duly announced in the changelog. The EIPs included here are used by projects in production and this may make them less likely to change significantly.
Cryptography
EIP712
EIP 712 is a standard for hashing and signing of typed structured data.
The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
they need in their contracts using a combination of abi.encode
and keccak256
.
This contract implements the EIP 712 domain separator (_domainSeparatorV4
) that is used as part of the encoding
scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
(_hashTypedDataV4
).
The implementation of the domain separator was designed to be as efficient as possible while still properly updating the chain id to protect against replay attacks on an eventual fork of the chain.
This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
eth_signTypedDataV4 in MetaMask.
|
Available since v3.4.
constructor(string name, string version)
internal
Initializes the domain separator and parameter caches.
The meaning of name
and version
is specified in
EIP 712:
-
name
: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. -
version
: the current major version of the signing domain.
These parameters cannot be changed except through a smart contract upgrade. |
_hashTypedDataV4(bytes32 structHash) → bytes32
internal
Given an already hashed struct, this function returns the hash of the fully encoded EIP712 message for this domain.
This hash can be used together with ECDSA.recover
to obtain the signer of a message. For example:
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
keccak256("Mail(address to,string contents)"),
mailTo,
keccak256(bytes(mailContents))
)));
address signer = ECDSA.recover(digest, signature);
ERC 20
IERC20Permit
Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in EIP-2612.
Adds the permit
method, which can be used to change an account’s ERC20 allowance (see IERC20.allowance
) by
presenting a message signed by the account. By not relying on
, the token holder account doesn’t
need to send a transaction, and thus is not required to hold Ether at all.IERC20.approve
permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external
Sets value
as the allowance of spender
over `owner’s tokens,
given `owner’s signed approval.
The same issues IERC20.approve has related to transaction
ordering also apply here.
|
Emits an {Approval} event.
Requirements:
-
spender
cannot be the zero address. -
deadline
must be a timestamp in the future. -
v
,r
ands
must be a validsecp256k1
signature fromowner
over the EIP712-formatted function arguments. -
the signature must use
owner
's current nonce (seenonces
).
For more information on the signature format, see the relevant EIP section.
nonces(address owner) → uint256
external
Returns the current nonce for owner
. This value must be
included whenever a signature is generated for permit
.
Every successful call to permit
increases owner
's nonce by one. This
prevents a signature from being used multiple times.
DOMAIN_SEPARATOR() → bytes32
external
Returns the domain separator used in the encoding of the signature for permit
, as defined by EIP712
.
ERC20Permit
Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in EIP-2612.
Adds the permit
method, which can be used to change an account’s ERC20 allowance (see IERC20.allowance
) by
presenting a message signed by the account. By not relying on
, the token holder account doesn’t
need to send a transaction, and thus is not required to hold Ether at all.IERC20.approve
Available since v3.4.
constructor(string name)
internal
Initializes the EIP712
domain separator using the name
parameter, and setting version
to "1"
.
It’s a good idea to use the same name
that is defined as the ERC20 token name.
permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
public
See IERC20Permit.permit
.
nonces(address owner) → uint256
public
See IERC20Permit.nonces
.