ERC-7201: Namespaced Storage Layout
ERC-7201 standardises how upgradeable Solidity contracts compute non-colliding storage slots: hash the namespace string with keccak256 and store everything under that root. Without this, two facets in a diamond proxy can collide on slot 0 and silently corrupt each other.
Required Convention
// keccak256(abi.encode(uint256(keccak256("erc7201:my.namespace")) - 1))
// & ~bytes32(uint256(0xff))
bytes32 constant MY_STORAGE = 0xa1b2c3...;
struct MyStorage { uint256 totalSupply; mapping(address => uint256) balances; }
function _store() private pure returns (MyStorage storage $) {
assembly { $.slot := MY_STORAGE }
}Neo Equivalent
The Neo storage model is byte-prefix based by convention — every contract picks a single-byte prefix per logical map. Collision is structurally avoided because prefix bytes are short, hand-picked, and visible in the source. The "port" below just demonstrates the canonical Neo idiom.
Live on Neo TestNet
Both implementations are deployed on Neo N3 TestNet (network magic 894710606).
| Implementation | Contract Hash | Deploy Tx |
|---|---|---|
Solidity (neo-solc) | 0xbb2553c79f3a740113bf22fbadb6828a9bdbdf32 | (reused — see 0xbb2553c79f3a740113bf22fbadb6828a9bdbdf32) |
Neo C# (nccs) | 0x0932ad78b3d71c7af06468604f1d00ef89c3205d | (reused — see 0x0932ad78b3d71c7af06468604f1d00ef89c3205d) |
Cross-implementation invocations match on all read methods. Source pairs under docs/standards-mirror/deployments/erc-7201/.
