Make Offer Signature Structure
Centralized Verification
NameService signatures are verified by Core.sol using validateAndConsumeNonce(). Uses NameServiceHashUtils.hashDataForMakeOffer() for hash generation.
To authorize the makeOffer operation within the Name Service, the user (the offeror) must generate a cryptographic signature compliant with the EIP-191 standard using the Ethereum Signed Message format.
Signature Format
{evvmId},{senderExecutor},{hashPayload},{originExecutor},{nonce},{isAsyncExec}
Components:
- evvmId: Network identifier (uint256, typically
1) - senderExecutor: Address that can call the function via msg.sender (
0x0...0for anyone) - hashPayload: Hash of offer parameters (bytes32, from NameServiceHashUtils)
- originExecutor: EOA that can initiate the transaction via tx.origin (
0x0...0for anyone) - nonce: User's centralized nonce from Core.sol (uint256)
- isAsyncExec: Always
truefor NameService (async execution)
Hash Payload Generation
The hashPayload is generated using NameServiceHashUtils.hashDataForMakeOffer():
import {NameServiceHashUtils} from "@evvm/testnet-contracts/library/signature/NameServiceHashUtils.sol";
bytes32 hashPayload = NameServiceHashUtils.hashDataForMakeOffer(
username, // Target username
amount, // Offer amount in tokens
expirationDate // Unix timestamp when offer expires
);
// Internal implementation
// keccak256(abi.encode("makeOffer", username, amount, expirationDate))
Example
Scenario: User wants to make an offer on username "alice"
Step 1: Generate Hash Payload
string memory username = "alice";
uint256 amount = 1000; // tokens
uint256 expirationDate = 1735689600; // January 1, 2025
bytes32 hashPayload = NameServiceHashUtils.hashDataForMakeOffer(
username,
amount,
expirationDate
);
Step 2: Construct and Sign Message
1,0x0000000000000000000000000000000000000000,0x[hashPayload],0x0000000000000000000000000000000000000000,5,true
Technical Details
- Hash Independence: The hash payload does NOT include executors (only username, amount, expirationDate)
- Operation Name: "makeOffer" is included in hash via NameServiceHashUtils
- Async Execution: Always uses async nonces (
isAsyncExec: true)
EIP-191 formatted message hash:
keccak256(abi.encodePacked(
"\x19Ethereum Signed Message:\n36",
"1,makeOffer,alice,1735689600,1000,5"
))
Concatenated parameters breakdown:
alice- The username being offered on1735689600- Unix timestamp when the offer expires1000- Amount of tokens being offered5- The offeror's name service nonce
Technical Details
- Message Format:
"{evvmID},{functionName},{parameters}" - EIP-191 Compliance: Uses
"\x19Ethereum Signed Message:\n"prefix with message length - Expiration Logic:
_dateExpiremust be a future Unix timestamp - Token Amount:
_amountrepresents the total tokens offered for the username - Replay Protection:
_nameServiceNonceprevents replay attacks for offer actions - EVVM ID: Identifies the specific EVVM instance for signature verification
tip
- The function selector
d82e5d8bis the first 4 bytes of the keccak256 hash of the function signature forverifyMessageSignedForMakeOffer Strings.toStringconverts a number to a string (standard OpenZeppelin utility)- The signature verification uses the EIP-191 standard for message signing
- The
_dateExpireparameter should be a Unix timestamp representing when the offer expires - The
_amountrepresents the total amount of tokens being offered for the username