EIP-712: Typed Structured Data Hashing and Signing
Before EIP-712, off-chain signing showed users a hex blob that even technical users couldn't verify. EIP-712 introduced typed structured data: signing requests carry a typed schema that wallets render as human-readable fields ("Approve 100 USDC for Uniswap until 2026-01-01").
Mechanics
- Define a Solidity-like type schema:
struct Permit { address owner; ...; uint256 deadline; }. - Compute
domainSeparatorfrom(name, version, chainId, verifyingContract). - Compute
structHash = keccak256(typeHash || encoded fields). - The digest is
keccak256(0x1901 || domainSeparator || structHash). - Wallet signs the digest;
ecrecoververifies on-chain.
Why Neo Doesn't Need It
Neo wallets sign the actual transaction by default, and Neo transactions are already structured: Signers, Witnesses, Script. Wallets render the script's invocation parameters (which contract, which method, which args) — humans see exactly what they're authorising.
For off-chain signed messages (e.g. marketplace listings), Neo uses a similar "sign hashed message" primitive but without the EIP-712 schema layer because the message format is application-specific and already documented in the dApp.
Live on Neo TestNet
Both implementations are deployed on Neo N3 TestNet (network magic 894710606).
| Implementation | Contract Hash | Deploy Tx |
|---|---|---|
Solidity (neo-solc) | 0x8e501310318f17d20674c639fc49b5e6100f5fdd | (reused — see 0x8e501310318f17d20674c639fc49b5e6100f5fdd) |
Neo C# (nccs) | 0x38e8f069271cbbbdfd2032629e733a528cd57c9a | (reused — see 0x38e8f069271cbbbdfd2032629e733a528cd57c9a) |
The source pair exposes the same domain separator, and the manifest now asserts it on both implementations. Source pairs under docs/standards-mirror/deployments/eip-712/.
