eip | title | description | author | discussions-to | status | type | category | created | requires |
---|---|---|---|---|---|---|---|---|---|
<to be assigned> |
ERC-721 zk-Provable Token Extension |
An extension to the ERC-721 standard to introduce private stealth addresses |
Anton Wahrstätter (@Nerolation) |
Idea |
Standards Track |
ERC |
2022-08-10 |
EIP 165, 721 |
This specification defines an extension to the ERC-721 standard. The extension adds standardized stealth addresses to the ERC-721 standard to enable users private token ownership.
A standard interface for private ERC-721 tokens that enables users to recieve tokens without letting other users know.
Using Stealth Addresses that are generated from a shared secret between the sender and the receiver, the recipients of transfers are obfuscated.
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.
Every ERC0000
compliant contract MUST implement the ERC-721
(0x80ac58cd
) and ERC165
(0x01ffc9a7
TBD) interfaces:
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.6;
...
interface ERC0001 /* is ERC721, ERC165 */ {
/// @notice Broadcasts event with a ``Shared Secret``.
/// @dev Emits event with private transfer information `S`.
/// S is generated by the sender an represents the public key to the private key `s`.
/// s is a user-generated secret (MUST NOT be the senders account private key).
/// The sender broadcasts S for every transfer. Users can use S to check if they were
/// the recipients of a respective transfer.
/// @param publishableData The public key to the sender's secret
event PrivateTransfer(bytes publishableData)
}
Stealth Address Generation
Sender Keypair --> (s,S) | S = s * G // s represents a sender-generated secret
Recipient Keypair --> (p,P) | P = p * G
For transfering:
sharedSecret = s*P
stealthAddress = pubtoaddr(P + (G * keccak(sharedSecret))) # // ``to`` value
publishableData = G * s = S // ``publishableData`` value
For receiving:
forall publishableData `S` do:
if pubtoaddr(P + (G * keccak(S * p))) has token:
store_key(p + keccak(S * p))
EIP-
emerged from the need of having privacy-preserving ways for interacting with non-fungible tokens (NFTs). NFTs can reveal sensitive private information about the owner. While users might want to prove the ownership of a NFT-concert ticket, they might not want to reveal personal account-related information at the same time. The standardization of stealth address generation for NFTs represents a significant step for privacy. Privacy-preserving solutions require standards to gain adoption, therefore it is critical to focus on generalisable ways of implement ownership-proofs into related contracts.
TBD This extension standardizes the method to create and look-up Stealth Addresses.
EIP--- is not backwards compatibly with basic ERC-721
contracts. EIP---
implements the EIP-165
standard.
You can find an implementation of this standard in assets/eip.sol.
TBD
Copyright and related rights waived via CC0.