OpenZeppelin SDK

repository·master·Indexed 19 days ago

https://github.com/openzeppelin/openzeppelin-sdk

A 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.

Tokens
52.3K
Snippets
206
Records
285
Agent score
66%

What's inside openzeppelin-sdk

  1. Understand how network file names are determined

    master

    The OpenZeppelin CLI does not use the name of the network entry from your networks.js file 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 have geth_ropsten and parity_ropsten both configured with network_id: 3, running oz push --network geth_ropsten or oz push --network parity_ropsten will both result in a ropsten.json file.

    // 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: *
        }
      }
    };
  2. API Reference: Application and Package Management

    master

    The 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.
  3. Understanding CREATE vs CREATE2 deployment flows

    master

    Smart contracts can be deployed using two different flows, which result in different address calculation methods:

    CREATE flow

    Addresses 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.

    CREATE2 flow

    Addresses 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, and bytecode are used, the contract will always deploy to the same new_address. This allows for 'counterfactual' deployments where users can interact with an address before the contract actually exists.

  4. How Ethereum Package architecture works

    master

    Ethereum Packages use a hierarchical contract structure to manage versions and contract implementations:

    1. App: The main entry point. It manages 'providers' (Ethereum Packages identified by name and version).
    2. Package: Tracks all versions of a specific Ethereum Package. Versions are mapped via a semver hash to Version structs.
    3. Version: A struct within a Package that contains the semantic version, the contractAddress of the implementation directory, and a contentURI.
    4. 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.
  5. How ProxyAdmin works in Upgrades

    master

    The ProxyAdmin contract 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 deploy or oz create2 command. You can force deployment using oz 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 the ProxyAdmin.upgrade method.
    • Inspection: You can check the current implementation of a proxy using ProxyAdmin.getProxyImplementation.

    You can find your ProxyAdmin address in your local configuration file: .openzeppelin/<network>.json.

    // .openzeppelin/<network>.json
    "proxyAdmin": {
       "address": <proxyAdmin-address>
    }
  6. Upgradeability Validations and Security Checks

    master

    The SDK performs several automated checks to ensure contract upgradeability and prevent storage corruption:

    • Storage Layout Validation: During push operations, 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 check command identifies common errors such as the presence of selfdestruct calls, default values for variables, or the use of constructor in logic contracts.
    • Self-destruct Protection: The SDK includes checks for selfdestruct calls in logic contracts to prevent orphaned proxies.