npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kyriework/upgrade-control-contracts

v1.1.3

Published

Upgrade Control Contracts

Readme

(已经迁移至 kyriework-contracts 仓库)

合约升级管理系统

这是一个基于代理模式的智能合约升级管理系统,提供了安全可靠的合约升级机制,类似信标代理的集中管理多个可升级合约。

核心功能

🔧 升级管理器 (UpgradeManager)

  • 管理可升级合约的注册与注销
  • 支持合约实现的升级和回滚
  • 版本历史记录和管理
  • 权限控制和管理员转移
  • 需要Owner权限进行合约注册

🌍 开放升级管理器 (UpgradeManagerOpen)

  • 无需许可,任何人都可以注册和管理自己的可升级合约
  • 使用命名空间隔离防止不同用户之间的tag冲突
  • 支持注册人和管理员角色分离
  • 提供完整的升级、回滚和管理功能
  • 继承 IUpgradeManagerOpen 接口

🔄 升级代理 (UpgradeProxy)

  • 基于OpenZeppelin的代理模式
  • 动态获取最新的逻辑合约地址
  • 透明的函数调用代理

📚 升级工具库 (UpgradeLib)

  • 提供升级相关的实用工具函数
  • 统一管理存储槽位和常量
  • 简化升级逻辑的实现

🏗️ 升级逻辑基类 (UpgradeLogicBase)

  • 为可升级逻辑合约提供基础功能
  • 集成初始化器和升级管理功能
  • 抽象基类,便于继承使用

系统架构

中心化管理模式 (UpgradeManager)

用户调用 → UpgradeProxy → 委托调用 → 逻辑合约 (继承 UpgradeLogicBase)
              ↓                            ↓
        UpgradeManager ← ← ← ← ← ← ← ← ← UpgradeLib (工具库)
          (需要Owner权限)

去中心化管理模式 (UpgradeManagerOpen)

用户调用 → UpgradeProxy → 委托调用 → 逻辑合约 (继承 UpgradeLogicBase)
              ↓                            ↓
    UpgradeManagerOpen ← ← ← ← ← ← ← ← ← UpgradeLib (工具库)
      (无需许可访问)
           ↓
    命名空间隔离 (registrant + tag)

合约组件

1. IUpgradeManager.sol

定义了升级管理器的接口,包含:

  • ContractInfo 结构体:存储合约信息(逻辑地址、代理地址、管理员、版本、激活状态)
  • 事件定义:注册、升级、注销、管理员转移
  • 核心函数接口:创建代理、注册、升级、回滚等

2. UpgradeManager.sol

升级管理器的核心实现:

  • 继承 Ownable2Step 提供所有权管理
  • 实现 IUpgradeManager 接口
  • 支持通过 CREATE2 部署代理合约
  • 版本管理和历史记录
  • 权限控制(只有Owner可以注册,只有管理员可以升级)

3. IUpgradeManagerOpen.sol

开放升级管理器的接口定义:

  • 基于 IUpgradeManager 扩展,使用 namespacedTag 参数
  • 支持无需许可的合约注册和管理
  • 提供 getNamespacedTag 函数用于命名空间计算
  • 明确区分注册函数和管理函数的参数类型

4. UpgradeManagerOpen.sol

无需许可的升级管理器实现:

  • 实现 IUpgradeManagerOpen 接口
  • 任何人都可以注册和管理自己的可升级合约
  • 使用 keccak256(abi.encodePacked(registrant, tag)) 进行命名空间隔离
  • 支持注册人和管理员角色分离
  • 提供完整的升级、回滚和管理功能

5. UpgradeProxy.sol

代理合约实现:

  • 继承 OpenZeppelin 的 Proxy 合约
  • 使用 UpgradeLib 管理存储槽位
  • 动态获取当前逻辑合约地址
  • 透明代理所有函数调用

6. UpgradeLib.sol

升级工具库:

  • 定义升级相关的存储槽位常量
  • 提供获取升级管理器地址的函数
  • 提供获取升级标签的函数
  • 提供获取注册信息和管理员地址的函数

7. UpgradeLogicBase.sol

升级逻辑基类:

  • 继承 OpenZeppelin 的 Initializable 合约
  • 使用 UpgradeLib 获取升级相关信息
  • 提供内部函数访问升级管理器、标签、注册信息和管理员
  • 抽象合约,需要被具体逻辑合约继承

核心特性

版本管理

  • 自动版本递增
  • 历史版本记录
  • 支持回滚到指定版本

权限控制

  • 中心化模式:Owner控制合约注册,管理员控制升级
  • 去中心化模式:任何人可以注册,管理员控制升级
  • 支持管理员转移
  • 只有管理员可以执行升级操作

安全机制

  • 地址零值检查
  • 重复注册防护
  • 逻辑合约地址验证
  • 命名空间隔离(UpgradeManagerOpen)

模块化设计

  • 工具库统一管理升级逻辑
  • 基类提供标准升级功能
  • 组件化架构,便于扩展和维护
  • 双模式支持:中心化 vs 去中心化

使用示例

中心化模式 (UpgradeManager)

创建可升级的逻辑合约

// OpenZeppelin
import { Initializable } from '@openzeppelin/contracts/proxy/utils/Initializable.sol';
// UpgradeLogicBase
import {
  UpgradeLogicBase
} from '@kyriework/upgrade-control-contracts/contracts/UpgradeLogicBase.sol';

// 继承 UpgradeLogicBase 基类
contract MyContract is UpgradeLogicBase, Initializable {
  uint256 public value;

  constructor() {
    _disableInitializers();
  }

  function initialize(uint256 _value) public initializer {
    value = _value;
  }

  function setValue(uint256 _value) public {
    // 可以使用基类提供的升级相关函数
    address admin = _upgradeAdminAddress();
    require(msg.sender == admin, 'Only admin can set value');
    value = _value;
  }

  function getUpgradeInfo() external view returns (address manager, bytes32 tag) {
    manager = _upgradeManagerAddress();
    tag = _upgradeTagBytes32();
  }
}

部署和注册合约

// 1. 部署UpgradeManager
UpgradeManager manager = new UpgradeManager(owner);

// 2. 创建代理并注册合约
bytes32 tag = keccak256("MyContract");
address logic = address(new MyContract());
bytes memory initData = abi.encodeWithSignature("initialize(uint256)", 100);
(address proxy, bytes memory result) = manager.createProxy(tag, logic, admin, initData);

// 3. 通过代理调用合约
MyContract(proxy).setValue(200);

去中心化模式 (UpgradeManagerOpen)

部署和注册合约

// 1. 部署UpgradeManagerOpen
UpgradeManagerOpen openManager = new UpgradeManagerOpen();

// 2. 任何人都可以创建代理并注册合约
bytes32 tag = keccak256("MyContract");
address logic = address(new MyContract());
bytes memory initData = abi.encodeWithSignature("initialize(uint256)", 100);
(address proxy, bytes memory result) = openManager.createProxy(tag, logic, admin, initData);

// 3. 获取命名空间标签
bytes32 namespacedTag = openManager.getNamespacedTag(msg.sender, tag);

// 4. 管理员可以升级合约
address newLogic = address(new MyContractV2());
openManager.upgrade(namespacedTag, newLogic); // 只有admin可以调用

权限管理

// 注册人和管理员可以是不同的地址
address registrant = msg.sender;      // 注册合约的用户
address admin = 0x1234...;           // 管理合约的管理员

// 创建代理时指定管理员
openManager.createProxy(tag, logic, admin, initData);

// 计算命名空间标签
bytes32 namespacedTag = openManager.getNamespacedTag(registrant, tag);

// 只有管理员可以升级
openManager.upgrade(namespacedTag, newLogic); // 必须由admin调用

升级合约

// OpenZeppelin
import { Initializable } from '@openzeppelin/contracts/proxy/utils/Initializable.sol';
// UpgradeLogicBase
import { UpgradeLogicBase } from '@kyriework/upgrade-control-contracts/contracts/UpgradeLogicBase.sol';

// 部署新的逻辑合约(继承 UpgradeLogicBase)
contract MyContractV2 is UpgradeLogicBase, Initializable {

    uint256 public value;
    uint256 public newFeature; // 新增功能

    constructor() {
        _disableInitializers();
    }

    function initialize(uint256 _value) public initializer {
        value = _value;
    }

    function setNewFeature(uint256 _newFeature) public {
        address admin = _upgradeAdminAddress();
        require(msg.sender == admin, "Only admin");
        newFeature = _newFeature;
    }
}

// 中心化模式升级
address newLogic = address(new MyContractV2());
manager.upgrade(tag, newLogic);

// 去中心化模式升级
bytes32 namespacedTag = openManager.getNamespacedTag(registrant, tag);
openManager.upgrade(namespacedTag, newLogic);

回滚合约

// 中心化模式回滚
manager.rollback(tag, 1); // 回滚到版本1

// 去中心化模式回滚
openManager.rollback(namespacedTag, 1); // 回滚到版本1

开发和测试

安装依赖

pnpm install

编译合约

npx hardhat compile

运行测试

npx hardhat test

部署合约

npx hardhat ignition deploy ./ignition/modules/UpgradeManager.js

获取测试报告

REPORT_GAS=true npx hardhat test

技术栈

  • Solidity ^0.8.20: 智能合约开发语言
  • OpenZeppelin: 安全的智能合约库
  • Hardhat: 以太坊开发环境
  • 代理模式: 可升级合约架构模式
  • 库模式: 代码复用和模块化
  • 命名空间隔离: 防止多用户环境下的冲突

注意事项

  1. 存储布局兼容性: 升级时需要保持存储布局的兼容性
  2. 权限管理: 合理设置管理员权限,避免权限滥用
  3. 版本管理: 建议在升级前进行充分测试
  4. Gas优化: 代理调用会产生额外的Gas开销
  5. 基类继承: 逻辑合约应该继承 UpgradeLogicBase 以获得完整的升级功能
  6. 初始化器: 使用 initializer 修饰符确保初始化函数只被调用一次
  7. 命名空间管理: 在 UpgradeManagerOpen 中,确保使用正确的 namespacedTag 进行管理操作
  8. 角色分离: 注册人和管理员可以是不同的地址,合理规划权限分配

选择指南

使用 UpgradeManager 的场景

  • 需要集中管理和控制合约注册
  • 企业级应用,需要严格的权限控制
  • 合约数量较少,管理相对简单
  • 有明确的系统管理员角色

使用 UpgradeManagerOpen 的场景

  • 开放平台,允许任何人注册可升级合约
  • 去中心化应用,减少中心化控制
  • 多用户环境,需要隔离不同用户的合约
  • 需要灵活的权限管理(注册人 ≠ 管理员)

许可证

MIT