Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
| Transaction Hash |
Method
|
Block
|
From
|
To
|
Amount
|
||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | Amount | ||
|---|---|---|---|---|---|---|
| 9658043 | 756 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
ERC6538Registry
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: CC0-1.0
pragma solidity 0.8.23;
/// @notice `ERC6538Registry` contract to map accounts to their stealth meta-address. See
/// [ERC-6538](https://eips.ethereum.org/EIPS/eip-6538) to learn more.
contract ERC6538Registry {
/// @notice Emitted when an invalid signature is provided to `registerKeysOnBehalf`.
error ERC6538Registry__InvalidSignature();
/// @notice Next nonce expected from `user` to use when signing for `registerKeysOnBehalf`.
/// @dev `registrant` may be a standard 160-bit address or any other identifier.
/// @dev `schemeId` is an integer identifier for the stealth address scheme.
mapping(address registrant => mapping(uint256 schemeId => bytes)) public stealthMetaAddressOf;
/// @notice A nonce used to ensure a signature can only be used once.
/// @dev `registrant` is the user address.
/// @dev `nonce` will be incremented after each valid `registerKeysOnBehalf` call.
mapping(address registrant => uint256) public nonceOf;
/// @notice The EIP-712 type hash used in `registerKeysOnBehalf`.
bytes32 public constant ERC6538REGISTRY_ENTRY_TYPE_HASH =
keccak256("Erc6538RegistryEntry(uint256 schemeId,bytes stealthMetaAddress,uint256 nonce)");
/// @notice The chain ID where this contract is initially deployed.
uint256 internal immutable INITIAL_CHAIN_ID;
/// @notice The domain separator used in this contract.
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
/// @notice Emitted when a registrant updates their stealth meta-address.
/// @param registrant The account that registered the stealth meta-address.
/// @param schemeId Identifier corresponding to the applied stealth address scheme, e.g. 1 for
/// secp256k1, as specified in ERC-5564.
/// @param stealthMetaAddress The stealth meta-address.
/// [ERC-5564](https://eips.ethereum.org/EIPS/eip-5564) bases the format for stealth
/// meta-addresses on [ERC-3770](https://eips.ethereum.org/EIPS/eip-3770) and specifies them as:
/// st:<shortName>:0x<spendingPubKey>:<viewingPubKey>
/// The chain (`shortName`) is implicit based on the chain the `ERC6538Registry` is deployed on,
/// therefore this `stealthMetaAddress` is just the compressed `spendingPubKey` and
/// `viewingPubKey` concatenated.
event StealthMetaAddressSet(
address indexed registrant, uint256 indexed schemeId, bytes stealthMetaAddress
);
/// @notice Emitted when a registrant increments their nonce.
/// @param registrant The account that incremented the nonce.
/// @param newNonce The new nonce value.
event NonceIncremented(address indexed registrant, uint256 newNonce);
constructor() {
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = _computeDomainSeparator();
}
/// @notice Sets the caller's stealth meta-address for the given scheme ID.
/// @param schemeId Identifier corresponding to the applied stealth address scheme, e.g. 1 for
/// secp256k1, as specified in ERC-5564.
/// @param stealthMetaAddress The stealth meta-address to register.
function registerKeys(uint256 schemeId, bytes calldata stealthMetaAddress) external {
stealthMetaAddressOf[msg.sender][schemeId] = stealthMetaAddress;
emit StealthMetaAddressSet(msg.sender, schemeId, stealthMetaAddress);
}
/// @notice Sets the `registrant`'s stealth meta-address for the given scheme ID.
/// @param registrant Address of the registrant.
/// @param schemeId Identifier corresponding to the applied stealth address scheme, e.g. 1 for
/// secp256k1, as specified in ERC-5564.
/// @param signature A signature from the `registrant` authorizing the registration.
/// @param stealthMetaAddress The stealth meta-address to register.
/// @dev Supports both EOA signatures and EIP-1271 signatures.
/// @dev Reverts if the signature is invalid.
function registerKeysOnBehalf(
address registrant,
uint256 schemeId,
bytes memory signature,
bytes calldata stealthMetaAddress
) external {
bytes32 dataHash;
address recoveredAddress;
unchecked {
dataHash = keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
ERC6538REGISTRY_ENTRY_TYPE_HASH,
schemeId,
keccak256(stealthMetaAddress),
nonceOf[registrant]++
)
)
)
);
}
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
assembly ("memory-safe") {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
recoveredAddress = ecrecover(dataHash, v, r, s);
}
if (
(
(recoveredAddress == address(0) || recoveredAddress != registrant)
&& (
IERC1271(registrant).isValidSignature(dataHash, signature)
!= IERC1271.isValidSignature.selector
)
)
) revert ERC6538Registry__InvalidSignature();
stealthMetaAddressOf[registrant][schemeId] = stealthMetaAddress;
emit StealthMetaAddressSet(registrant, schemeId, stealthMetaAddress);
}
/// @notice Increments the nonce of the sender to invalidate existing signatures.
function incrementNonce() external {
unchecked {
nonceOf[msg.sender]++;
}
emit NonceIncremented(msg.sender, nonceOf[msg.sender]);
}
/// @notice Returns the domain separator used in this contract.
/// @dev The domain separator is re-computed if there's a chain fork.
function DOMAIN_SEPARATOR() public view returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : _computeDomainSeparator();
}
/// @notice Computes the domain separator for this contract.
function _computeDomainSeparator() internal view returns (bytes32) {
return keccak256(
abi.encode(
keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
),
keccak256("ERC6538Registry"),
keccak256("1.0"),
block.chainid,
address(this)
)
);
}
}
/// @notice Interface of the ERC1271 standard signature validation method for contracts as defined
/// in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
interface IERC1271 {
/// @notice Should return whether the signature provided is valid for the provided data
/// @param hash Hash of the data to be signed
/// @param signature Signature byte array associated with _data
function isValidSignature(bytes32 hash, bytes memory signature)
external
view
returns (bytes4 magicValue);
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/"
],
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC6538Registry__InvalidSignature","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"registrant","type":"address"},{"indexed":false,"internalType":"uint256","name":"newNonce","type":"uint256"}],"name":"NonceIncremented","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"registrant","type":"address"},{"indexed":true,"internalType":"uint256","name":"schemeId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"stealthMetaAddress","type":"bytes"}],"name":"StealthMetaAddressSet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ERC6538REGISTRY_ENTRY_TYPE_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registrant","type":"address"}],"name":"nonceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"schemeId","type":"uint256"},{"internalType":"bytes","name":"stealthMetaAddress","type":"bytes"}],"name":"registerKeys","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registrant","type":"address"},{"internalType":"uint256","name":"schemeId","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"stealthMetaAddress","type":"bytes"}],"name":"registerKeysOnBehalf","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registrant","type":"address"},{"internalType":"uint256","name":"schemeId","type":"uint256"}],"name":"stealthMetaAddressOf","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60c060405234801561001057600080fd5b50466080526100bd604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6124ff9f656d31cbb8918f3698282fe3b3527cc4dede357f0fbf535d197bbb7f918101919091527fe6bbd6277e1bf288eed5e8d1780f9a50b239e86b153736bceebccf4ea79d90b360608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b60a05260805160a051610c4b6100e56000396000610287015260006101b20152610c4b6000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063627cdcb91161005b578063627cdcb9146100c55780637aa8b5ad146100cd578063ed2a2d64146100ed578063fe04b1061461010d57600080fd5b8063042c7aa3146100825780633644e51514610097578063428d3d0b146100b2575b600080fd5b610095610090366004610743565b610134565b005b61009f6101ae565b6040519081526020015b60405180910390f35b6100956100c03660046107e7565b6102a9565b61009561060a565b6100e06100db3660046108fc565b610658565b6040516100a9919061098a565b61009f6100fb3660046109a4565b60016020526000908152604090205481565b61009f7fad167d3025c204a322703b7e9c41f6179d0d174570f484391f50080b960d41d681565b336000908152602081815260408083208684529091529020610157828483610a63565b50823373ffffffffffffffffffffffffffffffffffffffff167f4e739a47dfa4fd3cfa92f8fe760cebe125565927e5c422cb28e7aa388a067af984846040516101a1929190610b7e565b60405180910390a3505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146102845761027f604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6124ff9f656d31cbb8918f3698282fe3b3527cc4dede357f0fbf535d197bbb7f918101919091527fe6bbd6277e1bf288eed5e8d1780f9a50b239e86b153736bceebccf4ea79d90b360608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6000806102b46101ae565b7fad167d3025c204a322703b7e9c41f6179d0d174570f484391f50080b960d41d68786866040516102e6929190610bcb565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8d166000908152600160208181529390912080549182019055610344959493919290910193845260208401929092526040830152606082015260800190565b6040516020818303038152906040528051906020012060405160200161039c9291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209150845160410361042d576020858101516040808801516060808a015183516000808252968101808652899052951a928501839052840183905260808401819052919260019060a0016020604051602081039080840390855afa15801561041d573d6000803e3d6000fd5b5050506020604051035193505050505b73ffffffffffffffffffffffffffffffffffffffff8116158061047c57508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561053f57506040517f1626ba7e000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff891690631626ba7e906104d99086908a90600401610bdb565b602060405180830381865afa1580156104f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051a9190610bfc565b7fffffffff000000000000000000000000000000000000000000000000000000001614155b15610576576040517fc5c2e66100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832089845290915290206105af848683610a63565b50858773ffffffffffffffffffffffffffffffffffffffff167f4e739a47dfa4fd3cfa92f8fe760cebe125565927e5c422cb28e7aa388a067af986866040516105f9929190610b7e565b60405180910390a350505050505050565b3360008181526001602081815260409283902080549092019182905591519081527fa82a649bbd060c9099cd7b7326e2b0dc9e9af0836480e0f849dc9eaa79710b3b910160405180910390a2565b600060208181529281526040808220909352908152208054610679906109bf565b80601f01602080910402602001604051908101604052809291908181526020018280546106a5906109bf565b80156106f25780601f106106c7576101008083540402835291602001916106f2565b820191906000526020600020905b8154815290600101906020018083116106d557829003601f168201915b505050505081565b60008083601f84011261070c57600080fd5b50813567ffffffffffffffff81111561072457600080fd5b60208301915083602082850101111561073c57600080fd5b9250929050565b60008060006040848603121561075857600080fd5b83359250602084013567ffffffffffffffff81111561077657600080fd5b610782868287016106fa565b9497909650939450505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146107b357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806000608086880312156107ff57600080fd5b6108088661078f565b945060208601359350604086013567ffffffffffffffff8082111561082c57600080fd5b818801915088601f83011261084057600080fd5b813581811115610852576108526107b8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610898576108986107b8565b816040528281528b60208487010111156108b157600080fd5b8260208601602083013760006020848301015280975050505060608801359150808211156108de57600080fd5b506108eb888289016106fa565b969995985093965092949392505050565b6000806040838503121561090f57600080fd5b6109188361078f565b946020939093013593505050565b6000815180845260005b8181101561094c57602081850181015186830182015201610930565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061099d6020830184610926565b9392505050565b6000602082840312156109b657600080fd5b61099d8261078f565b600181811c908216806109d357607f821691505b602082108103610a0c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610a5e576000816000526020600020601f850160051c81016020861015610a3b5750805b601f850160051c820191505b81811015610a5a57828155600101610a47565b5050505b505050565b67ffffffffffffffff831115610a7b57610a7b6107b8565b610a8f83610a8983546109bf565b83610a12565b6000601f841160018114610ae15760008515610aab5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355610b77565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015610b305786850135825560209485019460019092019101610b10565b5086821015610b6b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b8183823760009101908152919050565b828152604060208201526000610bf46040830184610926565b949350505050565b600060208284031215610c0e57600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461099d57600080fdfea164736f6c6343000817000a
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063627cdcb91161005b578063627cdcb9146100c55780637aa8b5ad146100cd578063ed2a2d64146100ed578063fe04b1061461010d57600080fd5b8063042c7aa3146100825780633644e51514610097578063428d3d0b146100b2575b600080fd5b610095610090366004610743565b610134565b005b61009f6101ae565b6040519081526020015b60405180910390f35b6100956100c03660046107e7565b6102a9565b61009561060a565b6100e06100db3660046108fc565b610658565b6040516100a9919061098a565b61009f6100fb3660046109a4565b60016020526000908152604090205481565b61009f7fad167d3025c204a322703b7e9c41f6179d0d174570f484391f50080b960d41d681565b336000908152602081815260408083208684529091529020610157828483610a63565b50823373ffffffffffffffffffffffffffffffffffffffff167f4e739a47dfa4fd3cfa92f8fe760cebe125565927e5c422cb28e7aa388a067af984846040516101a1929190610b7e565b60405180910390a3505050565b60007f0000000000000000000000000000000000000000000000000000000000aa37dc46146102845761027f604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6124ff9f656d31cbb8918f3698282fe3b3527cc4dede357f0fbf535d197bbb7f918101919091527fe6bbd6277e1bf288eed5e8d1780f9a50b239e86b153736bceebccf4ea79d90b360608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b905090565b507ff99e9567397fe70872680ca30fcddbe1e638037c2b94a4914fbd7d01d0ae821b90565b6000806102b46101ae565b7fad167d3025c204a322703b7e9c41f6179d0d174570f484391f50080b960d41d68786866040516102e6929190610bcb565b6040805191829003822073ffffffffffffffffffffffffffffffffffffffff8d166000908152600160208181529390912080549182019055610344959493919290910193845260208401929092526040830152606082015260800190565b6040516020818303038152906040528051906020012060405160200161039c9291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209150845160410361042d576020858101516040808801516060808a015183516000808252968101808652899052951a928501839052840183905260808401819052919260019060a0016020604051602081039080840390855afa15801561041d573d6000803e3d6000fd5b5050506020604051035193505050505b73ffffffffffffffffffffffffffffffffffffffff8116158061047c57508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b801561053f57506040517f1626ba7e000000000000000000000000000000000000000000000000000000008082529073ffffffffffffffffffffffffffffffffffffffff891690631626ba7e906104d99086908a90600401610bdb565b602060405180830381865afa1580156104f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061051a9190610bfc565b7fffffffff000000000000000000000000000000000000000000000000000000001614155b15610576576040517fc5c2e66100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832089845290915290206105af848683610a63565b50858773ffffffffffffffffffffffffffffffffffffffff167f4e739a47dfa4fd3cfa92f8fe760cebe125565927e5c422cb28e7aa388a067af986866040516105f9929190610b7e565b60405180910390a350505050505050565b3360008181526001602081815260409283902080549092019182905591519081527fa82a649bbd060c9099cd7b7326e2b0dc9e9af0836480e0f849dc9eaa79710b3b910160405180910390a2565b600060208181529281526040808220909352908152208054610679906109bf565b80601f01602080910402602001604051908101604052809291908181526020018280546106a5906109bf565b80156106f25780601f106106c7576101008083540402835291602001916106f2565b820191906000526020600020905b8154815290600101906020018083116106d557829003601f168201915b505050505081565b60008083601f84011261070c57600080fd5b50813567ffffffffffffffff81111561072457600080fd5b60208301915083602082850101111561073c57600080fd5b9250929050565b60008060006040848603121561075857600080fd5b83359250602084013567ffffffffffffffff81111561077657600080fd5b610782868287016106fa565b9497909650939450505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146107b357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000806000608086880312156107ff57600080fd5b6108088661078f565b945060208601359350604086013567ffffffffffffffff8082111561082c57600080fd5b818801915088601f83011261084057600080fd5b813581811115610852576108526107b8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908382118183101715610898576108986107b8565b816040528281528b60208487010111156108b157600080fd5b8260208601602083013760006020848301015280975050505060608801359150808211156108de57600080fd5b506108eb888289016106fa565b969995985093965092949392505050565b6000806040838503121561090f57600080fd5b6109188361078f565b946020939093013593505050565b6000815180845260005b8181101561094c57602081850181015186830182015201610930565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061099d6020830184610926565b9392505050565b6000602082840312156109b657600080fd5b61099d8261078f565b600181811c908216806109d357607f821691505b602082108103610a0c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f821115610a5e576000816000526020600020601f850160051c81016020861015610a3b5750805b601f850160051c820191505b81811015610a5a57828155600101610a47565b5050505b505050565b67ffffffffffffffff831115610a7b57610a7b6107b8565b610a8f83610a8983546109bf565b83610a12565b6000601f841160018114610ae15760008515610aab5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355610b77565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b82811015610b305786850135825560209485019460019092019101610b10565b5086821015610b6b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b8183823760009101908152919050565b828152604060208201526000610bf46040830184610926565b949350505050565b600060208284031215610c0e57600080fd5b81517fffffffff000000000000000000000000000000000000000000000000000000008116811461099d57600080fdfea164736f6c6343000817000a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.