{"content":{"title":"预女巫攻击：在隐私保护下进行合约速率限制","body":"> * 原文链接： https://github.com/rsproule/n-per-epoch#readme\r\n> * 译文出自：[登链翻译计划](https://github.com/lbc-team/Pioneer)\r\n> * 译者：[南小芽](https://learnblockchain.cn/people/6633)  校对：[Tiny 熊](https://learnblockchain.cn/people/15)\r\n> * 本文永久链接：[learnblockchain.cn/article…](https://learnblockchain.cn/article/6053)\r\n\r\n\r\n> [n-per-epoch](https://github.com/rsproule/n-per-epoch) 提供了一个简单的合约修改器（modifier），可用于在任何智能合约函数调用中进行访问频率的限制。\r\n\r\n![logo](https://img.learnblockchain.cn/attachments/2023/06/ayNQjZkw648ad4be9f655.jpg)\r\n\r\n## 速率限制？\r\n\r\n[n-per-epoch](https://github.com/rsproule/n-per-epoch) 库使合约创建者能够在定义的时间周期内限制特定用户调用函数的次数。时间周期的持续时间非常灵活，允许开发者将其设置为接近无限（永远只能调用一次）或者设置为很短的时间以实现更高的吞吐量。\r\n\r\n> ❗️警告\r\n>\r\n> 设置时间周期请一定要考虑到*证明生成时间*和*区块包含时间*。\"epochId\" 必须同时匹配链上的证明和结算。因此，时间周期长度必须大于证明生成时间和区块包含时间之和，并留出一些缓冲时间。\r\n\r\n## 隐私保护？\r\n\r\n你会注意到这些合约完全不关心 msg.sender（消息发起者）。这是有意设计的！在内部，n-per-epoch 利用了零知识包含证明，通过使用[semaphore](https://semaphore.appliedzkp.org/) 库来实现。该合约通过提供的 zk 证明来强制进行身份验证，而不依赖交易的签署者。[ERC4337](https://eips.ethereum.org/EIPS/eip-4337/) 类型的账户抽象化可以轻松利用这种类型的身份验证！\r\n\r\n## 人类？\r\n\r\n这个示例使用了由[Worldcoin](https://docs.worldcoin.org/) 开发的已有的 anonymity set （匿名集合），其中包括大约140万个已验证的人类用户。Worldcoin通过扫描人的虹膜，并确保每个虹膜之前未被添加到集合中，建立了这个集合。只需在设置中修改groupId，即可使用不同的集合。\r\n\r\n## 为什么速率限制有用的？\r\n\r\n1. **防止滥用**：通过限制每个用户的请求次数，有助于防止恶意行为者或机器人滥用服务或资源。这确保了真实用户能够公平地访问系统，而不会被自动化脚本或攻击排挤出去。\r\n2. **促进公平分配**：在资源、奖励或机会有限的情况下，对人类用户进行速率限制可以确保更加公平的分配。这有助于防止少数用户垄断对有价值的资产或服务的访问，例如 NFT 发行或代币水龙头。\r\n3. **提升用户体验**：当资源受限时，对人类用户进行速率限制可以帮助维持合法用户的流畅和响应式体验。通过防止系统过载或资源枯竭，确保用户可以继续与应用交互而不受干扰。\r\n4. **成本管理**：在区块链应用中，对人类用户进行速率限制有助于管理与Gas费用或其他运营费用相关的成本。通过控制交易或函数调用的频率，服务提供者可以优化开支，同时向用户提供有价值的服务。\r\n5. **保护隐私**：通过关注人类用户并利用隐私保护技术，可以在不牺牲用户隐私的前提下实施速率限制。这在去中心化系统中尤为重要，因为对系统的信任往往是建立在用户隐私和数据安全的基础上的。\r\n\r\n## 应用示例\r\n\r\n- **Gas赞助中继**：这些中继旨在为其应用的人类用户提供Gas，同时防止单个用户消耗资源。n-per-epoch 库有效地使协议能够管理单个用户的资源分配。\r\n- **水龙头**：以可控的速度向人类用户分发资产，防止滥用。\r\n- **奖励社交网络上的用户互动**：速率限制有助于限制垃圾信息的影响，同时鼓励真实的互动。\r\n- **稀缺资源的公平分配（例如，NFT 发行）**：通过实施速率限制，可以允许每个人类用户在特定时间内铸造一定数量的资产（例如，每小时一次），促进公平分配。\r\n\r\n------\r\n\r\n## 如何在你的合约中使用\r\n\r\n通过[Foundry](https://github.com/foundry-rs/foundry) 安装:\r\n\r\n```\r\nforge install rsproule/n-per-epoch\r\n```\r\n\r\n或者通过[Hardhat](https://learnblockchain.cn/docs/hardhat/getting-started/) 或 [Truffle](https://github.com/trufflesuite/truffle) 安装：\r\n\r\n```\r\nnpm i https://github.com/rsproule/n-per-epoch\r\n```\r\n\r\n查看[`ExampleNPerEpochContract.sol`](https://github.com/rsproule/n-per-epoch/blob/main/src/test/ExampleNPerEpochContract.sol) ，检查修改器已生效：\r\n\r\n```solidity\r\nimport { NPerEpoch} from \"../NPerEpoch.sol\";\r\n...\r\n...\r\n...\r\nconstructor(IWorldID _worldId) NPerEpoch(_worldId) {}\r\n\r\nfunction sendMessage(\r\n uint256 root,\r\n string calldata input,\r\n uint256 nullifierHash,\r\n uint256[8] calldata proof,\r\n RateLimitKey calldata actionId\r\n)\r\n public rateLimit(\r\n     root, \r\n     abi.encodePacked(input).hashToField(), \r\n     nullifierHash, \r\n     actionId, \r\n     proof\r\n )\r\n{\r\n if (nullifierHashes[nullifierHash]) revert InvalidNullifier();\r\n nullifierHashes[nullifierHash] = true;\r\n emit Message(input);\r\n}\r\n...\r\n...\r\n...\r\nfunction settings()\r\n public\r\n pure\r\n virtual\r\n override\r\n returns (NPerEpoch.Settings memory)\r\n{\r\n return Settings(1, 300, 2); // groupId (worldID=1), epochLength, numPerEpoch)\r\n}\r\n```\r\n\r\n## 安装 / 构建 / 测试\r\n\r\n安装：\r\n\r\n```\r\ngit clone git@github.com:rsproule/n-per-epoch.git\r\n```\r\n\r\n构建：\r\n\r\n```\r\nmake \r\n```\r\n\r\n执行单元测试：\r\n\r\n```\r\nmake test\r\n```\r\n\r\n\r\n\r\n\r\n\r\nn-per-epoch 代码库链接：https://github.com/rsproule/n-per-epoch#readme\r\n\r\n---\r\n\r\n\r\n\r\n感谢 [Chaintool](https://chaintool.tech/) 对本翻译的支持， Chaintool 是一个为区块链开发者准备的开源工具箱"},"author":{"user":"https://learnblockchain.cn/people/6633","address":null},"history":null,"timestamp":1687838968,"version":1}