forked from DecentralizedClimateFoundation/DCIPs
126 lines
7.3 KiB
Markdown
126 lines
7.3 KiB
Markdown
---
|
|
eip: 5732
|
|
title: Commit Interface
|
|
description: A simple but general commit interface to support commit-reveal scheme.
|
|
author: Zainan Victor Zhou (@xinbenlv), Matt Stam (@mattstam)
|
|
discussions-to: https://ethereum-magicians.org/t/erc-5732-simple-commit-interface-to-support-commit-reveal-schemes/11115
|
|
status: Final
|
|
type: Standards Track
|
|
category: ERC
|
|
created: 2022-09-29
|
|
requires: 165, 1271
|
|
---
|
|
|
|
## Abstract
|
|
|
|
A simple commit interface to support commit-reveal scheme which provides **only** a commit
|
|
method but no reveal method, allowing implementations to integrate this interface
|
|
with arbitrary reveal methods such as `vote` or `transfer`.
|
|
|
|
## Motivation
|
|
|
|
1. support commit-reveal privacy for applications such as voting.
|
|
2. make it harder for attackers for front-running, back-running or sandwich attacks.
|
|
|
|
## Specification
|
|
|
|
The key words “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.
|
|
|
|
Interfaces referenced in this specification are as follows:
|
|
|
|
```solidity
|
|
pragma solidity >=0.7.0 <0.9.0;
|
|
|
|
// The EIP-165 identifier of this interface is 0xf14fcbc8
|
|
interface IERC_COMMIT_CORE {
|
|
function commit(bytes32 _commitment) payable external;
|
|
}
|
|
|
|
pragma solidity >=0.7.0 <0.9.0;
|
|
|
|
// The EIP-165 identifier of this interface is 0x67b2ec2c
|
|
interface IERC_COMMIT_GENERAL {
|
|
event Commit(
|
|
uint256 indexed _timePoint,
|
|
address indexed _from,
|
|
bytes32 indexed _commitment,
|
|
bytes _extraData);
|
|
function commitFrom(
|
|
address _from,
|
|
bytes32 _commitment,
|
|
bytes calldata _extraData)
|
|
payable external returns(uint256 timePoint);
|
|
}
|
|
```
|
|
|
|
1. A compliant contract MUST implement the `IERC_COMMIT_CORE` interface.
|
|
2. A compliant contract SHOULD implement the `IERC_COMMIT_GENERAL` interface.
|
|
3. A compliant contract that implements the `IERC_COMMIT_GENERAL` interface MUST accept `commit(_commitment)` as equivalent to `commitFrom(msg.sender, _commitment, [/*empty array*/])`.
|
|
4. The `timePoint` return value of `commitFrom` is RECOMMENDED to use `block.timestamp` or `block.number` or a number that indicates the ordering of different commitments. When `commitFrom` is being called.
|
|
5. A compliant contract that implements `IERC_COMMIT_GENERAL` MUST emit event `Commit` when a commitment is accepted and recorded. In the parameter of both `Commit` and the `commitFrom` method, the `_timePoint` is a time-point-representing value that represents ordering of commitments in which a latter commitment will always have a _greater or equal value_ than a former commitment, such as `block.timestamp` or `block.number` or other time scale chosen by implementing contracts.
|
|
|
|
6. The `extraData` is reserved for future behavior extension. If the `_from` is different from the TX signer, it is RECOMMENDED that compliant contract SHOULD validate signature for `_from`. For EOAs this will be validating its ECDSA signatures on chain. For smart contract accounts, it is RECOMMENDED to use [EIP-1271](./eip-1271.md) to validate the signatures.
|
|
|
|
7. One or more methods of a compliant contract MAY be used for reveal.
|
|
|
|
But there MUST be a way to supply an extra field of `secret_salt`, so that committer can later open the `secret_salt` in the reveal TX that exposes the `secret_salt`. The size and location of `secret_salt` is intentionally unspecified in this EIP to maximize flexibility for integration.
|
|
|
|
8. It is RECOMMENDED for compliant contracts to implement [EIP-165](./eip-165.md).
|
|
|
|
## Rationale
|
|
|
|
1. One design options is that we can attach a Commit Interface to any individual ERCs such as voting standards or token standards. We choose to have a simple and generalize commit interface so all ERCs can be extended to support commit-reveal without changing their basic method signatures.
|
|
|
|
2. The key derived design decision we made is we will have a standardized `commit` method without a standardized `reveal` method, making room for customized reveal method or using `commit` with existing standard.
|
|
|
|
3. We chose to have a simple one parameter method of `commit` in our Core interface to make it fully backward compatible with a few prior-adoptions e.g. ENS
|
|
|
|
4. We also add a `commitFrom` to easy commitment being generated off-chain and submitted by some account on behalf by another account.
|
|
|
|
## Backwards Compatibility
|
|
|
|
This EIP is backward compatible with all existing ERCs method signature that has extraData. New EIPs can be designed with an extra field of "salt" to make it easier to support this EIP, but not required.
|
|
|
|
The `IERC_COMMIT_CORE` is backward compatible with ENS implementations and other existing prior-art.
|
|
|
|
## Reference Implementation
|
|
|
|
### Commit with ENS Register as Reveal
|
|
|
|
In ENS registering process, currently inside of `ETHRegistrarController` contract a commit function is being used to allow registerer fairly register a desire domain to avoid being front-run.
|
|
|
|
Here is how ENS uses commitment in its registration logic:
|
|
|
|
```solidity
|
|
function commit(bytes32 commitment) public {
|
|
require(commitments[commitment] + maxCommitmentAge < now);
|
|
commitments[commitment] = now;
|
|
}
|
|
```
|
|
|
|
With this EIP it can be updated to
|
|
|
|
```solidity
|
|
function commit(bytes32 commitment, bytes calldata data) public {
|
|
require(commitments[commitment] + maxCommitmentAge < now);
|
|
commitments[commitment] = now;
|
|
emit Commit(...);
|
|
}
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. Do not use the reference implementation in production. It is just for demonstration purposes.
|
|
2. The reveal transactions and parameters, especially `secret_salt`, MUST be kept secret before they are revealed.
|
|
3. The length of `secret_salt` must be cryptographically long enough and the random values used to generate `secret_salt` must be cryptographically safe.
|
|
4. Users must NEVER reuse a used `secret_salt`. It's recommended for client applications to warn users who attempt to do so.
|
|
5. Contract implementations should consider deleting the commitment of a given sender immediately to reduce the chances of a replay attack or re-entry attack.
|
|
6. Contract implementations may consider including the ordering of commitment received to add restrictions on the order of reveal transactions.
|
|
7. There is potential for replay attacks across different chainIds or chains resulting from forks. In these cases, the chainId must be included in the generation of commitment. For applications with a higher risk of replay attacks, implementors should consider battle-tested and cryptographically-secure solutions such as [EIP-712](./eip-712.md) to compose commitments before creating their own new solution.
|
|
8. Proper time gaps are suggested if the purpose is to avoid frontrunning attacks.
|
|
9. For compliant contract that requires the `_timePoint` from the next transaction to be _strictly greater_ than that of any previous transaction, `block.timestamp` and `block.number` are not reliable as two transactions could co-exist in the same block resulting in the same `_timePoint` value. In such case, extra measures to enforce this strict monotonicity are required, such as the use of a separate sate variable in the contract to keep track of number of commits it receives, or to reject any second/other TX that shares the same `block.timestamp` or `block.number`.
|
|
|
|
## Copyright
|
|
|
|
Copyright and related rights waived via [CC0](../LICENSE.md).
|