OpenZeppelin SDK
repository·master·Indexed 19 days ago
https://github.com/openzeppelin/openzeppelin-sdkA Command-Line Interface (CLI) and Upgrades Library for developing, deploying, and operating smart contract projects on EVM-compatible blockchains. It provides tools for managing upgradeable proxies, predictable address deployment via CREATE2, and programmatic contract operations. Note: This SDK (formerly ZeppelinOS) is deprecated in favor of Upgrades Plugins.
What's inside openzeppelin-sdk
- The Upgrades library allows developers to deploy and upgrade smart contracts securely from JavaScript code. It serves as the core engine for the OpenZeppelin CLI, providing all deployment and upgrade operations. Developers can either use the CLI or call the library directly in their own scripts.
Overview of OpenZeppelin CLI commands
masterThe OpenZeppelin CLI provides an interactive interface for developing, deploying, and operating upgradeable smart contract projects on Ethereum and other EVM-powered blockchains.
Note: If you are using Truffle or Buidler, it is recommended to use the Upgrades plugins instead for better integration with your existing workflow.
API Reference: Proxies
masterInformation regarding Proxy contracts and their documentation has moved to the main Contracts documentation. For details on how to use proxies, refer to the dedicated Contracts API documentation.Important notice: OpenZeppelin SDK is deprecated
masterThe OpenZeppelin SDK is not being actively developed. For modern smart contract development and upgrades, it is recommended to use the Upgrades Plugins instead. For more context on this transition, see the OpenZeppelin Forum discussion.Note on package and command renaming
masterIf you are following older documentation (pre-v2.5.0), note that the package was renamed fromzosto@openzeppelin/cliand the command was renamed fromzostoopenzeppelin.Understand how network file names are determined
masterThe OpenZeppelin CLI does not use the name of the network entry from your
networks.jsfile to name the JSON configuration file. Instead, it uses the canonical network ID associated with that entry.- Public Networks: The CLI uses
web3.network.getVersion()to identify the network and determine the filename (e.g.,ropsten.json). - Local Networks: Since local networks lack canonical names, the CLI generates files named
dev-<network_id>.json(e.g.,dev-1540303312049.json).
Example mapping from
networks.js: If you havegeth_ropstenandparity_ropstenboth configured withnetwork_id: 3, runningoz push --network geth_ropstenoroz push --network parity_ropstenwill both result in aropsten.jsonfile.// networks.js module.exports = { networks: { geth_ropsten: { host: 'localhost', port: 8555, network_id: 3 }, parity_ropsten: { host: 'localhost', port: 8565, network_id: 3 }, local: { host: 'localhost', port: 8545, network_id: * } } };- Public Networks: The CLI uses
API Reference: Application and Package Management
masterThe SDK provides abstractions for managing application state, implementation directories, and package structures. Key components include:
App: Represents the application instance.ImplementationDirectory: Manages the directory where implementations are stored.ImplementationProvider: Provides implementations.Package: Represents a package within the SDK ecosystem.
How ProxyFactory works in Upgrades
masterThe
ProxyFactorycontract is used for deploying contracts via theCREATE2opcode or for creating minimal non-upgradeable proxies.- Deployment: It is deployed during your first
openzeppelin create2oropenzeppelin deploy --kind minimalcommand. You can force deployment usingopenzeppelin push --deploy-proxy-factory.
- Deployment: It is deployed during your first
Understanding CREATE vs CREATE2 deployment flows
masterSmart contracts can be deployed using two different flows, which result in different address calculation methods:
CREATEflowAddresses are computed as a function of the sender's address and a nonce:
new_address = hash(sender, nonce)Because nonces are sequential and increase with every transaction or contract creation, the address of the next contract is predictable only if no other transactions occur in the interim. This makes it unsuitable for counterfactual systems.
CREATE2flowAddresses are computed using a constant, the sender's address, a salt, and the contract bytecode:
new_address = hash(0xFF, sender, salt, bytecode)This makes the resulting address independent of future events (like nonces). As long as the same
sender,salt, andbytecodeare used, the contract will always deploy to the samenew_address. This allows for 'counterfactual' deployments where users can interact with an address before the contract actually exists.How Ethereum Package architecture works
masterEthereum Packages use a hierarchical contract structure to manage versions and contract implementations:
- App: The main entry point. It manages 'providers' (Ethereum Packages identified by name and version).
- Package: Tracks all versions of a specific Ethereum Package. Versions are mapped via a semver hash to
Versionstructs. - Version: A struct within a
Packagethat contains the semantic version, thecontractAddressof the implementation directory, and acontentURI. - ImplementationDirectory: A contract that maps contract aliases (e.g., 'ERC20', 'MainContract') to specific deployed implementation addresses. This allows a single version of a package to point to different implementation addresses for different contracts. Directories can be 'frozen' to ensure immutability for official releases.
How ProxyAdmin works in Upgrades
masterThe
ProxyAdmincontract acts as a central administrator for all proxies in your project. It is used to implement the Transparent Proxy Pattern, preventing administrative functions from clashing with proxy logic.Key behaviors:
- Deployment: It is automatically deployed during your first
oz deployoroz create2command. You can force deployment usingoz push --deploy-proxy-admin. - Management: It is responsible for upgrading contracts and transferring ownership of proxies.
- Upgrades: When you run
oz upgrade, the CLI calls theProxyAdmin.upgrademethod. - Inspection: You can check the current implementation of a proxy using
ProxyAdmin.getProxyImplementation.
You can find your
ProxyAdminaddress in your local configuration file:.openzeppelin/<network>.json.// .openzeppelin/<network>.json "proxyAdmin": { "address": <proxyAdmin-address> }- Deployment: It is automatically deployed during your first
Upgradeability Validations and Security Checks
masterThe SDK performs several automated checks to ensure contract upgradeability and prevent storage corruption:
- Storage Layout Validation: During
pushoperations, the SDK validates storage layout changes between subsequent pushes to ensure upgrades do not corrupt existing storage. - Field Declaration Checks: The SDK validates that no initial values are set in field declarations, as these are not applied when initializing a contract instance.
- Upgradeability Error Checking: The
checkcommand identifies common errors such as the presence ofselfdestructcalls, default values for variables, or the use ofconstructorin logic contracts. - Self-destruct Protection: The SDK includes checks for
selfdestructcalls in logic contracts to prevent orphaned proxies.
- Storage Layout Validation: During