ERC-5202: Blueprint Contract Format
ERC-5202 standardises a container format for storing initcode (or any contract bytecode) inside another contract's runtime, with a 0xFE71 magic prefix that ensures the blueprint can never be executed directly. The pattern lets you "ship" deployable code as a regular contract — factory contracts read the blueprint via EXTCODECOPY, then deploy clones via CREATE / CREATE2. Vyper popularised it; Solidity toolchains added support for blueprint-aware factories soon after.
Container Format
0xFE71<version_bits><len_bits><preamble_data><initcode>0xFE71— magic bytes; the leading0xFEis a guaranteed-invalid EVM opcode, so the runtime is uncallable.<version_bits>— 2 bits, currently00.<len_bits>— 2 bits, encodes the preamble length width.<preamble_data>— optional metadata (compiler version, source hash, etc.).<initcode>— the actual contract code to deploy.
A factory reads EXTCODECOPY(blueprint_address, 0, size), parses the header, extracts the initcode, then CREATE2(0, initcode, salt) to deploy a fresh contract from it. The blueprint itself just holds bytes — it can be referenced by many factories or used as a template for clone swarms.
Why It Exists
Pre-5202, "deploy code from data" patterns were ad-hoc:
- Factories embedded the initcode as a
bytesconstant in their own runtime. - Some used
EXTCODECOPYagainst arbitrary contract addresses (fragile; the source contract might be self-destructed or callable in unexpected ways). - ERC-1167 minimal proxies stored only a fixed forwarding stub, which doesn't help when each clone needs distinct initcode.
ERC-5202 normalises the "blueprint as data container" pattern with a guaranteed-invalid runtime so blueprints can't be confused with callable contracts.
Neo Equivalent: NEF Blob Storage + ContractManagement.Deploy
Neo's deployment model already separates "the bytes that will be deployed" (the NEF + manifest) from "the act of deploying them" (ContractManagement.Deploy(nef, manifest)). Storing those bytes in a contract's Storage and looking them up at deploy time is the direct equivalent of ERC-5202's pattern — and it's been usable since day one, without needing an EVM opcode hack to render the storage uncallable (because Storage isn't callable to begin with).
public static void StoreBlueprint(ByteString name, ByteString nef, ByteString manifestJson)
{
if (!Runtime.CheckWitness(GetAdmin())) throw new Exception("admin only");
var ctx = Storage.CurrentContext;
Storage.Put(ctx, NefKey(name), nef);
Storage.Put(ctx, ManifestKey(name), manifestJson);
}
public static UInt160 DeployFromBlueprint(ByteString name, object data)
{
var ctx = Storage.CurrentContext;
var nef = Storage.Get(ctx, NefKey(name));
var manifestStr = Storage.Get(ctx, ManifestKey(name));
var contract = (Contract)ContractManagement.Deploy(nef, manifestStr, data);
return contract.Hash;
}| ERC-5202 (Ethereum) | Neo Equivalent | Notes |
|---|---|---|
Blueprint stored as a contract's runtime, prefixed with 0xFE71 | Blueprint stored as raw bytes in another contract's Storage | Storage isn't callable; no magic-prefix hack needed |
EXTCODECOPY(blueprint, 0, size) to extract | Storage.Get(ctx, key) to extract | Direct read, no opcode quirks |
CREATE / CREATE2(salt, initcode) to deploy | ContractManagement.Deploy(nef, manifest, data) | Native deploy primitive |
| Per-blueprint version/preamble bits in header | NEF version + checksum in the NEF header itself | Already structured; no need for parallel preamble |
| Factory must validate magic prefix | No validation needed; if it's not a valid NEF, Deploy reverts | Cleaner failure mode |
Why Neo Doesn't Need The ERC
ERC-5202 exists because Ethereum entangles "is this address a deployable template?" with "can I call this address?". The 0xFE prefix is a hack to ensure blueprints are uncallable. On Neo, deployable blobs live in storage, not in a contract's runtime — the entanglement doesn't exist, so the hack isn't needed.
The mirror page exists to make the equivalent pattern explicit: "blueprint contracts" on Neo are just contracts with Storage slots holding NEFs, plus a Deploy method that consumes them. The shape is the same as ERC-5202; the implementation is simpler.
Migration Notes
For Solidity factories using ERC-5202 blueprints:
- Store the NEF + manifest in your factory's storage instead of storing the runtime of a blueprint contract. Use a name → bytes map.
- Replace
EXTCODECOPYwithStorage.Getin your deploy method. - Replace
CREATE2(salt, initcode)withContractManagement.Deploy(nef, manifest, data). Salt becomes part ofdataor part of the manifest name (for address uniqueness). - Drop the magic-prefix validation — Neo's deploy primitive validates the NEF format itself.
For storing multiple blueprints (e.g. a factory that ships V1, V2, V3 versions of a contract), namespace storage keys by version: (blueprint, "v1") -> nef_bytes etc.
