本文详细介绍了如何使用OpenZeppelin合约库开发安全的智能合约,强调优先使用库组件而非自定义代码。它提供了从库源码中发现集成模式的详细步骤,涵盖了依赖识别、源码阅读、模式提取和应用。文章还提到了使用MCP生成器作为可选的快捷方式来加速集成。
对于概念性问题(例如“Ownable 是如何工作的?”),请解释而不生成代码。对于实现请求,请按照以下工作流程进行。
在生成代码或提出修改建议之前:
Glob 模式匹配 **/*.sol, **/*.cairo, **/*.rs 等)如果文件无法读取,请明确指出失败——报告尝试的路径和原因。询问路径是否正确。切勿在静默中回退到通用响应,仿佛文件不存在一样。
在编写任何逻辑之前,请在 OpenZeppelin 库中搜索现有组件:
切勿将库源代码复制或嵌入到用户的合约中。 始终从依赖项导入,以便项目能够接收安全更新。切勿手动编写库已提供的内容:
Pausable 或 ERC20Pausable 时,切勿编写自定义的 paused 修改器Ownable 时,切勿编写 require(msg.sender == owner)主要的工作流程是从库源代码中发现模式:
完整的逐步程序请参见下文的 模式发现与集成。
如果在运行时有可用的 MCP 生成器工具,请使用它们来加速模式发现:生成一个基线,启用一个功能后再次生成,比较差异,然后将更改应用到用户的代码中。这取代了手动阅读源代码的步骤,但遵循相同的原则——发现模式,然后集成它们。
有关检查可用性和使用生成-比较-应用捷径的详细信息,请参见 MCP 生成器(可选)。
如果没有适用于所需功能的 MCP 工具,请使用 模式发现与集成 中的通用模式发现方法。没有 MCP 工具并不意味着库缺乏支持——它仅表示没有生成器。
通过阅读依赖项源代码来发现和应用 OpenZeppelin 合约集成模式的程序指南。适用于任何生态系统和任何库版本。
先决条件:始终遵循上述库优先决策树(优先选择库组件而非自定义代码,切勿复制/嵌入源代码)。
Glob 模式匹配 **/*.sol, **/*.cairo, **/*.rs,或从下面的查找表中获取相关扩展名。node_modules/@openzeppelin/contracts/ (Hardhat/npm) 或 lib/openzeppelin-contracts/ (Foundry/forge)Scarb.toml 依赖项中解析——源代码由 Scarb 缓存Cargo.toml 中解析——源代码位于 target/ 或 cargo 注册表缓存中 (~/.cargo/registry/src/)Cargo.toml 中解析——与 Stylus 相同的 cargo 缓存位置Glob 模式(例如,node_modules/@openzeppelin/contracts/**/*.sol)。不要假设了解库的内容——始终通过列出目录进行验证。///, /** */),Rust 和 Cairo 中的文档注释(///),以及组件目录中的 README 文件。test/, tests/, examples/ 或 mocks/ 目录。根据步骤 2,构建所需的最小更改集:
如果合约是可升级的,上述任何更改都可能影响存储兼容性。在应用之前,请查阅相关的升级技能。
不要包含超出依赖项要求的内容。这是“不带此功能的合约”和“带此功能的合约”之间的最小差异。
Edit 工具应用步骤 3 中的更改。不要替换整个文件——集成到现有代码中。| Ecosystem | Repository | Documentation | File Extension | Dependency Location |
|---|---|---|---|---|
| Solidity | openzeppelin-contracts | docs.openzeppelin.com/contracts | .sol |
node_modules/@openzeppelin/contracts/ or lib/openzeppelin-contracts/ |
| Cairo | cairo-contracts | docs.openzeppelin.com/contracts-cairo | .cairo |
Scarb cache (resolve from Scarb.toml) |
| Stylus | rust-contracts-stylus | docs.openzeppelin.com/contracts-stylus | .rs |
Cargo cache (~/.cargo/registry/src/) |
| Stellar | stellar-contracts (Architecture) | docs.openzeppelin.com/stellar-contracts | .rs |
Cargo cache (~/.cargo/registry/src/) |
在每个存储库中查找组件的位置:
| Category | Solidity | Cairo | Stylus | Stellar |
|---|---|---|---|---|
| Tokens | contracts/token/{ERC20,ERC721,ERC1155}/ |
packages/token/ |
contracts/src/token/ |
packages/tokens/ |
| Access control | contracts/access/ |
packages/access/ |
contracts/src/access/ |
packages/access/ |
| Governance | contracts/governance/ |
packages/governance/ |
— | packages/governance/ |
| Proxies / Upgrades | contracts/proxy/ |
packages/upgrades/ |
contracts/src/proxy/ |
packages/contract-utils/ |
| Utilities / Security | contracts/utils/ |
packages/utils/, packages/security/ |
contracts/src/utils/ |
packages/contract-utils/ |
| Accounts | contracts/account/ |
packages/account/ |
— | packages/accounts/ |
不要根据先前的知识假设覆盖点——始终通过阅读已安装的源代码进行验证。在旧版本中是 virtual 的函数在当前版本中可能不再是 virtual,从而使其不可覆盖。源代码的 NatSpec 将指示正确的覆盖点(例如,注意:此函数不是 virtual,应覆盖 {X} 代替之)。
一个已知示例:Solidity ERC-20 transfer Hook在 v4 和 v5 之间发生了变化。在建议覆盖之前,请阅读已安装的 ERC20.sol 以确认哪个函数是 virtual。
MCP 生成器是模板/脚手架工具,用于生成 OpenZeppelin 合约样板代码。它们不是必需的——它们在可用时加速模式发现。
在运行时动态发现 MCP 工具。查找名称匹配 solidity-erc20, cairo-erc721, stellar-fungible 等模式的工具。服务器名称遵循 OpenZeppelinSolidityContracts, OpenZeppelinCairoContracts 或 OpenZeppelinContracts 等模式。
MCP 工具的 schema 是自描述的。要了解生成器支持什么,请检查其参数列表——每个布尔参数(例如,pausable, mintable, upgradeable)都对应一个功能切换。不要依赖关于存在哪些参数的先验知识;每次都阅读 schema,因为工具的更新独立于此技能。
当存在适用于合约类型的 MCP 生成器时:
对于交互功能(例如,访问控制 + 可升级性),也生成一个组合变体。
没有 MCP 工具并不意味着库缺乏支持。它仅表示该合约类型没有生成器。始终回退到 模式发现与集成 中的通用模式发现方法。
同样,当 MCP 工具存在但未暴露特定功能的参数时,不要就此止步。回退到该功能的模式发现:阅读已安装的库源代码以找到相关组件,提取集成要求,并将其应用于用户的合约。
- 原文链接: github.com/OpenZeppelin/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!