{"owner":"AmazingAng","repo":"WTF-Solidity","hasSkills":true,"totalSkillsCount":86,"totalTokensCount":82021,"categories":["plugin-manifest","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["Topics/Tools/TOOL05_Dune/readme.md","Topics/Tools/TOOL02_Infura/readme.md","Topics/Tools/TOOL04_Alchemy/readme.md","Topics/Tools/TOOL01_Remix/readme.md","Topics/Tools/TOOL03_Ganache/readme.md","Topics/Onchain_debug/01_tools/readme.md","Topics/Tools/TOOL07_Foundry/readme.md","Topics/Tools/TOOL06_Hardhat/package.json","Topics/Tools/TOOL06_Hardhat/readme.md","Topics/Tools/TOOL08_ZAN/readme.md","out/extensions/IERC721Metadata.sol/IERC721Metadata.json","Topics/Tools/TOOL06_Hardhat/package-lock.json","Topics/Onchain_debug/01_tools/en/readme.md","Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json","Topics/Tools/TOOL07_Foundry/hello_wtf/package.json","Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md","Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md","Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md","Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md","Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md","Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md","Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md","Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json"],"skills":{"Topics/Tools/TOOL05_Dune/readme.md":"# WTF Solidity极简入门-工具篇5：使用Dune可视化区块链数据 \n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n## Dune是什么？\n\n\n`Dune`是区块链查询分析工具，每个人可以通过写类sql语言查询区块链上的所有信息，例如巨鲸，链上交易的数据等等。同时`Dune`能便捷的将数据转换为可视化的图表。\n\n> 以太坊是数据库，智能合约是数据表，来自钱包的交易是每个表中的行。\n\n这句话讲出了区块链的精髓：区块链本质上就是公开的存储数据的分布式账本，现在我们可以通过Dune来查询这个分布式账本的数据。\n\n[Dune官网](https://dune.xyz/)\n\n![dune可视化](./img/1.png)\n\n![dune可视化](./img/2.png)\n\n\n## 第一个查询\n\n目标：查询**过去 24 小时在 Uniswap 上购买的 DAI稳定币**\n\n1. 注册登陆Dune。\n2. 点击右上角**new query**新建查询，输入代码：\n\n    ```sql\n    SELECT\n    SUM(token_a_amount) AS dai_bought\n    FROM\n    dex.\"trades\"\n    WHERE\n    block_time > now() - interval '24 hours'\n    AND token_a_symbol = 'DAI'\n    AND project = 'Uniswap';\n    ```\n3. 点击右下角的**Run**执行查询，得到最近的24h内通过uniswap购买DAI的数量。\n\n![dune sql query](./img/3.png)\n\n\n## 从0开始构建查询\n\n**目标：学会使用 SELECT, WHERE, LIMIT**\n\n我们查询其中一个表，以aave为例：[aave合约](https://etherscan.io/address/0x398ec7346dcd622edc5ae82352f02be94c62d119#writeProxyContract)\n\n通过查询aave这个合约，它有deposit（存储）这个方法，并且有该事件（事件会在执行的时候广播）。\n\n![etherscan](./img/6.png)\n\n回到Dune查找对应的表，根据在Ethereum上搜索aave相关的表，并对应事件,`LendingPool_evt_Deposit`找到该表。\n\n![dune query db table](./img/13.png)\n\n### 学习：SELECT 、 LIMIT、WHERE查询数据\n\n然后我们通过Dune可以查询对应的存储数据\n\n```sql\nSELECT * FROM aave.\"LendingPool_evt_Deposit\"\nlimit 100\n```\n\n![dune query](./img/7.png)\n\n就可以得到aave合约中存储方法的相应数据，通过这个数据可以做一些筛选\n\n#### 各个字段的意义\n\n_user：发起存款的钱包地址\n\n_reserve：作为抵押品存放的代币地址\n\n_amount：存入的代币数量\n\n_timestamp：交易被挖掘到区块链的时间戳\n\n\n#### 使用 WHERE过滤数据\n\n查询过滤特殊的地址`0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`\n\n```sql\nSELECT *, (_amount / 1e18) as _amount FROM aave.\"LendingPool_evt_Deposit\"\nWHERE _reserve = '\\xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'\nlimit 100\n```\n\n带上了查询条件，能够快速的筛选我们需要的数据\n\n查看抵押品为USDC，USDC合约地址：`xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`\n\n```sql\nSELECT * FROM aave.\"LendingPool_evt_Deposit\"\nWHERE _reserve = '\\xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'\nlimit 100\n```\n\n以上案例参考 [Your guide to basic SQL while learning Ethereum at the same time](https://towardsdatascience.com/your-guide-to-basic-sql-while-learning-ethereum-at-the-same-time-9eac17a05929)\n\n### 实践链上转账\n\n\n实践`Ethereum.Transactions`表的转账查询\n\n\n```sql\nselect * from ethereum.transactions\nLIMIT 10\n```\n\n![DUNE面板说明](./img/14.png)\n\n### 字段和转账对应说明\n\n看这个[hash](https://etherscan.io/tx/0xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51)转账 \n\n![image-20220314174346876](./img/16.png)\n\n由[0x22fff189c37302c02635322911c3b64f80ce7203](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7?a=0x22fff189c37302c02635322911c3b64f80ce7203) 转账到 [0x8aae242452471d2dfea145214ceedf87ca043198](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7?a=0x8aae242452471d2dfea145214ceedf87ca043198)\n\nhash：`0xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51`\n\n我们可以直接通过dune查到该条信息\n\n```sql\nselect * from ethereum.transactions\nWHERE hash='\\xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51'\n```\n\n![dune-查询](./img/15.png)\n\ndune中的字段，也是和etherscan中一一对应。\n\n\n\n### 数据可视化\n\n![dune query to visualization](./img/11.png)\n\n点击 New visualization 就可以选择你需要的视图，比如我点击 `bar chart`\n\n![dune visualization](./img/12.png)\n\n就会将我刚才筛选的数据可视化。看最长的几根，就是借贷最多的几个账号。\n\n\n\n## 总结\n\n这一讲，我们介绍了Dune的基础用法。通过Dune，我们能够将链上的数据转换为可视化的数据，更好的了解链上热点。\n","Topics/Tools/TOOL02_Infura/readme.md":"# WTF Solidity极简入门-工具篇2：Infura, 连接链下与链上的桥梁\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n`Infura`是Consensys(小狐狸钱包母公司)开发的区块链基础设施，帮助用户/开发者更好的与以太坊区块链交互。\n\n## 连接应用和区块链\n\n![链下链上交互](./img/infura1.png)\n\n在以太坊上开发的Dapp应用（链下）需要与区块链（链上）交互。早期，以太坊上的基础设施很少，开发者需要在本地部署以太坊节点来完成链下和链上的交互，非常麻烦，且耗时数日。\n\n`Infura`在链下、链上之间搭了一座桥，让两者的交互变的简单。它为用户提供对以太坊和IPFS网络的即时、可扩展的`API`访问。开发者在`Infura`官网注册后，就可以免费申请的以太坊`API KEY`，就可以利用`Infura`的节点与区块链交互。另外，小狐狸`metamask`钱包内置了`Infura`服务，方便用户访问以太坊网络。\n\n## 创建`Infura` API Key\n\n### 1. 打开Infura官网并注册\n\n网址：[infura.io](https://infura.io)\n![Infura官网](./img/infura2.png)\n\n### 2. 创建API Key\n注册后，进入控制台Dashboard，并点击右上角的 **CREATE NEW KEY** 按钮。\n\n![创建API Key](./img/infura3.png)\n\n### 3. 填写API Key信息\n\n`NETWORK`选择 **Web3 API (Formerly Ethereum)**，有的版本这里显示的是**Ethereum**，`NAME`随便填一个，我填的`WTF`，之后点击**CREATE**按钮。\n\n![填写信息](./img/infura4.png)\n\n### 4. API Key创建完毕\n\n回到控制台Dashboard，可以看到名为`WTF`的API Key已经创建完毕。在控制台Dashboard，点击  **MANAGE KEY** 按钮，可以查看API Key详情。\n\n\n![API Key创建完毕](./img/infura5.png)\n\n### 5. 查看API Key详情\n\n进入API Key详情页，我们可以看到我们的API Key（图中`184d`开头的一组密钥）。在下面的 **NETWORK ENDPOINT** 栏中，可以查到以太网主网/测试网的rpc节点链接，用于访问链上数据并交互。另外，你可以申请免费的Layer2 rpc节点，包括`Polygon`，`Optimism`和`Arbitrum`，但是需要绑定`visa`卡。领`Optimism`空投那次，公开rpc节点卡爆了，而使用`Infura`的私人rpc节点的人可以正常领取。\n\n![查看信息](./img/infura6.png)\n\n## 使用`Infura` API Key \n### Javascript (`ethers.js`)\n在`ether.js`中，我们可以利用`Infura` API Key来创建`JsonRpcProvider`，与链上交互。\n\n```javascript\nconst { ethers } = require(\"ethers\");\n// 填上你的Infura API Key\nconst INFURA_ID = '' \nconst provider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`)\n```\n\n### `MetaMask`小狐狸钱包\n\n进入小狐狸钱包设置 **Setting** 页面，点击网络 **Network**，点击添加网络 **Add Network**。你可以利用下面的参数在小狐狸中添加`Optimism` Layer2链：\n\n```\n网络名称（Network Name）: Optimism\nRPC URL：填在Infura申请的optimism rpc链接\n链ID (Chain ID): 10\n符号 (Chain Symbol): ETH\n区块链浏览器URL (Blockchain Explorer URL): https://optimistic.etherscan.io\n```\n\n![小狐狸配置私人rpc](./img/infura7.png)\n\n## 总结\n\n这一讲，我们介绍了如何创建并使用`Infura` API Key便捷访问以太坊区块链。","Topics/Tools/TOOL04_Alchemy/readme.md":"# WTF Solidity极简入门-工具篇4：Alchemy, 区块链API和节点基础设施\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n## Alchemy是什么\n\n`Alchemy` 超级节点是 Ethereum、Polygon、Solana、Arbitrum、Optimism、Flow 和 Crypto.org 使用最广泛的区块链 API。获得节点的所有功能，包括 JSON-RPC 支持，但具有在区块链上运行世界级应用程序所需的超强可靠性、数据准确性和可扩展性。\n\n## 连接应用和区块链\n\n在以太坊上开发的Dapp应用（链下）需要与区块链（链上）交互。早期，以太坊上的基础设施很少，开发者需要在本地部署以太坊节点来完成链下和链上的交互，非常麻烦，且耗时数日。\n\n`Alchemy` 和 `Infura`在链下、链上之间搭了一座桥，让两者的交互变的简单。它为用户提供对以太坊和IPFS网络的即时、可扩展的`API`访问。开发者在`Alchemy` 和 `Infura`官网注册后，就可以免费申请的以太坊`API KEY`，就可以利用它们的节点与区块链交互。另外，小狐狸`metamask`钱包内置了`Infura`服务，方便用户访问以太坊网络。\n\n关于`Infura`的介绍，可以参考 [WTF Solidity极简入门-工具篇2：Infura, 连接链下与链上的桥梁](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL02_Infura/readme.md)\n\n## Alchemy 和 Infura 的区别\n\n![Alchemy 和 Infura 的区别](./img/alchemy-1.png)\n\n左边是`alchemy` 右边是 `Infura`，我们来对比下免费的套餐\n\n### 访问量的区别\n\n`Alchemy`每天没有访问限制，`Infura`每天有100,000的访问限制。\n\n`Alchemy`每个月有`300,000,000`的访问量，`Infura`每个月有`3,000,000`的访问量。\n\n\n### 支持公链的区别（免费版本）\n\n![公链的区别](./img/alchemy-2.png)\n\n`Alchemy`支持：ETH、Polygon、Solana、Arbitrum、Optimism\n\n`Infura`支持：ETH、ETH2、IPFS、Filecoin \n\n### Alchemy支持enhanced-apis\n\n![Alchemy支持enhanced-apis](./img/alchemy-3.png)\n\n\nAlchemy自己封装了一些web3的api，大家可以自己看文档获取更多的细节。\n\n[Alchemy - enhanced-apis](https://dashboard.alchemyapi.io/enhanced-apis)\n\n## 创建`Alchemy` API Key\n\n### 1. 打开Alchemy官网并注册\n\n网址：[alchemy.com](https://www.alchemy.com/)\n\n![Alchemy官网](./img/alchemy-4.png)\n\n\n### 2. 创建API Key\n注册后，进入控制台Dashboard，并点击右上角的 **+ CREATE APP** 按钮。\n\n![创建API Key](./img/alchemy-5.png)\n\n\n### 3. 填写API Key信息\n\n`CHAIN`：选择你需要的网络，如果是以太网就是 `Ethereum`。\n\n`NETWORK`:并选择是主网还是测试网。\n\n![填写API Key信息](./img/alchemy-6.png)\n\n填写完成之后点击 `CREATE APP` 即可创建。\n\n### 4. API Key创建完毕\n\n回到控制台Dashboard，可以看到名为`WTFSolidity`的API Key已经创建完毕。在控制台Dashboard，点击  **view key** 按钮，可以查看API Key详情。\n\n![查看api key](./img/alchemy-7.png)\n\n\n### 5. 查看API Key详情\n\n可以看到我们创建好了相应的api key，最常用的https和websockets都支持。\n\n![查看api key 详情](./img/alchemy-8.png)\n\n\n## 使用`Alchemy` API Key \n\n### Javascript (`ethers.js`)\n在`ether.js`中，我们可以利用`Alchemy` API Key来创建`JsonRpcProvider`，与链上交互。\n\n```javascript\nconst { ethers } = require(\"ethers\");\n// 填上你的Alchemy API Key\nconst ALCHEMY_ID = '' \nconst provider = new ethers.providers.JsonRpcProvider(`https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`)\n```\n\n### `MetaMask`小狐狸钱包\n\n进入小狐狸钱包设置 **Setting** 页面，点击网络 **Network**，点击添加网络 **Add Network**。你可以利用下面的参数在小狐狸中添加`Alchemy` 的eth链：\n\n```\n网络名称（Network Name）: Alchemy-eth\nRPC URL：填在alchemy申请的optimism rpc链接\n链ID (Chain ID): 1\n符号 (Chain Symbol): ETH\n区块链浏览器URL (Blockchain Explorer URL): https://etherscan.io\n```\n\n![小狐狸钱包添加新的网络](./img/alchemy-9.png)\n\n\n## 总结\n\n这一讲，我们介绍了如何创建并使用`Alchemy` API Key便捷访问以太坊区块链。\n","Topics/Tools/TOOL01_Remix/readme.md":"# WTF Solidity极简入门-工具篇1：Remix\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\n`Remix`是以太坊官方推荐的智能合约开发IDE，非常易用。`Remix`让你可以直接在浏览器中快速部署测试智能合约，而不需要安装配置任何程序。这一讲，我们将完整的介绍如何使用`Remix`部署合约，并调用其中的函数。\n\n**Remix官网**：[remix.ethereum.org](https://remix.ethereum.org)\n\n## 1.打开Remix\n![Remix Layout](./img/remix1.png)\n\n打开官网进入`Remix`，我们可以看到Remix由四个面板组成：\n1. 图标面板：上面有代表不同功能的图标，点击后，相应的功能个会显示在侧面版上。\n2. 侧面版：各种功能的 `GUI`。\n3. 主面板：代码编辑器。\n4. 终端：将显示与 `GUI` 交互的结果，也可以在此处运行脚本。\n\n## 2. 图标面板\n![图标面板](./img/remix2.png)\n\n图标面板默认有4个图标，其中`文件`，`编译`，`部署`是最常用的。在你添加更多的`remix`插件后，它们也会显示在图标面板上。\n\n## 3. 部署简单合约\n### i. 选择合约文件\n首先点击`文件`图标，侧面版会变为`文件浏览器`。\n![文件图标](./img/remix3.png)\n\n我们可以在`文件浏览器`中管理我们的workspace，文件夹和文件。\n![文件浏览器](./img/remix4.png)\n\n在`contract`文件夹下面，有三个`remix`自带的合约例子，分别是`1_Storage.sol`, `2_Owner.sol`和`3_Ballot.sol`。\n\n点击`1_Storage.sol`，代码会显示在主面板的代码编辑器上。这个合约非常简单：它一个状态变量`number`，在链上存储一个`uint256`类型的数字；它有两个函数，`store()`函数将一个数字赋值给`number`变量；`retrieve()`展示`number`变量的数值。\n\n### ii. 编译\n接下来，点击`编译`图标，进入`Solidity Compiler`。在这里，我们选择`Solidity 0.8.7`版本，然后点击`Compile 1_Storage.sol`按钮进行编译。在合约成功编译后，`编译`图标上会显示绿色对勾。\n\n![编译](./img/remix5.png)\n\n你也可以尝试在优化中选在优化（`Enable Optimization`），次数设置为`200`，有时会省`gas`消耗。\n\n### iii. 部署\n下一步，我们要把编译好的合约部署到本地虚拟机或链上。首先点击`部署`，进入部署界面。\n\n![部署](./img/remix6.png)\n\n在`ENVIRONMENT`中，我们可以选择我们部署的环境，默认的是`JavaScript VM`，所有交易都在本地浏览器的沙盒区块链中执行，使用的是它给你的虚拟钱包地址；你也可以选择`Injected Web3`，即连接你的`metamask`钱包，所有交易会在真实的区块链中执行。\n\n这里，我们选择`JavaScript VM`，你可以在钱包地址（`ACCOUNT`）栏看到虚拟机给你分配的测试地址。不需要调整`Gas`，也不用往合约里发送`ETH`。在`CONTRACT`栏中选择你要部署的合约`Storage`。`1_Storage.sol`文件中只有一个合约，因此默认就是部署它；但当文件包含多个合约时，我们需要手动选择要部署的合约。\n\n点击`DEPLOY`键，部署完毕！\n\n**注意**：如果我们选择的是`Injected Web3`来部署合约，每一笔交易都将上链，需要钱包确认交易并支付`gas`。\n\n### iv. 调用\n在合约部署成功后，我们可以在`Deployed Contracts`中找到我们部署的合约`Storage`。展开它，我们将看到所有的外部函数：`store`和`retrieve`。\n\n![调用](./img/remix7.png)\n\n我们在`store`函数那行的文本框中输入`100`，并点击函数名调用它。调用成功后，我们可以在终端上看到`log`信息，点击`Debug`按钮可以查看交易详情。\n\n![交易详情](./img/remix8.png)\n\n之后，我们调用`retrieve`函数，显示`number`变量被成功更新为`100`。\n\n![变量被更新为100，调用成功](./img/remix9.png)\n\n## 总结\n\n这一讲，我们介绍了如何使用`Remix`编译，部署并调用智能合约。\n\n","Topics/Tools/TOOL03_Ganache/readme.md":"# WTF Solidity极简入门-工具篇3：Ganache，搭建本地测试网络\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\n`Ganache` 是一个适用于 “开发场景”（或开发过程中的）的 **以太坊区块链网络**，它使开发以太坊应用程序（的工作）更快、更容易、更安全。它包括所有流行的 RPC 功能和特性（如事件），并且可以确定性地运行以使开发变得轻而易举。\n\n> 可以理解 ganache 是一个以太坊区块链“模拟器”，在开发过程中 “模拟” 生产环境、方便的获取合约调用的上下文。\n\n> ⚠️ 注意：**请不要在生产环境中作为区块链网络使用** 如果需要请使用 geth 或 openethereum 等节点应用。\n\n`Ganache` 同时有着 GUI 版本，适合于新手快速配置使用。\n\n## Ganache 的项目设施\n\n- 官网：[https://trufflesuite.com/ganache/](https://trufflesuite.com/ganache/)\n- 文档：[https://trufflesuite.com/docs/ganache/](https://trufflesuite.com/docs/ganache/)\n- Github：\n  - UI: [https://github.com/trufflesuite/ganache-ui](https://github.com/trufflesuite/ganache-ui)\n  - CLI: [https://github.com/trufflesuite/ganache](https://github.com/trufflesuite/ganache)\n  - 旧版（已弃用）: [https://github.com/trufflesuite/ganache-cli](https://github.com/trufflesuite/ganache-cli)\n- 适用于命令行/npm的文档：[https://trufflesuite.com/blog/introducing-ganache-7/](https://trufflesuite.com/blog/introducing-ganache-7/)\n\n\n> ⚠️ 注意：Ganache 的官网中的 Github repo 为UI版本。CLI 版本在 npm 中有 `ganache` & `ganache-cli`，其中 `ganache-cli` 已被弃用。\n\n## 为什么要使用Ganache？\n\nGanache 的主要功能有：\n- 开箱即用，快速启动一个EVM区块链网络（可以设置 miner、出块时间）；\n- 方便的 fork（分叉）已经存在的区块链网络（无需等待区块同步）；\n- [使用 `console.log`](https://github.com/trufflesuite/ganache#consolelog-in-solidity) 在 Solidity 开发过程中方便的调试，；\n- [快进时间（Fast-forward time）](https://trufflesuite.com/blog/introducing-ganache-7/#6-fast-forward-time)，模拟智能合约在未来时间的状态；\n- 模拟任何一个账户（你可以无需私钥模拟环境中使用任意用户的Token）；\n\n有的时候想要实现合约的测试，或者一些合约开发，你需要去测试网领取eth。有时候faucet又没有eth可以领取，这个时候，其实你可以选择自己在本地 fork 一个网络，想要多少eth都可以直接生成。原理是 fork 一个主网的网络运行在本地（或是可以称作运行在本地的 Chain）。\n\nfork主网还有一个好处，你可以直接mock现在主网上的所有环境，比如dex交易所的代币余额等，你知道合约地址，可以直接进行测试和交换使用等。\n\n## 命令行安装（推荐）\n\n[完整包的说明 ganache - npm](https://www.npmjs.com/package/ganache)\n```shell\nnpm install ganache --global\n```\n您也可以单独安装该项至您的项目目录（在不使用 `--global` 的情况下）编写 `package.json` 中的 script 配置启动。  \n在 Ganache 7 后您可以在 node.js 的 Javascript 脚本中引入并直接使用。它将会提供一个 [EIP-1193(Ethereum Provider JavaScript API)](https://eips.ethereum.org/EIPS/eip-1193) provider、一个 JSON-RPC 服务端、Web3.js & ethers provider。同时您也可以在[浏览器中](https://github.com/trufflesuite/ganache#browser-use)使用它。\n\n\n### 启动GANACHE\n\n```shell\nganache\n```\n\n### 帮助 / 说明\n```\nganache --help\n```\n通过帮助，你可以了解 ganache 的主要功能和相关配置方法、参数。这其中包括：\n- **Chain**: 设置网络的版本、ID、时间、合约大小限制、hardfork的版本规则；\n- **Database**: 设置保存链到数据库；\n- **Logging**: 设置 EVM opcodes、RPC 请求和响应的 log；\n- **Miner**: 设置矿工，包括：出块时间、默认的 gas price、Txn gas limit、难度、instamine、价格上涨；\n- **Wallet**: 设置钱包的默认余额、解锁钱包；\n- **Fork**: 分叉（fork）网络的设置包括：fork 目标网络 RPC URL、块高、userAgent、缓存策略，支持提供用户名/密码（如果目标 RPC 存在 Basic Authentication）；\n- **Server**: 设置本地 Chain 的监听地址&端口；\n### Fork 主网启动\n\n以下命令会自动生成10个eth账号，每个账号带有100eth的数量。\n\n```shell\nganache -f https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY\n```\n\n您也可以fork其他以太坊区块链网络，例如 BSC、Polygon、Astar 等，您需要寻找并使用他们的RPC节点。\n\n### Fork主网固定账号启动\n\n`wallet.accounts`主要参数为私钥和需要生成的eth数量。\n\n注意单位为`wei`，案例中换算之后是`1000eth`\n\n```shell\nganache -f https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY --wallet.accounts=ACCOUNT_PRIATE_KEY,AMOUNT_WEI --wallet.accounts=ACCOUNT_PRIATE_KEY,1000000000000000000000\n```\n\n### 推进时间 (Fast Forward time)\n\n需要操纵时间的原因或场景：一些合约锁住了用户的Token，设计了释放周期/时间逐步释放这些被锁住的Token，或者在未来某个特定时间允许用户进行一些操作。\n\nGanache 允许我们通过 RPC 调用（方法 `evm_increaseTime` 和 `evm_setTime` ）来推进区块链上的时间。\n\n大多数情况下我们无法等到这个时间，我们可以使用 `evm_increaseTime` 将区块链当前时间戳**增加指定的时间量**（以秒为单位）（以十六进制格式传入）。这将返回以秒为单位调整的总时间。\n\n```\ncurl -H 'Content-Type: application/json' --data' {\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"evm_increaseTime\", \"params\": [\"0x15180\"] }' http://localhost:8545\n```\n\n此外，您可以使用 `evm_setTime` 将其设置为特定的时间戳；它接受具有毫秒精度的 JavaScript 时间戳，并返回给定时间戳和当前时间之间的秒数。\n\n这里有个在项目中应用的案例（很实用）：[liquity 项目合约测试 - ForwardTime 的功能实现](https://github.com/liquity/dev/blob/0c61ed8b7181450da214d4f10a1327c2082bd4f4/packages/contracts/utils/testHelpers.js#L1104-L1119)\n### 通过GUI使用 Ganache\n不太推荐，如果你是新上手，可以通过这个快速熟悉 Ganache。\n\n[点击下载Ganache - Truffle Suite](https://trufflesuite.com/ganache/)\n\n#### 客户端界面\n![](./img//ganache-7.png)\n\n#### 初始化新建工作空间\n\n![](./img//ganache-8.png)\n\n点击quickstart就可以快速启动，但是快速启动默认的网络端口是 7545，如果你用remix链接的时候需要修改一下。启动完成之后就如下图所示：\n\n![](./img/ganache-9.png)\n\n第一行可以看到你现在的网络`rpc server`, 默认是地址和端口是`127.0.0.1:7545`，如果你在remix中使用默认的，需要把端口改为7545。\n\n\n\n#### remix 链接默认ganache\n\n![](./img/ganache-10.png)\n\n选择环境为 ganache provider，具体端口看你的设置,需要跟ganache的端口一致。\n\n![](./img/ganache-11.png)\n\n端口改为和本地ganache默认一样的`7545`\n\n#### 测试部署一个合约\n\n这里能看到区块里的交易信息，显示我部署了一个合约地址。\n\n![](./img/ganache-12.png)\n\n![](./img/ganache-13.png)\n\n\n#### 自定义配置\n\n有时候你可能需要自定义配置，比如你的网络端口，或者你需要fork主网，你可以在初始化空间的时候配置。\n\n选择`new workspace`\n\n![](./img/ganache-14.png)\n\n\n#### 设置端口和网络ID\n\n端口：可以将默认端口7545改成8545，看你的习惯\n\n![](./img/ganache-15.png)\n\n\n#### fork主网\n\n这里的地址填入你alchemy的主网地址即可\n\n没有的话申请一个 [Alchemy - Blockchain APIs and Node Infrastructure](https://alchemy.com/?r=7ad384cba6732c9d) 或者参考 [Infura, 连接链下与链上的桥梁](https://github.com/AmazingAng/WTF-Solidity/tree/main/Topics/Tools/TOOL02_Infura/readme.md) 申请一个infura的链接。\n\n在chain forking下面的`ENTER CUSTOM URL`里面填入你的eth mainnet地址即可\n\n![](./img/ganache-16.png)\n\n\n#### 设置固定账号和余额\n\n![](./img/ganache-17.png)\n\n最后点击 save workspace 就可以启动啦。\n\n\n## web3js/ethersjs 链接 ganache\nganache生成的本地rpc地址为 `127.0.0.1:8545` UI的默认地址和命令行有区别，所以我上述做了变更。像remix默认使用的就是8454端口\n\n```js\n\n// web3js\n\nconst web3 = new Web3(Web3.givenProvider || \"http://127.0.0.1:8545\");\n\n// ethersjs\nconst provider = new ethers.providers.JsonRpcProvider(\"http://127.0.0.1:8545\");\n\n```\n\n## remix链接本地ganache\n\n把环境链接修改为 ganache即可没，这样你就可以把他部署在你本地的eth网络环境上了。\n\n![](./img/ganache-1.png)\n\n\n### 测试部署合约\n\n这里就将合约部署在了我们本地运行的ganache上。\n\n![](./img/ganache-2.png)\n\n命令行会输出部署的相应细节\n\n![](./img/ganache-3.png)\n\n可以看到部署成功之后，可以方便的调用各种方法\n\n![](./img/ganache-4.png)\n\n### 部署合约，查询v神余额\n\n这个合约写了一个可以查询eth余额的方法，因为我们fork了主网，所以查询一下v神在我们本地测试网络的余额，应该和主网的余额是一样的。\n\n```solidity\n// contracts/GLDToken.sol†\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract XBXToken {\n\n    function getETHBalance(address _address) view external returns(uint256) {\n        return address(_address).balance;\n    }\n\n}\n\n```\n\n[v神主网钱包地址](https://etherscan.io/address/0xab5801a7d398351b8be11c439e05c5b3259aec9b)\n\n![](./img/ganache-5.png)\n\n通过remix调用查看fork之后，本地部署该地址余额\n\n![](./img/ganache-6.png)\n\n本地fork的网络查询v神余额与主网上的余额一致，fork主网测试成功。\n\n## 总结\n\n至此我们就完整fork了一个主网，为下一步做合约开发搭建好了必要的本地环境。","Topics/Onchain_debug/01_tools/readme.md":"# OnChain Transaction Debugging: 1. Tools\n\nAuthor: [SunSec](https://twitter.com/1nf0s3cpt)\n\n当初我在学习链上交易分析时，很少相关教学文章，只能自己慢慢地收集资料从中挖掘如何分析到测试。我们将推出一系列 Web3 安全的教学文章, 帮助更多人加入 Web3 安全，共创安全网路。\n\n第一个系列我们将介绍如何进行链上分析到撰写攻击重现。此技能将能帮助你分析攻击过程和漏洞原因甚至套利机器人如何套利！\n\n## 工欲善其事，必先利其器\n\n在进入分析之前，我先介绍一些常用工具，正确的工具可以帮助你做研究时更有效率。\n\n### Transaction debugging tools\n\n[Phalcon](https://phalcon.blocksec.com/) | [Ethtx](https://ethtx.info/) | [Tenderly](https://dashboard.tenderly.co/explorer)\n\nTransaction Viewer 这类工具是最常用的，可以帮助我们针对想要分析的交易 Transaction，以可视化列出函数呼叫的流程以及每个函数带入了什么的参数等。\n每个工具大同小异，只差异在链的支援度不同和辅助功能，我个人是比较常用 Phalcon 的 Transaction Viewer，如果遇到不支援的链则会使用 Tenderly，Tenderly 支援最多链，但是可读性就不是这么方便，需要 Debug 慢慢分析。不过我最初在研究链上分析是先学习 Ethtx 和 Tenderly。\n\n#### 链支援度比较\n\nPhalcon： `Ethereum、BSC、Cronos、Avalanche C-Chain、Polygon`\n\nEthtx： `Ethereum、Goerli testnet`\n\nTendery： `Ethereum、Polygon、BSC、Sepolia、Goerli、Gnosis、POA、RSK、Avalanche C-Chain、Arbitrum、Optimism、Fantom、Moonbeam、Moonriver`\n\n#### 实务操作\n\n以 JayPeggers - Insufficient validation + Reentrancy [事件](https://github.com/SunWeb3Sec/DeFiHackLabs/#20221229---jay---insufficient-validation--reentrancy)来当例子 [TXID](https://phalcon.blocksec.com/tx/eth/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n使用 Blocksec 开发的 Phalcon 工具来说明，下图可以看到该交易的基本资讯和余额变化，从余额变化可以快速看出攻击者大概获利多少，以这个例子攻击者获利 15.32 ETH。\n\n![210571234-402d96aa-fe5e-4bc4-becc-190bd5a78e68-2](https://user-images.githubusercontent.com/107249780/210686382-cc02cc6a-b8ec-4cb7-ac19-402cd8ff86f6.png)\n\nInvocation Flow 可视化函数调用流程: 可以让我们知道这一笔交易调用流程和函数呼叫的层级，有没有使用闪电贷、涉及了哪些项目、呼叫了哪些函数带入了什么参数和原始 data 等等\n\n![图片](https://user-images.githubusercontent.com/52526645/210572053-eafdf62a-7ebe-4caa-a905-045e792add2b.png)\n\nPhalcon 2.0 新增了资金流向和 Debug + 源代码分析可以在 Trace 的过程中边看程式执行的片段、参数、返回值，分析上方便了不少。\n\n![image](https://user-images.githubusercontent.com/107249780/210821062-d1da8d1a-9615-4f1f-838d-34f27b9c3f41.png)\n\n换 Sam 的 Transaction Viewer 来看看 [TXID](https://tx.eth.samczsun.com/ethereum/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n跟 Phalcon 类似但 Sam 整合了许多小工具在里面，如下图的眼睛点下去可以看到 Storage 的变化和每个呼叫所消耗的 Gas。\n\n![210574290-790f6129-aa82-4152-b3e1-d21820524a0a-2](https://user-images.githubusercontent.com/107249780/210686653-f964a682-d2a7-4b49-bafc-c9a2b0fa2c55.png)\n\n点击最左边的 Call，可以把原始 Input data 尝试 Decode。\n\n![图片](https://user-images.githubusercontent.com/52526645/210575619-89c8e8de-e2f9-4243-9646-0661b9483913.png)\n\n再来换 Tendery 来看看 [TXID](https://dashboard.tenderly.co/tx/mainnet/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n在 Tendery 介面上，一样可以看到基本资讯，但在 Debug 的部分就不是可视化，需要一步一步 Debug 走下去分析，不过好处是可以边 Debug 边看程式码还有 Input data 的转换过程。\n\n![图片](https://user-images.githubusercontent.com/52526645/210577802-c455545c-80d7-4f35-974a-dadbe59c626e.png)\n\n到这边就可以帮我们厘清大概这笔交易做了哪些事情，在还没有开始写 Poc 时，如果想要快速重放攻击可以吗? 可以! 可以使用Tendery 或 Phalcon，这两个工具另外支援了模拟交易重现，在上图右上角有一个按钮 Re-Simulate，工具会自动帮你带上该交易的参数值如下图\n从图中的栏位可以依照需求任意改变如改block number, From, Value, Input data 等\n\n![图片](https://user-images.githubusercontent.com/52526645/210580340-f2abf864-e540-4881-8482-f28030e5e35b.png)\n\n### Ethereum Signature Database\n\n[4byte](https://www.4byte.directory/) | [etherface](https://www.etherface.io/hash)\n\n在原始 Input data，前面 4bytes 为 Function Signature. 有时遇到 Etherscan 或分析工具无法解出来时，可以透过 Signature Database 来查看看可能是什么 Function。\n\n以下举例假设我们不知道 `0xac9650d8` 是什么 Function\n![图片](https://user-images.githubusercontent.com/52526645/210582149-61a6d973-b458-432f-b586-250c94c3ae24.png)\n\n透过 sig.eth 查询，可以看到这个 4 bytes signature 为 `multicall(bytes[])`\n![图片](https://user-images.githubusercontent.com/52526645/210583416-c31bbe07-fa03-4701-880d-0ae485b171f7.png)\n\n### Useful tools\n\n[ABI to interface](https://gnidan.github.io/abi-to-sol/) | [Get ABI for unverified contracts](https://abi.w1nt3r.xyz/) | [ETH Calldata Decoder](https://apoorvlathey.com/eth-calldata-decoder/) | [ETHCMD - Guess ABI](https://www.ethcmd.com/)\n\nABI to interface: 在开发 Poc 时需要呼叫其他合约时要有 Interface 接口，我们可以透过这个工具帮你快速产生你要的接口。\n先去 Etherscan 把 ABI 复制下来，贴过去工具上就可以看到产生出来的 Interface。\n[例子](https://etherscan.io/address/0xb3da8d6da3ede239ccbf576ca0eaa74d86f0e9d3#code)\n\n![图片](https://user-images.githubusercontent.com/52526645/210587442-e7853d8b-0613-426e-8a27-d70c80e2a42d.png)\n![图片](https://user-images.githubusercontent.com/52526645/210587682-5fb07a01-2b21-41fa-9ed5-e7f45baa0b3e.png)\n\nETH Calldata Decoder: 有时候在没有 ABI 的情况下想要解看看 Input data 可以试试看 ETH Calldata Decoder，在前面介绍到 Sam 的工具就有支援 Input data decode。\n\n![图片](https://user-images.githubusercontent.com/52526645/210585761-efd8b6f1-b901-485f-ae66-efaf9c84869c.png)\n\nGet ABI for unverified contracts: 如果遇到未开源的合约，可以透过这个工具尝试列举出这个合约中存在的 Function Signature.\n[例子](https://abi.w1nt3r.xyz/mainnet/0xaE9C73fd0Fd237c1c6f66FE009d24ce969e98704)\n\n![图片](https://user-images.githubusercontent.com/52526645/210588945-701b0e22-7390-4539-9d2f-e13479b52824.png)\n\n### Decompile tools\n\n[Etherscan-decompile bytecode](https://etherscan.io/address/0xaE9C73fd0Fd237c1c6f66FE009d24ce969e98704#code) | [Dedaub](https://library.dedaub.com/decompile) | [heimdall-rs](https://github.com/Jon-Becker/heimdall-rs)\n\nEtherscan 内建有一个反编译功能但可读性偏差，个人比较常使用 Dedaub，可读性好一点，也是常常最多人DM 问我都使用哪个工具反编译。\n我们拿一个 MEV Bot 被攻击来当[例子](https://twitter.com/1nf0s3cpt/status/1577594615104172033)\n可以自己试试解看看 [例子](https://bscscan.com/address/0x64dd59d6c7f09dc05b472ce5cb961b6e10106e1d#code)\n\n首先把未开源合约的 Bytecodes 复制下来贴到 Dedaub 上，点 Decompile 即可。\n![截图 2023-01-05 上午10 33 15](https://user-images.githubusercontent.com/107249780/210688395-927c6126-b6c1-4c6d-a0c7-a3fea3db9cdb.png)\n\n![图片](https://user-images.githubusercontent.com/52526645/210591478-6fa928f3-455d-42b5-a1ac-6694f97386c2.png)\n\n第一课分享就先到这边，想学更多可以参考以下学习资源。\n\n---\n\n## 学习资源\n\n[samczsun's eth txn explorer and vscode extension](https://www.youtube.com/watch?v=HXgu239mPBc)\n\n[Vulnerabilities in DeFi by Daniel V.F.](https://www.youtube.com/watch?v=9fcOffCg2ig)\n\n[Tenderly.co - Debug Transaction](https://www.youtube.com/watch?v=90GN9Ut8LhU)\n\n[Reversing The EVM: Raw Calldata](https://degatchi.com/articles/reading-raw-evm-calldata)\n\nhttps://web3sec.xrex.io/\n","Topics/Tools/TOOL07_Foundry/readme.md":"# WTF Solidity 极简入门-工具篇 7：Foundry，以 Solidity 为中心的开发工具包\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity 极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy\\_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n---\n\n## 什么是 Foundry?\n来自 Foundry [官网 (getfoundry.sh) ](https://getfoundry.sh) 对该工具的介绍：\n\n> Foundry是 一个用 Rust编写的用于以太坊应用程序开发的极快、可移植和模块化的工具包 ( Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.)\n\n项目设施：\n- 官网：[https://getfoundry.sh](https://getfoundry.sh)\n- Github 仓库：[https://github.com/foundry-rs/foundry](https://github.com/foundry-rs/foundry)\n- 文档：[https://book.getfoundry.sh](https://book.getfoundry.sh)\n\n介绍的解释：\n- **用 Rust 语言编写**： Foundry 完全采用 Rust 语言开发， [Github 上的源代码仓库](https://github.com/foundry-rs/foundry) 是一个 Rust 语言工程。我们可以通过获取 [Release 的二进制文件](https://github.com/foundry-rs/foundry/releases)，也可以通过 Rust 语言的 cargo 包管理[工具编译&构建安装](https://github.com/foundry-rs/foundry#installing-from-source);\n- **用于以太坊应用程序开发**： Foundry 作为 以太坊（Solidity语言）项目/应用程序开发的 “工程化” 工具，提供专业 Solidity 开发环境与“工具链”。**通过它你可以快速、方便的完成依赖项管理、编译、运行测试、部署，并可以通过命令行和 Solidity 脚本与链进行交互**;\n- **极快**： Foundry 利用 [ethers-solc](https://github.com/gakonst/ethers-rs/tree/master/ethers-solc/) 比较于传统通过 Node.js 辅助完成的测试用例/工程，Foundry 构建、测试的执行速度很快（创建一个工程，写一些测试用例跑一下会感受到震撼）;\n- **可移植**: Foundry 工程支持与其他类型的工程集成（如：[与 Hardhat 集成](https://book.getfoundry.sh/config/hardhat)）;\n- **模块化**：通过 git submodule & 构建目录映射，快速方便的引入依赖;\n\n<!--👆TODO: some 🔗 LINKS can be added when our Hardhat tutorial is complete -->\n\n## 为什么选择 Foundry？\n\n如果你满足以下条件或有过类似体验，你一定要试试 Foundry：\n\n- ~~如果你有 Rust “语言信仰”~~，如果你是个专业的 以太坊（Solidity语言）应用开发者；\n- 你曾经用过类似 Hardhat.js 这样的工具；\n- 你厌倦了大量测试用例的等待，需要有工具**更加快速**的跑完你的测试用例；\n- 你觉得处理 BigNumber 稍微有一点点🤏麻烦;\n- 有过**通过 Solidity 语言本身完成测试用例**（或测试合约的合约）的需求；\n- 你觉得通过 git submodule 的方式管理依赖更加方便（而不是 npm）；\n- ···\n\n\n如果有以下情况 Foundry 可能不适合你：\n- Solidity 初学者；\n- 你的项目不需要写测试用例、不需要过多在 Solidity 工程方面的自动化操作；\n\n\n## Foundry 的主要功能\n> 该部分源于 Foundry book ([https://book.getfoundry.sh](https://book.getfoundry.sh))，让章节的理解更容易。\n\n- [创建以太坊（Solidity）智能合约应用开发项目](https://book.getfoundry.sh/projects/creating-a-new-project)，[开发已有的项目](https://book.getfoundry.sh/projects/working-on-an-existing-project);\n- [管理以太坊(Solidity)智能合约的依赖项目](https://book.getfoundry.sh/projects/dependencies);\n- [创建由 Solidity 语言编写的测试用例（并且能很快速的执行测试用例）](https://book.getfoundry.sh/forge/writing-tests): 并且支持[模糊测试](https://book.getfoundry.sh/forge/fuzz-testing)与[差异测试](https://book.getfoundry.sh/forge/differential-ffi-testing)等方便、专业的测试方式;\n- 通过 [Cheatcodes（作弊码）](https://book.getfoundry.sh/forge/cheatcodes) 在 Solidity语言 编写的测试用例中**进行 “EVM环境之外” 的 vm 功能进行交互与断言**：更换测试用例语句执行者的钱包地址（更换 `msg.sender`）、对 EVM 外的 Event 事件进行断言；\n- 执行过程与错误追踪：[“函数堆栈”级的错误追踪（Traces）](https://book.getfoundry.sh/forge/traces)；\n- [部署合约和自动化的完成scan上合约的开源验证](https://book.getfoundry.sh/forge/deploying)；\n- 在项目中支持[完整的gas使用情况追踪](https://book.getfoundry.sh/forge/gas-tracking)：包括合约测试细节的gas用量和gas报告；\n- 交互式[调试器](https://book.getfoundry.sh/forge/debugger)；\n\n## Foundry 的组成\n\nFoundry 项目由 `Forge`, `Cast`, `Anvil` 几个部分（命令行工具）组成\n\n- Forge: Foundry 项目中**执行初始化项目、管理依赖、测试、构建、部署智能合约**的命令行工具;\n- Cast: Foundry 项目中**与 RPC 节点交互**的命令行工具。可以进行智能合约的调用、发送交易数据或检索任何类型的链上数据;\n- Anvil:  Foundry 项目中**启动的本地测试网/节点**的命令行工具。可以使用它配合测试前端应用与部署在该测试网的合约或通过 RPC 进行交互; \n\n## 快速使用 --- 创建一个 Foundry 项目\n\n> 内容出自 Foundry book 的 Getting Start 部分\n\n即将完成的过程：\n1. 安装 Foundry;\n2. 初始化一个 Foundry 项目;\n3. 理解初始化过程中添加的智能合约、测试用例；\n4. 执行构建&测试;\n  \n  \n### 安装 Foundry\n\n对于不同的环境：\n- MacOS / Linux （等 Unix like 系统）：\n  - 通过 `foundryup` 安装（👈Foundry 项目首页推荐的方式）;\n  - 通过 源代码构建 安装;\n- Windows\n  - 通过 源代码构建 安装;\n- Docker 环境\n  - 参考 Foundry Package: [ https://github.com/gakonst/foundry/pkgs/container/foundry](https://github.com/gakonst/foundry/pkgs/container/foundry)\n- Github Action： 用于构建完整的 Action 流程\n  - 参考 [https://github.com/foundry-rs/foundry-toolchain](https://github.com/foundry-rs/foundry-toolchain)\n\n---\n\n#### 通过[脚本](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/install)快速安装\n通过有`bash`的（或者类Unix环境）快速安装\n```shell\n$ curl -L https://foundry.paradigm.xyz | bash\n```\n执行后将会安装 `foundryup`，在此后执行它\n```shell\n$ foundryup\n```\n如果一切顺利，您现在可以使用三个二进制文件：`forge`、`cast` 和 `anvil`。\n\n\n<!--\n\n---\n\n#### [通过源代码构建安装（需要你了解一点 Rust 环境）](https://book.getfoundry.sh/getting-started/installation#building-from-source)\n\n要从源代码构建，您需要获取 `Rust` 和 `Cargo`。获得两者的最简单方法是使用 `rustup`。\n\n```shell\n# clone 项目目录至本地\ngit clone https://github.com/foundry-rs/foundry\n\n# 进入项目目录\ncd foundry\n\n# 安装 cast + forge\ncargo install --path ./cli --profile local --bins --locked --force\n\n# 安装 anvil\ncargo install --path ./anvil --profile local --locked --force\n```\n-->\n### 初始化一个 Foundry 项目\n\n通过 `forge` 的 `forge init` 初始化项目 \"hello_wtf\"\n```shell\n$ forge init hello_wtf\n\nInitializing /Users/username/hello_wtf...\nInstalling forge-std in \"/Users/username/hello_wtf/lib/forge-std\" (url: Some(\"https://github.com/foundry-rs/forge-std\"), tag: None)\n    Installed forge-std\n    Initialized forge project.\n```\n该过程通过安装依赖`forge-std`初始化了一个 Foundry 项目\n\n在项目目录中看到\n\n```shell\n$ tree -L 2 \n.\n├── foundry.toml        # Foundry 的 package 配置文件\n├── lib                 # Foundry 的依赖库\n│   └── forge-std       # 工具 forge 的基础依赖\n├── script              # Foundry 的脚本\n│   └── Counter.s.sol   # 示例合约 Counter 的脚本\n├── src                 # 智能合约的业务逻辑、源代码将会放在这里\n│   └── Counter.sol     # 示例合约\n└── test                # 测试用例目录\n    └── Counter.t.sol   # 示例合约的测试用例\n```\n提示：\n- 依赖项作为 git submodule 在 `./lib` 目录中\n- 关于 Foundry 的 package 配置文件请详细参考: [https://github.com/foundry-rs/foundry/blob/master/config/README.md#all-options](https://github.com/foundry-rs/foundry/blob/master/config/README.md#all-options)\n\n\n### 理解初始化过程中添加的智能合约、测试用例\n\n#### src 目录\n\n主要由业务逻辑构成\n`src` 目录中的 `./src/Counter.sol`:\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {          // 一个很简单的 Counter 合约\n    uint256 public number;  // 维护一个 public 的 uint256 数字\n\n    // 设置 number 变量的内容\n    function setNumber(uint256 newNumber) public { \n        number = newNumber;\n    }\n\n    // 让 number 变量的内容自增\n    function increment() public {\n        number++;\n    }\n}\n```\n\n#### script 目录\n\n参考 Foundry 项目文档中的 [Solidity-scripting](https://book.getfoundry.sh/tutorials/solidity-scripting) 该目录主要由“部署”脚本构成（也可通过该脚本调用 Foundry 提供的 `vm` 功能实现应用业务逻辑之外的高级功能，等同于 Hardhat.js 中的 scripts）。\n\n详见script 目录中的 `./script/Counter.s.sol`：\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13; // 许可 和 Solidity版本标识\n\nimport \"forge-std/Script.sol\"; // 引入foundry forge中的Script库\nimport \"../src/Counter.sol\"; // 引入要部署的Counter合约\n\n// 部署脚本继承了Script合约\ncontract CounterScript is Script {\n    // 可选函数，在每个函数运行之前被调用\n    function setUp() public {}\n\n    // 部署合约时会调用run()函数\n    function run() public {\n        vm.startBroadcast(); // 开始记录脚本中合约的调用和创建\n        new Counter(); // 创建合约\n        vm.stopBroadcast(); // 结束记录\n    }\n}\n```\n\nFoundry的部署脚本是一个用Solidity写的智能合约，虽然它不会被部署，但符合Solidity的规范。你可以用`forge script`运行脚本并部署合约。\n\n```shell\nforge script script/Counter.s.sol:CounterScript\n```\n\n\n#### test 目录\n\n主要由合约的测试用例构成\n\ntest 目录中的 `./test/Counter.t.sol`\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";        // 引入 forge-std 中用于测试的依赖\nimport \"../src/Counter.sol\";        // 引入用于测试的业务合约\n\n// 基于 forge-std 的 test 合约依赖实现测试用例\ncontract CounterTest is Test {      \n    Counter public counter;\n\n    // 初始化测试用例\n    function setUp() public { \n       counter = new Counter();\n       counter.setNumber(0);\n    }\n\n    // 基于初始化测试用例\n    // 断言测试自增后的 counter 的 number 返回值 同等于 1\n    function testIncrement() public {\n        counter.increment();\n        assertEq(counter.number(), 1);\n    }\n\n    // 基于初始化测试用例\n    // 执行差异测试测试\n    // forge 测试的过程中\n    // 为 testSetNumber 函数参数传递不同的 unit256 类型的 x\n    // 达到测试 counter 的 setNumber 函数 为不同的 x 设置不同的数\n    // 断言 number() 的返回值等同于差异测试的 x 参数\n    function testSetNumber(uint256 x) public {\n        counter.setNumber(x);\n        assertEq(counter.number(), x);\n    }\n\n    // 差异测试：参考 https://book.getfoundry.sh/forge/differential-ffi-testing\n}\n```\n\n### 执行构建&测试\n\n在项目目录中通过执行 `forge build` 完成构建\n```shell\n$ forge build\n\n[⠒] Compiling...\n[⠢] Compiling 10 files with 0.8.17\n[⠰] Solc 0.8.17 finished in 1.06s\nCompiler run successful\n```\n\n完成构建后 通过 `forge test` 完成测试\n```shell\n$ forge test\n\n[⠢] Compiling...\nNo files changed, compilation skipped\n\nRunning 2 tests for test/Counter.t.sol:CounterTest\n[PASS] testIncrement() (gas: 28312)\n[PASS] testSetNumber(uint256) (runs: 256, μ: 27609, ~: 28387)\nTest result: ok. 2 passed; 0 failed; finished in 9.98ms\n```\n\n至此，您已完成上手使用 Foundry 并且初始化一个项目。\n\n<!--\n\n  TODO: For foundry advanced usage ...\n\n  We need cover: \n  \n  - cli forge `test` : reference https://book.getfoundry.sh/forge/writing-tests\n  - cheatcode.\n  - Logs and traces levels.\n\n... etc.\n\n-->\n\n\n\n## Foundry Cast的进阶使用\n主要介绍Foundry Cast的使用，使用Cast在命令行下达到[Ethereum (ETH) Blockchain Explorer](https://etherscan.io/) 的效果。\n\n练习如下目标\n* 查询区块\n* 查询交易\n* 交易解析\n* 账户管理\n* 合约查询\n* 合约交互\n* 编码解析\n* 本地模拟链上交易\n\n\n\n## 区块相关\n\n### 查询区块\n\n```shell\n# $RPC_MAIN 替换成需要的RPC地址\ncast block-number --rpc-url=$RPC_MAIN\n```\n\n输出结果：\n\n```\n15769241\n```\n> 将环境变量的ETH_RPC_URL设置为 --rpc-url 你就不需要在每个命令行后面增加 --rpc-url=$RPC_MAIN 我这里直接设置为主网\n\n### 查询区块信息\n\n```shell\n# cast block <BLOCK> --rpc-url=$RPC_MAIN\n\ncast block 15769241 --rpc-url=$RPC_MAIN\n\n# 格式化\n\ncast block 15769241 --json --rpc-url=$RPC_MAIN\n\n\n```\n\n输出结果：\n\n```shell \nbaseFeePerGas        22188748210\ndifficulty           0\nextraData            0x\ngasLimit             30000000\ngasUsed              10595142\nhash                 0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nlogsBloom            0x1c6150404140580410990400a61d01e30030b00100c2a6310b11b9405d012980125671129881101011501d399081855523a106443aef3ab07148626315f721550290981058030b2af90b213961204c6103d2002a076c9e12d0800475b8231f0d06a20100da57c60aa0c008280128284418503340087c8650104c34500c18aa1c2070878008c21c64207d1424000244811415afc507640448122060644c181204ba412f0af11365020880508105551226004c0801c1840183003a42062a5a2444c13266020c00081440008038492740a8204a0c6c050a29d52405b92e4b20f028a97a604c6b0849ca81c4d06009258b4206217803a168824484deb8513242f082\nminer                0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263\nmixHash              0x09b7a94ef1d6c93caaff49ca8bf387652e0e33e116076b61f4d5ee79f0b91f92\nnonce                0x0000000000000000\nnumber               15769241\nparentHash           0x95c60d89f2275a6a7b1a9545cf1fb6d8c614402cd7311c82bc7972c177f7812d\nreceiptsRoot         0xe0240d60c448387123e412114cd0165b2af7b926d34bb824f8c544b022aa76f9\nsealFields           []\nsha3Uncles           0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\nsize                 149912\nstateRoot            0xaa3e9d839e99c4791827c81df9c9129028a320432920205f191e3fb261d0951c\ntimestamp            1666026803\ntotalDifficulty      58750003716598352816469\ntransactions:        [\n\t0xc4f5c10e4419698edaf7431df464340b389e4b79db959d58f42e82e8d1ed18ae\n\t0xb90edeacf833ac6cb91a326c775ed86d8047a467404bd8c69782d2260983eaad\n\t0x6f280650e35238ab930c9a0f3163443fffe2efedc5b553f408174d4bcd89cd8d\n\t0x2e0eafea64aaf2f53240a16b11a4f250ba74ab9ca5a1a90e6f2a6e92185877d2\n\t0x34f41d22ed8209da379691640cec5bfb8bf9404ad0f7264709b7959d61532343\n\t0x7569ab5ce2d1ca13a0c65ad52cc901dfc186e8ff8800793550b97760cbe34db2\n\t0xcdeef0ffe859fcf96fb52e22a9789295c6f1a94280df9faf0ebb9d52abefb3e7\n\t0x00d6793f3dbdd616351441b9e3da9a0de51370174e0d9383b4aae5c3c9806c2a\n\t0xff3daf63a431af021351d3da5f2f39a894352328d7f3df96afab1888f5a7093f\n\t0x7938399bee5293c384831c8e5aa698cdb491d568f9ebfb6d5c946f4ef7bf7e51\n\t0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\n\t0x0435d78a1b62484fbe3a7680d68ba4bdf0d692f087f4a6b70eb377421c58a5dd\n\t0xe16d1fa4d60cca7447850337c63cdf7b888318cc1bbb893b115f262dc01132d7\n\t0x44af4f696dcfedee682d7e511ad2469780443052565eea731b86b652a175c05e\n\t0xe88732f92ac376efb6e7517e66fc586447e0d065b8686556f2c1a7c3b7a519ce\n\t0x7ee890b096e97fc0c7e3cf74e0f0402532e0f3b8fa0e0c494d3d691d031f57e7\n\t...]\n```\n\n## 交易相关\n\n### 查询交易\n\n```shell\n# 跟ethersjs中的 provider.getTransaction 类似\n# cast tx <HASH> [FIELD] --rpc-url=$RPC\n\n# 跟ethersjs中的 provider.getTransactionReceipt类似\n# cast receipt <HASH> [FIELD] --rpc-url=$RPC \n\ncast tx 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 --rpc-url=$RPC \n\ncast receipt 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 --rpc-url=$RPC\n\n# 只获取logs\n\ncast receipt 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 logs --rpc-url=$RPC\n\n```\n\n第一条命令行结果：\n\n```shell\nblockHash            0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nblockNumber          15769241\nfrom                 0x9C0649d7325990D98375F7864eA167B5EAdCD46a\ngas                  313863\ngasPrice             35000000000\nhash                 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\ninput                0x38ed173900000000000000000000000000000000000000000000000332ca1b67940c000000000000000000000000000000000000000000000000000416b4849e6ba1475000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a00000000000000000000000000000000000000000000000000000000634d91c1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\nnonce                14\nr                    0x288aef25af73a4d1916f8d37107ef5f24729a423f23acc38920829c4180fe794\ns                    0x7644d26a91da02ff1e774cc821febf6387b8ee9f3e3085140b781819d0d8ede0\nto                   0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D\ntransactionIndex     10\nv                    38\nvalue                0\n```\n\n第二行命令行结果：\n\n```shell\nblockHash               0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nblockNumber             15769241\ncontractAddress\ncumulativeGasUsed       805082\neffectiveGasPrice       35000000000\ngasUsed                 114938\nlogs                    [{\"address\":\"0x97be09f2523b39b835da9ea3857cfa1d3c660cbb\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\"],\"data\":\"0x00000000000000000000000000000000000000000000000332ca1b67940c0000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x2\",\"removed\":false},{\"address\":\"0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb\",\"topics\":[\"0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x0000000000000000000000000000000000000000000000044b0a580cbdcfc0d90000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x3\",\"removed\":false},{\"address\":\"0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x0000000000000000000000000000000000000000000000044b0a580cbdcfc0d9\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x4\",\"removed\":false},{\"address\":\"0xf848e97469538830b0b147152524184a255b9106\",\"topics\":[\"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1\"],\"data\":\"0x00000000000000000000000000000000000000000000213ebfba613ffdcdd6ad0000000000000000000000000000000000000000000018b4b7f855bdcaac3b14\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x5\",\"removed\":false},{\"address\":\"0xf848e97469538830b0b147152524184a255b9106\",\"topics\":[\"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822\",\"0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000332ca1b67940c00000000000000000000000000000000000000000000000000044b0a580cbdcfc0d90000000000000000000000000000000000000000000000000000000000000000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x6\",\"removed\":false}]\nlogsBloom               0x00200000000000000000000080000000000000000000000000010000000008000000000000800000000000000000000000000000002000000000000000000000000000000000000000000008000000200000000000000000000000400000100000000000800000002000000000000000000000400000000000000010000000000000000000000000005000000000040000000000000000080000004004000000000000084100000000000000000000000000000040000000000000000000040000000002000000000000000000000000000000000000001000002000000020000000000000000000000000000000000000004000000000000000000000000000\nroot\nstatus                  1\ntransactionHash         0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\ntransactionIndex        10\ntype                    0\n\n```\n\n### 交易解析\n\nCast 会从 [Ethereum Signature Database](https://sig.eth.samczsun.com.) 解析对应的方法名称\n\n```shell\n# cast 4byte <SELECTOR> 解析交易的名称\ncast 4byte 0x38ed1739\n```\n\n输出结果：\n\n```shell\nswapExactTokensForTokens(uint256,uint256,address[],address,uint256)\n```\n\n### 交易签名 \n\n> 使用 Keccak-256 能够计算出方法名\n> 函数名为被调函数原型[1]的Keccak-256哈希值的前4个字节。这允许EVM准确无误地识别被调函数。\n\n交易签名：\n\n```shell\n# cast sig <SIG>\n\ncast sig \"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)\"\n\n```\n\n输出结果：\n\n```shell\n0x38ed1739\n```\n\n所以你可以看到最终都是 `0x38ed1739`\n\n有些方法名称可能没有，你可以通过`cast upload-signature <SIG> `上传给 [Ethereum Signature Database](https://sig.eth.samczsun.com) \n\n### 交易解码\n\n```shell\n# 获得calldata\ncast tx 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 input --rpc-url=$RPC\n\n# 可以通过该方法decode交易的数据，类似etherscan中的decode方法\n# cast pretty-calldata <CALLDATA>\ncast pretty-calldata 0x38ed173900000000000000000000000000000000000000000000000332ca1b67940c000000000000000000000000000000000000000000000000000416b4849e6ba1475000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a00000000000000000000000000000000000000000000000000000000634d91c1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\n```\n\n输出结果：\n\n```shell\n Possible methods:\n - swapExactTokensForTokens(uint256,uint256,address[],address,uint256)\n ------------\n [0]:  00000000000000000000000000000000000000000000000332ca1b67940c0000\n [1]:  00000000000000000000000000000000000000000000000416b4849e6ba14750\n [2]:  00000000000000000000000000000000000000000000000000000000000000a0\n [3]:  0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\n [4]:  00000000000000000000000000000000000000000000000000000000634d91c1\n [5]:  0000000000000000000000000000000000000000000000000000000000000002\n [6]:  00000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb\n [7]:  0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\n```\n\n### 模拟运行\n\n```\n# Usage: cast run --rpc-url <URL> <TXHASH>\n\ncast run 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\n```\n\n运行结果：\n\n![cast-run](./img/1.png)\n\n可以在结果中看到运行消耗的gas，以及方法顺序调用的过程，以及释放的emit的事件。通过这个可以了解一个hash的内在过程。类似 [BlockSec Building BlockChain Security Infrastructure](https://blocksec.com/) 和 [Tenderly | Ethereum Developer Platform](https://tenderly.co/) 可以结合使用。\n\n## 账户管理\n\n### 新建账户\n\n```shell\n# 新建一个账号\n# cast wallet new [OUT_DIR] \ncast wallet new\n\n# 新建一个keystore的账号，带有密码\n# cast wallet new <PATH>\ncast wallet new  ~/Downloads\n```\n\n第一条命令行结果输出：\n\n```shell\nSuccessfully created new key pair.\nAddress: 0xDD20b18E001A80d8b27B8Caa94EeAC884D1c****\nPrivate Key: edb4444199bddea91879c0214af27c0c7f99****bf18e46ba4078a39ccdbe0bc\n```\n\n第二条命令行结果输出：\n\n```shell\nEnter secret:\nCreated new encrypted keystore file: `/Users/EasyPlux/Downloads/b5832df5-21e9-4959-8c85-969eec9c0***`\\nPublic Address of the key: 0x58c1C8f6A7D92A9b20A5343949cd624570Ab****\n```\n\n### 账户签名\n\n```shell\n# 两种方法都可以使用签名，第一种载入刚才生成的keystore私钥，第二种直接输入自己的私钥。\ncast wallet sign <MESSAGE> --keystore=<PATH> \ncast wallet sign <MESSAGE> -i\n```\n\n### 账户验证\n\n```shell\ncast wallet verify --address <ADDRESS> <MESSAGE> <SIGNATURE> \n```\n\n## 合约交互\n\n### 获取合约\n\n```shell\ncast etherscan-source <contract address>\n\ncast etherscan-source 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --etherscan-api-key='key'\n\n```\n\n### 下载合约\n\n```shell\n#cast etherscan-source -d <path>\n# 我这里已经将$WETH的地址写入环境变量，如果没写入的，可以写成合约地址\ncast etherscan-source $WETH -d ~/Downloads\n```\n\n### 调用合约(读数据)\n\n`cast call` 用于从区块链上读取数据（调用只读函数），该操作不会改变区块链状态，也不需要支付 Gas 费用。下面我们调用 `WETH` 合约的`balanceOf`方法,查看 `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` 账号的余额\n\n```shell\n#cast call [OPTIONS] [TO] [SIG] [ARGS]... [COMMAND] --rpc-url=$RPC\n\ncast call $WETH \"balanceOf(address)\" 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url=$RPC\n\n# 输出\n# 0x0000000000000000000000000000000000000000000000230d12770f2845219c\n\n# 格式化输出 在参数后面加一个返回值的格式\n\ncast call $WETH \"balanceOf(address)(uint256)\" 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url=$RPC\n\n# 输出\n# 646577988758891995548\n\n```\n\n### 调用合约(写数据)\n\n`cast send` 用于发送交易并修改区块链状态（调用改变状态的函数），该操作会消耗 Gas 费用，需要签名并发送交易。\n\n```shell\n#cast send [OPTIONS] [TO] [SIG] [ARGS]... [COMMAND] --rpc-url=$RPC\n\ncast send 0x... \"deposit(address,uint256)\" 0x... 1 --rpc-url=$RPC\n\n```\n\n\n### 解析ABI\n\n可以根据ABI反向解析出solidity代码\n```shell\n# cast interface [OPTIONS] <PATH_OR_ADDRESS>\ncast interface ./weth.abi\n```\n\n## 编码解码\n\n```shell\ncast --to-hex \n\ncast --to-dec \n\ncast --to-unit \n\ncast --to-wei \n\ncast --to-rlp \n\ncast --from-rlp\n\n```\n\n## Tips\n\n### 设置ETH_RPC_URL\n将环境变量的`ETH_RPC_URL`设置为 `--rpc-url`的值，这样你就不需要在每个命令行后面增加 `--rpc-url=$RPC_MAIN`，我这里直接设置为主网，如下：\n``` shell\nexport ETH_RPC_URL=your_rpc_url\nsource ~/.bashrc  # 如果你使用的是 Bash\nsource ~/.zshrc   # 如果你使用的是 Zsh\ncast block-number # 不用再配置 --rpc-url 参数\n```\n\n### 设置ETHERSCAN_API_KEY\n设置`ETHERSCAN_API_KEY`环境变量可以直接代替 `--etherscan-api-key`\n\n### JSON格式化\n\n加上 `--json`  可以格式化输出\n\n```shell\ncast block 15769241 --json --rpc-url=$RPC_MAIN\n```\n\n## Anvil本地节点的使用\n\n### 基本命令行\n\nanvil 跟 hardhat 还有 truffle中的ganache都是一样的，是一个本地的eth节点，同样拥有各种fork的功能。\n\n```shell\nanvil \nanvil --accounts=<NUM> --balance=<NUM> \nanvil --mnemonic=<MNEMONIC> \nanvil --fork-url=$RPC --fork-block-number=<BLOCK>\n```\n\n### RPC的使用\n\n```shell\nanvil_* -> hardhat_* \n\nanvil_impersonateAccount \n\nanvil_setStorageAt\n```\n\n## Forge命令行进阶的使用\n\n代码存放在`WTFSolidity/Topics/Tools/TOOL07_Foundry/hello_wtf`\n\n代码目录树如下：\n\n```shell\n.\n├── broadcast\n│   └── Counter.s.sol \n├── foundry.toml        # foundry配置文件\n├── lib\n│   └── forge-std\n├── node_modules        # 使用npm依赖包目录，你也可以直接使用forge install\n│   └── @openzeppelin\n├── package-lock.json\n├── package.json\n├── script\n│   └── Counter.s.sol   # 脚本合约\n├── src\n│   └── Counter.sol\n└── test\n    ├── Counter.t.sol\n    └── Test.t.sol      # 测试合约\n```\n\n### 初始化项目\n```shell\n\nforge init <dir_name> \n\n# 使用模板初始化项目\nforge init --template <template_path> <dir_name>\n\n```\n\n## 热更新\n\n```shell\nforge build -w\n```\n\n\n### 测试\n\n```shell\n# 三个v会现实详细的log信息，还显示失败测试的堆栈跟踪\nforge test -vvv\n# 四个v显示所有测试的堆栈跟踪，并显示失败测试的设置（setup）跟踪。\nforge test -vvvv\n# 热更新模式\nforge test -vvv -w\n\n# log打印 需要 - vv 2个v以上才可以\n```\n\n使用 console2.log(\"test\") 来打印\n\n```js\n\n\nfunction testSetNumber(uint256 x) public {\n        console2.log(\"testNumber: %s==============\", x);\n        counter.setNumber(x);\n        assertEq(counter.number(), x);\n    }\n```\n\n\n使用 emit log 来打印\n\n```js\nfunction testNumberIs42() public {\n        emit log(\"test\");\n        assertEq(testNumber, 42);\n    }\n```\n\n改变 block.timestamp\n\n```js\n\nfunction testCheatCode()public {\n  console2.Log(\"before:\"block.timestamp);\n  vm.warp(1000);\n  console2.log(\"after:\"block.timestamp);\n}\n\n```\n\n改变msg.sender 【可以模拟管理员账户】\n\n```js\n// 只有第一次有影响\nvm.prank(address)\n\n\n// 多次影响\nvm.startPrank(address)\n...code\nvm.stopPrank()\n\n```\n\n\n改变账户余额（也可以用于改变大多数ERC20代币余额）\n\n```js\nfunction testCheatCode()public{\n\tconsole2.Log(\"before:\"alice.balance);\n\tvm.deal(alice,1 ether);\n\tconsole2.Log(\"after:\"alice.balance);\n}\n\n```\n\n## 安装插件\n\n### 使用forge安装插件\n\n```shell\nforge install [OPTIONS] <github username>/<github project>@<tag>\n```\n\n### 使用npm安装插件\n\n```shell\nnpm init -y\nnpm i @openzeppelin/contracts \n// yarn add @openzeppelin/contracts\n```\n\n安装完成之后需要配置`foundry.toml`方法，在libs中添加 `node_modules`文件夹。\n\n```toml\n[profile.default]\nsrc = 'src'\nout = 'out'\nlibs = ['lib','node_modules']\n```\n\n\n## 测试一\n\n新建`test/Test.t.sol`\n\n```js\n// SPDX-License-Identifier: SEE LICENSE IN LICENSE\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/Counter.sol\";\n// 导入IERC20的接口，通过该接口可以调用对应的方法\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract IERC20Test is Test {\n  // 声明Counter合约对象变量\n  Counter public counter;\n  // 声明一个地址变量\n  address public alice;\n  // 声明一个msgSender\n  address public msgSender;\n  // 声明帮助合约函数\n  Helper public h;\n\n  //定义一个IERC20 合约对象\n  IERC20 public dai;\n\n  function setUp() public {\n    // new测试合约对象\n    counter = new Counter();\n    // 调用对象方法\n    counter.setNumber(0);\n    // new helper对象\n    h = new Helper();\n\n    alice = address(10086);\n    console2.log(alice);\n    dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);\n  }\n\n  // 测试给合约地址转账\n  function testCheatCode() public {\n    console2.log(\"before:\", dai.balanceOf(alice));\n    deal(address(dai), alice,1 ether);\n    console2.log(\"after:\", dai.balanceOf(alice));\n  }\n  // 测试改变合约msg.sender\n  function testCheatAddress() public {\n    console2.log(\"before:\", h.whoCalled());\n    vm.prank(address(1));\n    console2.log(\"after:\", h.whoCalled());\n  }\n}\n\n\ncontract Helper {\n  function whoCalled() public view returns (address) {\n    return msg.sender;\n  }\n}\n```\n\n\n运行测试：\n\n因为本地没有dai的部署合约，所以我们直接fork主网， -vvv可以显示console2.log，-w表示watch模式。\n\n```shell\nforge test -vvv --fork-url=$ETH_RPC_URL -w\n```\n\n输出结果：\n\n```shell\nRunning 2 tests for test/Test.t.sol:IERC20Test\n[PASS] testCheatAddress() (gas: 12873)\nLogs:\n  0x0000000000000000000000000000000000002766\n  before: 0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84\n  after: 0x0000000000000000000000000000000000000001\n\n[PASS] testCheatCode() (gas: 153596)\nLogs:\n  0x0000000000000000000000000000000000002766\n  before: 0\n  after: 1000000000000000000\n\nTest result: ok. 2 passed; 0 failed; finished in 5.61s\n```\n\n### 代码中fork网络\n\n```js\nfunction testCodeFork() public {\n    console2.log(address(dai));\n    string memory rpc = vm.envString(\"ETH_RPC_URL\");\n    uint256 mainnet = vm.createFork(rpc);\n    vm.selectFork(mainnet);\n    // 这边下面开始就是直接fork网络了\n    console2.log(\"before:\",dai.balanceOf(alice));\n    deal(address(dai),alice,1 ether);\n    console2.log(\"after:\",dai.balanceOf(alice));\n  }\n```\n\n### 从代码中读取环境变量\n\n```js\n// 通过 vm.envAddress 获取环境变量中的地址\n    dai = IERC20(vm.envAddress(\"DAI\"));\n```\n\n### 完整代码\n\n```js\n// SPDX-License-Identifier: SEE LICENSE IN LICENSE\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/Counter.sol\";\n// 导入IERC20的接口，通过该接口可以调用对应的方法\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract IERC20Test is Test {\n  // 声明Counter合约对象变量\n  Counter public counter;\n  // 声明一个地址变量\n  address public alice;\n  // 声明一个msgSender\n  address public msgSender;\n  // 声明帮助合约函数\n  Helper public h;\n\n  //定义一个IERC20 合约对象\n  IERC20 public dai;\n\n  function setUp() public {\n    // new测试合约对象\n    counter = new Counter();\n    // 调用对象方法\n    counter.setNumber(0);\n    // new helper对象\n    h = new Helper();\n\n    alice = address(10086);\n    console2.log(alice);\n    // 通过 vm.envAddress 获取环境变量中的地址\n    dai = IERC20(vm.envAddress(\"DAI\"));\n  }\n\n\n  // 测试给合约地址转账\n  function testCheatCode() public {\n    console2.log(\"before:\", dai.balanceOf(alice));\n    deal(address(dai), alice,1 ether);\n    console2.log(\"after:\", dai.balanceOf(alice));\n  }\n  // 测试改变合约msg.sender\n  function testCheatAddress() public {\n    console2.log(\"before:\", h.whoCalled());\n    vm.prank(address(1));\n    console2.log(\"after:\", h.whoCalled());\n  }\n\n  function testCodeFork() public {\n    console2.log(address(dai));\n    string memory rpc = vm.envString(\"ETH_RPC_URL\");\n    uint256 mainnet = vm.createFork(rpc);\n    vm.selectFork(mainnet);\n    // 这边下面开始就是直接fork网络了\n    console2.log(\"before:\",dai.balanceOf(alice));\n    deal(address(dai),alice,1 ether);\n    console2.log(\"after:\",dai.balanceOf(alice));\n  }\n\n}\n\n\ncontract Helper {\n  function whoCalled() public view returns (address) {\n    return msg.sender;\n  }\n}\n```\n\n### vm.sol\n\n`vm.sol` 中还有很多封装好的方法可以直接使用\n\n```js\n// Sets the *next* call's msg.sender to be the input address\n    function prank(address) external;\n    // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n    function startPrank(address) external;\n    // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n    function prank(address,address) external;\n    // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n    function startPrank(address,address) external;\n    // Resets subsequent calls' msg.sender to be `address(this)`\n    function stopPrank() external;\n    // Sets an address' balance, (who, newBalance)\n    function deal(address, uint256) external;\n    // Sets an address' code, (who, newCode)\n    function etch(address, bytes calldata) external;\n    // Expects an error on next call\n    function expectRevert(bytes calldata) external;\n    function expectRevert(bytes4) external;\n    function expectRevert() external;\n    // Records all storage reads and writes\n    function record() external;\n    // Gets all accessed reads and write slot from a recording session, for a given address\n    function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes);\n```\n\n\n##  运行脚本\n\n```shell\nforge script [OPTIONS] <PATH> [ARGS]...\nforge script script/Counter.s.sol:CounterScript\n```\n\n`script/Counter.s.sol` 脚本代码\n\n```js\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Script.sol\";\n\ncontract CounterScript is Script {\n// 每次初始化会运行\n    function setUp() public {\n        console2.log(\"setup \");\n    }\n\n    function run() public {\n        vm.broadcast();\n        console2.log(\"run\");\n    }\n\n    function someFunction(uint256 x) public {\n        console2.log(\"some other func\");\n        console2.log(x);\n    }\n}\n\n```\n\n指定方法，带参数的测试运行\n\n```shell\nforge script script/Counter.s.sol --sig=\"someFunction(uint256 x)\" 10\n```\n\n## 脚本部署合约\n\n编写部署脚本：\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Script.sol\";\n// 引入合约\nimport \"../src/Counter.sol\";\n\ncontract CounterScript is Script {\n  function setUp() public {\n    console2.log(\"setup \");\n  }\n\n  function run() public {\n    // 开始记录脚本中合约的调用和创建\n    vm.startBroadcast();\n    //生成合约对象\n    Counter c = new Counter();\n    // 结束记录\n    vm.stopBroadcast();\n  }\n}\n\n```\n\n测试部署：\n\n```shell\nforge script script/Counter.s.sol -vvvv --rpc-url=http://127.0.0.1:8545\n```\n\n正式部署：\n\n```\nforge script script/Counter.s.sol -vvvv --rpc-url=$RPC_MAIN --broadcast --private-key=privete_key\n```\n\n部署完成之后会多一个broadcast文件夹，查看该文件夹有`run-latest.json`可以看到部署的相应信息。\n\n### 部署多个网络\n\n使用fork代码可以部署多个网络\n\n\n```js\nuint256 mainnet = vm.createFork(rpc);\n```\n\n## 命令行部署合约\n\n部署并开源合约，其中 `--etherscan-api-key` 为以太坊浏览器（或其他 EVM 浏览器）中申请的 API key，`--verify` 为部署后开源合约。\n```solidity\n# forge create --rpc-url <your_rpc_url> --private-key <your_private_key> --etherscan-api-key <KEY> --verify src/YourContract.sol:YourContract --constructor-args <constructor_args>\n  forge create --rpc-url $RPC_MAIN \\ \n   --private-key privete_key  \\ \n   --etherscan-api-key xxxx  \\ \n   --verify \\\n   src/Counter.sol:Counter\n```\n\n## Tips： \n\n```shell\nforge test --gas-report\n\n# 获取合约相关信息，例如abi、bytecode等等\nforge inspect <CONTRACT> <FIELD>\n\n# 生成gas快照\nforge snapshot\n\n# 当前快照文件与最新更改进行比较，对比gas是否减少\nforge snapshot --diff \n\n# 交互式Debugger\nforge script script/Counter.s.sol --debug\n\n# 链上交易debugger\nforge run --debug\n\n```\n\n\n\n## 总结\n\n这一讲我们介绍了以Solidity为中心的开发工具，并介绍了如何利用Foundry编译，部署，测试智能合约。由于Foundry的部署和测试脚本都是用Solidity编写，免去了开发者学习javascript的时间成本，并提供了更多练习Solidity的机会，推荐大家使用。\n\n\n## 参考\n[使用 foundry 框架加速智能合约开发](https://www.youtube.com/watch?v=EXYeltwvftw) \n[cast Commands - Foundry Book](https://book.getfoundry.sh/reference/cast/)\n[https://twitter.com/wp__lai](https://twitter.com/wp__lai)\n","Topics/Tools/TOOL06_Hardhat/package.json":"{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"description\": \"我最近在重新学solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用），每周更新1-3讲。\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n    \"hardhat\": \"^2.22.2\"\n  },\n  \"directories\": {\n    \"test\": \"test\"\n  }\n}\n","Topics/Tools/TOOL06_Hardhat/readme.md":"# WTF Solidity极简入门-工具篇6：Hardhat以太坊开发环境\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\nHardhat是以太坊最流行的开发环境，它可以帮你编译和部署智能合约，并且提供了Hardhat Network支持本地测试和运行Solidity。这一讲，我们将介绍如何安装Hardhat，使用Hardhat编写并编译合约，并运行简单的测试。\n\n## Hardhat安装\n\n### 安装node\n\n可以使用 nvm 安装node\n\n[GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions](https://github.com/nvm-sh/nvm)\n\n### 安装Hardhat\n\n打开命令行工具，输入：\n```shell\nmkdir hardhat-demo\ncd hardhat-demo\nnpm init -y\nnpm install --save-dev hardhat\n```\n\n### 创建Hardhat项目\n打开命令行工具，输入：\n\n```shell\ncd hardhat-demo\nnpx hardhat\n```\n\n选择第三项：创建空白项目配置 `Create an empty hardhat.config.js`\n\n```shell\nWelcome to Hardhat v2.22.2\n\n? What do you want to do? ...\n> Create a JavaScript project\n  Create a TypeScript project\n  Create a TypeScript project (with Viem)\n  Create an empty hardhat.config.js\n  Quit\n```\n\n### 安装插件\n```shell\nnpm install --save-dev @nomicfoundation/hardhat-toolbox\n```\n\n将插件添加到你的hardhat配置文件中 `hardhat.config.js`\n\n```js\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n\n/** @type import('hardhat/config').HardhatUserConfig */\nmodule.exports = {\n  solidity: \"0.8.21\",\n};\n```\n\n## 编写并编译合约\n如果你用过remix，那么你直接在remix上点击保存的时候，会自动帮你编译的。但是在本地的hardhat开发环境中，你需要手动编译合约。\n\n### 新建合约目录\n\n新建`contracts`合约目录，并添加第31章节的ERC20合约。\n\n### 编写合约\n这里的合约直接使用[WTF Solidity第31讲](https://github.com/AmazingAng/WTF-Solidity/blob/main/31_ERC20/readme.md)的ERC20合约\n\n```js\n// SPDX-License-Identifier: MIT\n// WTF Solidity by 0xAA\n\npragma solidity ^0.8.21;\n\nimport \"./IERC20.sol\";\n\ncontract ERC20 is IERC20 {\n\n    mapping(address => uint256) public override balanceOf;\n\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    uint256 public override totalSupply;   // 代币总供给\n\n    string public name;   // 名称\n    string public symbol;  // 符号\n    \n    uint8 public decimals = 18; // 小数位数\n\n    // @dev 在合约部署的时候实现合约名称和符号\n    constructor(string memory name_, string memory symbol_){\n        name = name_;\n        symbol = symbol_;\n    }\n\n    // @dev 实现`transfer`函数，代币转账逻辑\n    function transfer(address recipient, uint amount) external override returns (bool) {\n        balanceOf[msg.sender] -= amount;\n        balanceOf[recipient] += amount;\n        emit Transfer(msg.sender, recipient, amount);\n        return true;\n    }\n\n    // @dev 实现 `approve` 函数, 代币授权逻辑\n    function approve(address spender, uint amount) external override returns (bool) {\n        allowance[msg.sender][spender] = amount;\n        emit Approval(msg.sender, spender, amount);\n        return true;\n    }\n\n    // @dev 实现`transferFrom`函数，代币授权转账逻辑\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint amount\n    ) external override returns (bool) {\n        allowance[sender][msg.sender] -= amount;\n        balanceOf[sender] -= amount;\n        balanceOf[recipient] += amount;\n        emit Transfer(sender, recipient, amount);\n        return true;\n    }\n\n    // @dev 铸造代币，从 `0` 地址转账给 调用者地址\n    function mint(uint amount) external {\n        balanceOf[msg.sender] += amount;\n        totalSupply += amount;\n        emit Transfer(address(0), msg.sender, amount);\n    }\n\n    // @dev 销毁代币，从 调用者地址 转账给  `0` 地址\n    function burn(uint amount) external {\n        balanceOf[msg.sender] -= amount;\n        totalSupply -= amount;\n        emit Transfer(msg.sender, address(0), amount);\n    }\n\n}\n\n```\n\n### 编译合约\n```shell\nnpx hardhat compile\n```\n\n看到如下输出，说明合约编译成功：\n\n```shell\nCompiling 2 Solidity files successfully\n```\n\n成功后，你会在文件夹下看到`artifacts`目录，里面的`json`文件就是编译结果。\n\n## 编写单元测试\n\n这里的单元测试非常简单，仅包含部署合约并测试合约地址是否合法（是否部署成功）。\n\n新建测试文件夹`test`，在其中新建`test.js`。单元测试中，我们会用到`chai`和`ethers.js`两个库，分别用于测试和链上交互。对`ethers.js`不了解的开发者，可以看下[WTF Ethers极简教程](https://github.com/WTFAcademy/WTF-Ethers)的前6讲。我们之后的教程会更详细的介绍`chai`和`mocha`。\n\n```js\nconst { expect } = require('chai');\nconst { ethers } = require('hardhat');\n\n\ndescribe(\"ERC20 合约测试\", ()=>{\n  it(\"合约部署\", async () => {\n     // ethers.getSigners,代表eth账号  ethers 是一个全局函数，可以直接调用\n     const [owner, addr1, addr2] = await ethers.getSigners();\n     // ethers.js 中的 ContractFactory 是用于部署新智能合约的抽象，因此这里的 ERC20 是我们代币合约实例的工厂。ERC20代表contracts 文件夹中的 ERC20.sol 文件\n     const Token = await ethers.getContractFactory(\"ERC20\");\n     // 部署合约, 传入参数 ERC20.sol 中的构造函数参数分别是 name, symbol 这里我们都叫做WTF\n     const hardhatToken = await Token.deploy(\"WTF\", \"WTF\"); \n     await hardhatToken.waitForDeployment();\n      // 获取合约地址\n     const ContractAddress = await hardhatToken.target;\n     expect(ContractAddress).to.properAddress;\n  });\n})\n```\n\n## 运行测试\n\n在命令行输入以下内容运行测试：\n\n```shell\nnpx hardhat test\n# 如果有多个文件想跑指定文件可以使用\nnpx mocha test/test.js\n```\n\n看到如下输出，说明测试成功。\n\n```shell\n  ERC20 合约测试\n    ✔ 合约部署 (1648ms)\n\n\n  1 passing (2s)\n```\n\n## 部署合约\n\n在remix中，我们只需要点击一下`deploy`就可以部署合约了，但是在本地hardhat中，我们需要编写一个部署脚本。\n\n新建一个`scripts`文件夹，我们来编写部署合约脚本。并在该目录下新建一个`deploy.js`\n\n输入以下代码\n\n```js\n// 我们可以通过 npx hardhat run <script> 来运行想要的脚本\n// 这里你可以使用 npx hardhat run deploy.js 来运行\nconst hre = require(\"hardhat\");\n\nasync function main() {\n  const Contract = await hre.ethers.getContractFactory(\"ERC20\");\n  const token = await Contract.deploy(\"WTF\",\"WTF\");\n\n  await token.waitForDeployment();\n\n  console.log(\"成功部署合约:\", token.target);\n}\n\n// 运行脚本\nmain().catch((error) => {\n  console.error(error);\n  process.exitCode = 1;\n});\n\n```\n\n运行以下代码部署合约到本地测试网络\n\nhardhat会提供一个默认的网络，参考：[hardhat默认网络](https://hardhat.org/hardhat-network/docs/overview)\n\n```shell\nnpx hardhat run --network hardhat  scripts/deploy.js\n```\n\n看到如下输出，说明合约部署成功：\n\n```shell\n(node:45779) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n成功部署合约: 0x5FbDB2315678afecb367f032d93F642f64180aa3\n```\n\n## 部署合约到Goerli测试网络 ｜ 网络配置\n\n### 前期准备\n\n1. 申请alchemy的api key\n参考【[第4讲：Alchemy, 区块链API和节点基础设施](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL04_Alchemy/readme.md)】 \n2. 申请Goerli测试代币\n[点击申请](https://goerlifaucet.com/) 登录alchemy账号每天可以领取0.2个代币\n3. 导出私钥\n因为需要把合约部署到Goerli测试网络，所以该测试账号中留有一定的测试代币。导出已有测试代币的账户的私钥，用于部署合约\n4. 申请 etherscan 的 api key，用于验证合约\n[点击申请](https://etherscan.io/myapikey)\n\n### 配置网络\n\n在`hardhat.config.js`中，我们可以配置多个网络，这里我们配置`Goerli`测试网络。\n\n\n编辑 `hardhat.config.js`\n\n\n```js\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n\n// 申请alchemy的api key\nconst ALCHEMY_API_KEY = \"KEY\";\n\n//将此私钥替换为测试账号私钥\n//从MetaMask导出您的私钥，打开MetaMask和进入“帐户详细信息”>导出私钥\n//注意:永远不要把真正的以太放入测试帐户\nconst GOERLI_PRIVATE_KEY = \"YOUR GOERLI PRIVATE KEY\";\n\n// 申请etherscan的api key\nconst ETHERSCAN_API_KEY = \"YOUR_ETHERSCAN_API_KEY\";\n\nmodule.exports = {\n  solidity: \"0.8.21\", // solidity的编译版本\n  networks: {\n    goerli: {\n      url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`,\n      accounts: [GOERLI_PRIVATE_KEY]\n    }\n  },\n  etherscan: {\n    apiKey: ETHERSCAN_API_KEY,\n  },\n};\n```\n\n配置完成运行\n\n```shell\nnpx hardhat run --network goerli scripts/deploy.js\n```\n\n你就可以把你的合约部署到Goerli测试网络了。\n\n看到如下信息，你就成功部署到Goerli测试网络了。\n\n```shell\n(node:46996) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n(node:46999) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n成功部署合约: 0xeEAcef71084Dd1Ae542***9D8F64E3c68e15****\n```\n\n可以通过[etherscan](https://etherscan.io/)查看合约部署情况\n\n同理你也可以配置多个网络，比如`mainnet`，`rinkeby`等。\n\n最后验证你的合约：\n\n```shell\nnpx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS \"Constructor argument 1\"\n```\n\n\n## 总结\n\n这一讲，我们介绍了Hardhat基础用法。通过Hardhat我们能够工程化solidity的项目，并提供了很多有用的脚手架。在后续的文章中，我们会介绍更多的Hardhat的高级用法，例如使用Hardhat的插件、测试框架等等。","Topics/Tools/TOOL08_ZAN/readme.md":"# WTF Solidity 极简入门-工具篇 8：ZAN，节点服务和合约审计等 Web3 技术服务\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity 极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy\\_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n---\n\n## ZAN 是什么\n\n[ZAN](https://zan.top?chInfo=wtf) 是一家 Web3 技术服务提供商，是蚂蚁集团下的一个技术品牌。它提供多种技术服务，有类似 Infura 和 Alchemy 提供的节点服务，包括各种链的 JSON-RPC 支持，以及其他高级的链 API。还有安全相关的合约审计、链上数据分析、KYC 等服务。另外还提供 toB 的解决方案，包括 RWA 资产的链上发行、零知识证明加速以及提供安全和可定制的区块链等。\n\n接下来会针对开发者常用的节点服务、合约审计和链上数据分析（KNOW YOUR TRANSACTION）功能做介绍。在学习之前你可以先访问 [https://zan.top](https://zan.top?chInfo=wtf) 并完成注册和登录。\n\n## 节点服务\n\n### 创建 API Key\n\n之后进入到节点服务的控制台 [https://zan.top/service/apikeys](https://zan.top/service/apikeys?chInfo=wtf) 创建一个 Key，每个 Key 都有默认的免费额度，对于小项目来说够用了。\n\n创建成功后你会看到如下的页面：\n\n![](./img/zan-service.png)\n\n接下来你就可以直接点击网站上的 Copy 按钮复制获取 API Key 了，但是大部分情况我们都是直接复制你需要的链的 RPC 地址，然后在你的 DApp 中使用。\n\n### 使用 RPC 地址\n\n不同的区块链通常都会有自己的基础的 JSON-RPC 的接口规范，比如以太坊的 JSON-RPC 接口规范，你可以在 [https://ethereum.org/en/developers/docs/apis/json-rpc/](https://ethereum.org/en/developers/docs/apis/json-rpc/) 获取。\n\nZAN 提供的接口自然也遵循这样的规范，比如你可以通过访问 `https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}` 来访问以太坊上的数据。当然，我们通常可以直接使用链官方或者生态提供的 SDK 来调用接口。下面我们会介绍如何使用以太坊常用的一些 SDK 来调用 ZAN 提供的节点服务。\n\n需要注意上面代码中的 `YourZANApiKey` 需要替换成你自己的 Key。另外在实际的项目中，为了避免你的 Key 被滥用，建议你将 Key 放到后端服务中，然后通过后端服务来调用节点服务，或者在 ZAN 的控制台中设置域名白名单来降低被滥用的风险。\n\n#### 使用 ethers\n\n在 ethers.js 中，我们可以利用 ZAN 提供的 API Key 来创建 JsonRpcProvider，与链上交互。\n\n```javascript\nimport { ethers } from \"ethers\";\n\nconst provider = new ethers.providers.JsonRpcProvider(\n  \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n);\n\nprovider.getBlockNumber().then((blockNumber) => {\n  console.log(\"Current block number: \" + blockNumber);\n});\n```\n\n如上所示，我们可以通过 ethers.js 提供的 JsonRpcProvider 来访问 ZAN 提供的节点服务，获取当前区块的高度。更多的 ethers.js 的使用方法可以参考 ethers.js 官方文档：[ethers V5](https://docs.ethers.org/v5/api/providers/jsonrpc-provider/) | [ethers V6](https://docs.ethers.org/v6/api/providers/jsonrpc/#JsonRpcProvider)。\n\n#### 使用 web3.js\n\n在 web3.js 中，我们可以利用 ZAN 提供的 API Key 来创建 Web3Provider，与链上交互。\n\n```javascript\nimport Web3 from \"web3\";\n\nconst web3 = new Web3(\n  \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n);\nweb3.eth.getBlockNumber().then((blockNumber) => {\n  console.log(\"Current block number: \" + blockNumber);\n});\n```\n\n如上所示，我们可以通过 web3.js 提供的 Web3Provider 来访问 ZAN 提供的节点服务，获取当前区块的高度。更多的 web3.js 的使用方法可以参考 [web3.js 官方文档](https://web3js.readthedocs.io/)\n\n#### 使用 wagmi\n\n在 ZAN 的控制台中选择以太坊主网的节点服务地址复制，复制后的地址添加到 wagmi 的 `http()` 方法中，如下：\n\n```jsx\nimport { createConfig, http, WagmiProvider } from \"wagmi\";\nimport { mainnet } from \"wagmi/chains\";\n\nconst config = createConfig({\n  chains: [mainnet],\n  transports: {\n    [mainnet.id]: http(\n      \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n    ),\n  },\n});\n\nexport default function App() {\n  return <WagmiProvider config={config}>{/** ... */}</WagmiProvider>;\n}\n```\n\n如上，在 `WagmiProvider` 包裹的组件中你就可以使用 wagmi 提供的各种 hook 来访问以太坊的数据了。\n\n### 安全设置\n\n如果你在生产环境中使用，为了避免你的 API Key 被滥用或者攻击，你可以在 ZAN 的控制台中设置域名白名单，这样只有在白名单中的域名才能使用你的 API Key。\n\n![setting](./img/service-setting.png)\n\n还有其他设置你也可以在 ZAN 的控制台中找到，比如你可以设置每个 Key 的访问频率限制，这样可以避免你的 Key 被滥用。也可以查看每个 Key 的使用情况，设置团队共同管理 Key 等。\n\n### 测试网代币水龙头\n\n在开发中，我们经常需要获取测试网的代币，你可以通过水龙头获取测试代币，ZAN 也提供了测试网代币的水龙头服务，你可以在 [https://zan.top/faucet](https://zan.top/faucet?chInfo=wtf) 中获取测试代币。\n\n## 合约安全审计\n\n合约安全审计是一个非常重要的环节，尤其是在 DeFi 项目中，合约的安全性直接关系到用户的资金安全。ZAN 提供了合约安全审计服务，你可以在 [https://zan.top/home/contract-review](https://zan.top/home/contract-review) 中提交你的合约进行审计。ZAN 提供了免费版和专家版，专家版是有人工介入，需要收费。我们以免费版为例，说明如何在 ZAN 中提交合约审计任务。你有两种方法，一种是在网站上提交，另外一种是通过 VSCode 插件提交。\n\n### 通过 ZAN 网站提交\n\n你可以在 [https://zan.top/review/reports/apply](https://zan.top/review/reports/apply?chInfo=wtf) 提交一个合约审计任务：\n\n![create](./img/scr-new.png)\n\n有多种提交方式，提交后会进入到自动化的程序进行审计，如下图所示，你需要等待几分钟。\n\n![waiting](./img/scr-wait.png)\n\n需要注意的是，这种方式是自动化的审计，只能检测一些常见的漏洞，并无法保障合约的逻辑正确性，如果你的合约比较复杂，还是需要人工介入审计的。\n\n### 通过 VSCode 插件提交\n\nZAN 提供了一个 [VSCode 插件](https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review)，你可以在你的 VSCode 中安装该插件，直接在 VSCode 中提交合约审计任务。\n\n首先方案插件地址 [https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review](https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review) 点击 Install 唤起 VSCode 安装插件。\n\n安装成功后左侧会有一个 ZAN 的图标，点击图标后可以看到一个 `Config Access Key` 的按钮。\n\n![config-vscode](./img/config-vscode.png)\n\n点击按钮后配置你的 Access Key，Key 需要在 ZAN 的合约审计控制台中获取：\n\n![getkey](./img/vscode-key.png)\n\n获取 Key 后填入 VSCode 插件配置中，然后你就可以在 VSCode 中提交合约审计任务了。\n\n### 合约报告查看\n\n合约分析完成后你可以在网站上查看报告：\n\n![src-report](./img/scr-report.png)\n\n比如上图是对一个简单的 ERC721 的[合约](https://github.com/ourmetaverse/our-metaverse-contract)的分析结果，你可以通过[https://zan.top/review/reports/public/b82c9992-bfce-4986-baff-5bb4e76e1eb9](https://zan.top/review/reports/public/b82c9992-bfce-4986-baff-5bb4e76e1eb9?chInfo=wtf)查看报告。\n\n对于专家服务，会有多轮 AI + 专家人工审计后得到一个 PDF 报告，你可以访问[该链接](https://mdn.alipayobjects.com/huamei_hsbbrh/afts/file/A*tl-PR5pIIt4AAAAAAAAAAAAADiOMAQ/hebao_v3_20240313.pdf) 查看一个示例。\n\n![pdf](./img/scr-pdf.png)\n\n## 链上数据分析（KNOW YOUR TRANSACTION）\n\n区块链上的数据都是公开透明的，然而要在浩瀚的链上数据中分析问题，查找线索也不是那么容易的事情。ZAN 提供了链上数据分析服务，你可以在 [https://zan.top/kyt/controller](https://zan.top/kyt/controller?chInfo=wtf) 中提交你的地址，查看交易的详细信息。\n\n![kyt](./img/kyt-submit.png)\n\n提交的内容可以是一个地址，也可以是一笔交易，如下图所示，你可以看到资金的流动情况，还会标记出有风险的地址：\n\n![kyt-demo](./img/kyt-demo.png)\n\n可以用于资金追踪、巨鲸监控、反洗钱等等服务。对于专业用户，你可以使用 API 来调用，如下图你可以在控制台中获取你的 API Key：\n\n![kyt-key](./img/kyt-key.png)\n\n```sh\n## Replace {apiKey} with the API key you obtained from the ZAN dashboard.\n## You can also replace the \"eth\" and \"mainnet\" with any other supported networks.\ncurl https://api.zan.top/kyt/v1/score \\\n     -H \"Content-Type: application/json\" \\\n     -H \"Authorization:Bearer {apiKey}\" \\\n     -X POST \\\n     -d \"{\\\"objectId\\\":\\\"0xA160cdAB225685dA1d56aa342Ad8841c3b53f291\\\",\\\"objectType\\\":\\\"address\\\",\\\"analysisType\\\":\\\"\\\",\\\"chainShortName\\\":\\\"eth\\\",\\\"depth\\\":\\\"\\\"}\"\n```\n\n如上面示例代码，你可以通过访问 `https://api.zan.top/kyt/v1/score` 来获取某一个地址的相关数据。\n\n## 总结\n\n这一讲，我们介绍了如何使用 ZAN 提供的各种 Web3 技术服务。ZAN 提供了丰富的服务，有面向 DApp 开发者的，也有面向商业机构，安全团队，研究机构等的服务，你可以根据自己的需求选择合适的服务。\n","out/extensions/IERC721Metadata.sol/IERC721Metadata.json":"{\"abi\":[{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApproved\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isApprovedForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerOf\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setApprovalForAll\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenURI\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ApprovalForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false}],\"bytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"methodIdentifiers\":{\"approve(address,uint256)\":\"095ea7b3\",\"balanceOf(address)\":\"70a08231\",\"getApproved(uint256)\":\"081812fc\",\"isApprovedForAll(address,address)\":\"e985e9c5\",\"name()\":\"06fdde03\",\"ownerOf(uint256)\":\"6352211e\",\"safeTransferFrom(address,address,uint256)\":\"42842e0e\",\"safeTransferFrom(address,address,uint256,bytes)\":\"b88d4fde\",\"setApprovalForAll(address,bool)\":\"a22cb465\",\"supportsInterface(bytes4)\":\"01ffc9a7\",\"symbol()\":\"95d89b41\",\"tokenURI(uint256)\":\"c87b56dd\",\"transferFrom(address,address,uint256)\":\"23b872dd\"},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.34+commit.80d5c536\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Approval\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"ApprovalForAll\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Transfer\\\",\\\"type\\\":\\\"event\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"approve\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"balanceOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"balance\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"getApproved\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"isApprovedForAll\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"name\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"ownerOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"setApprovalForAll\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"bytes4\\\",\\\"name\\\":\\\"interfaceId\\\",\\\"type\\\":\\\"bytes4\\\"}],\\\"name\\\":\\\"supportsInterface\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"symbol\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"tokenURI\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"transferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"See https://eips.ethereum.org/EIPS/eip-721\\\",\\\"events\\\":{\\\"Approval(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\\\"},\\\"ApprovalForAll(address,address,bool)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\\"},\\\"Transfer(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `tokenId` token is transferred from `from` to `to`.\\\"}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"approve(address,uint256)\\\":{\\\"details\\\":\\\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\\\"},\\\"balanceOf(address)\\\":{\\\"details\\\":\\\"Returns the number of tokens in ``owner``'s account.\\\"},\\\"getApproved(uint256)\\\":{\\\"details\\\":\\\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"isApprovedForAll(address,address)\\\":{\\\"details\\\":\\\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\\\"},\\\"name()\\\":{\\\"details\\\":\\\"Returns the token collection name.\\\"},\\\"ownerOf(uint256)\\\":{\\\"details\\\":\\\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"safeTransferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"safeTransferFrom(address,address,uint256,bytes)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"setApprovalForAll(address,bool)\\\":{\\\"details\\\":\\\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\\\"},\\\"supportsInterface(bytes4)\\\":{\\\"details\\\":\\\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\\\"},\\\"symbol()\\\":{\\\"details\\\":\\\"Returns the token collection symbol.\\\"},\\\"tokenURI(uint256)\\\":{\\\"details\\\":\\\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\\"},\\\"transferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\\\"}},\\\"title\\\":\\\"ERC-721 Non-Fungible Token Standard, optional metadata extension\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":\\\"IERC721Metadata\\\"},\\\"evmVersion\\\":\\\"prague\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\\\",\\\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\\\",\\\":forge-std/=lib/forge-std/src/\\\",\\\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\\\",\\\":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\\\"]},\\\"sources\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\\\":{\\\"keccak256\\\":\\\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\\\",\\\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\\\"]},\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":{\\\"keccak256\\\":\\\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\\\",\\\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\\\"]},\\\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\\\":{\\\"keccak256\\\":\\\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\\\",\\\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.34+commit.80d5c536\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Approval\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ApprovalForAll\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Transfer\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"approve\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setApprovalForAll\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferFrom\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"name()\":{\"details\":\"Returns the token collection name.\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the token collection symbol.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\"forge-std/=lib/forge-std/src/\",\"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\"openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"compilationTarget\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":\"IERC721Metadata\"},\"evmVersion\":\"prague\",\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\",\"urls\":[\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\",\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\",\"urls\":[\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\",\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"],\"license\":\"MIT\"}},\"version\":1},\"id\":28}","Topics/Tools/TOOL06_Hardhat/package-lock.json":"{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 2,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"tool06_hardhat\",\n      \"version\": \"1.0.0\",\n      \"license\": \"ISC\",\n      \"devDependencies\": {\n        \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n        \"hardhat\": \"^2.22.2\"\n      }\n    },\n    \"node_modules/@adraffy/ens-normalize\": {\n      \"version\": \"1.10.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz\",\n      \"integrity\": \"sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@cspotcode/source-map-support\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@ethersproject/abi\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abi/-/abi-5.7.0.tgz\",\n      \"integrity\": \"sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/hash\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-provider\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz\",\n      \"integrity\": \"sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/networks\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/transactions\": \"^5.7.0\",\n        \"@ethersproject/web\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-signer\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz\",\n      \"integrity\": \"sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-provider\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/address\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/address/-/address-5.7.0.tgz\",\n      \"integrity\": \"sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/base64\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/base64/-/base64-5.7.0.tgz\",\n      \"integrity\": \"sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/bignumber\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz\",\n      \"integrity\": \"sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\"\n      }\n    },\n    \"node_modules/@ethersproject/bytes\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bytes/-/bytes-5.7.0.tgz\",\n      \"integrity\": \"sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/constants\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/constants/-/constants-5.7.0.tgz\",\n      \"integrity\": \"sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/hash\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/hash/-/hash-5.7.0.tgz\",\n      \"integrity\": \"sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-signer\": \"^5.7.0\",\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/keccak256\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz\",\n      \"integrity\": \"sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"js-sha3\": \"0.8.0\"\n      }\n    },\n    \"node_modules/@ethersproject/logger\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/logger/-/logger-5.7.0.tgz\",\n      \"integrity\": \"sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==\",\n      \"dev\": true\n    },\n    \"node_modules/@ethersproject/networks\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/networks/-/networks-5.7.1.tgz\",\n      \"integrity\": \"sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/properties\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/properties/-/properties-5.7.0.tgz\",\n      \"integrity\": \"sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/rlp\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/rlp/-/rlp-5.7.0.tgz\",\n      \"integrity\": \"sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/signing-key\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz\",\n      \"integrity\": \"sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\",\n        \"elliptic\": \"6.5.4\",\n        \"hash.js\": \"1.1.7\"\n      }\n    },\n    \"node_modules/@ethersproject/strings\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/strings/-/strings-5.7.0.tgz\",\n      \"integrity\": \"sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/transactions\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/transactions/-/transactions-5.7.0.tgz\",\n      \"integrity\": \"sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\",\n        \"@ethersproject/signing-key\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/web\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/web/-/web-5.7.1.tgz\",\n      \"integrity\": \"sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@fastify/busboy\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@fastify/busboy/-/busboy-2.1.1.tgz\",\n      \"integrity\": \"sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14\"\n      }\n    },\n    \"node_modules/@jridgewell/resolve-uri\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz\",\n      \"integrity\": \"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz\",\n      \"integrity\": \"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\n      }\n    },\n    \"node_modules/@metamask/eth-sig-util\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz\",\n      \"integrity\": \"sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ethereumjs-abi\": \"^0.6.8\",\n        \"ethereumjs-util\": \"^6.2.1\",\n        \"ethjs-util\": \"^0.1.6\",\n        \"tweetnacl\": \"^1.0.3\",\n        \"tweetnacl-util\": \"^0.15.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12.0.0\"\n      }\n    },\n    \"node_modules/@noble/curves\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/curves/-/curves-1.2.0.tgz\",\n      \"integrity\": \"sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"1.3.2\"\n      }\n    },\n    \"node_modules/@noble/curves/node_modules/@noble/hashes\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.3.2.tgz\",\n      \"integrity\": \"sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 16\"\n      }\n    },\n    \"node_modules/@noble/hashes\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.1.2.tgz\",\n      \"integrity\": \"sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==\",\n      \"dev\": true\n    },\n    \"node_modules/@noble/secp256k1\": {\n      \"version\": \"1.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz\",\n      \"integrity\": \"sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@nodelib/fs.scandir\": {\n      \"version\": \"2.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.stat\": \"2.0.5\",\n        \"run-parallel\": \"^1.1.9\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.stat\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.walk\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.scandir\": \"2.1.5\",\n        \"fastq\": \"^1.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr/-/edr-0.3.2.tgz\",\n      \"integrity\": \"sha512-HGWtjibAK1mo4I2A7nJ/fXqe/J9G54OrSPJnnkY2K8TiXotYLShGd9GvHkae3PuFjTJKm6ZgBy7tveJj5yrCfw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/edr-darwin-arm64\": \"0.3.2\",\n        \"@nomicfoundation/edr-darwin-x64\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-arm64-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-ia32-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-x64-msvc\": \"0.3.2\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-arm64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.2.tgz\",\n      \"integrity\": \"sha512-l6wfSBUUbGJiCENT6272CDI8yoMuf0sZH56H5qz3HnAyVzenkOvmzyF6/lar54m986kdAQqWls4cLvDxiOuLxg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-x64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.2.tgz\",\n      \"integrity\": \"sha512-OboExL7vEw+TRJQl3KkaEKU4K7PTdZPTInZ0fxMAtOpcWp7EKR+dQo68vc/iAOusB3xszHKxt7t+WpisItfdcg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-xtEK+1eg++3pHi6405NDXd80S3CGOFEGQIyVGCwjMGQFOLSzBGGCsrb/0GB4J19zd1o/8ftCd/HjZcbVAWWTLQ==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-3cIsskJOXQ1yEVsImmCacY7O03tUTiWrmd54F05PnPFrDLkjbzodQ3b2gUWzfbzUZWl67ZTJd1CvVSzpe7XGzw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-ouPdphHNsyO7wqwa4hwahC5WqBglK/fIvMmhR/SXNZ9qruIpsA8ZZKIURaHMOv/2h2BbNGcyTX9uEk6+5rK/MQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-sRhwhiPbkpJMOUwXW1FZw9ks6xWyQhIhM0E8o3TXEXKSPKTE6whQLEk1R37iFITaI36vb6rSwLKTU1cb32gCoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-arm64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-IEwVealKfumu1HSSnama26yPuQC/uthRPK5IWtFsQUOGwOXaS1r9Bu7cGYH2jBHl3IT/JbxD4xzPq/2pM9uK0A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-ia32-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-jYMnf6SFgguqROswwdsjJ1wvneD/5c16pVu9OD4DxNqhKNP5bHEw6L2N4DcJ89tpXMpJ6AlOpc0QuwzddiZ3tA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-x64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-Byn4QuWczRy/DUUQM3WjglgX/jGVUURVFaUsmIhnGg//MPlCLawubBGRqsrMuvaYedlIIJ4I2rgKvZlxdgHrqg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-common\": {\n      \"version\": \"4.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz\",\n      \"integrity\": \"sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-rlp\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz\",\n      \"integrity\": \"sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"rlp\": \"bin/rlp.cjs\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz\",\n      \"integrity\": \"sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-common\": \"4.0.4\",\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util\": {\n      \"version\": \"9.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz\",\n      \"integrity\": \"sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-chai-matchers\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz\",\n      \"integrity\": \"sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai-as-promised\": \"^7.1.3\",\n        \"chai-as-promised\": \"^7.1.1\",\n        \"deep-eql\": \"^4.0.1\",\n        \"ordinal\": \"^1.0.3\"\n      },\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-ethers\": {\n      \"version\": \"3.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz\",\n      \"integrity\": \"sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"debug\": \"^4.1.1\",\n        \"lodash.isequal\": \"^4.5.0\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.6.tgz\",\n      \"integrity\": \"sha512-a35iVD4ycF6AoTfllAnKm96IPIzzHpgKX/ep4oKc2bsUKFfMlacWdyntgC/7d5blyCTXfFssgNAvXDZfzNWVGQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"ethereumjs-util\": \"^7.1.4\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.9.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereumjs-util\": {\n      \"version\": \"7.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz\",\n      \"integrity\": \"sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/bn.js\": \"^5.1.0\",\n        \"bn.js\": \"^5.1.2\",\n        \"create-hash\": \"^1.1.2\",\n        \"ethereum-cryptography\": \"^0.1.3\",\n        \"rlp\": \"^2.2.4\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-toolbox\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz\",\n      \"integrity\": \"sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA==\",\n      \"dev\": true,\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-chai-matchers\": \"^2.0.0\",\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"@nomicfoundation/hardhat-network-helpers\": \"^1.0.0\",\n        \"@nomicfoundation/hardhat-verify\": \"^2.0.0\",\n        \"@typechain/ethers-v6\": \"^0.5.0\",\n        \"@typechain/hardhat\": \"^9.0.0\",\n        \"@types/chai\": \"^4.2.0\",\n        \"@types/mocha\": \">=9.1.0\",\n        \"@types/node\": \">=16.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.4.0\",\n        \"hardhat\": \"^2.11.0\",\n        \"hardhat-gas-reporter\": \"^1.0.8\",\n        \"solidity-coverage\": \"^0.8.1\",\n        \"ts-node\": \">=8.0.0\",\n        \"typechain\": \"^8.3.0\",\n        \"typescript\": \">=4.5.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-verify\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.5.tgz\",\n      \"integrity\": \"sha512-Tg4zu8RkWpyADSFIgF4FlJIUEI4VkxcvELsmbJn2OokbvH2SnUrqKmw0BBfDrtvP0hhmx8wsnrRKP5DV/oTyTA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@ethersproject/abi\": \"^5.1.2\",\n        \"@ethersproject/address\": \"^5.0.2\",\n        \"cbor\": \"^8.1.0\",\n        \"chalk\": \"^2.4.2\",\n        \"debug\": \"^4.1.1\",\n        \"lodash.clonedeep\": \"^4.5.0\",\n        \"semver\": \"^6.3.0\",\n        \"table\": \"^6.8.0\",\n        \"undici\": \"^5.14.0\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz\",\n      \"integrity\": \"sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 12\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/solidity-analyzer-darwin-arm64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-darwin-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-freebsd-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-x64-msvc\": \"0.1.1\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz\",\n      \"integrity\": \"sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@scure/base\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/base/-/base-1.1.1.tgz\",\n      \"integrity\": \"sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==\",\n      \"dev\": true\n    },\n    \"node_modules/@scure/bip32\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip32/-/bip32-1.1.0.tgz\",\n      \"integrity\": \"sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@noble/secp256k1\": \"~1.6.0\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@scure/bip39\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip39/-/bip39-1.1.0.tgz\",\n      \"integrity\": \"sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@sentry/core\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/core/-/core-5.30.0.tgz\",\n      \"integrity\": \"sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/hub\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/hub/-/hub-5.30.0.tgz\",\n      \"integrity\": \"sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/minimal\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/minimal/-/minimal-5.30.0.tgz\",\n      \"integrity\": \"sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/node\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/node/-/node-5.30.0.tgz\",\n      \"integrity\": \"sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/core\": \"5.30.0\",\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/tracing\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"cookie\": \"^0.4.1\",\n        \"https-proxy-agent\": \"^5.0.0\",\n        \"lru_map\": \"^0.3.3\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/tracing\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/tracing/-/tracing-5.30.0.tgz\",\n      \"integrity\": \"sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/types\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/types/-/types-5.30.0.tgz\",\n      \"integrity\": \"sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/utils\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/utils/-/utils-5.30.0.tgz\",\n      \"integrity\": \"sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@solidity-parser/parser\": {\n      \"version\": \"0.14.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@solidity-parser/parser/-/parser-0.14.3.tgz\",\n      \"integrity\": \"sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"antlr4ts\": \"^0.5.0-alpha.4\"\n      }\n    },\n    \"node_modules/@tsconfig/node10\": {\n      \"version\": \"1.0.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz\",\n      \"integrity\": \"sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node12\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz\",\n      \"integrity\": \"sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node14\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz\",\n      \"integrity\": \"sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node16\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz\",\n      \"integrity\": \"sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@typechain/ethers-v6\": {\n      \"version\": \"0.5.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz\",\n      \"integrity\": \"sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"lodash\": \"^4.17.15\",\n        \"ts-essentials\": \"^7.0.1\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"6.x\",\n        \"typechain\": \"^8.3.2\",\n        \"typescript\": \">=4.7.0\"\n      }\n    },\n    \"node_modules/@typechain/hardhat\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/hardhat/-/hardhat-9.1.0.tgz\",\n      \"integrity\": \"sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"fs-extra\": \"^9.1.0\"\n      },\n      \"peerDependencies\": {\n        \"@typechain/ethers-v6\": \"^0.5.1\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.9\",\n        \"typechain\": \"^8.3.2\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/fs-extra\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz\",\n      \"integrity\": \"sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"at-least-node\": \"^1.0.0\",\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/jsonfile\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz\",\n      \"integrity\": \"sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"universalify\": \"^2.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"graceful-fs\": \"^4.1.6\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/universalify\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz\",\n      \"integrity\": \"sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      }\n    },\n    \"node_modules/@types/bn.js\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/bn.js/-/bn.js-5.1.1.tgz\",\n      \"integrity\": \"sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/chai\": {\n      \"version\": \"4.3.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai/-/chai-4.3.14.tgz\",\n      \"integrity\": \"sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/chai-as-promised\": {\n      \"version\": \"7.1.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz\",\n      \"integrity\": \"sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai\": \"*\"\n      }\n    },\n    \"node_modules/@types/concat-stream\": {\n      \"version\": \"1.6.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/concat-stream/-/concat-stream-1.6.1.tgz\",\n      \"integrity\": \"sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/form-data\": {\n      \"version\": \"0.0.33\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/form-data/-/form-data-0.0.33.tgz\",\n      \"integrity\": \"sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/glob\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/glob/-/glob-7.2.0.tgz\",\n      \"integrity\": \"sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/minimatch\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/lru-cache\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/lru-cache/-/lru-cache-5.1.1.tgz\",\n      \"integrity\": \"sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/minimatch\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/minimatch/-/minimatch-5.1.2.tgz\",\n      \"integrity\": \"sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/mocha\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/mocha/-/mocha-9.1.1.tgz\",\n      \"integrity\": \"sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"18.15.13\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/node/-/node-18.15.13.tgz\",\n      \"integrity\": \"sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/pbkdf2\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz\",\n      \"integrity\": \"sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/prettier\": {\n      \"version\": \"2.7.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz\",\n      \"integrity\": \"sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/qs\": {\n      \"version\": \"6.9.7\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/qs/-/qs-6.9.7.tgz\",\n      \"integrity\": \"sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/secp256k1\": {\n      \"version\": \"4.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/secp256k1/-/secp256k1-4.0.3.tgz\",\n      \"integrity\": \"sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@ungap/promise-all-settled\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz\",\n      \"integrity\": \"sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsm","Topics/Onchain_debug/01_tools/en/readme.md":"# en Documentation\n\nPath: `Topics/Onchain_debug/01_tools/en/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Onchain_debug/01_tools/en/readme.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json":"# Hello_wtf Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/package.json":"# Hello_wtf Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)","Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md":"# 01_tools Documentation\n\nPath: `Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md)","Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md":"# TOOL01_Remix Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md)","Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md":"# TOOL02_Infura Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md)","Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md":"# TOOL03_Ganache Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md)","Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md":"# TOOL04_Alchemy Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md)","Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md":"# TOOL05_Dune Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md)","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json":"# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json)","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json":"# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json)","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md":"# TOOL06_Hardhat Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md":"# TOOL07_Foundry Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md)","Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md":"# en Documentation\n\nPath: `Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json":"# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json":"# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md":"# forge-std Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md":"# openzeppelin-contracts Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md":"# .github Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md":"# Audits Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md":"# audits Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json":"# Contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md":"# docs Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md":"# fv Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md":"# Test Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md":"# forge-std Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json":"# Forge-std Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md":"# ISSUE_TEMPLATE Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md":"# ISSUE_TEMPLATE Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md":"# erc4626-tests Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md":"# forge-std Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md":"# halmos-cheatcodes Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json":"# Solhint-custom Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md":"# upgradeable Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json":"# Cryptography Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json":"# Fixtures Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)"},"files":{"Topics/Tools/TOOL05_Dune/readme.md":"# WTF Solidity极简入门-工具篇5：使用Dune可视化区块链数据 \n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n## Dune是什么？\n\n\n`Dune`是区块链查询分析工具，每个人可以通过写类sql语言查询区块链上的所有信息，例如巨鲸，链上交易的数据等等。同时`Dune`能便捷的将数据转换为可视化的图表。\n\n> 以太坊是数据库，智能合约是数据表，来自钱包的交易是每个表中的行。\n\n这句话讲出了区块链的精髓：区块链本质上就是公开的存储数据的分布式账本，现在我们可以通过Dune来查询这个分布式账本的数据。\n\n[Dune官网](https://dune.xyz/)\n\n![dune可视化](./img/1.png)\n\n![dune可视化](./img/2.png)\n\n\n## 第一个查询\n\n目标：查询**过去 24 小时在 Uniswap 上购买的 DAI稳定币**\n\n1. 注册登陆Dune。\n2. 点击右上角**new query**新建查询，输入代码：\n\n    ```sql\n    SELECT\n    SUM(token_a_amount) AS dai_bought\n    FROM\n    dex.\"trades\"\n    WHERE\n    block_time > now() - interval '24 hours'\n    AND token_a_symbol = 'DAI'\n    AND project = 'Uniswap';\n    ```\n3. 点击右下角的**Run**执行查询，得到最近的24h内通过uniswap购买DAI的数量。\n\n![dune sql query](./img/3.png)\n\n\n## 从0开始构建查询\n\n**目标：学会使用 SELECT, WHERE, LIMIT**\n\n我们查询其中一个表，以aave为例：[aave合约](https://etherscan.io/address/0x398ec7346dcd622edc5ae82352f02be94c62d119#writeProxyContract)\n\n通过查询aave这个合约，它有deposit（存储）这个方法，并且有该事件（事件会在执行的时候广播）。\n\n![etherscan](./img/6.png)\n\n回到Dune查找对应的表，根据在Ethereum上搜索aave相关的表，并对应事件,`LendingPool_evt_Deposit`找到该表。\n\n![dune query db table](./img/13.png)\n\n### 学习：SELECT 、 LIMIT、WHERE查询数据\n\n然后我们通过Dune可以查询对应的存储数据\n\n```sql\nSELECT * FROM aave.\"LendingPool_evt_Deposit\"\nlimit 100\n```\n\n![dune query](./img/7.png)\n\n就可以得到aave合约中存储方法的相应数据，通过这个数据可以做一些筛选\n\n#### 各个字段的意义\n\n_user：发起存款的钱包地址\n\n_reserve：作为抵押品存放的代币地址\n\n_amount：存入的代币数量\n\n_timestamp：交易被挖掘到区块链的时间戳\n\n\n#### 使用 WHERE过滤数据\n\n查询过滤特殊的地址`0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`\n\n```sql\nSELECT *, (_amount / 1e18) as _amount FROM aave.\"LendingPool_evt_Deposit\"\nWHERE _reserve = '\\xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'\nlimit 100\n```\n\n带上了查询条件，能够快速的筛选我们需要的数据\n\n查看抵押品为USDC，USDC合约地址：`xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`\n\n```sql\nSELECT * FROM aave.\"LendingPool_evt_Deposit\"\nWHERE _reserve = '\\xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'\nlimit 100\n```\n\n以上案例参考 [Your guide to basic SQL while learning Ethereum at the same time](https://towardsdatascience.com/your-guide-to-basic-sql-while-learning-ethereum-at-the-same-time-9eac17a05929)\n\n### 实践链上转账\n\n\n实践`Ethereum.Transactions`表的转账查询\n\n\n```sql\nselect * from ethereum.transactions\nLIMIT 10\n```\n\n![DUNE面板说明](./img/14.png)\n\n### 字段和转账对应说明\n\n看这个[hash](https://etherscan.io/tx/0xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51)转账 \n\n![image-20220314174346876](./img/16.png)\n\n由[0x22fff189c37302c02635322911c3b64f80ce7203](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7?a=0x22fff189c37302c02635322911c3b64f80ce7203) 转账到 [0x8aae242452471d2dfea145214ceedf87ca043198](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7?a=0x8aae242452471d2dfea145214ceedf87ca043198)\n\nhash：`0xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51`\n\n我们可以直接通过dune查到该条信息\n\n```sql\nselect * from ethereum.transactions\nWHERE hash='\\xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51'\n```\n\n![dune-查询](./img/15.png)\n\ndune中的字段，也是和etherscan中一一对应。\n\n\n\n### 数据可视化\n\n![dune query to visualization](./img/11.png)\n\n点击 New visualization 就可以选择你需要的视图，比如我点击 `bar chart`\n\n![dune visualization](./img/12.png)\n\n就会将我刚才筛选的数据可视化。看最长的几根，就是借贷最多的几个账号。\n\n\n\n## 总结\n\n这一讲，我们介绍了Dune的基础用法。通过Dune，我们能够将链上的数据转换为可视化的数据，更好的了解链上热点。\n","Topics/Tools/TOOL02_Infura/readme.md":"# WTF Solidity极简入门-工具篇2：Infura, 连接链下与链上的桥梁\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n`Infura`是Consensys(小狐狸钱包母公司)开发的区块链基础设施，帮助用户/开发者更好的与以太坊区块链交互。\n\n## 连接应用和区块链\n\n![链下链上交互](./img/infura1.png)\n\n在以太坊上开发的Dapp应用（链下）需要与区块链（链上）交互。早期，以太坊上的基础设施很少，开发者需要在本地部署以太坊节点来完成链下和链上的交互，非常麻烦，且耗时数日。\n\n`Infura`在链下、链上之间搭了一座桥，让两者的交互变的简单。它为用户提供对以太坊和IPFS网络的即时、可扩展的`API`访问。开发者在`Infura`官网注册后，就可以免费申请的以太坊`API KEY`，就可以利用`Infura`的节点与区块链交互。另外，小狐狸`metamask`钱包内置了`Infura`服务，方便用户访问以太坊网络。\n\n## 创建`Infura` API Key\n\n### 1. 打开Infura官网并注册\n\n网址：[infura.io](https://infura.io)\n![Infura官网](./img/infura2.png)\n\n### 2. 创建API Key\n注册后，进入控制台Dashboard，并点击右上角的 **CREATE NEW KEY** 按钮。\n\n![创建API Key](./img/infura3.png)\n\n### 3. 填写API Key信息\n\n`NETWORK`选择 **Web3 API (Formerly Ethereum)**，有的版本这里显示的是**Ethereum**，`NAME`随便填一个，我填的`WTF`，之后点击**CREATE**按钮。\n\n![填写信息](./img/infura4.png)\n\n### 4. API Key创建完毕\n\n回到控制台Dashboard，可以看到名为`WTF`的API Key已经创建完毕。在控制台Dashboard，点击  **MANAGE KEY** 按钮，可以查看API Key详情。\n\n\n![API Key创建完毕](./img/infura5.png)\n\n### 5. 查看API Key详情\n\n进入API Key详情页，我们可以看到我们的API Key（图中`184d`开头的一组密钥）。在下面的 **NETWORK ENDPOINT** 栏中，可以查到以太网主网/测试网的rpc节点链接，用于访问链上数据并交互。另外，你可以申请免费的Layer2 rpc节点，包括`Polygon`，`Optimism`和`Arbitrum`，但是需要绑定`visa`卡。领`Optimism`空投那次，公开rpc节点卡爆了，而使用`Infura`的私人rpc节点的人可以正常领取。\n\n![查看信息](./img/infura6.png)\n\n## 使用`Infura` API Key \n### Javascript (`ethers.js`)\n在`ether.js`中，我们可以利用`Infura` API Key来创建`JsonRpcProvider`，与链上交互。\n\n```javascript\nconst { ethers } = require(\"ethers\");\n// 填上你的Infura API Key\nconst INFURA_ID = '' \nconst provider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`)\n```\n\n### `MetaMask`小狐狸钱包\n\n进入小狐狸钱包设置 **Setting** 页面，点击网络 **Network**，点击添加网络 **Add Network**。你可以利用下面的参数在小狐狸中添加`Optimism` Layer2链：\n\n```\n网络名称（Network Name）: Optimism\nRPC URL：填在Infura申请的optimism rpc链接\n链ID (Chain ID): 10\n符号 (Chain Symbol): ETH\n区块链浏览器URL (Blockchain Explorer URL): https://optimistic.etherscan.io\n```\n\n![小狐狸配置私人rpc](./img/infura7.png)\n\n## 总结\n\n这一讲，我们介绍了如何创建并使用`Infura` API Key便捷访问以太坊区块链。","Topics/Tools/TOOL04_Alchemy/readme.md":"# WTF Solidity极简入门-工具篇4：Alchemy, 区块链API和节点基础设施\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n## Alchemy是什么\n\n`Alchemy` 超级节点是 Ethereum、Polygon、Solana、Arbitrum、Optimism、Flow 和 Crypto.org 使用最广泛的区块链 API。获得节点的所有功能，包括 JSON-RPC 支持，但具有在区块链上运行世界级应用程序所需的超强可靠性、数据准确性和可扩展性。\n\n## 连接应用和区块链\n\n在以太坊上开发的Dapp应用（链下）需要与区块链（链上）交互。早期，以太坊上的基础设施很少，开发者需要在本地部署以太坊节点来完成链下和链上的交互，非常麻烦，且耗时数日。\n\n`Alchemy` 和 `Infura`在链下、链上之间搭了一座桥，让两者的交互变的简单。它为用户提供对以太坊和IPFS网络的即时、可扩展的`API`访问。开发者在`Alchemy` 和 `Infura`官网注册后，就可以免费申请的以太坊`API KEY`，就可以利用它们的节点与区块链交互。另外，小狐狸`metamask`钱包内置了`Infura`服务，方便用户访问以太坊网络。\n\n关于`Infura`的介绍，可以参考 [WTF Solidity极简入门-工具篇2：Infura, 连接链下与链上的桥梁](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL02_Infura/readme.md)\n\n## Alchemy 和 Infura 的区别\n\n![Alchemy 和 Infura 的区别](./img/alchemy-1.png)\n\n左边是`alchemy` 右边是 `Infura`，我们来对比下免费的套餐\n\n### 访问量的区别\n\n`Alchemy`每天没有访问限制，`Infura`每天有100,000的访问限制。\n\n`Alchemy`每个月有`300,000,000`的访问量，`Infura`每个月有`3,000,000`的访问量。\n\n\n### 支持公链的区别（免费版本）\n\n![公链的区别](./img/alchemy-2.png)\n\n`Alchemy`支持：ETH、Polygon、Solana、Arbitrum、Optimism\n\n`Infura`支持：ETH、ETH2、IPFS、Filecoin \n\n### Alchemy支持enhanced-apis\n\n![Alchemy支持enhanced-apis](./img/alchemy-3.png)\n\n\nAlchemy自己封装了一些web3的api，大家可以自己看文档获取更多的细节。\n\n[Alchemy - enhanced-apis](https://dashboard.alchemyapi.io/enhanced-apis)\n\n## 创建`Alchemy` API Key\n\n### 1. 打开Alchemy官网并注册\n\n网址：[alchemy.com](https://www.alchemy.com/)\n\n![Alchemy官网](./img/alchemy-4.png)\n\n\n### 2. 创建API Key\n注册后，进入控制台Dashboard，并点击右上角的 **+ CREATE APP** 按钮。\n\n![创建API Key](./img/alchemy-5.png)\n\n\n### 3. 填写API Key信息\n\n`CHAIN`：选择你需要的网络，如果是以太网就是 `Ethereum`。\n\n`NETWORK`:并选择是主网还是测试网。\n\n![填写API Key信息](./img/alchemy-6.png)\n\n填写完成之后点击 `CREATE APP` 即可创建。\n\n### 4. API Key创建完毕\n\n回到控制台Dashboard，可以看到名为`WTFSolidity`的API Key已经创建完毕。在控制台Dashboard，点击  **view key** 按钮，可以查看API Key详情。\n\n![查看api key](./img/alchemy-7.png)\n\n\n### 5. 查看API Key详情\n\n可以看到我们创建好了相应的api key，最常用的https和websockets都支持。\n\n![查看api key 详情](./img/alchemy-8.png)\n\n\n## 使用`Alchemy` API Key \n\n### Javascript (`ethers.js`)\n在`ether.js`中，我们可以利用`Alchemy` API Key来创建`JsonRpcProvider`，与链上交互。\n\n```javascript\nconst { ethers } = require(\"ethers\");\n// 填上你的Alchemy API Key\nconst ALCHEMY_ID = '' \nconst provider = new ethers.providers.JsonRpcProvider(`https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`)\n```\n\n### `MetaMask`小狐狸钱包\n\n进入小狐狸钱包设置 **Setting** 页面，点击网络 **Network**，点击添加网络 **Add Network**。你可以利用下面的参数在小狐狸中添加`Alchemy` 的eth链：\n\n```\n网络名称（Network Name）: Alchemy-eth\nRPC URL：填在alchemy申请的optimism rpc链接\n链ID (Chain ID): 1\n符号 (Chain Symbol): ETH\n区块链浏览器URL (Blockchain Explorer URL): https://etherscan.io\n```\n\n![小狐狸钱包添加新的网络](./img/alchemy-9.png)\n\n\n## 总结\n\n这一讲，我们介绍了如何创建并使用`Alchemy` API Key便捷访问以太坊区块链。\n","Topics/Tools/TOOL01_Remix/readme.md":"# WTF Solidity极简入门-工具篇1：Remix\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\n`Remix`是以太坊官方推荐的智能合约开发IDE，非常易用。`Remix`让你可以直接在浏览器中快速部署测试智能合约，而不需要安装配置任何程序。这一讲，我们将完整的介绍如何使用`Remix`部署合约，并调用其中的函数。\n\n**Remix官网**：[remix.ethereum.org](https://remix.ethereum.org)\n\n## 1.打开Remix\n![Remix Layout](./img/remix1.png)\n\n打开官网进入`Remix`，我们可以看到Remix由四个面板组成：\n1. 图标面板：上面有代表不同功能的图标，点击后，相应的功能个会显示在侧面版上。\n2. 侧面版：各种功能的 `GUI`。\n3. 主面板：代码编辑器。\n4. 终端：将显示与 `GUI` 交互的结果，也可以在此处运行脚本。\n\n## 2. 图标面板\n![图标面板](./img/remix2.png)\n\n图标面板默认有4个图标，其中`文件`，`编译`，`部署`是最常用的。在你添加更多的`remix`插件后，它们也会显示在图标面板上。\n\n## 3. 部署简单合约\n### i. 选择合约文件\n首先点击`文件`图标，侧面版会变为`文件浏览器`。\n![文件图标](./img/remix3.png)\n\n我们可以在`文件浏览器`中管理我们的workspace，文件夹和文件。\n![文件浏览器](./img/remix4.png)\n\n在`contract`文件夹下面，有三个`remix`自带的合约例子，分别是`1_Storage.sol`, `2_Owner.sol`和`3_Ballot.sol`。\n\n点击`1_Storage.sol`，代码会显示在主面板的代码编辑器上。这个合约非常简单：它一个状态变量`number`，在链上存储一个`uint256`类型的数字；它有两个函数，`store()`函数将一个数字赋值给`number`变量；`retrieve()`展示`number`变量的数值。\n\n### ii. 编译\n接下来，点击`编译`图标，进入`Solidity Compiler`。在这里，我们选择`Solidity 0.8.7`版本，然后点击`Compile 1_Storage.sol`按钮进行编译。在合约成功编译后，`编译`图标上会显示绿色对勾。\n\n![编译](./img/remix5.png)\n\n你也可以尝试在优化中选在优化（`Enable Optimization`），次数设置为`200`，有时会省`gas`消耗。\n\n### iii. 部署\n下一步，我们要把编译好的合约部署到本地虚拟机或链上。首先点击`部署`，进入部署界面。\n\n![部署](./img/remix6.png)\n\n在`ENVIRONMENT`中，我们可以选择我们部署的环境，默认的是`JavaScript VM`，所有交易都在本地浏览器的沙盒区块链中执行，使用的是它给你的虚拟钱包地址；你也可以选择`Injected Web3`，即连接你的`metamask`钱包，所有交易会在真实的区块链中执行。\n\n这里，我们选择`JavaScript VM`，你可以在钱包地址（`ACCOUNT`）栏看到虚拟机给你分配的测试地址。不需要调整`Gas`，也不用往合约里发送`ETH`。在`CONTRACT`栏中选择你要部署的合约`Storage`。`1_Storage.sol`文件中只有一个合约，因此默认就是部署它；但当文件包含多个合约时，我们需要手动选择要部署的合约。\n\n点击`DEPLOY`键，部署完毕！\n\n**注意**：如果我们选择的是`Injected Web3`来部署合约，每一笔交易都将上链，需要钱包确认交易并支付`gas`。\n\n### iv. 调用\n在合约部署成功后，我们可以在`Deployed Contracts`中找到我们部署的合约`Storage`。展开它，我们将看到所有的外部函数：`store`和`retrieve`。\n\n![调用](./img/remix7.png)\n\n我们在`store`函数那行的文本框中输入`100`，并点击函数名调用它。调用成功后，我们可以在终端上看到`log`信息，点击`Debug`按钮可以查看交易详情。\n\n![交易详情](./img/remix8.png)\n\n之后，我们调用`retrieve`函数，显示`number`变量被成功更新为`100`。\n\n![变量被更新为100，调用成功](./img/remix9.png)\n\n## 总结\n\n这一讲，我们介绍了如何使用`Remix`编译，部署并调用智能合约。\n\n","Topics/Tools/TOOL03_Ganache/readme.md":"# WTF Solidity极简入门-工具篇3：Ganache，搭建本地测试网络\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\n`Ganache` 是一个适用于 “开发场景”（或开发过程中的）的 **以太坊区块链网络**，它使开发以太坊应用程序（的工作）更快、更容易、更安全。它包括所有流行的 RPC 功能和特性（如事件），并且可以确定性地运行以使开发变得轻而易举。\n\n> 可以理解 ganache 是一个以太坊区块链“模拟器”，在开发过程中 “模拟” 生产环境、方便的获取合约调用的上下文。\n\n> ⚠️ 注意：**请不要在生产环境中作为区块链网络使用** 如果需要请使用 geth 或 openethereum 等节点应用。\n\n`Ganache` 同时有着 GUI 版本，适合于新手快速配置使用。\n\n## Ganache 的项目设施\n\n- 官网：[https://trufflesuite.com/ganache/](https://trufflesuite.com/ganache/)\n- 文档：[https://trufflesuite.com/docs/ganache/](https://trufflesuite.com/docs/ganache/)\n- Github：\n  - UI: [https://github.com/trufflesuite/ganache-ui](https://github.com/trufflesuite/ganache-ui)\n  - CLI: [https://github.com/trufflesuite/ganache](https://github.com/trufflesuite/ganache)\n  - 旧版（已弃用）: [https://github.com/trufflesuite/ganache-cli](https://github.com/trufflesuite/ganache-cli)\n- 适用于命令行/npm的文档：[https://trufflesuite.com/blog/introducing-ganache-7/](https://trufflesuite.com/blog/introducing-ganache-7/)\n\n\n> ⚠️ 注意：Ganache 的官网中的 Github repo 为UI版本。CLI 版本在 npm 中有 `ganache` & `ganache-cli`，其中 `ganache-cli` 已被弃用。\n\n## 为什么要使用Ganache？\n\nGanache 的主要功能有：\n- 开箱即用，快速启动一个EVM区块链网络（可以设置 miner、出块时间）；\n- 方便的 fork（分叉）已经存在的区块链网络（无需等待区块同步）；\n- [使用 `console.log`](https://github.com/trufflesuite/ganache#consolelog-in-solidity) 在 Solidity 开发过程中方便的调试，；\n- [快进时间（Fast-forward time）](https://trufflesuite.com/blog/introducing-ganache-7/#6-fast-forward-time)，模拟智能合约在未来时间的状态；\n- 模拟任何一个账户（你可以无需私钥模拟环境中使用任意用户的Token）；\n\n有的时候想要实现合约的测试，或者一些合约开发，你需要去测试网领取eth。有时候faucet又没有eth可以领取，这个时候，其实你可以选择自己在本地 fork 一个网络，想要多少eth都可以直接生成。原理是 fork 一个主网的网络运行在本地（或是可以称作运行在本地的 Chain）。\n\nfork主网还有一个好处，你可以直接mock现在主网上的所有环境，比如dex交易所的代币余额等，你知道合约地址，可以直接进行测试和交换使用等。\n\n## 命令行安装（推荐）\n\n[完整包的说明 ganache - npm](https://www.npmjs.com/package/ganache)\n```shell\nnpm install ganache --global\n```\n您也可以单独安装该项至您的项目目录（在不使用 `--global` 的情况下）编写 `package.json` 中的 script 配置启动。  \n在 Ganache 7 后您可以在 node.js 的 Javascript 脚本中引入并直接使用。它将会提供一个 [EIP-1193(Ethereum Provider JavaScript API)](https://eips.ethereum.org/EIPS/eip-1193) provider、一个 JSON-RPC 服务端、Web3.js & ethers provider。同时您也可以在[浏览器中](https://github.com/trufflesuite/ganache#browser-use)使用它。\n\n\n### 启动GANACHE\n\n```shell\nganache\n```\n\n### 帮助 / 说明\n```\nganache --help\n```\n通过帮助，你可以了解 ganache 的主要功能和相关配置方法、参数。这其中包括：\n- **Chain**: 设置网络的版本、ID、时间、合约大小限制、hardfork的版本规则；\n- **Database**: 设置保存链到数据库；\n- **Logging**: 设置 EVM opcodes、RPC 请求和响应的 log；\n- **Miner**: 设置矿工，包括：出块时间、默认的 gas price、Txn gas limit、难度、instamine、价格上涨；\n- **Wallet**: 设置钱包的默认余额、解锁钱包；\n- **Fork**: 分叉（fork）网络的设置包括：fork 目标网络 RPC URL、块高、userAgent、缓存策略，支持提供用户名/密码（如果目标 RPC 存在 Basic Authentication）；\n- **Server**: 设置本地 Chain 的监听地址&端口；\n### Fork 主网启动\n\n以下命令会自动生成10个eth账号，每个账号带有100eth的数量。\n\n```shell\nganache -f https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY\n```\n\n您也可以fork其他以太坊区块链网络，例如 BSC、Polygon、Astar 等，您需要寻找并使用他们的RPC节点。\n\n### Fork主网固定账号启动\n\n`wallet.accounts`主要参数为私钥和需要生成的eth数量。\n\n注意单位为`wei`，案例中换算之后是`1000eth`\n\n```shell\nganache -f https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY --wallet.accounts=ACCOUNT_PRIATE_KEY,AMOUNT_WEI --wallet.accounts=ACCOUNT_PRIATE_KEY,1000000000000000000000\n```\n\n### 推进时间 (Fast Forward time)\n\n需要操纵时间的原因或场景：一些合约锁住了用户的Token，设计了释放周期/时间逐步释放这些被锁住的Token，或者在未来某个特定时间允许用户进行一些操作。\n\nGanache 允许我们通过 RPC 调用（方法 `evm_increaseTime` 和 `evm_setTime` ）来推进区块链上的时间。\n\n大多数情况下我们无法等到这个时间，我们可以使用 `evm_increaseTime` 将区块链当前时间戳**增加指定的时间量**（以秒为单位）（以十六进制格式传入）。这将返回以秒为单位调整的总时间。\n\n```\ncurl -H 'Content-Type: application/json' --data' {\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"evm_increaseTime\", \"params\": [\"0x15180\"] }' http://localhost:8545\n```\n\n此外，您可以使用 `evm_setTime` 将其设置为特定的时间戳；它接受具有毫秒精度的 JavaScript 时间戳，并返回给定时间戳和当前时间之间的秒数。\n\n这里有个在项目中应用的案例（很实用）：[liquity 项目合约测试 - ForwardTime 的功能实现](https://github.com/liquity/dev/blob/0c61ed8b7181450da214d4f10a1327c2082bd4f4/packages/contracts/utils/testHelpers.js#L1104-L1119)\n### 通过GUI使用 Ganache\n不太推荐，如果你是新上手，可以通过这个快速熟悉 Ganache。\n\n[点击下载Ganache - Truffle Suite](https://trufflesuite.com/ganache/)\n\n#### 客户端界面\n![](./img//ganache-7.png)\n\n#### 初始化新建工作空间\n\n![](./img//ganache-8.png)\n\n点击quickstart就可以快速启动，但是快速启动默认的网络端口是 7545，如果你用remix链接的时候需要修改一下。启动完成之后就如下图所示：\n\n![](./img/ganache-9.png)\n\n第一行可以看到你现在的网络`rpc server`, 默认是地址和端口是`127.0.0.1:7545`，如果你在remix中使用默认的，需要把端口改为7545。\n\n\n\n#### remix 链接默认ganache\n\n![](./img/ganache-10.png)\n\n选择环境为 ganache provider，具体端口看你的设置,需要跟ganache的端口一致。\n\n![](./img/ganache-11.png)\n\n端口改为和本地ganache默认一样的`7545`\n\n#### 测试部署一个合约\n\n这里能看到区块里的交易信息，显示我部署了一个合约地址。\n\n![](./img/ganache-12.png)\n\n![](./img/ganache-13.png)\n\n\n#### 自定义配置\n\n有时候你可能需要自定义配置，比如你的网络端口，或者你需要fork主网，你可以在初始化空间的时候配置。\n\n选择`new workspace`\n\n![](./img/ganache-14.png)\n\n\n#### 设置端口和网络ID\n\n端口：可以将默认端口7545改成8545，看你的习惯\n\n![](./img/ganache-15.png)\n\n\n#### fork主网\n\n这里的地址填入你alchemy的主网地址即可\n\n没有的话申请一个 [Alchemy - Blockchain APIs and Node Infrastructure](https://alchemy.com/?r=7ad384cba6732c9d) 或者参考 [Infura, 连接链下与链上的桥梁](https://github.com/AmazingAng/WTF-Solidity/tree/main/Topics/Tools/TOOL02_Infura/readme.md) 申请一个infura的链接。\n\n在chain forking下面的`ENTER CUSTOM URL`里面填入你的eth mainnet地址即可\n\n![](./img/ganache-16.png)\n\n\n#### 设置固定账号和余额\n\n![](./img/ganache-17.png)\n\n最后点击 save workspace 就可以启动啦。\n\n\n## web3js/ethersjs 链接 ganache\nganache生成的本地rpc地址为 `127.0.0.1:8545` UI的默认地址和命令行有区别，所以我上述做了变更。像remix默认使用的就是8454端口\n\n```js\n\n// web3js\n\nconst web3 = new Web3(Web3.givenProvider || \"http://127.0.0.1:8545\");\n\n// ethersjs\nconst provider = new ethers.providers.JsonRpcProvider(\"http://127.0.0.1:8545\");\n\n```\n\n## remix链接本地ganache\n\n把环境链接修改为 ganache即可没，这样你就可以把他部署在你本地的eth网络环境上了。\n\n![](./img/ganache-1.png)\n\n\n### 测试部署合约\n\n这里就将合约部署在了我们本地运行的ganache上。\n\n![](./img/ganache-2.png)\n\n命令行会输出部署的相应细节\n\n![](./img/ganache-3.png)\n\n可以看到部署成功之后，可以方便的调用各种方法\n\n![](./img/ganache-4.png)\n\n### 部署合约，查询v神余额\n\n这个合约写了一个可以查询eth余额的方法，因为我们fork了主网，所以查询一下v神在我们本地测试网络的余额，应该和主网的余额是一样的。\n\n```solidity\n// contracts/GLDToken.sol†\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract XBXToken {\n\n    function getETHBalance(address _address) view external returns(uint256) {\n        return address(_address).balance;\n    }\n\n}\n\n```\n\n[v神主网钱包地址](https://etherscan.io/address/0xab5801a7d398351b8be11c439e05c5b3259aec9b)\n\n![](./img/ganache-5.png)\n\n通过remix调用查看fork之后，本地部署该地址余额\n\n![](./img/ganache-6.png)\n\n本地fork的网络查询v神余额与主网上的余额一致，fork主网测试成功。\n\n## 总结\n\n至此我们就完整fork了一个主网，为下一步做合约开发搭建好了必要的本地环境。","Topics/Onchain_debug/01_tools/readme.md":"# OnChain Transaction Debugging: 1. Tools\n\nAuthor: [SunSec](https://twitter.com/1nf0s3cpt)\n\n当初我在学习链上交易分析时，很少相关教学文章，只能自己慢慢地收集资料从中挖掘如何分析到测试。我们将推出一系列 Web3 安全的教学文章, 帮助更多人加入 Web3 安全，共创安全网路。\n\n第一个系列我们将介绍如何进行链上分析到撰写攻击重现。此技能将能帮助你分析攻击过程和漏洞原因甚至套利机器人如何套利！\n\n## 工欲善其事，必先利其器\n\n在进入分析之前，我先介绍一些常用工具，正确的工具可以帮助你做研究时更有效率。\n\n### Transaction debugging tools\n\n[Phalcon](https://phalcon.blocksec.com/) | [Ethtx](https://ethtx.info/) | [Tenderly](https://dashboard.tenderly.co/explorer)\n\nTransaction Viewer 这类工具是最常用的，可以帮助我们针对想要分析的交易 Transaction，以可视化列出函数呼叫的流程以及每个函数带入了什么的参数等。\n每个工具大同小异，只差异在链的支援度不同和辅助功能，我个人是比较常用 Phalcon 的 Transaction Viewer，如果遇到不支援的链则会使用 Tenderly，Tenderly 支援最多链，但是可读性就不是这么方便，需要 Debug 慢慢分析。不过我最初在研究链上分析是先学习 Ethtx 和 Tenderly。\n\n#### 链支援度比较\n\nPhalcon： `Ethereum、BSC、Cronos、Avalanche C-Chain、Polygon`\n\nEthtx： `Ethereum、Goerli testnet`\n\nTendery： `Ethereum、Polygon、BSC、Sepolia、Goerli、Gnosis、POA、RSK、Avalanche C-Chain、Arbitrum、Optimism、Fantom、Moonbeam、Moonriver`\n\n#### 实务操作\n\n以 JayPeggers - Insufficient validation + Reentrancy [事件](https://github.com/SunWeb3Sec/DeFiHackLabs/#20221229---jay---insufficient-validation--reentrancy)来当例子 [TXID](https://phalcon.blocksec.com/tx/eth/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n使用 Blocksec 开发的 Phalcon 工具来说明，下图可以看到该交易的基本资讯和余额变化，从余额变化可以快速看出攻击者大概获利多少，以这个例子攻击者获利 15.32 ETH。\n\n![210571234-402d96aa-fe5e-4bc4-becc-190bd5a78e68-2](https://user-images.githubusercontent.com/107249780/210686382-cc02cc6a-b8ec-4cb7-ac19-402cd8ff86f6.png)\n\nInvocation Flow 可视化函数调用流程: 可以让我们知道这一笔交易调用流程和函数呼叫的层级，有没有使用闪电贷、涉及了哪些项目、呼叫了哪些函数带入了什么参数和原始 data 等等\n\n![图片](https://user-images.githubusercontent.com/52526645/210572053-eafdf62a-7ebe-4caa-a905-045e792add2b.png)\n\nPhalcon 2.0 新增了资金流向和 Debug + 源代码分析可以在 Trace 的过程中边看程式执行的片段、参数、返回值，分析上方便了不少。\n\n![image](https://user-images.githubusercontent.com/107249780/210821062-d1da8d1a-9615-4f1f-838d-34f27b9c3f41.png)\n\n换 Sam 的 Transaction Viewer 来看看 [TXID](https://tx.eth.samczsun.com/ethereum/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n跟 Phalcon 类似但 Sam 整合了许多小工具在里面，如下图的眼睛点下去可以看到 Storage 的变化和每个呼叫所消耗的 Gas。\n\n![210574290-790f6129-aa82-4152-b3e1-d21820524a0a-2](https://user-images.githubusercontent.com/107249780/210686653-f964a682-d2a7-4b49-bafc-c9a2b0fa2c55.png)\n\n点击最左边的 Call，可以把原始 Input data 尝试 Decode。\n\n![图片](https://user-images.githubusercontent.com/52526645/210575619-89c8e8de-e2f9-4243-9646-0661b9483913.png)\n\n再来换 Tendery 来看看 [TXID](https://dashboard.tenderly.co/tx/mainnet/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n在 Tendery 介面上，一样可以看到基本资讯，但在 Debug 的部分就不是可视化，需要一步一步 Debug 走下去分析，不过好处是可以边 Debug 边看程式码还有 Input data 的转换过程。\n\n![图片](https://user-images.githubusercontent.com/52526645/210577802-c455545c-80d7-4f35-974a-dadbe59c626e.png)\n\n到这边就可以帮我们厘清大概这笔交易做了哪些事情，在还没有开始写 Poc 时，如果想要快速重放攻击可以吗? 可以! 可以使用Tendery 或 Phalcon，这两个工具另外支援了模拟交易重现，在上图右上角有一个按钮 Re-Simulate，工具会自动帮你带上该交易的参数值如下图\n从图中的栏位可以依照需求任意改变如改block number, From, Value, Input data 等\n\n![图片](https://user-images.githubusercontent.com/52526645/210580340-f2abf864-e540-4881-8482-f28030e5e35b.png)\n\n### Ethereum Signature Database\n\n[4byte](https://www.4byte.directory/) | [etherface](https://www.etherface.io/hash)\n\n在原始 Input data，前面 4bytes 为 Function Signature. 有时遇到 Etherscan 或分析工具无法解出来时，可以透过 Signature Database 来查看看可能是什么 Function。\n\n以下举例假设我们不知道 `0xac9650d8` 是什么 Function\n![图片](https://user-images.githubusercontent.com/52526645/210582149-61a6d973-b458-432f-b586-250c94c3ae24.png)\n\n透过 sig.eth 查询，可以看到这个 4 bytes signature 为 `multicall(bytes[])`\n![图片](https://user-images.githubusercontent.com/52526645/210583416-c31bbe07-fa03-4701-880d-0ae485b171f7.png)\n\n### Useful tools\n\n[ABI to interface](https://gnidan.github.io/abi-to-sol/) | [Get ABI for unverified contracts](https://abi.w1nt3r.xyz/) | [ETH Calldata Decoder](https://apoorvlathey.com/eth-calldata-decoder/) | [ETHCMD - Guess ABI](https://www.ethcmd.com/)\n\nABI to interface: 在开发 Poc 时需要呼叫其他合约时要有 Interface 接口，我们可以透过这个工具帮你快速产生你要的接口。\n先去 Etherscan 把 ABI 复制下来，贴过去工具上就可以看到产生出来的 Interface。\n[例子](https://etherscan.io/address/0xb3da8d6da3ede239ccbf576ca0eaa74d86f0e9d3#code)\n\n![图片](https://user-images.githubusercontent.com/52526645/210587442-e7853d8b-0613-426e-8a27-d70c80e2a42d.png)\n![图片](https://user-images.githubusercontent.com/52526645/210587682-5fb07a01-2b21-41fa-9ed5-e7f45baa0b3e.png)\n\nETH Calldata Decoder: 有时候在没有 ABI 的情况下想要解看看 Input data 可以试试看 ETH Calldata Decoder，在前面介绍到 Sam 的工具就有支援 Input data decode。\n\n![图片](https://user-images.githubusercontent.com/52526645/210585761-efd8b6f1-b901-485f-ae66-efaf9c84869c.png)\n\nGet ABI for unverified contracts: 如果遇到未开源的合约，可以透过这个工具尝试列举出这个合约中存在的 Function Signature.\n[例子](https://abi.w1nt3r.xyz/mainnet/0xaE9C73fd0Fd237c1c6f66FE009d24ce969e98704)\n\n![图片](https://user-images.githubusercontent.com/52526645/210588945-701b0e22-7390-4539-9d2f-e13479b52824.png)\n\n### Decompile tools\n\n[Etherscan-decompile bytecode](https://etherscan.io/address/0xaE9C73fd0Fd237c1c6f66FE009d24ce969e98704#code) | [Dedaub](https://library.dedaub.com/decompile) | [heimdall-rs](https://github.com/Jon-Becker/heimdall-rs)\n\nEtherscan 内建有一个反编译功能但可读性偏差，个人比较常使用 Dedaub，可读性好一点，也是常常最多人DM 问我都使用哪个工具反编译。\n我们拿一个 MEV Bot 被攻击来当[例子](https://twitter.com/1nf0s3cpt/status/1577594615104172033)\n可以自己试试解看看 [例子](https://bscscan.com/address/0x64dd59d6c7f09dc05b472ce5cb961b6e10106e1d#code)\n\n首先把未开源合约的 Bytecodes 复制下来贴到 Dedaub 上，点 Decompile 即可。\n![截图 2023-01-05 上午10 33 15](https://user-images.githubusercontent.com/107249780/210688395-927c6126-b6c1-4c6d-a0c7-a3fea3db9cdb.png)\n\n![图片](https://user-images.githubusercontent.com/52526645/210591478-6fa928f3-455d-42b5-a1ac-6694f97386c2.png)\n\n第一课分享就先到这边，想学更多可以参考以下学习资源。\n\n---\n\n## 学习资源\n\n[samczsun's eth txn explorer and vscode extension](https://www.youtube.com/watch?v=HXgu239mPBc)\n\n[Vulnerabilities in DeFi by Daniel V.F.](https://www.youtube.com/watch?v=9fcOffCg2ig)\n\n[Tenderly.co - Debug Transaction](https://www.youtube.com/watch?v=90GN9Ut8LhU)\n\n[Reversing The EVM: Raw Calldata](https://degatchi.com/articles/reading-raw-evm-calldata)\n\nhttps://web3sec.xrex.io/\n","Topics/Tools/TOOL07_Foundry/readme.md":"# WTF Solidity 极简入门-工具篇 7：Foundry，以 Solidity 为中心的开发工具包\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity 极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy\\_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n---\n\n## 什么是 Foundry?\n来自 Foundry [官网 (getfoundry.sh) ](https://getfoundry.sh) 对该工具的介绍：\n\n> Foundry是 一个用 Rust编写的用于以太坊应用程序开发的极快、可移植和模块化的工具包 ( Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.)\n\n项目设施：\n- 官网：[https://getfoundry.sh](https://getfoundry.sh)\n- Github 仓库：[https://github.com/foundry-rs/foundry](https://github.com/foundry-rs/foundry)\n- 文档：[https://book.getfoundry.sh](https://book.getfoundry.sh)\n\n介绍的解释：\n- **用 Rust 语言编写**： Foundry 完全采用 Rust 语言开发， [Github 上的源代码仓库](https://github.com/foundry-rs/foundry) 是一个 Rust 语言工程。我们可以通过获取 [Release 的二进制文件](https://github.com/foundry-rs/foundry/releases)，也可以通过 Rust 语言的 cargo 包管理[工具编译&构建安装](https://github.com/foundry-rs/foundry#installing-from-source);\n- **用于以太坊应用程序开发**： Foundry 作为 以太坊（Solidity语言）项目/应用程序开发的 “工程化” 工具，提供专业 Solidity 开发环境与“工具链”。**通过它你可以快速、方便的完成依赖项管理、编译、运行测试、部署，并可以通过命令行和 Solidity 脚本与链进行交互**;\n- **极快**： Foundry 利用 [ethers-solc](https://github.com/gakonst/ethers-rs/tree/master/ethers-solc/) 比较于传统通过 Node.js 辅助完成的测试用例/工程，Foundry 构建、测试的执行速度很快（创建一个工程，写一些测试用例跑一下会感受到震撼）;\n- **可移植**: Foundry 工程支持与其他类型的工程集成（如：[与 Hardhat 集成](https://book.getfoundry.sh/config/hardhat)）;\n- **模块化**：通过 git submodule & 构建目录映射，快速方便的引入依赖;\n\n<!--👆TODO: some 🔗 LINKS can be added when our Hardhat tutorial is complete -->\n\n## 为什么选择 Foundry？\n\n如果你满足以下条件或有过类似体验，你一定要试试 Foundry：\n\n- ~~如果你有 Rust “语言信仰”~~，如果你是个专业的 以太坊（Solidity语言）应用开发者；\n- 你曾经用过类似 Hardhat.js 这样的工具；\n- 你厌倦了大量测试用例的等待，需要有工具**更加快速**的跑完你的测试用例；\n- 你觉得处理 BigNumber 稍微有一点点🤏麻烦;\n- 有过**通过 Solidity 语言本身完成测试用例**（或测试合约的合约）的需求；\n- 你觉得通过 git submodule 的方式管理依赖更加方便（而不是 npm）；\n- ···\n\n\n如果有以下情况 Foundry 可能不适合你：\n- Solidity 初学者；\n- 你的项目不需要写测试用例、不需要过多在 Solidity 工程方面的自动化操作；\n\n\n## Foundry 的主要功能\n> 该部分源于 Foundry book ([https://book.getfoundry.sh](https://book.getfoundry.sh))，让章节的理解更容易。\n\n- [创建以太坊（Solidity）智能合约应用开发项目](https://book.getfoundry.sh/projects/creating-a-new-project)，[开发已有的项目](https://book.getfoundry.sh/projects/working-on-an-existing-project);\n- [管理以太坊(Solidity)智能合约的依赖项目](https://book.getfoundry.sh/projects/dependencies);\n- [创建由 Solidity 语言编写的测试用例（并且能很快速的执行测试用例）](https://book.getfoundry.sh/forge/writing-tests): 并且支持[模糊测试](https://book.getfoundry.sh/forge/fuzz-testing)与[差异测试](https://book.getfoundry.sh/forge/differential-ffi-testing)等方便、专业的测试方式;\n- 通过 [Cheatcodes（作弊码）](https://book.getfoundry.sh/forge/cheatcodes) 在 Solidity语言 编写的测试用例中**进行 “EVM环境之外” 的 vm 功能进行交互与断言**：更换测试用例语句执行者的钱包地址（更换 `msg.sender`）、对 EVM 外的 Event 事件进行断言；\n- 执行过程与错误追踪：[“函数堆栈”级的错误追踪（Traces）](https://book.getfoundry.sh/forge/traces)；\n- [部署合约和自动化的完成scan上合约的开源验证](https://book.getfoundry.sh/forge/deploying)；\n- 在项目中支持[完整的gas使用情况追踪](https://book.getfoundry.sh/forge/gas-tracking)：包括合约测试细节的gas用量和gas报告；\n- 交互式[调试器](https://book.getfoundry.sh/forge/debugger)；\n\n## Foundry 的组成\n\nFoundry 项目由 `Forge`, `Cast`, `Anvil` 几个部分（命令行工具）组成\n\n- Forge: Foundry 项目中**执行初始化项目、管理依赖、测试、构建、部署智能合约**的命令行工具;\n- Cast: Foundry 项目中**与 RPC 节点交互**的命令行工具。可以进行智能合约的调用、发送交易数据或检索任何类型的链上数据;\n- Anvil:  Foundry 项目中**启动的本地测试网/节点**的命令行工具。可以使用它配合测试前端应用与部署在该测试网的合约或通过 RPC 进行交互; \n\n## 快速使用 --- 创建一个 Foundry 项目\n\n> 内容出自 Foundry book 的 Getting Start 部分\n\n即将完成的过程：\n1. 安装 Foundry;\n2. 初始化一个 Foundry 项目;\n3. 理解初始化过程中添加的智能合约、测试用例；\n4. 执行构建&测试;\n  \n  \n### 安装 Foundry\n\n对于不同的环境：\n- MacOS / Linux （等 Unix like 系统）：\n  - 通过 `foundryup` 安装（👈Foundry 项目首页推荐的方式）;\n  - 通过 源代码构建 安装;\n- Windows\n  - 通过 源代码构建 安装;\n- Docker 环境\n  - 参考 Foundry Package: [ https://github.com/gakonst/foundry/pkgs/container/foundry](https://github.com/gakonst/foundry/pkgs/container/foundry)\n- Github Action： 用于构建完整的 Action 流程\n  - 参考 [https://github.com/foundry-rs/foundry-toolchain](https://github.com/foundry-rs/foundry-toolchain)\n\n---\n\n#### 通过[脚本](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/install)快速安装\n通过有`bash`的（或者类Unix环境）快速安装\n```shell\n$ curl -L https://foundry.paradigm.xyz | bash\n```\n执行后将会安装 `foundryup`，在此后执行它\n```shell\n$ foundryup\n```\n如果一切顺利，您现在可以使用三个二进制文件：`forge`、`cast` 和 `anvil`。\n\n\n<!--\n\n---\n\n#### [通过源代码构建安装（需要你了解一点 Rust 环境）](https://book.getfoundry.sh/getting-started/installation#building-from-source)\n\n要从源代码构建，您需要获取 `Rust` 和 `Cargo`。获得两者的最简单方法是使用 `rustup`。\n\n```shell\n# clone 项目目录至本地\ngit clone https://github.com/foundry-rs/foundry\n\n# 进入项目目录\ncd foundry\n\n# 安装 cast + forge\ncargo install --path ./cli --profile local --bins --locked --force\n\n# 安装 anvil\ncargo install --path ./anvil --profile local --locked --force\n```\n-->\n### 初始化一个 Foundry 项目\n\n通过 `forge` 的 `forge init` 初始化项目 \"hello_wtf\"\n```shell\n$ forge init hello_wtf\n\nInitializing /Users/username/hello_wtf...\nInstalling forge-std in \"/Users/username/hello_wtf/lib/forge-std\" (url: Some(\"https://github.com/foundry-rs/forge-std\"), tag: None)\n    Installed forge-std\n    Initialized forge project.\n```\n该过程通过安装依赖`forge-std`初始化了一个 Foundry 项目\n\n在项目目录中看到\n\n```shell\n$ tree -L 2 \n.\n├── foundry.toml        # Foundry 的 package 配置文件\n├── lib                 # Foundry 的依赖库\n│   └── forge-std       # 工具 forge 的基础依赖\n├── script              # Foundry 的脚本\n│   └── Counter.s.sol   # 示例合约 Counter 的脚本\n├── src                 # 智能合约的业务逻辑、源代码将会放在这里\n│   └── Counter.sol     # 示例合约\n└── test                # 测试用例目录\n    └── Counter.t.sol   # 示例合约的测试用例\n```\n提示：\n- 依赖项作为 git submodule 在 `./lib` 目录中\n- 关于 Foundry 的 package 配置文件请详细参考: [https://github.com/foundry-rs/foundry/blob/master/config/README.md#all-options](https://github.com/foundry-rs/foundry/blob/master/config/README.md#all-options)\n\n\n### 理解初始化过程中添加的智能合约、测试用例\n\n#### src 目录\n\n主要由业务逻辑构成\n`src` 目录中的 `./src/Counter.sol`:\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {          // 一个很简单的 Counter 合约\n    uint256 public number;  // 维护一个 public 的 uint256 数字\n\n    // 设置 number 变量的内容\n    function setNumber(uint256 newNumber) public { \n        number = newNumber;\n    }\n\n    // 让 number 变量的内容自增\n    function increment() public {\n        number++;\n    }\n}\n```\n\n#### script 目录\n\n参考 Foundry 项目文档中的 [Solidity-scripting](https://book.getfoundry.sh/tutorials/solidity-scripting) 该目录主要由“部署”脚本构成（也可通过该脚本调用 Foundry 提供的 `vm` 功能实现应用业务逻辑之外的高级功能，等同于 Hardhat.js 中的 scripts）。\n\n详见script 目录中的 `./script/Counter.s.sol`：\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13; // 许可 和 Solidity版本标识\n\nimport \"forge-std/Script.sol\"; // 引入foundry forge中的Script库\nimport \"../src/Counter.sol\"; // 引入要部署的Counter合约\n\n// 部署脚本继承了Script合约\ncontract CounterScript is Script {\n    // 可选函数，在每个函数运行之前被调用\n    function setUp() public {}\n\n    // 部署合约时会调用run()函数\n    function run() public {\n        vm.startBroadcast(); // 开始记录脚本中合约的调用和创建\n        new Counter(); // 创建合约\n        vm.stopBroadcast(); // 结束记录\n    }\n}\n```\n\nFoundry的部署脚本是一个用Solidity写的智能合约，虽然它不会被部署，但符合Solidity的规范。你可以用`forge script`运行脚本并部署合约。\n\n```shell\nforge script script/Counter.s.sol:CounterScript\n```\n\n\n#### test 目录\n\n主要由合约的测试用例构成\n\ntest 目录中的 `./test/Counter.t.sol`\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";        // 引入 forge-std 中用于测试的依赖\nimport \"../src/Counter.sol\";        // 引入用于测试的业务合约\n\n// 基于 forge-std 的 test 合约依赖实现测试用例\ncontract CounterTest is Test {      \n    Counter public counter;\n\n    // 初始化测试用例\n    function setUp() public { \n       counter = new Counter();\n       counter.setNumber(0);\n    }\n\n    // 基于初始化测试用例\n    // 断言测试自增后的 counter 的 number 返回值 同等于 1\n    function testIncrement() public {\n        counter.increment();\n        assertEq(counter.number(), 1);\n    }\n\n    // 基于初始化测试用例\n    // 执行差异测试测试\n    // forge 测试的过程中\n    // 为 testSetNumber 函数参数传递不同的 unit256 类型的 x\n    // 达到测试 counter 的 setNumber 函数 为不同的 x 设置不同的数\n    // 断言 number() 的返回值等同于差异测试的 x 参数\n    function testSetNumber(uint256 x) public {\n        counter.setNumber(x);\n        assertEq(counter.number(), x);\n    }\n\n    // 差异测试：参考 https://book.getfoundry.sh/forge/differential-ffi-testing\n}\n```\n\n### 执行构建&测试\n\n在项目目录中通过执行 `forge build` 完成构建\n```shell\n$ forge build\n\n[⠒] Compiling...\n[⠢] Compiling 10 files with 0.8.17\n[⠰] Solc 0.8.17 finished in 1.06s\nCompiler run successful\n```\n\n完成构建后 通过 `forge test` 完成测试\n```shell\n$ forge test\n\n[⠢] Compiling...\nNo files changed, compilation skipped\n\nRunning 2 tests for test/Counter.t.sol:CounterTest\n[PASS] testIncrement() (gas: 28312)\n[PASS] testSetNumber(uint256) (runs: 256, μ: 27609, ~: 28387)\nTest result: ok. 2 passed; 0 failed; finished in 9.98ms\n```\n\n至此，您已完成上手使用 Foundry 并且初始化一个项目。\n\n<!--\n\n  TODO: For foundry advanced usage ...\n\n  We need cover: \n  \n  - cli forge `test` : reference https://book.getfoundry.sh/forge/writing-tests\n  - cheatcode.\n  - Logs and traces levels.\n\n... etc.\n\n-->\n\n\n\n## Foundry Cast的进阶使用\n主要介绍Foundry Cast的使用，使用Cast在命令行下达到[Ethereum (ETH) Blockchain Explorer](https://etherscan.io/) 的效果。\n\n练习如下目标\n* 查询区块\n* 查询交易\n* 交易解析\n* 账户管理\n* 合约查询\n* 合约交互\n* 编码解析\n* 本地模拟链上交易\n\n\n\n## 区块相关\n\n### 查询区块\n\n```shell\n# $RPC_MAIN 替换成需要的RPC地址\ncast block-number --rpc-url=$RPC_MAIN\n```\n\n输出结果：\n\n```\n15769241\n```\n> 将环境变量的ETH_RPC_URL设置为 --rpc-url 你就不需要在每个命令行后面增加 --rpc-url=$RPC_MAIN 我这里直接设置为主网\n\n### 查询区块信息\n\n```shell\n# cast block <BLOCK> --rpc-url=$RPC_MAIN\n\ncast block 15769241 --rpc-url=$RPC_MAIN\n\n# 格式化\n\ncast block 15769241 --json --rpc-url=$RPC_MAIN\n\n\n```\n\n输出结果：\n\n```shell \nbaseFeePerGas        22188748210\ndifficulty           0\nextraData            0x\ngasLimit             30000000\ngasUsed              10595142\nhash                 0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nlogsBloom            0x1c6150404140580410990400a61d01e30030b00100c2a6310b11b9405d012980125671129881101011501d399081855523a106443aef3ab07148626315f721550290981058030b2af90b213961204c6103d2002a076c9e12d0800475b8231f0d06a20100da57c60aa0c008280128284418503340087c8650104c34500c18aa1c2070878008c21c64207d1424000244811415afc507640448122060644c181204ba412f0af11365020880508105551226004c0801c1840183003a42062a5a2444c13266020c00081440008038492740a8204a0c6c050a29d52405b92e4b20f028a97a604c6b0849ca81c4d06009258b4206217803a168824484deb8513242f082\nminer                0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263\nmixHash              0x09b7a94ef1d6c93caaff49ca8bf387652e0e33e116076b61f4d5ee79f0b91f92\nnonce                0x0000000000000000\nnumber               15769241\nparentHash           0x95c60d89f2275a6a7b1a9545cf1fb6d8c614402cd7311c82bc7972c177f7812d\nreceiptsRoot         0xe0240d60c448387123e412114cd0165b2af7b926d34bb824f8c544b022aa76f9\nsealFields           []\nsha3Uncles           0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\nsize                 149912\nstateRoot            0xaa3e9d839e99c4791827c81df9c9129028a320432920205f191e3fb261d0951c\ntimestamp            1666026803\ntotalDifficulty      58750003716598352816469\ntransactions:        [\n\t0xc4f5c10e4419698edaf7431df464340b389e4b79db959d58f42e82e8d1ed18ae\n\t0xb90edeacf833ac6cb91a326c775ed86d8047a467404bd8c69782d2260983eaad\n\t0x6f280650e35238ab930c9a0f3163443fffe2efedc5b553f408174d4bcd89cd8d\n\t0x2e0eafea64aaf2f53240a16b11a4f250ba74ab9ca5a1a90e6f2a6e92185877d2\n\t0x34f41d22ed8209da379691640cec5bfb8bf9404ad0f7264709b7959d61532343\n\t0x7569ab5ce2d1ca13a0c65ad52cc901dfc186e8ff8800793550b97760cbe34db2\n\t0xcdeef0ffe859fcf96fb52e22a9789295c6f1a94280df9faf0ebb9d52abefb3e7\n\t0x00d6793f3dbdd616351441b9e3da9a0de51370174e0d9383b4aae5c3c9806c2a\n\t0xff3daf63a431af021351d3da5f2f39a894352328d7f3df96afab1888f5a7093f\n\t0x7938399bee5293c384831c8e5aa698cdb491d568f9ebfb6d5c946f4ef7bf7e51\n\t0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\n\t0x0435d78a1b62484fbe3a7680d68ba4bdf0d692f087f4a6b70eb377421c58a5dd\n\t0xe16d1fa4d60cca7447850337c63cdf7b888318cc1bbb893b115f262dc01132d7\n\t0x44af4f696dcfedee682d7e511ad2469780443052565eea731b86b652a175c05e\n\t0xe88732f92ac376efb6e7517e66fc586447e0d065b8686556f2c1a7c3b7a519ce\n\t0x7ee890b096e97fc0c7e3cf74e0f0402532e0f3b8fa0e0c494d3d691d031f57e7\n\t...]\n```\n\n## 交易相关\n\n### 查询交易\n\n```shell\n# 跟ethersjs中的 provider.getTransaction 类似\n# cast tx <HASH> [FIELD] --rpc-url=$RPC\n\n# 跟ethersjs中的 provider.getTransactionReceipt类似\n# cast receipt <HASH> [FIELD] --rpc-url=$RPC \n\ncast tx 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 --rpc-url=$RPC \n\ncast receipt 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 --rpc-url=$RPC\n\n# 只获取logs\n\ncast receipt 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 logs --rpc-url=$RPC\n\n```\n\n第一条命令行结果：\n\n```shell\nblockHash            0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nblockNumber          15769241\nfrom                 0x9C0649d7325990D98375F7864eA167B5EAdCD46a\ngas                  313863\ngasPrice             35000000000\nhash                 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\ninput                0x38ed173900000000000000000000000000000000000000000000000332ca1b67940c000000000000000000000000000000000000000000000000000416b4849e6ba1475000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a00000000000000000000000000000000000000000000000000000000634d91c1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\nnonce                14\nr                    0x288aef25af73a4d1916f8d37107ef5f24729a423f23acc38920829c4180fe794\ns                    0x7644d26a91da02ff1e774cc821febf6387b8ee9f3e3085140b781819d0d8ede0\nto                   0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D\ntransactionIndex     10\nv                    38\nvalue                0\n```\n\n第二行命令行结果：\n\n```shell\nblockHash               0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nblockNumber             15769241\ncontractAddress\ncumulativeGasUsed       805082\neffectiveGasPrice       35000000000\ngasUsed                 114938\nlogs                    [{\"address\":\"0x97be09f2523b39b835da9ea3857cfa1d3c660cbb\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\"],\"data\":\"0x00000000000000000000000000000000000000000000000332ca1b67940c0000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x2\",\"removed\":false},{\"address\":\"0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb\",\"topics\":[\"0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x0000000000000000000000000000000000000000000000044b0a580cbdcfc0d90000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x3\",\"removed\":false},{\"address\":\"0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x0000000000000000000000000000000000000000000000044b0a580cbdcfc0d9\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x4\",\"removed\":false},{\"address\":\"0xf848e97469538830b0b147152524184a255b9106\",\"topics\":[\"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1\"],\"data\":\"0x00000000000000000000000000000000000000000000213ebfba613ffdcdd6ad0000000000000000000000000000000000000000000018b4b7f855bdcaac3b14\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x5\",\"removed\":false},{\"address\":\"0xf848e97469538830b0b147152524184a255b9106\",\"topics\":[\"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822\",\"0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000332ca1b67940c00000000000000000000000000000000000000000000000000044b0a580cbdcfc0d90000000000000000000000000000000000000000000000000000000000000000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x6\",\"removed\":false}]\nlogsBloom               0x00200000000000000000000080000000000000000000000000010000000008000000000000800000000000000000000000000000002000000000000000000000000000000000000000000008000000200000000000000000000000400000100000000000800000002000000000000000000000400000000000000010000000000000000000000000005000000000040000000000000000080000004004000000000000084100000000000000000000000000000040000000000000000000040000000002000000000000000000000000000000000000001000002000000020000000000000000000000000000000000000004000000000000000000000000000\nroot\nstatus                  1\ntransactionHash         0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\ntransactionIndex        10\ntype                    0\n\n```\n\n### 交易解析\n\nCast 会从 [Ethereum Signature Database](https://sig.eth.samczsun.com.) 解析对应的方法名称\n\n```shell\n# cast 4byte <SELECTOR> 解析交易的名称\ncast 4byte 0x38ed1739\n```\n\n输出结果：\n\n```shell\nswapExactTokensForTokens(uint256,uint256,address[],address,uint256)\n```\n\n### 交易签名 \n\n> 使用 Keccak-256 能够计算出方法名\n> 函数名为被调函数原型[1]的Keccak-256哈希值的前4个字节。这允许EVM准确无误地识别被调函数。\n\n交易签名：\n\n```shell\n# cast sig <SIG>\n\ncast sig \"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)\"\n\n```\n\n输出结果：\n\n```shell\n0x38ed1739\n```\n\n所以你可以看到最终都是 `0x38ed1739`\n\n有些方法名称可能没有，你可以通过`cast upload-signature <SIG> `上传给 [Ethereum Signature Database](https://sig.eth.samczsun.com) \n\n### 交易解码\n\n```shell\n# 获得calldata\ncast tx 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 input --rpc-url=$RPC\n\n# 可以通过该方法decode交易的数据，类似etherscan中的decode方法\n# cast pretty-calldata <CALLDATA>\ncast pretty-calldata 0x38ed173900000000000000000000000000000000000000000000000332ca1b67940c000000000000000000000000000000000000000000000000000416b4849e6ba1475000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a00000000000000000000000000000000000000000000000000000000634d91c1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\n```\n\n输出结果：\n\n```shell\n Possible methods:\n - swapExactTokensForTokens(uint256,uint256,address[],address,uint256)\n ------------\n [0]:  00000000000000000000000000000000000000000000000332ca1b67940c0000\n [1]:  00000000000000000000000000000000000000000000000416b4849e6ba14750\n [2]:  00000000000000000000000000000000000000000000000000000000000000a0\n [3]:  0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\n [4]:  00000000000000000000000000000000000000000000000000000000634d91c1\n [5]:  0000000000000000000000000000000000000000000000000000000000000002\n [6]:  00000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb\n [7]:  0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\n```\n\n### 模拟运行\n\n```\n# Usage: cast run --rpc-url <URL> <TXHASH>\n\ncast run 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\n```\n\n运行结果：\n\n![cast-run](./img/1.png)\n\n可以在结果中看到运行消耗的gas，以及方法顺序调用的过程，以及释放的emit的事件。通过这个可以了解一个hash的内在过程。类似 [BlockSec Building BlockChain Security Infrastructure](https://blocksec.com/) 和 [Tenderly | Ethereum Developer Platform](https://tenderly.co/) 可以结合使用。\n\n## 账户管理\n\n### 新建账户\n\n```shell\n# 新建一个账号\n# cast wallet new [OUT_DIR] \ncast wallet new\n\n# 新建一个keystore的账号，带有密码\n# cast wallet new <PATH>\ncast wallet new  ~/Downloads\n```\n\n第一条命令行结果输出：\n\n```shell\nSuccessfully created new key pair.\nAddress: 0xDD20b18E001A80d8b27B8Caa94EeAC884D1c****\nPrivate Key: edb4444199bddea91879c0214af27c0c7f99****bf18e46ba4078a39ccdbe0bc\n```\n\n第二条命令行结果输出：\n\n```shell\nEnter secret:\nCreated new encrypted keystore file: `/Users/EasyPlux/Downloads/b5832df5-21e9-4959-8c85-969eec9c0***`\\nPublic Address of the key: 0x58c1C8f6A7D92A9b20A5343949cd624570Ab****\n```\n\n### 账户签名\n\n```shell\n# 两种方法都可以使用签名，第一种载入刚才生成的keystore私钥，第二种直接输入自己的私钥。\ncast wallet sign <MESSAGE> --keystore=<PATH> \ncast wallet sign <MESSAGE> -i\n```\n\n### 账户验证\n\n```shell\ncast wallet verify --address <ADDRESS> <MESSAGE> <SIGNATURE> \n```\n\n## 合约交互\n\n### 获取合约\n\n```shell\ncast etherscan-source <contract address>\n\ncast etherscan-source 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --etherscan-api-key='key'\n\n```\n\n### 下载合约\n\n```shell\n#cast etherscan-source -d <path>\n# 我这里已经将$WETH的地址写入环境变量，如果没写入的，可以写成合约地址\ncast etherscan-source $WETH -d ~/Downloads\n```\n\n### 调用合约(读数据)\n\n`cast call` 用于从区块链上读取数据（调用只读函数），该操作不会改变区块链状态，也不需要支付 Gas 费用。下面我们调用 `WETH` 合约的`balanceOf`方法,查看 `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` 账号的余额\n\n```shell\n#cast call [OPTIONS] [TO] [SIG] [ARGS]... [COMMAND] --rpc-url=$RPC\n\ncast call $WETH \"balanceOf(address)\" 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url=$RPC\n\n# 输出\n# 0x0000000000000000000000000000000000000000000000230d12770f2845219c\n\n# 格式化输出 在参数后面加一个返回值的格式\n\ncast call $WETH \"balanceOf(address)(uint256)\" 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url=$RPC\n\n# 输出\n# 646577988758891995548\n\n```\n\n### 调用合约(写数据)\n\n`cast send` 用于发送交易并修改区块链状态（调用改变状态的函数），该操作会消耗 Gas 费用，需要签名并发送交易。\n\n```shell\n#cast send [OPTIONS] [TO] [SIG] [ARGS]... [COMMAND] --rpc-url=$RPC\n\ncast send 0x... \"deposit(address,uint256)\" 0x... 1 --rpc-url=$RPC\n\n```\n\n\n### 解析ABI\n\n可以根据ABI反向解析出solidity代码\n```shell\n# cast interface [OPTIONS] <PATH_OR_ADDRESS>\ncast interface ./weth.abi\n```\n\n## 编码解码\n\n```shell\ncast --to-hex \n\ncast --to-dec \n\ncast --to-unit \n\ncast --to-wei \n\ncast --to-rlp \n\ncast --from-rlp\n\n```\n\n## Tips\n\n### 设置ETH_RPC_URL\n将环境变量的`ETH_RPC_URL`设置为 `--rpc-url`的值，这样你就不需要在每个命令行后面增加 `--rpc-url=$RPC_MAIN`，我这里直接设置为主网，如下：\n``` shell\nexport ETH_RPC_URL=your_rpc_url\nsource ~/.bashrc  # 如果你使用的是 Bash\nsource ~/.zshrc   # 如果你使用的是 Zsh\ncast block-number # 不用再配置 --rpc-url 参数\n```\n\n### 设置ETHERSCAN_API_KEY\n设置`ETHERSCAN_API_KEY`环境变量可以直接代替 `--etherscan-api-key`\n\n### JSON格式化\n\n加上 `--json`  可以格式化输出\n\n```shell\ncast block 15769241 --json --rpc-url=$RPC_MAIN\n```\n\n## Anvil本地节点的使用\n\n### 基本命令行\n\nanvil 跟 hardhat 还有 truffle中的ganache都是一样的，是一个本地的eth节点，同样拥有各种fork的功能。\n\n```shell\nanvil \nanvil --accounts=<NUM> --balance=<NUM> \nanvil --mnemonic=<MNEMONIC> \nanvil --fork-url=$RPC --fork-block-number=<BLOCK>\n```\n\n### RPC的使用\n\n```shell\nanvil_* -> hardhat_* \n\nanvil_impersonateAccount \n\nanvil_setStorageAt\n```\n\n## Forge命令行进阶的使用\n\n代码存放在`WTFSolidity/Topics/Tools/TOOL07_Foundry/hello_wtf`\n\n代码目录树如下：\n\n```shell\n.\n├── broadcast\n│   └── Counter.s.sol \n├── foundry.toml        # foundry配置文件\n├── lib\n│   └── forge-std\n├── node_modules        # 使用npm依赖包目录，你也可以直接使用forge install\n│   └── @openzeppelin\n├── package-lock.json\n├── package.json\n├── script\n│   └── Counter.s.sol   # 脚本合约\n├── src\n│   └── Counter.sol\n└── test\n    ├── Counter.t.sol\n    └── Test.t.sol      # 测试合约\n```\n\n### 初始化项目\n```shell\n\nforge init <dir_name> \n\n# 使用模板初始化项目\nforge init --template <template_path> <dir_name>\n\n```\n\n## 热更新\n\n```shell\nforge build -w\n```\n\n\n### 测试\n\n```shell\n# 三个v会现实详细的log信息，还显示失败测试的堆栈跟踪\nforge test -vvv\n# 四个v显示所有测试的堆栈跟踪，并显示失败测试的设置（setup）跟踪。\nforge test -vvvv\n# 热更新模式\nforge test -vvv -w\n\n# log打印 需要 - vv 2个v以上才可以\n```\n\n使用 console2.log(\"test\") 来打印\n\n```js\n\n\nfunction testSetNumber(uint256 x) public {\n        console2.log(\"testNumber: %s==============\", x);\n        counter.setNumber(x);\n        assertEq(counter.number(), x);\n    }\n```\n\n\n使用 emit log 来打印\n\n```js\nfunction testNumberIs42() public {\n        emit log(\"test\");\n        assertEq(testNumber, 42);\n    }\n```\n\n改变 block.timestamp\n\n```js\n\nfunction testCheatCode()public {\n  console2.Log(\"before:\"block.timestamp);\n  vm.warp(1000);\n  console2.log(\"after:\"block.timestamp);\n}\n\n```\n\n改变msg.sender 【可以模拟管理员账户】\n\n```js\n// 只有第一次有影响\nvm.prank(address)\n\n\n// 多次影响\nvm.startPrank(address)\n...code\nvm.stopPrank()\n\n```\n\n\n改变账户余额（也可以用于改变大多数ERC20代币余额）\n\n```js\nfunction testCheatCode()public{\n\tconsole2.Log(\"before:\"alice.balance);\n\tvm.deal(alice,1 ether);\n\tconsole2.Log(\"after:\"alice.balance);\n}\n\n```\n\n## 安装插件\n\n### 使用forge安装插件\n\n```shell\nforge install [OPTIONS] <github username>/<github project>@<tag>\n```\n\n### 使用npm安装插件\n\n```shell\nnpm init -y\nnpm i @openzeppelin/contracts \n// yarn add @openzeppelin/contracts\n```\n\n安装完成之后需要配置`foundry.toml`方法，在libs中添加 `node_modules`文件夹。\n\n```toml\n[profile.default]\nsrc = 'src'\nout = 'out'\nlibs = ['lib','node_modules']\n```\n\n\n## 测试一\n\n新建`test/Test.t.sol`\n\n```js\n// SPDX-License-Identifier: SEE LICENSE IN LICENSE\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/Counter.sol\";\n// 导入IERC20的接口，通过该接口可以调用对应的方法\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract IERC20Test is Test {\n  // 声明Counter合约对象变量\n  Counter public counter;\n  // 声明一个地址变量\n  address public alice;\n  // 声明一个msgSender\n  address public msgSender;\n  // 声明帮助合约函数\n  Helper public h;\n\n  //定义一个IERC20 合约对象\n  IERC20 public dai;\n\n  function setUp() public {\n    // new测试合约对象\n    counter = new Counter();\n    // 调用对象方法\n    counter.setNumber(0);\n    // new helper对象\n    h = new Helper();\n\n    alice = address(10086);\n    console2.log(alice);\n    dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);\n  }\n\n  // 测试给合约地址转账\n  function testCheatCode() public {\n    console2.log(\"before:\", dai.balanceOf(alice));\n    deal(address(dai), alice,1 ether);\n    console2.log(\"after:\", dai.balanceOf(alice));\n  }\n  // 测试改变合约msg.sender\n  function testCheatAddress() public {\n    console2.log(\"before:\", h.whoCalled());\n    vm.prank(address(1));\n    console2.log(\"after:\", h.whoCalled());\n  }\n}\n\n\ncontract Helper {\n  function whoCalled() public view returns (address) {\n    return msg.sender;\n  }\n}\n```\n\n\n运行测试：\n\n因为本地没有dai的部署合约，所以我们直接fork主网， -vvv可以显示console2.log，-w表示watch模式。\n\n```shell\nforge test -vvv --fork-url=$ETH_RPC_URL -w\n```\n\n输出结果：\n\n```shell\nRunning 2 tests for test/Test.t.sol:IERC20Test\n[PASS] testCheatAddress() (gas: 12873)\nLogs:\n  0x0000000000000000000000000000000000002766\n  before: 0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84\n  after: 0x0000000000000000000000000000000000000001\n\n[PASS] testCheatCode() (gas: 153596)\nLogs:\n  0x0000000000000000000000000000000000002766\n  before: 0\n  after: 1000000000000000000\n\nTest result: ok. 2 passed; 0 failed; finished in 5.61s\n```\n\n### 代码中fork网络\n\n```js\nfunction testCodeFork() public {\n    console2.log(address(dai));\n    string memory rpc = vm.envString(\"ETH_RPC_URL\");\n    uint256 mainnet = vm.createFork(rpc);\n    vm.selectFork(mainnet);\n    // 这边下面开始就是直接fork网络了\n    console2.log(\"before:\",dai.balanceOf(alice));\n    deal(address(dai),alice,1 ether);\n    console2.log(\"after:\",dai.balanceOf(alice));\n  }\n```\n\n### 从代码中读取环境变量\n\n```js\n// 通过 vm.envAddress 获取环境变量中的地址\n    dai = IERC20(vm.envAddress(\"DAI\"));\n```\n\n### 完整代码\n\n```js\n// SPDX-License-Identifier: SEE LICENSE IN LICENSE\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/Counter.sol\";\n// 导入IERC20的接口，通过该接口可以调用对应的方法\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract IERC20Test is Test {\n  // 声明Counter合约对象变量\n  Counter public counter;\n  // 声明一个地址变量\n  address public alice;\n  // 声明一个msgSender\n  address public msgSender;\n  // 声明帮助合约函数\n  Helper public h;\n\n  //定义一个IERC20 合约对象\n  IERC20 public dai;\n\n  function setUp() public {\n    // new测试合约对象\n    counter = new Counter();\n    // 调用对象方法\n    counter.setNumber(0);\n    // new helper对象\n    h = new Helper();\n\n    alice = address(10086);\n    console2.log(alice);\n    // 通过 vm.envAddress 获取环境变量中的地址\n    dai = IERC20(vm.envAddress(\"DAI\"));\n  }\n\n\n  // 测试给合约地址转账\n  function testCheatCode() public {\n    console2.log(\"before:\", dai.balanceOf(alice));\n    deal(address(dai), alice,1 ether);\n    console2.log(\"after:\", dai.balanceOf(alice));\n  }\n  // 测试改变合约msg.sender\n  function testCheatAddress() public {\n    console2.log(\"before:\", h.whoCalled());\n    vm.prank(address(1));\n    console2.log(\"after:\", h.whoCalled());\n  }\n\n  function testCodeFork() public {\n    console2.log(address(dai));\n    string memory rpc = vm.envString(\"ETH_RPC_URL\");\n    uint256 mainnet = vm.createFork(rpc);\n    vm.selectFork(mainnet);\n    // 这边下面开始就是直接fork网络了\n    console2.log(\"before:\",dai.balanceOf(alice));\n    deal(address(dai),alice,1 ether);\n    console2.log(\"after:\",dai.balanceOf(alice));\n  }\n\n}\n\n\ncontract Helper {\n  function whoCalled() public view returns (address) {\n    return msg.sender;\n  }\n}\n```\n\n### vm.sol\n\n`vm.sol` 中还有很多封装好的方法可以直接使用\n\n```js\n// Sets the *next* call's msg.sender to be the input address\n    function prank(address) external;\n    // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n    function startPrank(address) external;\n    // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n    function prank(address,address) external;\n    // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n    function startPrank(address,address) external;\n    // Resets subsequent calls' msg.sender to be `address(this)`\n    function stopPrank() external;\n    // Sets an address' balance, (who, newBalance)\n    function deal(address, uint256) external;\n    // Sets an address' code, (who, newCode)\n    function etch(address, bytes calldata) external;\n    // Expects an error on next call\n    function expectRevert(bytes calldata) external;\n    function expectRevert(bytes4) external;\n    function expectRevert() external;\n    // Records all storage reads and writes\n    function record() external;\n    // Gets all accessed reads and write slot from a recording session, for a given address\n    function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes);\n```\n\n\n##  运行脚本\n\n```shell\nforge script [OPTIONS] <PATH> [ARGS]...\nforge script script/Counter.s.sol:CounterScript\n```\n\n`script/Counter.s.sol` 脚本代码\n\n```js\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Script.sol\";\n\ncontract CounterScript is Script {\n// 每次初始化会运行\n    function setUp() public {\n        console2.log(\"setup \");\n    }\n\n    function run() public {\n        vm.broadcast();\n        console2.log(\"run\");\n    }\n\n    function someFunction(uint256 x) public {\n        console2.log(\"some other func\");\n        console2.log(x);\n    }\n}\n\n```\n\n指定方法，带参数的测试运行\n\n```shell\nforge script script/Counter.s.sol --sig=\"someFunction(uint256 x)\" 10\n```\n\n## 脚本部署合约\n\n编写部署脚本：\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Script.sol\";\n// 引入合约\nimport \"../src/Counter.sol\";\n\ncontract CounterScript is Script {\n  function setUp() public {\n    console2.log(\"setup \");\n  }\n\n  function run() public {\n    // 开始记录脚本中合约的调用和创建\n    vm.startBroadcast();\n    //生成合约对象\n    Counter c = new Counter();\n    // 结束记录\n    vm.stopBroadcast();\n  }\n}\n\n```\n\n测试部署：\n\n```shell\nforge script script/Counter.s.sol -vvvv --rpc-url=http://127.0.0.1:8545\n```\n\n正式部署：\n\n```\nforge script script/Counter.s.sol -vvvv --rpc-url=$RPC_MAIN --broadcast --private-key=privete_key\n```\n\n部署完成之后会多一个broadcast文件夹，查看该文件夹有`run-latest.json`可以看到部署的相应信息。\n\n### 部署多个网络\n\n使用fork代码可以部署多个网络\n\n\n```js\nuint256 mainnet = vm.createFork(rpc);\n```\n\n## 命令行部署合约\n\n部署并开源合约，其中 `--etherscan-api-key` 为以太坊浏览器（或其他 EVM 浏览器）中申请的 API key，`--verify` 为部署后开源合约。\n```solidity\n# forge create --rpc-url <your_rpc_url> --private-key <your_private_key> --etherscan-api-key <KEY> --verify src/YourContract.sol:YourContract --constructor-args <constructor_args>\n  forge create --rpc-url $RPC_MAIN \\ \n   --private-key privete_key  \\ \n   --etherscan-api-key xxxx  \\ \n   --verify \\\n   src/Counter.sol:Counter\n```\n\n## Tips： \n\n```shell\nforge test --gas-report\n\n# 获取合约相关信息，例如abi、bytecode等等\nforge inspect <CONTRACT> <FIELD>\n\n# 生成gas快照\nforge snapshot\n\n# 当前快照文件与最新更改进行比较，对比gas是否减少\nforge snapshot --diff \n\n# 交互式Debugger\nforge script script/Counter.s.sol --debug\n\n# 链上交易debugger\nforge run --debug\n\n```\n\n\n\n## 总结\n\n这一讲我们介绍了以Solidity为中心的开发工具，并介绍了如何利用Foundry编译，部署，测试智能合约。由于Foundry的部署和测试脚本都是用Solidity编写，免去了开发者学习javascript的时间成本，并提供了更多练习Solidity的机会，推荐大家使用。\n\n\n## 参考\n[使用 foundry 框架加速智能合约开发](https://www.youtube.com/watch?v=EXYeltwvftw) \n[cast Commands - Foundry Book](https://book.getfoundry.sh/reference/cast/)\n[https://twitter.com/wp__lai](https://twitter.com/wp__lai)\n","Topics/Tools/TOOL06_Hardhat/package.json":"{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"description\": \"我最近在重新学solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用），每周更新1-3讲。\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n    \"hardhat\": \"^2.22.2\"\n  },\n  \"directories\": {\n    \"test\": \"test\"\n  }\n}\n","Topics/Tools/TOOL06_Hardhat/readme.md":"# WTF Solidity极简入门-工具篇6：Hardhat以太坊开发环境\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\nHardhat是以太坊最流行的开发环境，它可以帮你编译和部署智能合约，并且提供了Hardhat Network支持本地测试和运行Solidity。这一讲，我们将介绍如何安装Hardhat，使用Hardhat编写并编译合约，并运行简单的测试。\n\n## Hardhat安装\n\n### 安装node\n\n可以使用 nvm 安装node\n\n[GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions](https://github.com/nvm-sh/nvm)\n\n### 安装Hardhat\n\n打开命令行工具，输入：\n```shell\nmkdir hardhat-demo\ncd hardhat-demo\nnpm init -y\nnpm install --save-dev hardhat\n```\n\n### 创建Hardhat项目\n打开命令行工具，输入：\n\n```shell\ncd hardhat-demo\nnpx hardhat\n```\n\n选择第三项：创建空白项目配置 `Create an empty hardhat.config.js`\n\n```shell\nWelcome to Hardhat v2.22.2\n\n? What do you want to do? ...\n> Create a JavaScript project\n  Create a TypeScript project\n  Create a TypeScript project (with Viem)\n  Create an empty hardhat.config.js\n  Quit\n```\n\n### 安装插件\n```shell\nnpm install --save-dev @nomicfoundation/hardhat-toolbox\n```\n\n将插件添加到你的hardhat配置文件中 `hardhat.config.js`\n\n```js\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n\n/** @type import('hardhat/config').HardhatUserConfig */\nmodule.exports = {\n  solidity: \"0.8.21\",\n};\n```\n\n## 编写并编译合约\n如果你用过remix，那么你直接在remix上点击保存的时候，会自动帮你编译的。但是在本地的hardhat开发环境中，你需要手动编译合约。\n\n### 新建合约目录\n\n新建`contracts`合约目录，并添加第31章节的ERC20合约。\n\n### 编写合约\n这里的合约直接使用[WTF Solidity第31讲](https://github.com/AmazingAng/WTF-Solidity/blob/main/31_ERC20/readme.md)的ERC20合约\n\n```js\n// SPDX-License-Identifier: MIT\n// WTF Solidity by 0xAA\n\npragma solidity ^0.8.21;\n\nimport \"./IERC20.sol\";\n\ncontract ERC20 is IERC20 {\n\n    mapping(address => uint256) public override balanceOf;\n\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    uint256 public override totalSupply;   // 代币总供给\n\n    string public name;   // 名称\n    string public symbol;  // 符号\n    \n    uint8 public decimals = 18; // 小数位数\n\n    // @dev 在合约部署的时候实现合约名称和符号\n    constructor(string memory name_, string memory symbol_){\n        name = name_;\n        symbol = symbol_;\n    }\n\n    // @dev 实现`transfer`函数，代币转账逻辑\n    function transfer(address recipient, uint amount) external override returns (bool) {\n        balanceOf[msg.sender] -= amount;\n        balanceOf[recipient] += amount;\n        emit Transfer(msg.sender, recipient, amount);\n        return true;\n    }\n\n    // @dev 实现 `approve` 函数, 代币授权逻辑\n    function approve(address spender, uint amount) external override returns (bool) {\n        allowance[msg.sender][spender] = amount;\n        emit Approval(msg.sender, spender, amount);\n        return true;\n    }\n\n    // @dev 实现`transferFrom`函数，代币授权转账逻辑\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint amount\n    ) external override returns (bool) {\n        allowance[sender][msg.sender] -= amount;\n        balanceOf[sender] -= amount;\n        balanceOf[recipient] += amount;\n        emit Transfer(sender, recipient, amount);\n        return true;\n    }\n\n    // @dev 铸造代币，从 `0` 地址转账给 调用者地址\n    function mint(uint amount) external {\n        balanceOf[msg.sender] += amount;\n        totalSupply += amount;\n        emit Transfer(address(0), msg.sender, amount);\n    }\n\n    // @dev 销毁代币，从 调用者地址 转账给  `0` 地址\n    function burn(uint amount) external {\n        balanceOf[msg.sender] -= amount;\n        totalSupply -= amount;\n        emit Transfer(msg.sender, address(0), amount);\n    }\n\n}\n\n```\n\n### 编译合约\n```shell\nnpx hardhat compile\n```\n\n看到如下输出，说明合约编译成功：\n\n```shell\nCompiling 2 Solidity files successfully\n```\n\n成功后，你会在文件夹下看到`artifacts`目录，里面的`json`文件就是编译结果。\n\n## 编写单元测试\n\n这里的单元测试非常简单，仅包含部署合约并测试合约地址是否合法（是否部署成功）。\n\n新建测试文件夹`test`，在其中新建`test.js`。单元测试中，我们会用到`chai`和`ethers.js`两个库，分别用于测试和链上交互。对`ethers.js`不了解的开发者，可以看下[WTF Ethers极简教程](https://github.com/WTFAcademy/WTF-Ethers)的前6讲。我们之后的教程会更详细的介绍`chai`和`mocha`。\n\n```js\nconst { expect } = require('chai');\nconst { ethers } = require('hardhat');\n\n\ndescribe(\"ERC20 合约测试\", ()=>{\n  it(\"合约部署\", async () => {\n     // ethers.getSigners,代表eth账号  ethers 是一个全局函数，可以直接调用\n     const [owner, addr1, addr2] = await ethers.getSigners();\n     // ethers.js 中的 ContractFactory 是用于部署新智能合约的抽象，因此这里的 ERC20 是我们代币合约实例的工厂。ERC20代表contracts 文件夹中的 ERC20.sol 文件\n     const Token = await ethers.getContractFactory(\"ERC20\");\n     // 部署合约, 传入参数 ERC20.sol 中的构造函数参数分别是 name, symbol 这里我们都叫做WTF\n     const hardhatToken = await Token.deploy(\"WTF\", \"WTF\"); \n     await hardhatToken.waitForDeployment();\n      // 获取合约地址\n     const ContractAddress = await hardhatToken.target;\n     expect(ContractAddress).to.properAddress;\n  });\n})\n```\n\n## 运行测试\n\n在命令行输入以下内容运行测试：\n\n```shell\nnpx hardhat test\n# 如果有多个文件想跑指定文件可以使用\nnpx mocha test/test.js\n```\n\n看到如下输出，说明测试成功。\n\n```shell\n  ERC20 合约测试\n    ✔ 合约部署 (1648ms)\n\n\n  1 passing (2s)\n```\n\n## 部署合约\n\n在remix中，我们只需要点击一下`deploy`就可以部署合约了，但是在本地hardhat中，我们需要编写一个部署脚本。\n\n新建一个`scripts`文件夹，我们来编写部署合约脚本。并在该目录下新建一个`deploy.js`\n\n输入以下代码\n\n```js\n// 我们可以通过 npx hardhat run <script> 来运行想要的脚本\n// 这里你可以使用 npx hardhat run deploy.js 来运行\nconst hre = require(\"hardhat\");\n\nasync function main() {\n  const Contract = await hre.ethers.getContractFactory(\"ERC20\");\n  const token = await Contract.deploy(\"WTF\",\"WTF\");\n\n  await token.waitForDeployment();\n\n  console.log(\"成功部署合约:\", token.target);\n}\n\n// 运行脚本\nmain().catch((error) => {\n  console.error(error);\n  process.exitCode = 1;\n});\n\n```\n\n运行以下代码部署合约到本地测试网络\n\nhardhat会提供一个默认的网络，参考：[hardhat默认网络](https://hardhat.org/hardhat-network/docs/overview)\n\n```shell\nnpx hardhat run --network hardhat  scripts/deploy.js\n```\n\n看到如下输出，说明合约部署成功：\n\n```shell\n(node:45779) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n成功部署合约: 0x5FbDB2315678afecb367f032d93F642f64180aa3\n```\n\n## 部署合约到Goerli测试网络 ｜ 网络配置\n\n### 前期准备\n\n1. 申请alchemy的api key\n参考【[第4讲：Alchemy, 区块链API和节点基础设施](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL04_Alchemy/readme.md)】 \n2. 申请Goerli测试代币\n[点击申请](https://goerlifaucet.com/) 登录alchemy账号每天可以领取0.2个代币\n3. 导出私钥\n因为需要把合约部署到Goerli测试网络，所以该测试账号中留有一定的测试代币。导出已有测试代币的账户的私钥，用于部署合约\n4. 申请 etherscan 的 api key，用于验证合约\n[点击申请](https://etherscan.io/myapikey)\n\n### 配置网络\n\n在`hardhat.config.js`中，我们可以配置多个网络，这里我们配置`Goerli`测试网络。\n\n\n编辑 `hardhat.config.js`\n\n\n```js\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n\n// 申请alchemy的api key\nconst ALCHEMY_API_KEY = \"KEY\";\n\n//将此私钥替换为测试账号私钥\n//从MetaMask导出您的私钥，打开MetaMask和进入“帐户详细信息”>导出私钥\n//注意:永远不要把真正的以太放入测试帐户\nconst GOERLI_PRIVATE_KEY = \"YOUR GOERLI PRIVATE KEY\";\n\n// 申请etherscan的api key\nconst ETHERSCAN_API_KEY = \"YOUR_ETHERSCAN_API_KEY\";\n\nmodule.exports = {\n  solidity: \"0.8.21\", // solidity的编译版本\n  networks: {\n    goerli: {\n      url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`,\n      accounts: [GOERLI_PRIVATE_KEY]\n    }\n  },\n  etherscan: {\n    apiKey: ETHERSCAN_API_KEY,\n  },\n};\n```\n\n配置完成运行\n\n```shell\nnpx hardhat run --network goerli scripts/deploy.js\n```\n\n你就可以把你的合约部署到Goerli测试网络了。\n\n看到如下信息，你就成功部署到Goerli测试网络了。\n\n```shell\n(node:46996) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n(node:46999) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n成功部署合约: 0xeEAcef71084Dd1Ae542***9D8F64E3c68e15****\n```\n\n可以通过[etherscan](https://etherscan.io/)查看合约部署情况\n\n同理你也可以配置多个网络，比如`mainnet`，`rinkeby`等。\n\n最后验证你的合约：\n\n```shell\nnpx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS \"Constructor argument 1\"\n```\n\n\n## 总结\n\n这一讲，我们介绍了Hardhat基础用法。通过Hardhat我们能够工程化solidity的项目，并提供了很多有用的脚手架。在后续的文章中，我们会介绍更多的Hardhat的高级用法，例如使用Hardhat的插件、测试框架等等。","Topics/Tools/TOOL08_ZAN/readme.md":"# WTF Solidity 极简入门-工具篇 8：ZAN，节点服务和合约审计等 Web3 技术服务\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity 极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy\\_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n---\n\n## ZAN 是什么\n\n[ZAN](https://zan.top?chInfo=wtf) 是一家 Web3 技术服务提供商，是蚂蚁集团下的一个技术品牌。它提供多种技术服务，有类似 Infura 和 Alchemy 提供的节点服务，包括各种链的 JSON-RPC 支持，以及其他高级的链 API。还有安全相关的合约审计、链上数据分析、KYC 等服务。另外还提供 toB 的解决方案，包括 RWA 资产的链上发行、零知识证明加速以及提供安全和可定制的区块链等。\n\n接下来会针对开发者常用的节点服务、合约审计和链上数据分析（KNOW YOUR TRANSACTION）功能做介绍。在学习之前你可以先访问 [https://zan.top](https://zan.top?chInfo=wtf) 并完成注册和登录。\n\n## 节点服务\n\n### 创建 API Key\n\n之后进入到节点服务的控制台 [https://zan.top/service/apikeys](https://zan.top/service/apikeys?chInfo=wtf) 创建一个 Key，每个 Key 都有默认的免费额度，对于小项目来说够用了。\n\n创建成功后你会看到如下的页面：\n\n![](./img/zan-service.png)\n\n接下来你就可以直接点击网站上的 Copy 按钮复制获取 API Key 了，但是大部分情况我们都是直接复制你需要的链的 RPC 地址，然后在你的 DApp 中使用。\n\n### 使用 RPC 地址\n\n不同的区块链通常都会有自己的基础的 JSON-RPC 的接口规范，比如以太坊的 JSON-RPC 接口规范，你可以在 [https://ethereum.org/en/developers/docs/apis/json-rpc/](https://ethereum.org/en/developers/docs/apis/json-rpc/) 获取。\n\nZAN 提供的接口自然也遵循这样的规范，比如你可以通过访问 `https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}` 来访问以太坊上的数据。当然，我们通常可以直接使用链官方或者生态提供的 SDK 来调用接口。下面我们会介绍如何使用以太坊常用的一些 SDK 来调用 ZAN 提供的节点服务。\n\n需要注意上面代码中的 `YourZANApiKey` 需要替换成你自己的 Key。另外在实际的项目中，为了避免你的 Key 被滥用，建议你将 Key 放到后端服务中，然后通过后端服务来调用节点服务，或者在 ZAN 的控制台中设置域名白名单来降低被滥用的风险。\n\n#### 使用 ethers\n\n在 ethers.js 中，我们可以利用 ZAN 提供的 API Key 来创建 JsonRpcProvider，与链上交互。\n\n```javascript\nimport { ethers } from \"ethers\";\n\nconst provider = new ethers.providers.JsonRpcProvider(\n  \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n);\n\nprovider.getBlockNumber().then((blockNumber) => {\n  console.log(\"Current block number: \" + blockNumber);\n});\n```\n\n如上所示，我们可以通过 ethers.js 提供的 JsonRpcProvider 来访问 ZAN 提供的节点服务，获取当前区块的高度。更多的 ethers.js 的使用方法可以参考 ethers.js 官方文档：[ethers V5](https://docs.ethers.org/v5/api/providers/jsonrpc-provider/) | [ethers V6](https://docs.ethers.org/v6/api/providers/jsonrpc/#JsonRpcProvider)。\n\n#### 使用 web3.js\n\n在 web3.js 中，我们可以利用 ZAN 提供的 API Key 来创建 Web3Provider，与链上交互。\n\n```javascript\nimport Web3 from \"web3\";\n\nconst web3 = new Web3(\n  \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n);\nweb3.eth.getBlockNumber().then((blockNumber) => {\n  console.log(\"Current block number: \" + blockNumber);\n});\n```\n\n如上所示，我们可以通过 web3.js 提供的 Web3Provider 来访问 ZAN 提供的节点服务，获取当前区块的高度。更多的 web3.js 的使用方法可以参考 [web3.js 官方文档](https://web3js.readthedocs.io/)\n\n#### 使用 wagmi\n\n在 ZAN 的控制台中选择以太坊主网的节点服务地址复制，复制后的地址添加到 wagmi 的 `http()` 方法中，如下：\n\n```jsx\nimport { createConfig, http, WagmiProvider } from \"wagmi\";\nimport { mainnet } from \"wagmi/chains\";\n\nconst config = createConfig({\n  chains: [mainnet],\n  transports: {\n    [mainnet.id]: http(\n      \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n    ),\n  },\n});\n\nexport default function App() {\n  return <WagmiProvider config={config}>{/** ... */}</WagmiProvider>;\n}\n```\n\n如上，在 `WagmiProvider` 包裹的组件中你就可以使用 wagmi 提供的各种 hook 来访问以太坊的数据了。\n\n### 安全设置\n\n如果你在生产环境中使用，为了避免你的 API Key 被滥用或者攻击，你可以在 ZAN 的控制台中设置域名白名单，这样只有在白名单中的域名才能使用你的 API Key。\n\n![setting](./img/service-setting.png)\n\n还有其他设置你也可以在 ZAN 的控制台中找到，比如你可以设置每个 Key 的访问频率限制，这样可以避免你的 Key 被滥用。也可以查看每个 Key 的使用情况，设置团队共同管理 Key 等。\n\n### 测试网代币水龙头\n\n在开发中，我们经常需要获取测试网的代币，你可以通过水龙头获取测试代币，ZAN 也提供了测试网代币的水龙头服务，你可以在 [https://zan.top/faucet](https://zan.top/faucet?chInfo=wtf) 中获取测试代币。\n\n## 合约安全审计\n\n合约安全审计是一个非常重要的环节，尤其是在 DeFi 项目中，合约的安全性直接关系到用户的资金安全。ZAN 提供了合约安全审计服务，你可以在 [https://zan.top/home/contract-review](https://zan.top/home/contract-review) 中提交你的合约进行审计。ZAN 提供了免费版和专家版，专家版是有人工介入，需要收费。我们以免费版为例，说明如何在 ZAN 中提交合约审计任务。你有两种方法，一种是在网站上提交，另外一种是通过 VSCode 插件提交。\n\n### 通过 ZAN 网站提交\n\n你可以在 [https://zan.top/review/reports/apply](https://zan.top/review/reports/apply?chInfo=wtf) 提交一个合约审计任务：\n\n![create](./img/scr-new.png)\n\n有多种提交方式，提交后会进入到自动化的程序进行审计，如下图所示，你需要等待几分钟。\n\n![waiting](./img/scr-wait.png)\n\n需要注意的是，这种方式是自动化的审计，只能检测一些常见的漏洞，并无法保障合约的逻辑正确性，如果你的合约比较复杂，还是需要人工介入审计的。\n\n### 通过 VSCode 插件提交\n\nZAN 提供了一个 [VSCode 插件](https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review)，你可以在你的 VSCode 中安装该插件，直接在 VSCode 中提交合约审计任务。\n\n首先方案插件地址 [https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review](https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review) 点击 Install 唤起 VSCode 安装插件。\n\n安装成功后左侧会有一个 ZAN 的图标，点击图标后可以看到一个 `Config Access Key` 的按钮。\n\n![config-vscode](./img/config-vscode.png)\n\n点击按钮后配置你的 Access Key，Key 需要在 ZAN 的合约审计控制台中获取：\n\n![getkey](./img/vscode-key.png)\n\n获取 Key 后填入 VSCode 插件配置中，然后你就可以在 VSCode 中提交合约审计任务了。\n\n### 合约报告查看\n\n合约分析完成后你可以在网站上查看报告：\n\n![src-report](./img/scr-report.png)\n\n比如上图是对一个简单的 ERC721 的[合约](https://github.com/ourmetaverse/our-metaverse-contract)的分析结果，你可以通过[https://zan.top/review/reports/public/b82c9992-bfce-4986-baff-5bb4e76e1eb9](https://zan.top/review/reports/public/b82c9992-bfce-4986-baff-5bb4e76e1eb9?chInfo=wtf)查看报告。\n\n对于专家服务，会有多轮 AI + 专家人工审计后得到一个 PDF 报告，你可以访问[该链接](https://mdn.alipayobjects.com/huamei_hsbbrh/afts/file/A*tl-PR5pIIt4AAAAAAAAAAAAADiOMAQ/hebao_v3_20240313.pdf) 查看一个示例。\n\n![pdf](./img/scr-pdf.png)\n\n## 链上数据分析（KNOW YOUR TRANSACTION）\n\n区块链上的数据都是公开透明的，然而要在浩瀚的链上数据中分析问题，查找线索也不是那么容易的事情。ZAN 提供了链上数据分析服务，你可以在 [https://zan.top/kyt/controller](https://zan.top/kyt/controller?chInfo=wtf) 中提交你的地址，查看交易的详细信息。\n\n![kyt](./img/kyt-submit.png)\n\n提交的内容可以是一个地址，也可以是一笔交易，如下图所示，你可以看到资金的流动情况，还会标记出有风险的地址：\n\n![kyt-demo](./img/kyt-demo.png)\n\n可以用于资金追踪、巨鲸监控、反洗钱等等服务。对于专业用户，你可以使用 API 来调用，如下图你可以在控制台中获取你的 API Key：\n\n![kyt-key](./img/kyt-key.png)\n\n```sh\n## Replace {apiKey} with the API key you obtained from the ZAN dashboard.\n## You can also replace the \"eth\" and \"mainnet\" with any other supported networks.\ncurl https://api.zan.top/kyt/v1/score \\\n     -H \"Content-Type: application/json\" \\\n     -H \"Authorization:Bearer {apiKey}\" \\\n     -X POST \\\n     -d \"{\\\"objectId\\\":\\\"0xA160cdAB225685dA1d56aa342Ad8841c3b53f291\\\",\\\"objectType\\\":\\\"address\\\",\\\"analysisType\\\":\\\"\\\",\\\"chainShortName\\\":\\\"eth\\\",\\\"depth\\\":\\\"\\\"}\"\n```\n\n如上面示例代码，你可以通过访问 `https://api.zan.top/kyt/v1/score` 来获取某一个地址的相关数据。\n\n## 总结\n\n这一讲，我们介绍了如何使用 ZAN 提供的各种 Web3 技术服务。ZAN 提供了丰富的服务，有面向 DApp 开发者的，也有面向商业机构，安全团队，研究机构等的服务，你可以根据自己的需求选择合适的服务。\n","out/extensions/IERC721Metadata.sol/IERC721Metadata.json":"{\"abi\":[{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApproved\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isApprovedForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerOf\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setApprovalForAll\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenURI\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ApprovalForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false}],\"bytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"methodIdentifiers\":{\"approve(address,uint256)\":\"095ea7b3\",\"balanceOf(address)\":\"70a08231\",\"getApproved(uint256)\":\"081812fc\",\"isApprovedForAll(address,address)\":\"e985e9c5\",\"name()\":\"06fdde03\",\"ownerOf(uint256)\":\"6352211e\",\"safeTransferFrom(address,address,uint256)\":\"42842e0e\",\"safeTransferFrom(address,address,uint256,bytes)\":\"b88d4fde\",\"setApprovalForAll(address,bool)\":\"a22cb465\",\"supportsInterface(bytes4)\":\"01ffc9a7\",\"symbol()\":\"95d89b41\",\"tokenURI(uint256)\":\"c87b56dd\",\"transferFrom(address,address,uint256)\":\"23b872dd\"},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.34+commit.80d5c536\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Approval\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"ApprovalForAll\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Transfer\\\",\\\"type\\\":\\\"event\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"approve\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"balanceOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"balance\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"getApproved\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"isApprovedForAll\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"name\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"ownerOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"setApprovalForAll\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"bytes4\\\",\\\"name\\\":\\\"interfaceId\\\",\\\"type\\\":\\\"bytes4\\\"}],\\\"name\\\":\\\"supportsInterface\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"symbol\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"tokenURI\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"transferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"See https://eips.ethereum.org/EIPS/eip-721\\\",\\\"events\\\":{\\\"Approval(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\\\"},\\\"ApprovalForAll(address,address,bool)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\\"},\\\"Transfer(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `tokenId` token is transferred from `from` to `to`.\\\"}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"approve(address,uint256)\\\":{\\\"details\\\":\\\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\\\"},\\\"balanceOf(address)\\\":{\\\"details\\\":\\\"Returns the number of tokens in ``owner``'s account.\\\"},\\\"getApproved(uint256)\\\":{\\\"details\\\":\\\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"isApprovedForAll(address,address)\\\":{\\\"details\\\":\\\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\\\"},\\\"name()\\\":{\\\"details\\\":\\\"Returns the token collection name.\\\"},\\\"ownerOf(uint256)\\\":{\\\"details\\\":\\\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"safeTransferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"safeTransferFrom(address,address,uint256,bytes)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"setApprovalForAll(address,bool)\\\":{\\\"details\\\":\\\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\\\"},\\\"supportsInterface(bytes4)\\\":{\\\"details\\\":\\\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\\\"},\\\"symbol()\\\":{\\\"details\\\":\\\"Returns the token collection symbol.\\\"},\\\"tokenURI(uint256)\\\":{\\\"details\\\":\\\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\\"},\\\"transferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\\\"}},\\\"title\\\":\\\"ERC-721 Non-Fungible Token Standard, optional metadata extension\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":\\\"IERC721Metadata\\\"},\\\"evmVersion\\\":\\\"prague\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\\\",\\\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\\\",\\\":forge-std/=lib/forge-std/src/\\\",\\\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\\\",\\\":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\\\"]},\\\"sources\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\\\":{\\\"keccak256\\\":\\\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\\\",\\\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\\\"]},\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":{\\\"keccak256\\\":\\\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\\\",\\\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\\\"]},\\\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\\\":{\\\"keccak256\\\":\\\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\\\",\\\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.34+commit.80d5c536\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Approval\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ApprovalForAll\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Transfer\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"approve\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setApprovalForAll\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferFrom\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"name()\":{\"details\":\"Returns the token collection name.\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the token collection symbol.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\"forge-std/=lib/forge-std/src/\",\"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\"openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"compilationTarget\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":\"IERC721Metadata\"},\"evmVersion\":\"prague\",\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\",\"urls\":[\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\",\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\",\"urls\":[\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\",\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"],\"license\":\"MIT\"}},\"version\":1},\"id\":28}","Topics/Tools/TOOL06_Hardhat/package-lock.json":"{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 2,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"tool06_hardhat\",\n      \"version\": \"1.0.0\",\n      \"license\": \"ISC\",\n      \"devDependencies\": {\n        \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n        \"hardhat\": \"^2.22.2\"\n      }\n    },\n    \"node_modules/@adraffy/ens-normalize\": {\n      \"version\": \"1.10.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz\",\n      \"integrity\": \"sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@cspotcode/source-map-support\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@ethersproject/abi\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abi/-/abi-5.7.0.tgz\",\n      \"integrity\": \"sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/hash\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-provider\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz\",\n      \"integrity\": \"sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/networks\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/transactions\": \"^5.7.0\",\n        \"@ethersproject/web\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-signer\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz\",\n      \"integrity\": \"sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-provider\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/address\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/address/-/address-5.7.0.tgz\",\n      \"integrity\": \"sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/base64\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/base64/-/base64-5.7.0.tgz\",\n      \"integrity\": \"sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/bignumber\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz\",\n      \"integrity\": \"sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\"\n      }\n    },\n    \"node_modules/@ethersproject/bytes\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bytes/-/bytes-5.7.0.tgz\",\n      \"integrity\": \"sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/constants\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/constants/-/constants-5.7.0.tgz\",\n      \"integrity\": \"sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/hash\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/hash/-/hash-5.7.0.tgz\",\n      \"integrity\": \"sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-signer\": \"^5.7.0\",\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/keccak256\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz\",\n      \"integrity\": \"sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"js-sha3\": \"0.8.0\"\n      }\n    },\n    \"node_modules/@ethersproject/logger\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/logger/-/logger-5.7.0.tgz\",\n      \"integrity\": \"sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==\",\n      \"dev\": true\n    },\n    \"node_modules/@ethersproject/networks\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/networks/-/networks-5.7.1.tgz\",\n      \"integrity\": \"sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/properties\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/properties/-/properties-5.7.0.tgz\",\n      \"integrity\": \"sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/rlp\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/rlp/-/rlp-5.7.0.tgz\",\n      \"integrity\": \"sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/signing-key\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz\",\n      \"integrity\": \"sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\",\n        \"elliptic\": \"6.5.4\",\n        \"hash.js\": \"1.1.7\"\n      }\n    },\n    \"node_modules/@ethersproject/strings\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/strings/-/strings-5.7.0.tgz\",\n      \"integrity\": \"sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/transactions\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/transactions/-/transactions-5.7.0.tgz\",\n      \"integrity\": \"sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\",\n        \"@ethersproject/signing-key\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/web\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/web/-/web-5.7.1.tgz\",\n      \"integrity\": \"sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@fastify/busboy\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@fastify/busboy/-/busboy-2.1.1.tgz\",\n      \"integrity\": \"sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14\"\n      }\n    },\n    \"node_modules/@jridgewell/resolve-uri\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz\",\n      \"integrity\": \"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz\",\n      \"integrity\": \"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\n      }\n    },\n    \"node_modules/@metamask/eth-sig-util\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz\",\n      \"integrity\": \"sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ethereumjs-abi\": \"^0.6.8\",\n        \"ethereumjs-util\": \"^6.2.1\",\n        \"ethjs-util\": \"^0.1.6\",\n        \"tweetnacl\": \"^1.0.3\",\n        \"tweetnacl-util\": \"^0.15.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12.0.0\"\n      }\n    },\n    \"node_modules/@noble/curves\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/curves/-/curves-1.2.0.tgz\",\n      \"integrity\": \"sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"1.3.2\"\n      }\n    },\n    \"node_modules/@noble/curves/node_modules/@noble/hashes\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.3.2.tgz\",\n      \"integrity\": \"sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 16\"\n      }\n    },\n    \"node_modules/@noble/hashes\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.1.2.tgz\",\n      \"integrity\": \"sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==\",\n      \"dev\": true\n    },\n    \"node_modules/@noble/secp256k1\": {\n      \"version\": \"1.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz\",\n      \"integrity\": \"sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@nodelib/fs.scandir\": {\n      \"version\": \"2.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.stat\": \"2.0.5\",\n        \"run-parallel\": \"^1.1.9\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.stat\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.walk\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.scandir\": \"2.1.5\",\n        \"fastq\": \"^1.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr/-/edr-0.3.2.tgz\",\n      \"integrity\": \"sha512-HGWtjibAK1mo4I2A7nJ/fXqe/J9G54OrSPJnnkY2K8TiXotYLShGd9GvHkae3PuFjTJKm6ZgBy7tveJj5yrCfw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/edr-darwin-arm64\": \"0.3.2\",\n        \"@nomicfoundation/edr-darwin-x64\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-arm64-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-ia32-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-x64-msvc\": \"0.3.2\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-arm64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.2.tgz\",\n      \"integrity\": \"sha512-l6wfSBUUbGJiCENT6272CDI8yoMuf0sZH56H5qz3HnAyVzenkOvmzyF6/lar54m986kdAQqWls4cLvDxiOuLxg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-x64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.2.tgz\",\n      \"integrity\": \"sha512-OboExL7vEw+TRJQl3KkaEKU4K7PTdZPTInZ0fxMAtOpcWp7EKR+dQo68vc/iAOusB3xszHKxt7t+WpisItfdcg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-xtEK+1eg++3pHi6405NDXd80S3CGOFEGQIyVGCwjMGQFOLSzBGGCsrb/0GB4J19zd1o/8ftCd/HjZcbVAWWTLQ==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-3cIsskJOXQ1yEVsImmCacY7O03tUTiWrmd54F05PnPFrDLkjbzodQ3b2gUWzfbzUZWl67ZTJd1CvVSzpe7XGzw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-ouPdphHNsyO7wqwa4hwahC5WqBglK/fIvMmhR/SXNZ9qruIpsA8ZZKIURaHMOv/2h2BbNGcyTX9uEk6+5rK/MQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-sRhwhiPbkpJMOUwXW1FZw9ks6xWyQhIhM0E8o3TXEXKSPKTE6whQLEk1R37iFITaI36vb6rSwLKTU1cb32gCoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-arm64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-IEwVealKfumu1HSSnama26yPuQC/uthRPK5IWtFsQUOGwOXaS1r9Bu7cGYH2jBHl3IT/JbxD4xzPq/2pM9uK0A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-ia32-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-jYMnf6SFgguqROswwdsjJ1wvneD/5c16pVu9OD4DxNqhKNP5bHEw6L2N4DcJ89tpXMpJ6AlOpc0QuwzddiZ3tA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-x64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-Byn4QuWczRy/DUUQM3WjglgX/jGVUURVFaUsmIhnGg//MPlCLawubBGRqsrMuvaYedlIIJ4I2rgKvZlxdgHrqg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-common\": {\n      \"version\": \"4.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz\",\n      \"integrity\": \"sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-rlp\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz\",\n      \"integrity\": \"sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"rlp\": \"bin/rlp.cjs\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz\",\n      \"integrity\": \"sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-common\": \"4.0.4\",\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util\": {\n      \"version\": \"9.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz\",\n      \"integrity\": \"sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-chai-matchers\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz\",\n      \"integrity\": \"sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai-as-promised\": \"^7.1.3\",\n        \"chai-as-promised\": \"^7.1.1\",\n        \"deep-eql\": \"^4.0.1\",\n        \"ordinal\": \"^1.0.3\"\n      },\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-ethers\": {\n      \"version\": \"3.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz\",\n      \"integrity\": \"sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"debug\": \"^4.1.1\",\n        \"lodash.isequal\": \"^4.5.0\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.6.tgz\",\n      \"integrity\": \"sha512-a35iVD4ycF6AoTfllAnKm96IPIzzHpgKX/ep4oKc2bsUKFfMlacWdyntgC/7d5blyCTXfFssgNAvXDZfzNWVGQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"ethereumjs-util\": \"^7.1.4\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.9.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereumjs-util\": {\n      \"version\": \"7.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz\",\n      \"integrity\": \"sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/bn.js\": \"^5.1.0\",\n        \"bn.js\": \"^5.1.2\",\n        \"create-hash\": \"^1.1.2\",\n        \"ethereum-cryptography\": \"^0.1.3\",\n        \"rlp\": \"^2.2.4\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-toolbox\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz\",\n      \"integrity\": \"sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA==\",\n      \"dev\": true,\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-chai-matchers\": \"^2.0.0\",\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"@nomicfoundation/hardhat-network-helpers\": \"^1.0.0\",\n        \"@nomicfoundation/hardhat-verify\": \"^2.0.0\",\n        \"@typechain/ethers-v6\": \"^0.5.0\",\n        \"@typechain/hardhat\": \"^9.0.0\",\n        \"@types/chai\": \"^4.2.0\",\n        \"@types/mocha\": \">=9.1.0\",\n        \"@types/node\": \">=16.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.4.0\",\n        \"hardhat\": \"^2.11.0\",\n        \"hardhat-gas-reporter\": \"^1.0.8\",\n        \"solidity-coverage\": \"^0.8.1\",\n        \"ts-node\": \">=8.0.0\",\n        \"typechain\": \"^8.3.0\",\n        \"typescript\": \">=4.5.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-verify\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.5.tgz\",\n      \"integrity\": \"sha512-Tg4zu8RkWpyADSFIgF4FlJIUEI4VkxcvELsmbJn2OokbvH2SnUrqKmw0BBfDrtvP0hhmx8wsnrRKP5DV/oTyTA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@ethersproject/abi\": \"^5.1.2\",\n        \"@ethersproject/address\": \"^5.0.2\",\n        \"cbor\": \"^8.1.0\",\n        \"chalk\": \"^2.4.2\",\n        \"debug\": \"^4.1.1\",\n        \"lodash.clonedeep\": \"^4.5.0\",\n        \"semver\": \"^6.3.0\",\n        \"table\": \"^6.8.0\",\n        \"undici\": \"^5.14.0\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz\",\n      \"integrity\": \"sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 12\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/solidity-analyzer-darwin-arm64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-darwin-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-freebsd-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-x64-msvc\": \"0.1.1\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz\",\n      \"integrity\": \"sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@scure/base\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/base/-/base-1.1.1.tgz\",\n      \"integrity\": \"sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==\",\n      \"dev\": true\n    },\n    \"node_modules/@scure/bip32\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip32/-/bip32-1.1.0.tgz\",\n      \"integrity\": \"sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@noble/secp256k1\": \"~1.6.0\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@scure/bip39\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip39/-/bip39-1.1.0.tgz\",\n      \"integrity\": \"sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@sentry/core\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/core/-/core-5.30.0.tgz\",\n      \"integrity\": \"sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/hub\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/hub/-/hub-5.30.0.tgz\",\n      \"integrity\": \"sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/minimal\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/minimal/-/minimal-5.30.0.tgz\",\n      \"integrity\": \"sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/node\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/node/-/node-5.30.0.tgz\",\n      \"integrity\": \"sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/core\": \"5.30.0\",\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/tracing\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"cookie\": \"^0.4.1\",\n        \"https-proxy-agent\": \"^5.0.0\",\n        \"lru_map\": \"^0.3.3\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/tracing\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/tracing/-/tracing-5.30.0.tgz\",\n      \"integrity\": \"sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/types\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/types/-/types-5.30.0.tgz\",\n      \"integrity\": \"sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/utils\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/utils/-/utils-5.30.0.tgz\",\n      \"integrity\": \"sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@solidity-parser/parser\": {\n      \"version\": \"0.14.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@solidity-parser/parser/-/parser-0.14.3.tgz\",\n      \"integrity\": \"sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"antlr4ts\": \"^0.5.0-alpha.4\"\n      }\n    },\n    \"node_modules/@tsconfig/node10\": {\n      \"version\": \"1.0.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz\",\n      \"integrity\": \"sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node12\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz\",\n      \"integrity\": \"sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node14\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz\",\n      \"integrity\": \"sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node16\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz\",\n      \"integrity\": \"sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@typechain/ethers-v6\": {\n      \"version\": \"0.5.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz\",\n      \"integrity\": \"sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"lodash\": \"^4.17.15\",\n        \"ts-essentials\": \"^7.0.1\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"6.x\",\n        \"typechain\": \"^8.3.2\",\n        \"typescript\": \">=4.7.0\"\n      }\n    },\n    \"node_modules/@typechain/hardhat\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/hardhat/-/hardhat-9.1.0.tgz\",\n      \"integrity\": \"sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"fs-extra\": \"^9.1.0\"\n      },\n      \"peerDependencies\": {\n        \"@typechain/ethers-v6\": \"^0.5.1\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.9\",\n        \"typechain\": \"^8.3.2\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/fs-extra\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz\",\n      \"integrity\": \"sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"at-least-node\": \"^1.0.0\",\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/jsonfile\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz\",\n      \"integrity\": \"sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"universalify\": \"^2.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"graceful-fs\": \"^4.1.6\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/universalify\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz\",\n      \"integrity\": \"sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      }\n    },\n    \"node_modules/@types/bn.js\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/bn.js/-/bn.js-5.1.1.tgz\",\n      \"integrity\": \"sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/chai\": {\n      \"version\": \"4.3.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai/-/chai-4.3.14.tgz\",\n      \"integrity\": \"sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/chai-as-promised\": {\n      \"version\": \"7.1.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz\",\n      \"integrity\": \"sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai\": \"*\"\n      }\n    },\n    \"node_modules/@types/concat-stream\": {\n      \"version\": \"1.6.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/concat-stream/-/concat-stream-1.6.1.tgz\",\n      \"integrity\": \"sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/form-data\": {\n      \"version\": \"0.0.33\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/form-data/-/form-data-0.0.33.tgz\",\n      \"integrity\": \"sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/glob\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/glob/-/glob-7.2.0.tgz\",\n      \"integrity\": \"sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/minimatch\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/lru-cache\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/lru-cache/-/lru-cache-5.1.1.tgz\",\n      \"integrity\": \"sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/minimatch\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/minimatch/-/minimatch-5.1.2.tgz\",\n      \"integrity\": \"sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/mocha\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/mocha/-/mocha-9.1.1.tgz\",\n      \"integrity\": \"sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"18.15.13\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/node/-/node-18.15.13.tgz\",\n      \"integrity\": \"sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/pbkdf2\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz\",\n      \"integrity\": \"sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/prettier\": {\n      \"version\": \"2.7.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz\",\n      \"integrity\": \"sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/qs\": {\n      \"version\": \"6.9.7\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/qs/-/qs-6.9.7.tgz\",\n      \"integrity\": \"sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/secp256k1\": {\n      \"version\": \"4.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/secp256k1/-/secp256k1-4.0.3.tgz\",\n      \"integrity\": \"sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@ungap/promise-all-settled\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz\",\n      \"integrity\": \"sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsm","Topics/Onchain_debug/01_tools/en/readme.md":"# en Documentation\n\nPath: `Topics/Onchain_debug/01_tools/en/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Onchain_debug/01_tools/en/readme.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json":"# Hello_wtf Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/package.json":"# Hello_wtf Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)","Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md":"# 01_tools Documentation\n\nPath: `Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md)","Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md":"# TOOL01_Remix Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md)","Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md":"# TOOL02_Infura Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md)","Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md":"# TOOL03_Ganache Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md)","Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md":"# TOOL04_Alchemy Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md)","Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md":"# TOOL05_Dune Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md)","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json":"# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json)","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json":"# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json)","Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md":"# TOOL06_Hardhat Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md":"# TOOL07_Foundry Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md)","Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md":"# en Documentation\n\nPath: `Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json":"# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json":"# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md":"# forge-std Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md":"# openzeppelin-contracts Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md":"# .github Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md":"# Audits Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md":"# audits Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json":"# Contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md":"# docs Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md":"# fv Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md":"# Test Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md":"# forge-std Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json":"# Forge-std Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md":"# ISSUE_TEMPLATE Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md":"# ISSUE_TEMPLATE Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md":"# erc4626-tests Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md":"# forge-std Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md":"# halmos-cheatcodes Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json":"# Solhint-custom Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md":"# upgradeable Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json":"# Cryptography Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json)","Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json)","Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json":"# Fixtures Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)"},"items":[{"name":"package-lock.json","path":"Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json","title":"TOOL06_Hardhat Skill","category":"anthropic-skill","format":"json","content":"# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json)","tokens":300,"sizeBytes":249},{"name":"package.json","path":"Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json","title":"TOOL06_Hardhat Skill","category":"anthropic-skill","format":"json","content":"# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json)","tokens":300,"sizeBytes":239},{"name":"run-1666193264.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json","title":"1 Skill","category":"anthropic-skill","format":"json","content":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)","tokens":300,"sizeBytes":312},{"name":"run-1666193265.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json","title":"1 Skill","category":"anthropic-skill","format":"json","content":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)","tokens":300,"sizeBytes":312},{"name":"run-latest.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json","title":"1 Skill","category":"anthropic-skill","format":"json","content":"# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)","tokens":300,"sizeBytes":304},{"name":"package.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json","title":"Forge-std Skill","category":"anthropic-skill","format":"json","content":"# Forge-std Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)","tokens":300,"sizeBytes":282},{"name":"broadcast.log.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json","title":"Fixtures Skill","category":"anthropic-skill","format":"json","content":"# Fixtures Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)","tokens":300,"sizeBytes":329},{"name":"package-lock.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json","title":"Hello_wtf Skill","category":"anthropic-skill","format":"json","content":"# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)","tokens":300,"sizeBytes":264},{"name":"package.json","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json","title":"Hello_wtf Skill","category":"anthropic-skill","format":"json","content":"# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)","tokens":300,"sizeBytes":254},{"name":"IERC721Metadata.json","path":"out/extensions/IERC721Metadata.sol/IERC721Metadata.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/out/extensions/IERC721Metadata.sol/IERC721Metadata.json","title":"IERC721Metadata.sol Skill","category":"anthropic-skill","format":"json","content":"{\"abi\":[{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApproved\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isApprovedForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerOf\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setApprovalForAll\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenURI\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ApprovalForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false}],\"bytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"methodIdentifiers\":{\"approve(address,uint256)\":\"095ea7b3\",\"balanceOf(address)\":\"70a08231\",\"getApproved(uint256)\":\"081812fc\",\"isApprovedForAll(address,address)\":\"e985e9c5\",\"name()\":\"06fdde03\",\"ownerOf(uint256)\":\"6352211e\",\"safeTransferFrom(address,address,uint256)\":\"42842e0e\",\"safeTransferFrom(address,address,uint256,bytes)\":\"b88d4fde\",\"setApprovalForAll(address,bool)\":\"a22cb465\",\"supportsInterface(bytes4)\":\"01ffc9a7\",\"symbol()\":\"95d89b41\",\"tokenURI(uint256)\":\"c87b56dd\",\"transferFrom(address,address,uint256)\":\"23b872dd\"},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.34+commit.80d5c536\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Approval\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"ApprovalForAll\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Transfer\\\",\\\"type\\\":\\\"event\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"approve\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"balanceOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"balance\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"getApproved\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"isApprovedForAll\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"name\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"ownerOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"setApprovalForAll\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"bytes4\\\",\\\"name\\\":\\\"interfaceId\\\",\\\"type\\\":\\\"bytes4\\\"}],\\\"name\\\":\\\"supportsInterface\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"symbol\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"tokenURI\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"transferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"See https://eips.ethereum.org/EIPS/eip-721\\\",\\\"events\\\":{\\\"Approval(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\\\"},\\\"ApprovalForAll(address,address,bool)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\\"},\\\"Transfer(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `tokenId` token is transferred from `from` to `to`.\\\"}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"approve(address,uint256)\\\":{\\\"details\\\":\\\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\\\"},\\\"balanceOf(address)\\\":{\\\"details\\\":\\\"Returns the number of tokens in ``owner``'s account.\\\"},\\\"getApproved(uint256)\\\":{\\\"details\\\":\\\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"isApprovedForAll(address,address)\\\":{\\\"details\\\":\\\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\\\"},\\\"name()\\\":{\\\"details\\\":\\\"Returns the token collection name.\\\"},\\\"ownerOf(uint256)\\\":{\\\"details\\\":\\\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"safeTransferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"safeTransferFrom(address,address,uint256,bytes)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"setApprovalForAll(address,bool)\\\":{\\\"details\\\":\\\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\\\"},\\\"supportsInterface(bytes4)\\\":{\\\"details\\\":\\\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\\\"},\\\"symbol()\\\":{\\\"details\\\":\\\"Returns the token collection symbol.\\\"},\\\"tokenURI(uint256)\\\":{\\\"details\\\":\\\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\\"},\\\"transferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\\\"}},\\\"title\\\":\\\"ERC-721 Non-Fungible Token Standard, optional metadata extension\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":\\\"IERC721Metadata\\\"},\\\"evmVersion\\\":\\\"prague\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\\\",\\\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\\\",\\\":forge-std/=lib/forge-std/src/\\\",\\\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\\\",\\\":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\\\"]},\\\"sources\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\\\":{\\\"keccak256\\\":\\\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\\\",\\\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\\\"]},\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":{\\\"keccak256\\\":\\\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\\\",\\\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\\\"]},\\\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\\\":{\\\"keccak256\\\":\\\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\\\",\\\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.34+commit.80d5c536\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Approval\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ApprovalForAll\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Transfer\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"approve\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setApprovalForAll\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferFrom\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"name()\":{\"details\":\"Returns the token collection name.\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the token collection symbol.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\"forge-std/=lib/forge-std/src/\",\"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\"openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"compilationTarget\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":\"IERC721Metadata\"},\"evmVersion\":\"prague\",\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\",\"urls\":[\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\",\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\",\"urls\":[\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\",\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"],\"license\":\"MIT\"}},\"version\":1},\"id\":28}","frontmatter":{"abi":[{"type":"function","name":"approve","inputs":[{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"balanceOf","inputs":[{"name":"owner","type":"address","internalType":"address"}],"outputs":[{"name":"balance","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"getApproved","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"operator","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"isApprovedForAll","inputs":[{"name":"owner","type":"address","internalType":"address"},{"name":"operator","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"ownerOf","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"owner","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"safeTransferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"safeTransferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"setApprovalForAll","inputs":[{"name":"operator","type":"address","internalType":"address"},{"name":"approved","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"supportsInterface","inputs":[{"name":"interfaceId","type":"bytes4","internalType":"bytes4"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"tokenURI","inputs":[{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"view"},{"type":"function","name":"transferFrom","inputs":[{"name":"from","type":"address","internalType":"address"},{"name":"to","type":"address","internalType":"address"},{"name":"tokenId","type":"uint256","internalType":"uint256"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"event","name":"Approval","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false},{"type":"event","name":"ApprovalForAll","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"operator","type":"address","indexed":true,"internalType":"address"},{"name":"approved","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"tokenId","type":"uint256","indexed":true,"internalType":"uint256"}],"anonymous":false}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"approve(address,uint256)":"095ea7b3","balanceOf(address)":"70a08231","getApproved(uint256)":"081812fc","isApprovedForAll(address,address)":"e985e9c5","name()":"06fdde03","ownerOf(uint256)":"6352211e","safeTransferFrom(address,address,uint256)":"42842e0e","safeTransferFrom(address,address,uint256,bytes)":"b88d4fde","setApprovalForAll(address,bool)":"a22cb465","supportsInterface(bytes4)":"01ffc9a7","symbol()":"95d89b41","tokenURI(uint256)":"c87b56dd","transferFrom(address,address,uint256)":"23b872dd"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.34+commit.80d5c536\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"See https://eips.ethereum.org/EIPS/eip-721\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\"},\"ApprovalForAll(address,address,bool)\":{\"details\":\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `tokenId` token is transferred from `from` to `to`.\"}},\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"name()\":{\"details\":\"Returns the token collection name.\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the token collection symbol.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"title\":\"ERC-721 Non-Fungible Token Standard, optional metadata extension\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":\"IERC721Metadata\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\"]},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\",\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\"]},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\",\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\"]},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.34+commit.80d5c536"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"approved","type":"address","indexed":true},{"internalType":"uint256","name":"tokenId","type":"uint256","indexed":true}],"type":"event","name":"Approval","anonymous":false},{"inputs":[{"internalType":"address","name":"owner","type":"address","indexed":true},{"internalType":"address","name":"operator","type":"address","indexed":true},{"internalType":"bool","name":"approved","type":"bool","indexed":false}],"type":"event","name":"ApprovalForAll","anonymous":false},{"inputs":[{"internalType":"address","name":"from","type":"address","indexed":true},{"internalType":"address","name":"to","type":"address","indexed":true},{"internalType":"uint256","name":"tokenId","type":"uint256","indexed":true}],"type":"event","name":"Transfer","anonymous":false},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"approve"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function","name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"getApproved","outputs":[{"internalType":"address","name":"operator","type":"address"}]},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"view","type":"function","name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"name","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"safeTransferFrom"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"nonpayable","type":"function","name":"safeTransferFrom"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"stateMutability":"nonpayable","type":"function","name":"setApprovalForAll"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"stateMutability":"view","type":"function","name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}]},{"inputs":[],"stateMutability":"view","type":"function","name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"view","type":"function","name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}]},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function","name":"transferFrom"}],"devdoc":{"kind":"dev","methods":{"approve(address,uint256)":{"details":"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event."},"balanceOf(address)":{"details":"Returns the number of tokens in ``owner``'s account."},"getApproved(uint256)":{"details":"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist."},"isApprovedForAll(address,address)":{"details":"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}"},"name()":{"details":"Returns the token collection name."},"ownerOf(uint256)":{"details":"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist."},"safeTransferFrom(address,address,uint256)":{"details":"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event."},"safeTransferFrom(address,address,uint256,bytes)":{"details":"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event."},"setApprovalForAll(address,bool)":{"details":"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event."},"supportsInterface(bytes4)":{"details":"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas."},"symbol()":{"details":"Returns the token collection symbol."},"tokenURI(uint256)":{"details":"Returns the Uniform Resource Identifier (URI) for `tokenId` token."},"transferFrom(address,address,uint256)":{"details":"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event."}},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/","erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","forge-std/=lib/forge-std/src/","halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/","openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/"],"optimizer":{"enabled":false,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":"IERC721Metadata"},"evmVersion":"prague","libraries":{}},"sources":{"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol":{"keccak256":"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f","urls":["bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3","dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol":{"keccak256":"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76","urls":["bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e","dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u"],"license":"MIT"},"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol":{"keccak256":"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c","urls":["bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617","dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u"],"license":"MIT"}},"version":1},"id":28},"isInternal":false,"tokens":6169,"sizeBytes":23922},{"name":"package-lock.json","path":"Topics/Tools/TOOL06_Hardhat/package-lock.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL06_Hardhat/package-lock.json","title":"TOOL06_Hardhat Skill","category":"anthropic-skill","format":"json","content":"{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 2,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"tool06_hardhat\",\n      \"version\": \"1.0.0\",\n      \"license\": \"ISC\",\n      \"devDependencies\": {\n        \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n        \"hardhat\": \"^2.22.2\"\n      }\n    },\n    \"node_modules/@adraffy/ens-normalize\": {\n      \"version\": \"1.10.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz\",\n      \"integrity\": \"sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@cspotcode/source-map-support\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@ethersproject/abi\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abi/-/abi-5.7.0.tgz\",\n      \"integrity\": \"sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/hash\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-provider\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz\",\n      \"integrity\": \"sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/networks\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/transactions\": \"^5.7.0\",\n        \"@ethersproject/web\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-signer\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz\",\n      \"integrity\": \"sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-provider\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/address\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/address/-/address-5.7.0.tgz\",\n      \"integrity\": \"sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/base64\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/base64/-/base64-5.7.0.tgz\",\n      \"integrity\": \"sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/bignumber\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz\",\n      \"integrity\": \"sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\"\n      }\n    },\n    \"node_modules/@ethersproject/bytes\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bytes/-/bytes-5.7.0.tgz\",\n      \"integrity\": \"sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/constants\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/constants/-/constants-5.7.0.tgz\",\n      \"integrity\": \"sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/hash\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/hash/-/hash-5.7.0.tgz\",\n      \"integrity\": \"sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-signer\": \"^5.7.0\",\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/keccak256\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz\",\n      \"integrity\": \"sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"js-sha3\": \"0.8.0\"\n      }\n    },\n    \"node_modules/@ethersproject/logger\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/logger/-/logger-5.7.0.tgz\",\n      \"integrity\": \"sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==\",\n      \"dev\": true\n    },\n    \"node_modules/@ethersproject/networks\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/networks/-/networks-5.7.1.tgz\",\n      \"integrity\": \"sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/properties\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/properties/-/properties-5.7.0.tgz\",\n      \"integrity\": \"sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/rlp\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/rlp/-/rlp-5.7.0.tgz\",\n      \"integrity\": \"sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/signing-key\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz\",\n      \"integrity\": \"sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\",\n        \"elliptic\": \"6.5.4\",\n        \"hash.js\": \"1.1.7\"\n      }\n    },\n    \"node_modules/@ethersproject/strings\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/strings/-/strings-5.7.0.tgz\",\n      \"integrity\": \"sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/transactions\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/transactions/-/transactions-5.7.0.tgz\",\n      \"integrity\": \"sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\",\n        \"@ethersproject/signing-key\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/web\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/web/-/web-5.7.1.tgz\",\n      \"integrity\": \"sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@fastify/busboy\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@fastify/busboy/-/busboy-2.1.1.tgz\",\n      \"integrity\": \"sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14\"\n      }\n    },\n    \"node_modules/@jridgewell/resolve-uri\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz\",\n      \"integrity\": \"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz\",\n      \"integrity\": \"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\n      }\n    },\n    \"node_modules/@metamask/eth-sig-util\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz\",\n      \"integrity\": \"sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ethereumjs-abi\": \"^0.6.8\",\n        \"ethereumjs-util\": \"^6.2.1\",\n        \"ethjs-util\": \"^0.1.6\",\n        \"tweetnacl\": \"^1.0.3\",\n        \"tweetnacl-util\": \"^0.15.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12.0.0\"\n      }\n    },\n    \"node_modules/@noble/curves\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/curves/-/curves-1.2.0.tgz\",\n      \"integrity\": \"sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"1.3.2\"\n      }\n    },\n    \"node_modules/@noble/curves/node_modules/@noble/hashes\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.3.2.tgz\",\n      \"integrity\": \"sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 16\"\n      }\n    },\n    \"node_modules/@noble/hashes\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.1.2.tgz\",\n      \"integrity\": \"sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==\",\n      \"dev\": true\n    },\n    \"node_modules/@noble/secp256k1\": {\n      \"version\": \"1.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz\",\n      \"integrity\": \"sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@nodelib/fs.scandir\": {\n      \"version\": \"2.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.stat\": \"2.0.5\",\n        \"run-parallel\": \"^1.1.9\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.stat\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.walk\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.scandir\": \"2.1.5\",\n        \"fastq\": \"^1.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr/-/edr-0.3.2.tgz\",\n      \"integrity\": \"sha512-HGWtjibAK1mo4I2A7nJ/fXqe/J9G54OrSPJnnkY2K8TiXotYLShGd9GvHkae3PuFjTJKm6ZgBy7tveJj5yrCfw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/edr-darwin-arm64\": \"0.3.2\",\n        \"@nomicfoundation/edr-darwin-x64\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-arm64-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-ia32-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-x64-msvc\": \"0.3.2\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-arm64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.2.tgz\",\n      \"integrity\": \"sha512-l6wfSBUUbGJiCENT6272CDI8yoMuf0sZH56H5qz3HnAyVzenkOvmzyF6/lar54m986kdAQqWls4cLvDxiOuLxg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-x64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.2.tgz\",\n      \"integrity\": \"sha512-OboExL7vEw+TRJQl3KkaEKU4K7PTdZPTInZ0fxMAtOpcWp7EKR+dQo68vc/iAOusB3xszHKxt7t+WpisItfdcg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-xtEK+1eg++3pHi6405NDXd80S3CGOFEGQIyVGCwjMGQFOLSzBGGCsrb/0GB4J19zd1o/8ftCd/HjZcbVAWWTLQ==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-3cIsskJOXQ1yEVsImmCacY7O03tUTiWrmd54F05PnPFrDLkjbzodQ3b2gUWzfbzUZWl67ZTJd1CvVSzpe7XGzw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-ouPdphHNsyO7wqwa4hwahC5WqBglK/fIvMmhR/SXNZ9qruIpsA8ZZKIURaHMOv/2h2BbNGcyTX9uEk6+5rK/MQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-sRhwhiPbkpJMOUwXW1FZw9ks6xWyQhIhM0E8o3TXEXKSPKTE6whQLEk1R37iFITaI36vb6rSwLKTU1cb32gCoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-arm64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-IEwVealKfumu1HSSnama26yPuQC/uthRPK5IWtFsQUOGwOXaS1r9Bu7cGYH2jBHl3IT/JbxD4xzPq/2pM9uK0A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-ia32-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-jYMnf6SFgguqROswwdsjJ1wvneD/5c16pVu9OD4DxNqhKNP5bHEw6L2N4DcJ89tpXMpJ6AlOpc0QuwzddiZ3tA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-x64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-Byn4QuWczRy/DUUQM3WjglgX/jGVUURVFaUsmIhnGg//MPlCLawubBGRqsrMuvaYedlIIJ4I2rgKvZlxdgHrqg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-common\": {\n      \"version\": \"4.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz\",\n      \"integrity\": \"sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-rlp\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz\",\n      \"integrity\": \"sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"rlp\": \"bin/rlp.cjs\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz\",\n      \"integrity\": \"sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-common\": \"4.0.4\",\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util\": {\n      \"version\": \"9.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz\",\n      \"integrity\": \"sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-chai-matchers\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz\",\n      \"integrity\": \"sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai-as-promised\": \"^7.1.3\",\n        \"chai-as-promised\": \"^7.1.1\",\n        \"deep-eql\": \"^4.0.1\",\n        \"ordinal\": \"^1.0.3\"\n      },\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-ethers\": {\n      \"version\": \"3.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz\",\n      \"integrity\": \"sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"debug\": \"^4.1.1\",\n        \"lodash.isequal\": \"^4.5.0\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.6.tgz\",\n      \"integrity\": \"sha512-a35iVD4ycF6AoTfllAnKm96IPIzzHpgKX/ep4oKc2bsUKFfMlacWdyntgC/7d5blyCTXfFssgNAvXDZfzNWVGQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"ethereumjs-util\": \"^7.1.4\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.9.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereumjs-util\": {\n      \"version\": \"7.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz\",\n      \"integrity\": \"sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/bn.js\": \"^5.1.0\",\n        \"bn.js\": \"^5.1.2\",\n        \"create-hash\": \"^1.1.2\",\n        \"ethereum-cryptography\": \"^0.1.3\",\n        \"rlp\": \"^2.2.4\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-toolbox\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz\",\n      \"integrity\": \"sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA==\",\n      \"dev\": true,\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-chai-matchers\": \"^2.0.0\",\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"@nomicfoundation/hardhat-network-helpers\": \"^1.0.0\",\n        \"@nomicfoundation/hardhat-verify\": \"^2.0.0\",\n        \"@typechain/ethers-v6\": \"^0.5.0\",\n        \"@typechain/hardhat\": \"^9.0.0\",\n        \"@types/chai\": \"^4.2.0\",\n        \"@types/mocha\": \">=9.1.0\",\n        \"@types/node\": \">=16.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.4.0\",\n        \"hardhat\": \"^2.11.0\",\n        \"hardhat-gas-reporter\": \"^1.0.8\",\n        \"solidity-coverage\": \"^0.8.1\",\n        \"ts-node\": \">=8.0.0\",\n        \"typechain\": \"^8.3.0\",\n        \"typescript\": \">=4.5.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-verify\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.5.tgz\",\n      \"integrity\": \"sha512-Tg4zu8RkWpyADSFIgF4FlJIUEI4VkxcvELsmbJn2OokbvH2SnUrqKmw0BBfDrtvP0hhmx8wsnrRKP5DV/oTyTA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@ethersproject/abi\": \"^5.1.2\",\n        \"@ethersproject/address\": \"^5.0.2\",\n        \"cbor\": \"^8.1.0\",\n        \"chalk\": \"^2.4.2\",\n        \"debug\": \"^4.1.1\",\n        \"lodash.clonedeep\": \"^4.5.0\",\n        \"semver\": \"^6.3.0\",\n        \"table\": \"^6.8.0\",\n        \"undici\": \"^5.14.0\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz\",\n      \"integrity\": \"sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 12\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/solidity-analyzer-darwin-arm64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-darwin-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-freebsd-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-x64-msvc\": \"0.1.1\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz\",\n      \"integrity\": \"sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@scure/base\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/base/-/base-1.1.1.tgz\",\n      \"integrity\": \"sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==\",\n      \"dev\": true\n    },\n    \"node_modules/@scure/bip32\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip32/-/bip32-1.1.0.tgz\",\n      \"integrity\": \"sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@noble/secp256k1\": \"~1.6.0\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@scure/bip39\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip39/-/bip39-1.1.0.tgz\",\n      \"integrity\": \"sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@sentry/core\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/core/-/core-5.30.0.tgz\",\n      \"integrity\": \"sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/hub\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/hub/-/hub-5.30.0.tgz\",\n      \"integrity\": \"sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/minimal\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/minimal/-/minimal-5.30.0.tgz\",\n      \"integrity\": \"sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/node\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/node/-/node-5.30.0.tgz\",\n      \"integrity\": \"sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/core\": \"5.30.0\",\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/tracing\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"cookie\": \"^0.4.1\",\n        \"https-proxy-agent\": \"^5.0.0\",\n        \"lru_map\": \"^0.3.3\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/tracing\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/tracing/-/tracing-5.30.0.tgz\",\n      \"integrity\": \"sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/types\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/types/-/types-5.30.0.tgz\",\n      \"integrity\": \"sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/utils\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/utils/-/utils-5.30.0.tgz\",\n      \"integrity\": \"sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@solidity-parser/parser\": {\n      \"version\": \"0.14.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@solidity-parser/parser/-/parser-0.14.3.tgz\",\n      \"integrity\": \"sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"antlr4ts\": \"^0.5.0-alpha.4\"\n      }\n    },\n    \"node_modules/@tsconfig/node10\": {\n      \"version\": \"1.0.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz\",\n      \"integrity\": \"sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node12\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz\",\n      \"integrity\": \"sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node14\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz\",\n      \"integrity\": \"sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node16\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz\",\n      \"integrity\": \"sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@typechain/ethers-v6\": {\n      \"version\": \"0.5.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz\",\n      \"integrity\": \"sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"lodash\": \"^4.17.15\",\n        \"ts-essentials\": \"^7.0.1\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"6.x\",\n        \"typechain\": \"^8.3.2\",\n        \"typescript\": \">=4.7.0\"\n      }\n    },\n    \"node_modules/@typechain/hardhat\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/hardhat/-/hardhat-9.1.0.tgz\",\n      \"integrity\": \"sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"fs-extra\": \"^9.1.0\"\n      },\n      \"peerDependencies\": {\n        \"@typechain/ethers-v6\": \"^0.5.1\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.9\",\n        \"typechain\": \"^8.3.2\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/fs-extra\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz\",\n      \"integrity\": \"sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"at-least-node\": \"^1.0.0\",\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/jsonfile\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz\",\n      \"integrity\": \"sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"universalify\": \"^2.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"graceful-fs\": \"^4.1.6\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/universalify\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz\",\n      \"integrity\": \"sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      }\n    },\n    \"node_modules/@types/bn.js\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/bn.js/-/bn.js-5.1.1.tgz\",\n      \"integrity\": \"sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/chai\": {\n      \"version\": \"4.3.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai/-/chai-4.3.14.tgz\",\n      \"integrity\": \"sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/chai-as-promised\": {\n      \"version\": \"7.1.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz\",\n      \"integrity\": \"sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai\": \"*\"\n      }\n    },\n    \"node_modules/@types/concat-stream\": {\n      \"version\": \"1.6.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/concat-stream/-/concat-stream-1.6.1.tgz\",\n      \"integrity\": \"sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/form-data\": {\n      \"version\": \"0.0.33\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/form-data/-/form-data-0.0.33.tgz\",\n      \"integrity\": \"sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/glob\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/glob/-/glob-7.2.0.tgz\",\n      \"integrity\": \"sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/minimatch\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/lru-cache\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/lru-cache/-/lru-cache-5.1.1.tgz\",\n      \"integrity\": \"sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/minimatch\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/minimatch/-/minimatch-5.1.2.tgz\",\n      \"integrity\": \"sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/mocha\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/mocha/-/mocha-9.1.1.tgz\",\n      \"integrity\": \"sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"18.15.13\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/node/-/node-18.15.13.tgz\",\n      \"integrity\": \"sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/pbkdf2\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz\",\n      \"integrity\": \"sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/prettier\": {\n      \"version\": \"2.7.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz\",\n      \"integrity\": \"sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/qs\": {\n      \"version\": \"6.9.7\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/qs/-/qs-6.9.7.tgz\",\n      \"integrity\": \"sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/secp256k1\": {\n      \"version\": \"4.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/secp256k1/-/secp256k1-4.0.3.tgz\",\n      \"integrity\": \"sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@ungap/promise-all-settled\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz\",\n      \"integrity\": \"sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsm","isInternal":false,"tokens":19981,"sizeBytes":50000},{"name":"package.json","path":"Topics/Tools/TOOL06_Hardhat/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL06_Hardhat/package.json","title":"tool06_hardhat","category":"anthropic-skill","format":"json","content":"{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"description\": \"我最近在重新学solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用），每周更新1-3讲。\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n    \"hardhat\": \"^2.22.2\"\n  },\n  \"directories\": {\n    \"test\": \"test\"\n  }\n}\n","frontmatter":{"name":"tool06_hardhat","version":"1.0.0","description":"我最近在重新学solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用），每周更新1-3讲。","main":"index.js","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":[],"author":"","license":"ISC","devDependencies":{"@nomicfoundation/hardhat-toolbox":"^4.0.0","hardhat":"^2.22.2"},"directories":{"test":"test"}},"isInternal":false,"tokens":179,"sizeBytes":517},{"name":"run-1666193264.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json","title":"1 Skill","category":"anthropic-skill","format":"json","content":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)","tokens":300,"sizeBytes":280},{"name":"run-1666193265.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json","title":"1 Skill","category":"anthropic-skill","format":"json","content":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)","tokens":300,"sizeBytes":280},{"name":"run-latest.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json","title":"1 Skill","category":"anthropic-skill","format":"json","content":"# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)","tokens":300,"sizeBytes":272},{"name":"package.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json","title":"Forge-std Skill","category":"anthropic-skill","format":"json","content":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)","tokens":300,"sizeBytes":250},{"name":"broadcast.log.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json","title":"Fixtures Skill","category":"anthropic-skill","format":"json","content":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)","tokens":300,"sizeBytes":297},{"name":"better-tires-pull.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md)","tokens":300,"sizeBytes":315},{"name":"blue-jars-lay.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md)","tokens":300,"sizeBytes":307},{"name":"bright-cooks-brush.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md)","tokens":300,"sizeBytes":317},{"name":"config.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json","title":".changeset Skill","category":"anthropic-skill","format":"json","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json)","tokens":300,"sizeBytes":297},{"name":"curly-pandas-flow.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md)","tokens":300,"sizeBytes":315},{"name":"flat-flies-hear.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md)","tokens":300,"sizeBytes":311},{"name":"fruity-coats-smash.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md)","tokens":300,"sizeBytes":317},{"name":"gentle-apples-dance.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md)","tokens":300,"sizeBytes":319},{"name":"happy-pants-decide.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md)","tokens":300,"sizeBytes":317},{"name":"smooth-cows-notice.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md)","tokens":300,"sizeBytes":317},{"name":"spicy-seals-bake.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md)","tokens":300,"sizeBytes":313},{"name":"sweet-houses-cheer.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md)","tokens":300,"sizeBytes":317},{"name":"tangy-jokes-begin.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md)","tokens":300,"sizeBytes":315},{"name":"tidy-turkeys-build.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md","title":".changeset Skill","category":"anthropic-skill","format":"markdown","content":"# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tidy-turkeys-build.md)","tokens":300,"sizeBytes":317},{"name":"bug_report.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md","title":"ISSUE_TEMPLATE Skill","category":"anthropic-skill","format":"markdown","content":"# ISSUE_TEMPLATE Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/bug_report.md)","tokens":300,"sizeBytes":329},{"name":"feature_request.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md","title":"ISSUE_TEMPLATE Skill","category":"anthropic-skill","format":"markdown","content":"# ISSUE_TEMPLATE Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/ISSUE_TEMPLATE/feature_request.md)","tokens":300,"sizeBytes":339},{"name":"PULL_REQUEST_TEMPLATE.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md","title":".github Skill","category":"anthropic-skill","format":"markdown","content":"# .github Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.github/PULL_REQUEST_TEMPLATE.md)","tokens":300,"sizeBytes":314},{"name":"2017-03.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md","title":"Audits Skill","category":"anthropic-skill","format":"markdown","content":"# Audits Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/2017-03.md)","tokens":300,"sizeBytes":283},{"name":"CHANGELOG.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"markdown","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CHANGELOG.md)","tokens":300,"sizeBytes":289},{"name":"CODE_OF_CONDUCT.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"markdown","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CODE_OF_CONDUCT.md)","tokens":300,"sizeBytes":301},{"name":"package.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json","title":"Contracts Skill","category":"anthropic-skill","format":"json","content":"# Contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/contracts/package.json)","tokens":300,"sizeBytes":296},{"name":"CONTRIBUTING.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"markdown","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/CONTRIBUTING.md)","tokens":300,"sizeBytes":295},{"name":"FUNDING.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"json","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/FUNDING.json)","tokens":300,"sizeBytes":289},{"name":"GUIDELINES.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"markdown","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/GUIDELINES.md)","tokens":300,"sizeBytes":291},{"name":"CONTRIBUTING.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md","title":"Forge-std Skill","category":"anthropic-skill","format":"markdown","content":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/CONTRIBUTING.md)","tokens":300,"sizeBytes":310},{"name":"package.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json","title":"Forge-std Skill","category":"anthropic-skill","format":"json","content":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/package.json)","tokens":300,"sizeBytes":304},{"name":"RELEASE_CHECKLIST.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md","title":"Forge-std Skill","category":"anthropic-skill","format":"markdown","content":"# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/RELEASE_CHECKLIST.md)","tokens":300,"sizeBytes":320},{"name":"broadcast.log.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json","title":"Fixtures Skill","category":"anthropic-skill","format":"json","content":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/broadcast.log.json)","tokens":300,"sizeBytes":343},{"name":"test.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json","title":"Fixtures Skill","category":"anthropic-skill","format":"json","content":"# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/test/fixtures/test.json)","tokens":300,"sizeBytes":325},{"name":"package-lock.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"json","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package-lock.json)","tokens":300,"sizeBytes":299},{"name":"package.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"json","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/package.json)","tokens":300,"sizeBytes":289},{"name":"RELEASING.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"markdown","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/RELEASING.md)","tokens":300,"sizeBytes":289},{"name":"renovate.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"json","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/renovate.json)","tokens":300,"sizeBytes":291},{"name":"package.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json","title":"Solhint-custom Skill","category":"anthropic-skill","format":"json","content":"# Solhint-custom Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/solhint-custom/package.json)","tokens":300,"sizeBytes":327},{"name":"SECURITY.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"markdown","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/SECURITY.md)","tokens":300,"sizeBytes":287},{"name":"slither.config.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json","title":"Openzeppelin-contracts Skill","category":"anthropic-skill","format":"json","content":"# Openzeppelin-contracts Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/slither.config.json)","tokens":300,"sizeBytes":303},{"name":"TESTING.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md","title":"Test Skill","category":"anthropic-skill","format":"markdown","content":"# Test Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/TESTING.md)","tokens":300,"sizeBytes":277},{"name":"ecdsa_secp256r1_sha256_p1363_test.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json","title":"Cryptography Skill","category":"anthropic-skill","format":"json","content":"# Cryptography Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json)","tokens":300,"sizeBytes":379},{"name":"package-lock.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json","title":"Hello_wtf Skill","category":"anthropic-skill","format":"json","content":"# Hello_wtf Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)","tokens":300,"sizeBytes":232},{"name":"package.json","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/package.json","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json","title":"Hello_wtf Skill","category":"anthropic-skill","format":"json","content":"# Hello_wtf Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)","tokens":300,"sizeBytes":222},{"name":"readme.md","path":"Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md","title":"en Documentation","category":"plugin-manifest","format":"markdown","content":"# en Documentation\n\nPath: `Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/en/readme.md)","tokens":300,"sizeBytes":239},{"name":"readme.md","path":"Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md","title":"01_tools Documentation","category":"plugin-manifest","format":"markdown","content":"# 01_tools Documentation\n\nPath: `Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Onchain_debug/01_tools/readme.md)","tokens":300,"sizeBytes":239},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md","title":"TOOL01_Remix Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL01_Remix Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL01_Remix/readme.md)","tokens":300,"sizeBytes":235},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md","title":"TOOL02_Infura Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL02_Infura Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL02_Infura/readme.md)","tokens":300,"sizeBytes":238},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md","title":"TOOL03_Ganache Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL03_Ganache Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL03_Ganache/readme.md)","tokens":300,"sizeBytes":241},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md","title":"TOOL04_Alchemy Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL04_Alchemy Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL04_Alchemy/readme.md)","tokens":300,"sizeBytes":241},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md","title":"TOOL05_Dune Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL05_Dune Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL05_Dune/readme.md)","tokens":300,"sizeBytes":232},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md","title":"TOOL06_Hardhat Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL06_Hardhat Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/readme.md)","tokens":300,"sizeBytes":241},{"name":"README.md","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md","title":"forge-std Documentation","category":"plugin-manifest","format":"markdown","content":"# forge-std Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md)","tokens":300,"sizeBytes":284},{"name":"readme.md","path":"Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md","title":"TOOL07_Foundry Documentation","category":"plugin-manifest","format":"markdown","content":"# TOOL07_Foundry Documentation\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/readme.md)","tokens":300,"sizeBytes":241},{"name":"readme.md","path":"Topics/Onchain_debug/01_tools/en/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Onchain_debug/01_tools/en/readme.md","title":"en Documentation","category":"plugin-manifest","format":"markdown","content":"# en Documentation\n\nPath: `Topics/Onchain_debug/01_tools/en/readme.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Onchain_debug/01_tools/en/readme.md)","tokens":300,"sizeBytes":207},{"name":"readme.md","path":"Topics/Onchain_debug/01_tools/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Onchain_debug/01_tools/readme.md","title":"01_tools Documentation","category":"plugin-manifest","format":"markdown","content":"# OnChain Transaction Debugging: 1. Tools\n\nAuthor: [SunSec](https://twitter.com/1nf0s3cpt)\n\n当初我在学习链上交易分析时，很少相关教学文章，只能自己慢慢地收集资料从中挖掘如何分析到测试。我们将推出一系列 Web3 安全的教学文章, 帮助更多人加入 Web3 安全，共创安全网路。\n\n第一个系列我们将介绍如何进行链上分析到撰写攻击重现。此技能将能帮助你分析攻击过程和漏洞原因甚至套利机器人如何套利！\n\n## 工欲善其事，必先利其器\n\n在进入分析之前，我先介绍一些常用工具，正确的工具可以帮助你做研究时更有效率。\n\n### Transaction debugging tools\n\n[Phalcon](https://phalcon.blocksec.com/) | [Ethtx](https://ethtx.info/) | [Tenderly](https://dashboard.tenderly.co/explorer)\n\nTransaction Viewer 这类工具是最常用的，可以帮助我们针对想要分析的交易 Transaction，以可视化列出函数呼叫的流程以及每个函数带入了什么的参数等。\n每个工具大同小异，只差异在链的支援度不同和辅助功能，我个人是比较常用 Phalcon 的 Transaction Viewer，如果遇到不支援的链则会使用 Tenderly，Tenderly 支援最多链，但是可读性就不是这么方便，需要 Debug 慢慢分析。不过我最初在研究链上分析是先学习 Ethtx 和 Tenderly。\n\n#### 链支援度比较\n\nPhalcon： `Ethereum、BSC、Cronos、Avalanche C-Chain、Polygon`\n\nEthtx： `Ethereum、Goerli testnet`\n\nTendery： `Ethereum、Polygon、BSC、Sepolia、Goerli、Gnosis、POA、RSK、Avalanche C-Chain、Arbitrum、Optimism、Fantom、Moonbeam、Moonriver`\n\n#### 实务操作\n\n以 JayPeggers - Insufficient validation + Reentrancy [事件](https://github.com/SunWeb3Sec/DeFiHackLabs/#20221229---jay---insufficient-validation--reentrancy)来当例子 [TXID](https://phalcon.blocksec.com/tx/eth/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n使用 Blocksec 开发的 Phalcon 工具来说明，下图可以看到该交易的基本资讯和余额变化，从余额变化可以快速看出攻击者大概获利多少，以这个例子攻击者获利 15.32 ETH。\n\n![210571234-402d96aa-fe5e-4bc4-becc-190bd5a78e68-2](https://user-images.githubusercontent.com/107249780/210686382-cc02cc6a-b8ec-4cb7-ac19-402cd8ff86f6.png)\n\nInvocation Flow 可视化函数调用流程: 可以让我们知道这一笔交易调用流程和函数呼叫的层级，有没有使用闪电贷、涉及了哪些项目、呼叫了哪些函数带入了什么参数和原始 data 等等\n\n![图片](https://user-images.githubusercontent.com/52526645/210572053-eafdf62a-7ebe-4caa-a905-045e792add2b.png)\n\nPhalcon 2.0 新增了资金流向和 Debug + 源代码分析可以在 Trace 的过程中边看程式执行的片段、参数、返回值，分析上方便了不少。\n\n![image](https://user-images.githubusercontent.com/107249780/210821062-d1da8d1a-9615-4f1f-838d-34f27b9c3f41.png)\n\n换 Sam 的 Transaction Viewer 来看看 [TXID](https://tx.eth.samczsun.com/ethereum/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n跟 Phalcon 类似但 Sam 整合了许多小工具在里面，如下图的眼睛点下去可以看到 Storage 的变化和每个呼叫所消耗的 Gas。\n\n![210574290-790f6129-aa82-4152-b3e1-d21820524a0a-2](https://user-images.githubusercontent.com/107249780/210686653-f964a682-d2a7-4b49-bafc-c9a2b0fa2c55.png)\n\n点击最左边的 Call，可以把原始 Input data 尝试 Decode。\n\n![图片](https://user-images.githubusercontent.com/52526645/210575619-89c8e8de-e2f9-4243-9646-0661b9483913.png)\n\n再来换 Tendery 来看看 [TXID](https://dashboard.tenderly.co/tx/mainnet/0xd4fafa1261f6e4f9c8543228a67caf9d02811e4ad3058a2714323964a8db61f6)\n在 Tendery 介面上，一样可以看到基本资讯，但在 Debug 的部分就不是可视化，需要一步一步 Debug 走下去分析，不过好处是可以边 Debug 边看程式码还有 Input data 的转换过程。\n\n![图片](https://user-images.githubusercontent.com/52526645/210577802-c455545c-80d7-4f35-974a-dadbe59c626e.png)\n\n到这边就可以帮我们厘清大概这笔交易做了哪些事情，在还没有开始写 Poc 时，如果想要快速重放攻击可以吗? 可以! 可以使用Tendery 或 Phalcon，这两个工具另外支援了模拟交易重现，在上图右上角有一个按钮 Re-Simulate，工具会自动帮你带上该交易的参数值如下图\n从图中的栏位可以依照需求任意改变如改block number, From, Value, Input data 等\n\n![图片](https://user-images.githubusercontent.com/52526645/210580340-f2abf864-e540-4881-8482-f28030e5e35b.png)\n\n### Ethereum Signature Database\n\n[4byte](https://www.4byte.directory/) | [etherface](https://www.etherface.io/hash)\n\n在原始 Input data，前面 4bytes 为 Function Signature. 有时遇到 Etherscan 或分析工具无法解出来时，可以透过 Signature Database 来查看看可能是什么 Function。\n\n以下举例假设我们不知道 `0xac9650d8` 是什么 Function\n![图片](https://user-images.githubusercontent.com/52526645/210582149-61a6d973-b458-432f-b586-250c94c3ae24.png)\n\n透过 sig.eth 查询，可以看到这个 4 bytes signature 为 `multicall(bytes[])`\n![图片](https://user-images.githubusercontent.com/52526645/210583416-c31bbe07-fa03-4701-880d-0ae485b171f7.png)\n\n### Useful tools\n\n[ABI to interface](https://gnidan.github.io/abi-to-sol/) | [Get ABI for unverified contracts](https://abi.w1nt3r.xyz/) | [ETH Calldata Decoder](https://apoorvlathey.com/eth-calldata-decoder/) | [ETHCMD - Guess ABI](https://www.ethcmd.com/)\n\nABI to interface: 在开发 Poc 时需要呼叫其他合约时要有 Interface 接口，我们可以透过这个工具帮你快速产生你要的接口。\n先去 Etherscan 把 ABI 复制下来，贴过去工具上就可以看到产生出来的 Interface。\n[例子](https://etherscan.io/address/0xb3da8d6da3ede239ccbf576ca0eaa74d86f0e9d3#code)\n\n![图片](https://user-images.githubusercontent.com/52526645/210587442-e7853d8b-0613-426e-8a27-d70c80e2a42d.png)\n![图片](https://user-images.githubusercontent.com/52526645/210587682-5fb07a01-2b21-41fa-9ed5-e7f45baa0b3e.png)\n\nETH Calldata Decoder: 有时候在没有 ABI 的情况下想要解看看 Input data 可以试试看 ETH Calldata Decoder，在前面介绍到 Sam 的工具就有支援 Input data decode。\n\n![图片](https://user-images.githubusercontent.com/52526645/210585761-efd8b6f1-b901-485f-ae66-efaf9c84869c.png)\n\nGet ABI for unverified contracts: 如果遇到未开源的合约，可以透过这个工具尝试列举出这个合约中存在的 Function Signature.\n[例子](https://abi.w1nt3r.xyz/mainnet/0xaE9C73fd0Fd237c1c6f66FE009d24ce969e98704)\n\n![图片](https://user-images.githubusercontent.com/52526645/210588945-701b0e22-7390-4539-9d2f-e13479b52824.png)\n\n### Decompile tools\n\n[Etherscan-decompile bytecode](https://etherscan.io/address/0xaE9C73fd0Fd237c1c6f66FE009d24ce969e98704#code) | [Dedaub](https://library.dedaub.com/decompile) | [heimdall-rs](https://github.com/Jon-Becker/heimdall-rs)\n\nEtherscan 内建有一个反编译功能但可读性偏差，个人比较常使用 Dedaub，可读性好一点，也是常常最多人DM 问我都使用哪个工具反编译。\n我们拿一个 MEV Bot 被攻击来当[例子](https://twitter.com/1nf0s3cpt/status/1577594615104172033)\n可以自己试试解看看 [例子](https://bscscan.com/address/0x64dd59d6c7f09dc05b472ce5cb961b6e10106e1d#code)\n\n首先把未开源合约的 Bytecodes 复制下来贴到 Dedaub 上，点 Decompile 即可。\n![截图 2023-01-05 上午10 33 15](https://user-images.githubusercontent.com/107249780/210688395-927c6126-b6c1-4c6d-a0c7-a3fea3db9cdb.png)\n\n![图片](https://user-images.githubusercontent.com/52526645/210591478-6fa928f3-455d-42b5-a1ac-6694f97386c2.png)\n\n第一课分享就先到这边，想学更多可以参考以下学习资源。\n\n---\n\n## 学习资源\n\n[samczsun's eth txn explorer and vscode extension](https://www.youtube.com/watch?v=HXgu239mPBc)\n\n[Vulnerabilities in DeFi by Daniel V.F.](https://www.youtube.com/watch?v=9fcOffCg2ig)\n\n[Tenderly.co - Debug Transaction](https://www.youtube.com/watch?v=90GN9Ut8LhU)\n\n[Reversing The EVM: Raw Calldata](https://degatchi.com/articles/reading-raw-evm-calldata)\n\nhttps://web3sec.xrex.io/\n","isInternal":false,"tokens":2952,"sizeBytes":8307},{"name":"readme.md","path":"Topics/Tools/TOOL01_Remix/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL01_Remix/readme.md","title":"TOOL01_Remix Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity极简入门-工具篇1：Remix\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\n`Remix`是以太坊官方推荐的智能合约开发IDE，非常易用。`Remix`让你可以直接在浏览器中快速部署测试智能合约，而不需要安装配置任何程序。这一讲，我们将完整的介绍如何使用`Remix`部署合约，并调用其中的函数。\n\n**Remix官网**：[remix.ethereum.org](https://remix.ethereum.org)\n\n## 1.打开Remix\n![Remix Layout](./img/remix1.png)\n\n打开官网进入`Remix`，我们可以看到Remix由四个面板组成：\n1. 图标面板：上面有代表不同功能的图标，点击后，相应的功能个会显示在侧面版上。\n2. 侧面版：各种功能的 `GUI`。\n3. 主面板：代码编辑器。\n4. 终端：将显示与 `GUI` 交互的结果，也可以在此处运行脚本。\n\n## 2. 图标面板\n![图标面板](./img/remix2.png)\n\n图标面板默认有4个图标，其中`文件`，`编译`，`部署`是最常用的。在你添加更多的`remix`插件后，它们也会显示在图标面板上。\n\n## 3. 部署简单合约\n### i. 选择合约文件\n首先点击`文件`图标，侧面版会变为`文件浏览器`。\n![文件图标](./img/remix3.png)\n\n我们可以在`文件浏览器`中管理我们的workspace，文件夹和文件。\n![文件浏览器](./img/remix4.png)\n\n在`contract`文件夹下面，有三个`remix`自带的合约例子，分别是`1_Storage.sol`, `2_Owner.sol`和`3_Ballot.sol`。\n\n点击`1_Storage.sol`，代码会显示在主面板的代码编辑器上。这个合约非常简单：它一个状态变量`number`，在链上存储一个`uint256`类型的数字；它有两个函数，`store()`函数将一个数字赋值给`number`变量；`retrieve()`展示`number`变量的数值。\n\n### ii. 编译\n接下来，点击`编译`图标，进入`Solidity Compiler`。在这里，我们选择`Solidity 0.8.7`版本，然后点击`Compile 1_Storage.sol`按钮进行编译。在合约成功编译后，`编译`图标上会显示绿色对勾。\n\n![编译](./img/remix5.png)\n\n你也可以尝试在优化中选在优化（`Enable Optimization`），次数设置为`200`，有时会省`gas`消耗。\n\n### iii. 部署\n下一步，我们要把编译好的合约部署到本地虚拟机或链上。首先点击`部署`，进入部署界面。\n\n![部署](./img/remix6.png)\n\n在`ENVIRONMENT`中，我们可以选择我们部署的环境，默认的是`JavaScript VM`，所有交易都在本地浏览器的沙盒区块链中执行，使用的是它给你的虚拟钱包地址；你也可以选择`Injected Web3`，即连接你的`metamask`钱包，所有交易会在真实的区块链中执行。\n\n这里，我们选择`JavaScript VM`，你可以在钱包地址（`ACCOUNT`）栏看到虚拟机给你分配的测试地址。不需要调整`Gas`，也不用往合约里发送`ETH`。在`CONTRACT`栏中选择你要部署的合约`Storage`。`1_Storage.sol`文件中只有一个合约，因此默认就是部署它；但当文件包含多个合约时，我们需要手动选择要部署的合约。\n\n点击`DEPLOY`键，部署完毕！\n\n**注意**：如果我们选择的是`Injected Web3`来部署合约，每一笔交易都将上链，需要钱包确认交易并支付`gas`。\n\n### iv. 调用\n在合约部署成功后，我们可以在`Deployed Contracts`中找到我们部署的合约`Storage`。展开它，我们将看到所有的外部函数：`store`和`retrieve`。\n\n![调用](./img/remix7.png)\n\n我们在`store`函数那行的文本框中输入`100`，并点击函数名调用它。调用成功后，我们可以在终端上看到`log`信息，点击`Debug`按钮可以查看交易详情。\n\n![交易详情](./img/remix8.png)\n\n之后，我们调用`retrieve`函数，显示`number`变量被成功更新为`100`。\n\n![变量被更新为100，调用成功](./img/remix9.png)\n\n## 总结\n\n这一讲，我们介绍了如何使用`Remix`编译，部署并调用智能合约。\n\n","isInternal":false,"tokens":1588,"sizeBytes":4554},{"name":"readme.md","path":"Topics/Tools/TOOL02_Infura/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL02_Infura/readme.md","title":"TOOL02_Infura Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity极简入门-工具篇2：Infura, 连接链下与链上的桥梁\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n`Infura`是Consensys(小狐狸钱包母公司)开发的区块链基础设施，帮助用户/开发者更好的与以太坊区块链交互。\n\n## 连接应用和区块链\n\n![链下链上交互](./img/infura1.png)\n\n在以太坊上开发的Dapp应用（链下）需要与区块链（链上）交互。早期，以太坊上的基础设施很少，开发者需要在本地部署以太坊节点来完成链下和链上的交互，非常麻烦，且耗时数日。\n\n`Infura`在链下、链上之间搭了一座桥，让两者的交互变的简单。它为用户提供对以太坊和IPFS网络的即时、可扩展的`API`访问。开发者在`Infura`官网注册后，就可以免费申请的以太坊`API KEY`，就可以利用`Infura`的节点与区块链交互。另外，小狐狸`metamask`钱包内置了`Infura`服务，方便用户访问以太坊网络。\n\n## 创建`Infura` API Key\n\n### 1. 打开Infura官网并注册\n\n网址：[infura.io](https://infura.io)\n![Infura官网](./img/infura2.png)\n\n### 2. 创建API Key\n注册后，进入控制台Dashboard，并点击右上角的 **CREATE NEW KEY** 按钮。\n\n![创建API Key](./img/infura3.png)\n\n### 3. 填写API Key信息\n\n`NETWORK`选择 **Web3 API (Formerly Ethereum)**，有的版本这里显示的是**Ethereum**，`NAME`随便填一个，我填的`WTF`，之后点击**CREATE**按钮。\n\n![填写信息](./img/infura4.png)\n\n### 4. API Key创建完毕\n\n回到控制台Dashboard，可以看到名为`WTF`的API Key已经创建完毕。在控制台Dashboard，点击  **MANAGE KEY** 按钮，可以查看API Key详情。\n\n\n![API Key创建完毕](./img/infura5.png)\n\n### 5. 查看API Key详情\n\n进入API Key详情页，我们可以看到我们的API Key（图中`184d`开头的一组密钥）。在下面的 **NETWORK ENDPOINT** 栏中，可以查到以太网主网/测试网的rpc节点链接，用于访问链上数据并交互。另外，你可以申请免费的Layer2 rpc节点，包括`Polygon`，`Optimism`和`Arbitrum`，但是需要绑定`visa`卡。领`Optimism`空投那次，公开rpc节点卡爆了，而使用`Infura`的私人rpc节点的人可以正常领取。\n\n![查看信息](./img/infura6.png)\n\n## 使用`Infura` API Key \n### Javascript (`ethers.js`)\n在`ether.js`中，我们可以利用`Infura` API Key来创建`JsonRpcProvider`，与链上交互。\n\n```javascript\nconst { ethers } = require(\"ethers\");\n// 填上你的Infura API Key\nconst INFURA_ID = '' \nconst provider = new ethers.providers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`)\n```\n\n### `MetaMask`小狐狸钱包\n\n进入小狐狸钱包设置 **Setting** 页面，点击网络 **Network**，点击添加网络 **Add Network**。你可以利用下面的参数在小狐狸中添加`Optimism` Layer2链：\n\n```\n网络名称（Network Name）: Optimism\nRPC URL：填在Infura申请的optimism rpc链接\n链ID (Chain ID): 10\n符号 (Chain Symbol): ETH\n区块链浏览器URL (Blockchain Explorer URL): https://optimistic.etherscan.io\n```\n\n![小狐狸配置私人rpc](./img/infura7.png)\n\n## 总结\n\n这一讲，我们介绍了如何创建并使用`Infura` API Key便捷访问以太坊区块链。","isInternal":false,"tokens":1396,"sizeBytes":3856},{"name":"readme.md","path":"Topics/Tools/TOOL03_Ganache/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL03_Ganache/readme.md","title":"TOOL03_Ganache Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity极简入门-工具篇3：Ganache，搭建本地测试网络\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\n`Ganache` 是一个适用于 “开发场景”（或开发过程中的）的 **以太坊区块链网络**，它使开发以太坊应用程序（的工作）更快、更容易、更安全。它包括所有流行的 RPC 功能和特性（如事件），并且可以确定性地运行以使开发变得轻而易举。\n\n> 可以理解 ganache 是一个以太坊区块链“模拟器”，在开发过程中 “模拟” 生产环境、方便的获取合约调用的上下文。\n\n> ⚠️ 注意：**请不要在生产环境中作为区块链网络使用** 如果需要请使用 geth 或 openethereum 等节点应用。\n\n`Ganache` 同时有着 GUI 版本，适合于新手快速配置使用。\n\n## Ganache 的项目设施\n\n- 官网：[https://trufflesuite.com/ganache/](https://trufflesuite.com/ganache/)\n- 文档：[https://trufflesuite.com/docs/ganache/](https://trufflesuite.com/docs/ganache/)\n- Github：\n  - UI: [https://github.com/trufflesuite/ganache-ui](https://github.com/trufflesuite/ganache-ui)\n  - CLI: [https://github.com/trufflesuite/ganache](https://github.com/trufflesuite/ganache)\n  - 旧版（已弃用）: [https://github.com/trufflesuite/ganache-cli](https://github.com/trufflesuite/ganache-cli)\n- 适用于命令行/npm的文档：[https://trufflesuite.com/blog/introducing-ganache-7/](https://trufflesuite.com/blog/introducing-ganache-7/)\n\n\n> ⚠️ 注意：Ganache 的官网中的 Github repo 为UI版本。CLI 版本在 npm 中有 `ganache` & `ganache-cli`，其中 `ganache-cli` 已被弃用。\n\n## 为什么要使用Ganache？\n\nGanache 的主要功能有：\n- 开箱即用，快速启动一个EVM区块链网络（可以设置 miner、出块时间）；\n- 方便的 fork（分叉）已经存在的区块链网络（无需等待区块同步）；\n- [使用 `console.log`](https://github.com/trufflesuite/ganache#consolelog-in-solidity) 在 Solidity 开发过程中方便的调试，；\n- [快进时间（Fast-forward time）](https://trufflesuite.com/blog/introducing-ganache-7/#6-fast-forward-time)，模拟智能合约在未来时间的状态；\n- 模拟任何一个账户（你可以无需私钥模拟环境中使用任意用户的Token）；\n\n有的时候想要实现合约的测试，或者一些合约开发，你需要去测试网领取eth。有时候faucet又没有eth可以领取，这个时候，其实你可以选择自己在本地 fork 一个网络，想要多少eth都可以直接生成。原理是 fork 一个主网的网络运行在本地（或是可以称作运行在本地的 Chain）。\n\nfork主网还有一个好处，你可以直接mock现在主网上的所有环境，比如dex交易所的代币余额等，你知道合约地址，可以直接进行测试和交换使用等。\n\n## 命令行安装（推荐）\n\n[完整包的说明 ganache - npm](https://www.npmjs.com/package/ganache)\n```shell\nnpm install ganache --global\n```\n您也可以单独安装该项至您的项目目录（在不使用 `--global` 的情况下）编写 `package.json` 中的 script 配置启动。  \n在 Ganache 7 后您可以在 node.js 的 Javascript 脚本中引入并直接使用。它将会提供一个 [EIP-1193(Ethereum Provider JavaScript API)](https://eips.ethereum.org/EIPS/eip-1193) provider、一个 JSON-RPC 服务端、Web3.js & ethers provider。同时您也可以在[浏览器中](https://github.com/trufflesuite/ganache#browser-use)使用它。\n\n\n### 启动GANACHE\n\n```shell\nganache\n```\n\n### 帮助 / 说明\n```\nganache --help\n```\n通过帮助，你可以了解 ganache 的主要功能和相关配置方法、参数。这其中包括：\n- **Chain**: 设置网络的版本、ID、时间、合约大小限制、hardfork的版本规则；\n- **Database**: 设置保存链到数据库；\n- **Logging**: 设置 EVM opcodes、RPC 请求和响应的 log；\n- **Miner**: 设置矿工，包括：出块时间、默认的 gas price、Txn gas limit、难度、instamine、价格上涨；\n- **Wallet**: 设置钱包的默认余额、解锁钱包；\n- **Fork**: 分叉（fork）网络的设置包括：fork 目标网络 RPC URL、块高、userAgent、缓存策略，支持提供用户名/密码（如果目标 RPC 存在 Basic Authentication）；\n- **Server**: 设置本地 Chain 的监听地址&端口；\n### Fork 主网启动\n\n以下命令会自动生成10个eth账号，每个账号带有100eth的数量。\n\n```shell\nganache -f https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY\n```\n\n您也可以fork其他以太坊区块链网络，例如 BSC、Polygon、Astar 等，您需要寻找并使用他们的RPC节点。\n\n### Fork主网固定账号启动\n\n`wallet.accounts`主要参数为私钥和需要生成的eth数量。\n\n注意单位为`wei`，案例中换算之后是`1000eth`\n\n```shell\nganache -f https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY --wallet.accounts=ACCOUNT_PRIATE_KEY,AMOUNT_WEI --wallet.accounts=ACCOUNT_PRIATE_KEY,1000000000000000000000\n```\n\n### 推进时间 (Fast Forward time)\n\n需要操纵时间的原因或场景：一些合约锁住了用户的Token，设计了释放周期/时间逐步释放这些被锁住的Token，或者在未来某个特定时间允许用户进行一些操作。\n\nGanache 允许我们通过 RPC 调用（方法 `evm_increaseTime` 和 `evm_setTime` ）来推进区块链上的时间。\n\n大多数情况下我们无法等到这个时间，我们可以使用 `evm_increaseTime` 将区块链当前时间戳**增加指定的时间量**（以秒为单位）（以十六进制格式传入）。这将返回以秒为单位调整的总时间。\n\n```\ncurl -H 'Content-Type: application/json' --data' {\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"evm_increaseTime\", \"params\": [\"0x15180\"] }' http://localhost:8545\n```\n\n此外，您可以使用 `evm_setTime` 将其设置为特定的时间戳；它接受具有毫秒精度的 JavaScript 时间戳，并返回给定时间戳和当前时间之间的秒数。\n\n这里有个在项目中应用的案例（很实用）：[liquity 项目合约测试 - ForwardTime 的功能实现](https://github.com/liquity/dev/blob/0c61ed8b7181450da214d4f10a1327c2082bd4f4/packages/contracts/utils/testHelpers.js#L1104-L1119)\n### 通过GUI使用 Ganache\n不太推荐，如果你是新上手，可以通过这个快速熟悉 Ganache。\n\n[点击下载Ganache - Truffle Suite](https://trufflesuite.com/ganache/)\n\n#### 客户端界面\n![](./img//ganache-7.png)\n\n#### 初始化新建工作空间\n\n![](./img//ganache-8.png)\n\n点击quickstart就可以快速启动，但是快速启动默认的网络端口是 7545，如果你用remix链接的时候需要修改一下。启动完成之后就如下图所示：\n\n![](./img/ganache-9.png)\n\n第一行可以看到你现在的网络`rpc server`, 默认是地址和端口是`127.0.0.1:7545`，如果你在remix中使用默认的，需要把端口改为7545。\n\n\n\n#### remix 链接默认ganache\n\n![](./img/ganache-10.png)\n\n选择环境为 ganache provider，具体端口看你的设置,需要跟ganache的端口一致。\n\n![](./img/ganache-11.png)\n\n端口改为和本地ganache默认一样的`7545`\n\n#### 测试部署一个合约\n\n这里能看到区块里的交易信息，显示我部署了一个合约地址。\n\n![](./img/ganache-12.png)\n\n![](./img/ganache-13.png)\n\n\n#### 自定义配置\n\n有时候你可能需要自定义配置，比如你的网络端口，或者你需要fork主网，你可以在初始化空间的时候配置。\n\n选择`new workspace`\n\n![](./img/ganache-14.png)\n\n\n#### 设置端口和网络ID\n\n端口：可以将默认端口7545改成8545，看你的习惯\n\n![](./img/ganache-15.png)\n\n\n#### fork主网\n\n这里的地址填入你alchemy的主网地址即可\n\n没有的话申请一个 [Alchemy - Blockchain APIs and Node Infrastructure](https://alchemy.com/?r=7ad384cba6732c9d) 或者参考 [Infura, 连接链下与链上的桥梁](https://github.com/AmazingAng/WTF-Solidity/tree/main/Topics/Tools/TOOL02_Infura/readme.md) 申请一个infura的链接。\n\n在chain forking下面的`ENTER CUSTOM URL`里面填入你的eth mainnet地址即可\n\n![](./img/ganache-16.png)\n\n\n#### 设置固定账号和余额\n\n![](./img/ganache-17.png)\n\n最后点击 save workspace 就可以启动啦。\n\n\n## web3js/ethersjs 链接 ganache\nganache生成的本地rpc地址为 `127.0.0.1:8545` UI的默认地址和命令行有区别，所以我上述做了变更。像remix默认使用的就是8454端口\n\n```js\n\n// web3js\n\nconst web3 = new Web3(Web3.givenProvider || \"http://127.0.0.1:8545\");\n\n// ethersjs\nconst provider = new ethers.providers.JsonRpcProvider(\"http://127.0.0.1:8545\");\n\n```\n\n## remix链接本地ganache\n\n把环境链接修改为 ganache即可没，这样你就可以把他部署在你本地的eth网络环境上了。\n\n![](./img/ganache-1.png)\n\n\n### 测试部署合约\n\n这里就将合约部署在了我们本地运行的ganache上。\n\n![](./img/ganache-2.png)\n\n命令行会输出部署的相应细节\n\n![](./img/ganache-3.png)\n\n可以看到部署成功之后，可以方便的调用各种方法\n\n![](./img/ganache-4.png)\n\n### 部署合约，查询v神余额\n\n这个合约写了一个可以查询eth余额的方法，因为我们fork了主网，所以查询一下v神在我们本地测试网络的余额，应该和主网的余额是一样的。\n\n```solidity\n// contracts/GLDToken.sol†\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ncontract XBXToken {\n\n    function getETHBalance(address _address) view external returns(uint256) {\n        return address(_address).balance;\n    }\n\n}\n\n```\n\n[v神主网钱包地址](https://etherscan.io/address/0xab5801a7d398351b8be11c439e05c5b3259aec9b)\n\n![](./img/ganache-5.png)\n\n通过remix调用查看fork之后，本地部署该地址余额\n\n![](./img/ganache-6.png)\n\n本地fork的网络查询v神余额与主网上的余额一致，fork主网测试成功。\n\n## 总结\n\n至此我们就完整fork了一个主网，为下一步做合约开发搭建好了必要的本地环境。","isInternal":false,"tokens":3447,"sizeBytes":10563},{"name":"readme.md","path":"Topics/Tools/TOOL04_Alchemy/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL04_Alchemy/readme.md","title":"TOOL04_Alchemy Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity极简入门-工具篇4：Alchemy, 区块链API和节点基础设施\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n## Alchemy是什么\n\n`Alchemy` 超级节点是 Ethereum、Polygon、Solana、Arbitrum、Optimism、Flow 和 Crypto.org 使用最广泛的区块链 API。获得节点的所有功能，包括 JSON-RPC 支持，但具有在区块链上运行世界级应用程序所需的超强可靠性、数据准确性和可扩展性。\n\n## 连接应用和区块链\n\n在以太坊上开发的Dapp应用（链下）需要与区块链（链上）交互。早期，以太坊上的基础设施很少，开发者需要在本地部署以太坊节点来完成链下和链上的交互，非常麻烦，且耗时数日。\n\n`Alchemy` 和 `Infura`在链下、链上之间搭了一座桥，让两者的交互变的简单。它为用户提供对以太坊和IPFS网络的即时、可扩展的`API`访问。开发者在`Alchemy` 和 `Infura`官网注册后，就可以免费申请的以太坊`API KEY`，就可以利用它们的节点与区块链交互。另外，小狐狸`metamask`钱包内置了`Infura`服务，方便用户访问以太坊网络。\n\n关于`Infura`的介绍，可以参考 [WTF Solidity极简入门-工具篇2：Infura, 连接链下与链上的桥梁](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL02_Infura/readme.md)\n\n## Alchemy 和 Infura 的区别\n\n![Alchemy 和 Infura 的区别](./img/alchemy-1.png)\n\n左边是`alchemy` 右边是 `Infura`，我们来对比下免费的套餐\n\n### 访问量的区别\n\n`Alchemy`每天没有访问限制，`Infura`每天有100,000的访问限制。\n\n`Alchemy`每个月有`300,000,000`的访问量，`Infura`每个月有`3,000,000`的访问量。\n\n\n### 支持公链的区别（免费版本）\n\n![公链的区别](./img/alchemy-2.png)\n\n`Alchemy`支持：ETH、Polygon、Solana、Arbitrum、Optimism\n\n`Infura`支持：ETH、ETH2、IPFS、Filecoin \n\n### Alchemy支持enhanced-apis\n\n![Alchemy支持enhanced-apis](./img/alchemy-3.png)\n\n\nAlchemy自己封装了一些web3的api，大家可以自己看文档获取更多的细节。\n\n[Alchemy - enhanced-apis](https://dashboard.alchemyapi.io/enhanced-apis)\n\n## 创建`Alchemy` API Key\n\n### 1. 打开Alchemy官网并注册\n\n网址：[alchemy.com](https://www.alchemy.com/)\n\n![Alchemy官网](./img/alchemy-4.png)\n\n\n### 2. 创建API Key\n注册后，进入控制台Dashboard，并点击右上角的 **+ CREATE APP** 按钮。\n\n![创建API Key](./img/alchemy-5.png)\n\n\n### 3. 填写API Key信息\n\n`CHAIN`：选择你需要的网络，如果是以太网就是 `Ethereum`。\n\n`NETWORK`:并选择是主网还是测试网。\n\n![填写API Key信息](./img/alchemy-6.png)\n\n填写完成之后点击 `CREATE APP` 即可创建。\n\n### 4. API Key创建完毕\n\n回到控制台Dashboard，可以看到名为`WTFSolidity`的API Key已经创建完毕。在控制台Dashboard，点击  **view key** 按钮，可以查看API Key详情。\n\n![查看api key](./img/alchemy-7.png)\n\n\n### 5. 查看API Key详情\n\n可以看到我们创建好了相应的api key，最常用的https和websockets都支持。\n\n![查看api key 详情](./img/alchemy-8.png)\n\n\n## 使用`Alchemy` API Key \n\n### Javascript (`ethers.js`)\n在`ether.js`中，我们可以利用`Alchemy` API Key来创建`JsonRpcProvider`，与链上交互。\n\n```javascript\nconst { ethers } = require(\"ethers\");\n// 填上你的Alchemy API Key\nconst ALCHEMY_ID = '' \nconst provider = new ethers.providers.JsonRpcProvider(`https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_ID}`)\n```\n\n### `MetaMask`小狐狸钱包\n\n进入小狐狸钱包设置 **Setting** 页面，点击网络 **Network**，点击添加网络 **Add Network**。你可以利用下面的参数在小狐狸中添加`Alchemy` 的eth链：\n\n```\n网络名称（Network Name）: Alchemy-eth\nRPC URL：填在alchemy申请的optimism rpc链接\n链ID (Chain ID): 1\n符号 (Chain Symbol): ETH\n区块链浏览器URL (Blockchain Explorer URL): https://etherscan.io\n```\n\n![小狐狸钱包添加新的网络](./img/alchemy-9.png)\n\n\n## 总结\n\n这一讲，我们介绍了如何创建并使用`Alchemy` API Key便捷访问以太坊区块链。\n","isInternal":false,"tokens":1652,"sizeBytes":4726},{"name":"readme.md","path":"Topics/Tools/TOOL05_Dune/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL05_Dune/readme.md","title":"TOOL05_Dune Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity极简入门-工具篇5：使用Dune可视化区块链数据 \n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n## Dune是什么？\n\n\n`Dune`是区块链查询分析工具，每个人可以通过写类sql语言查询区块链上的所有信息，例如巨鲸，链上交易的数据等等。同时`Dune`能便捷的将数据转换为可视化的图表。\n\n> 以太坊是数据库，智能合约是数据表，来自钱包的交易是每个表中的行。\n\n这句话讲出了区块链的精髓：区块链本质上就是公开的存储数据的分布式账本，现在我们可以通过Dune来查询这个分布式账本的数据。\n\n[Dune官网](https://dune.xyz/)\n\n![dune可视化](./img/1.png)\n\n![dune可视化](./img/2.png)\n\n\n## 第一个查询\n\n目标：查询**过去 24 小时在 Uniswap 上购买的 DAI稳定币**\n\n1. 注册登陆Dune。\n2. 点击右上角**new query**新建查询，输入代码：\n\n    ```sql\n    SELECT\n    SUM(token_a_amount) AS dai_bought\n    FROM\n    dex.\"trades\"\n    WHERE\n    block_time > now() - interval '24 hours'\n    AND token_a_symbol = 'DAI'\n    AND project = 'Uniswap';\n    ```\n3. 点击右下角的**Run**执行查询，得到最近的24h内通过uniswap购买DAI的数量。\n\n![dune sql query](./img/3.png)\n\n\n## 从0开始构建查询\n\n**目标：学会使用 SELECT, WHERE, LIMIT**\n\n我们查询其中一个表，以aave为例：[aave合约](https://etherscan.io/address/0x398ec7346dcd622edc5ae82352f02be94c62d119#writeProxyContract)\n\n通过查询aave这个合约，它有deposit（存储）这个方法，并且有该事件（事件会在执行的时候广播）。\n\n![etherscan](./img/6.png)\n\n回到Dune查找对应的表，根据在Ethereum上搜索aave相关的表，并对应事件,`LendingPool_evt_Deposit`找到该表。\n\n![dune query db table](./img/13.png)\n\n### 学习：SELECT 、 LIMIT、WHERE查询数据\n\n然后我们通过Dune可以查询对应的存储数据\n\n```sql\nSELECT * FROM aave.\"LendingPool_evt_Deposit\"\nlimit 100\n```\n\n![dune query](./img/7.png)\n\n就可以得到aave合约中存储方法的相应数据，通过这个数据可以做一些筛选\n\n#### 各个字段的意义\n\n_user：发起存款的钱包地址\n\n_reserve：作为抵押品存放的代币地址\n\n_amount：存入的代币数量\n\n_timestamp：交易被挖掘到区块链的时间戳\n\n\n#### 使用 WHERE过滤数据\n\n查询过滤特殊的地址`0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`\n\n```sql\nSELECT *, (_amount / 1e18) as _amount FROM aave.\"LendingPool_evt_Deposit\"\nWHERE _reserve = '\\xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee'\nlimit 100\n```\n\n带上了查询条件，能够快速的筛选我们需要的数据\n\n查看抵押品为USDC，USDC合约地址：`xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48`\n\n```sql\nSELECT * FROM aave.\"LendingPool_evt_Deposit\"\nWHERE _reserve = '\\xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'\nlimit 100\n```\n\n以上案例参考 [Your guide to basic SQL while learning Ethereum at the same time](https://towardsdatascience.com/your-guide-to-basic-sql-while-learning-ethereum-at-the-same-time-9eac17a05929)\n\n### 实践链上转账\n\n\n实践`Ethereum.Transactions`表的转账查询\n\n\n```sql\nselect * from ethereum.transactions\nLIMIT 10\n```\n\n![DUNE面板说明](./img/14.png)\n\n### 字段和转账对应说明\n\n看这个[hash](https://etherscan.io/tx/0xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51)转账 \n\n![image-20220314174346876](./img/16.png)\n\n由[0x22fff189c37302c02635322911c3b64f80ce7203](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7?a=0x22fff189c37302c02635322911c3b64f80ce7203) 转账到 [0x8aae242452471d2dfea145214ceedf87ca043198](https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7?a=0x8aae242452471d2dfea145214ceedf87ca043198)\n\nhash：`0xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51`\n\n我们可以直接通过dune查到该条信息\n\n```sql\nselect * from ethereum.transactions\nWHERE hash='\\xfa69f5eb0218f56ae602ef7f01588d9193a891e6fe7ba7e1c3994075a689bb51'\n```\n\n![dune-查询](./img/15.png)\n\ndune中的字段，也是和etherscan中一一对应。\n\n\n\n### 数据可视化\n\n![dune query to visualization](./img/11.png)\n\n点击 New visualization 就可以选择你需要的视图，比如我点击 `bar chart`\n\n![dune visualization](./img/12.png)\n\n就会将我刚才筛选的数据可视化。看最长的几根，就是借贷最多的几个账号。\n\n\n\n## 总结\n\n这一讲，我们介绍了Dune的基础用法。通过Dune，我们能够将链上的数据转换为可视化的数据，更好的了解链上热点。\n","isInternal":false,"tokens":1850,"sizeBytes":5163},{"name":"readme.md","path":"Topics/Tools/TOOL06_Hardhat/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL06_Hardhat/readme.md","title":"TOOL06_Hardhat Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity极简入门-工具篇6：Hardhat以太坊开发环境\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n-----\n\nHardhat是以太坊最流行的开发环境，它可以帮你编译和部署智能合约，并且提供了Hardhat Network支持本地测试和运行Solidity。这一讲，我们将介绍如何安装Hardhat，使用Hardhat编写并编译合约，并运行简单的测试。\n\n## Hardhat安装\n\n### 安装node\n\n可以使用 nvm 安装node\n\n[GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions](https://github.com/nvm-sh/nvm)\n\n### 安装Hardhat\n\n打开命令行工具，输入：\n```shell\nmkdir hardhat-demo\ncd hardhat-demo\nnpm init -y\nnpm install --save-dev hardhat\n```\n\n### 创建Hardhat项目\n打开命令行工具，输入：\n\n```shell\ncd hardhat-demo\nnpx hardhat\n```\n\n选择第三项：创建空白项目配置 `Create an empty hardhat.config.js`\n\n```shell\nWelcome to Hardhat v2.22.2\n\n? What do you want to do? ...\n> Create a JavaScript project\n  Create a TypeScript project\n  Create a TypeScript project (with Viem)\n  Create an empty hardhat.config.js\n  Quit\n```\n\n### 安装插件\n```shell\nnpm install --save-dev @nomicfoundation/hardhat-toolbox\n```\n\n将插件添加到你的hardhat配置文件中 `hardhat.config.js`\n\n```js\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n\n/** @type import('hardhat/config').HardhatUserConfig */\nmodule.exports = {\n  solidity: \"0.8.21\",\n};\n```\n\n## 编写并编译合约\n如果你用过remix，那么你直接在remix上点击保存的时候，会自动帮你编译的。但是在本地的hardhat开发环境中，你需要手动编译合约。\n\n### 新建合约目录\n\n新建`contracts`合约目录，并添加第31章节的ERC20合约。\n\n### 编写合约\n这里的合约直接使用[WTF Solidity第31讲](https://github.com/AmazingAng/WTF-Solidity/blob/main/31_ERC20/readme.md)的ERC20合约\n\n```js\n// SPDX-License-Identifier: MIT\n// WTF Solidity by 0xAA\n\npragma solidity ^0.8.21;\n\nimport \"./IERC20.sol\";\n\ncontract ERC20 is IERC20 {\n\n    mapping(address => uint256) public override balanceOf;\n\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    uint256 public override totalSupply;   // 代币总供给\n\n    string public name;   // 名称\n    string public symbol;  // 符号\n    \n    uint8 public decimals = 18; // 小数位数\n\n    // @dev 在合约部署的时候实现合约名称和符号\n    constructor(string memory name_, string memory symbol_){\n        name = name_;\n        symbol = symbol_;\n    }\n\n    // @dev 实现`transfer`函数，代币转账逻辑\n    function transfer(address recipient, uint amount) external override returns (bool) {\n        balanceOf[msg.sender] -= amount;\n        balanceOf[recipient] += amount;\n        emit Transfer(msg.sender, recipient, amount);\n        return true;\n    }\n\n    // @dev 实现 `approve` 函数, 代币授权逻辑\n    function approve(address spender, uint amount) external override returns (bool) {\n        allowance[msg.sender][spender] = amount;\n        emit Approval(msg.sender, spender, amount);\n        return true;\n    }\n\n    // @dev 实现`transferFrom`函数，代币授权转账逻辑\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint amount\n    ) external override returns (bool) {\n        allowance[sender][msg.sender] -= amount;\n        balanceOf[sender] -= amount;\n        balanceOf[recipient] += amount;\n        emit Transfer(sender, recipient, amount);\n        return true;\n    }\n\n    // @dev 铸造代币，从 `0` 地址转账给 调用者地址\n    function mint(uint amount) external {\n        balanceOf[msg.sender] += amount;\n        totalSupply += amount;\n        emit Transfer(address(0), msg.sender, amount);\n    }\n\n    // @dev 销毁代币，从 调用者地址 转账给  `0` 地址\n    function burn(uint amount) external {\n        balanceOf[msg.sender] -= amount;\n        totalSupply -= amount;\n        emit Transfer(msg.sender, address(0), amount);\n    }\n\n}\n\n```\n\n### 编译合约\n```shell\nnpx hardhat compile\n```\n\n看到如下输出，说明合约编译成功：\n\n```shell\nCompiling 2 Solidity files successfully\n```\n\n成功后，你会在文件夹下看到`artifacts`目录，里面的`json`文件就是编译结果。\n\n## 编写单元测试\n\n这里的单元测试非常简单，仅包含部署合约并测试合约地址是否合法（是否部署成功）。\n\n新建测试文件夹`test`，在其中新建`test.js`。单元测试中，我们会用到`chai`和`ethers.js`两个库，分别用于测试和链上交互。对`ethers.js`不了解的开发者，可以看下[WTF Ethers极简教程](https://github.com/WTFAcademy/WTF-Ethers)的前6讲。我们之后的教程会更详细的介绍`chai`和`mocha`。\n\n```js\nconst { expect } = require('chai');\nconst { ethers } = require('hardhat');\n\n\ndescribe(\"ERC20 合约测试\", ()=>{\n  it(\"合约部署\", async () => {\n     // ethers.getSigners,代表eth账号  ethers 是一个全局函数，可以直接调用\n     const [owner, addr1, addr2] = await ethers.getSigners();\n     // ethers.js 中的 ContractFactory 是用于部署新智能合约的抽象，因此这里的 ERC20 是我们代币合约实例的工厂。ERC20代表contracts 文件夹中的 ERC20.sol 文件\n     const Token = await ethers.getContractFactory(\"ERC20\");\n     // 部署合约, 传入参数 ERC20.sol 中的构造函数参数分别是 name, symbol 这里我们都叫做WTF\n     const hardhatToken = await Token.deploy(\"WTF\", \"WTF\"); \n     await hardhatToken.waitForDeployment();\n      // 获取合约地址\n     const ContractAddress = await hardhatToken.target;\n     expect(ContractAddress).to.properAddress;\n  });\n})\n```\n\n## 运行测试\n\n在命令行输入以下内容运行测试：\n\n```shell\nnpx hardhat test\n# 如果有多个文件想跑指定文件可以使用\nnpx mocha test/test.js\n```\n\n看到如下输出，说明测试成功。\n\n```shell\n  ERC20 合约测试\n    ✔ 合约部署 (1648ms)\n\n\n  1 passing (2s)\n```\n\n## 部署合约\n\n在remix中，我们只需要点击一下`deploy`就可以部署合约了，但是在本地hardhat中，我们需要编写一个部署脚本。\n\n新建一个`scripts`文件夹，我们来编写部署合约脚本。并在该目录下新建一个`deploy.js`\n\n输入以下代码\n\n```js\n// 我们可以通过 npx hardhat run <script> 来运行想要的脚本\n// 这里你可以使用 npx hardhat run deploy.js 来运行\nconst hre = require(\"hardhat\");\n\nasync function main() {\n  const Contract = await hre.ethers.getContractFactory(\"ERC20\");\n  const token = await Contract.deploy(\"WTF\",\"WTF\");\n\n  await token.waitForDeployment();\n\n  console.log(\"成功部署合约:\", token.target);\n}\n\n// 运行脚本\nmain().catch((error) => {\n  console.error(error);\n  process.exitCode = 1;\n});\n\n```\n\n运行以下代码部署合约到本地测试网络\n\nhardhat会提供一个默认的网络，参考：[hardhat默认网络](https://hardhat.org/hardhat-network/docs/overview)\n\n```shell\nnpx hardhat run --network hardhat  scripts/deploy.js\n```\n\n看到如下输出，说明合约部署成功：\n\n```shell\n(node:45779) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n成功部署合约: 0x5FbDB2315678afecb367f032d93F642f64180aa3\n```\n\n## 部署合约到Goerli测试网络 ｜ 网络配置\n\n### 前期准备\n\n1. 申请alchemy的api key\n参考【[第4讲：Alchemy, 区块链API和节点基础设施](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/Tools/TOOL04_Alchemy/readme.md)】 \n2. 申请Goerli测试代币\n[点击申请](https://goerlifaucet.com/) 登录alchemy账号每天可以领取0.2个代币\n3. 导出私钥\n因为需要把合约部署到Goerli测试网络，所以该测试账号中留有一定的测试代币。导出已有测试代币的账户的私钥，用于部署合约\n4. 申请 etherscan 的 api key，用于验证合约\n[点击申请](https://etherscan.io/myapikey)\n\n### 配置网络\n\n在`hardhat.config.js`中，我们可以配置多个网络，这里我们配置`Goerli`测试网络。\n\n\n编辑 `hardhat.config.js`\n\n\n```js\nrequire(\"@nomicfoundation/hardhat-toolbox\");\n\n// 申请alchemy的api key\nconst ALCHEMY_API_KEY = \"KEY\";\n\n//将此私钥替换为测试账号私钥\n//从MetaMask导出您的私钥，打开MetaMask和进入“帐户详细信息”>导出私钥\n//注意:永远不要把真正的以太放入测试帐户\nconst GOERLI_PRIVATE_KEY = \"YOUR GOERLI PRIVATE KEY\";\n\n// 申请etherscan的api key\nconst ETHERSCAN_API_KEY = \"YOUR_ETHERSCAN_API_KEY\";\n\nmodule.exports = {\n  solidity: \"0.8.21\", // solidity的编译版本\n  networks: {\n    goerli: {\n      url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`,\n      accounts: [GOERLI_PRIVATE_KEY]\n    }\n  },\n  etherscan: {\n    apiKey: ETHERSCAN_API_KEY,\n  },\n};\n```\n\n配置完成运行\n\n```shell\nnpx hardhat run --network goerli scripts/deploy.js\n```\n\n你就可以把你的合约部署到Goerli测试网络了。\n\n看到如下信息，你就成功部署到Goerli测试网络了。\n\n```shell\n(node:46996) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n(node:46999) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time\n(Use `node --trace-warnings ...` to show where the warning was created)\n成功部署合约: 0xeEAcef71084Dd1Ae542***9D8F64E3c68e15****\n```\n\n可以通过[etherscan](https://etherscan.io/)查看合约部署情况\n\n同理你也可以配置多个网络，比如`mainnet`，`rinkeby`等。\n\n最后验证你的合约：\n\n```shell\nnpx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS \"Constructor argument 1\"\n```\n\n\n## 总结\n\n这一讲，我们介绍了Hardhat基础用法。通过Hardhat我们能够工程化solidity的项目，并提供了很多有用的脚手架。在后续的文章中，我们会介绍更多的Hardhat的高级用法，例如使用Hardhat的插件、测试框架等等。","isInternal":false,"tokens":3269,"sizeBytes":10721},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md","title":"forge-std Documentation","category":"plugin-manifest","format":"markdown","content":"# forge-std Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/README.md)","tokens":300,"sizeBytes":252},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md","title":"audits Documentation","category":"plugin-manifest","format":"markdown","content":"# audits Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/audits/README.md)","tokens":300,"sizeBytes":289},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md","title":"docs Documentation","category":"plugin-manifest","format":"markdown","content":"# docs Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/docs/README.md)","tokens":300,"sizeBytes":283},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md","title":"fv Documentation","category":"plugin-manifest","format":"markdown","content":"# fv Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/fv/README.md)","tokens":300,"sizeBytes":277},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md","title":"erc4626-tests Documentation","category":"plugin-manifest","format":"markdown","content":"# erc4626-tests Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/erc4626-tests/README.md)","tokens":300,"sizeBytes":318},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md","title":"forge-std Documentation","category":"plugin-manifest","format":"markdown","content":"# forge-std Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/forge-std/README.md)","tokens":300,"sizeBytes":306},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md","title":"halmos-cheatcodes Documentation","category":"plugin-manifest","format":"markdown","content":"# halmos-cheatcodes Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/lib/halmos-cheatcodes/README.md)","tokens":300,"sizeBytes":330},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md","title":"openzeppelin-contracts Documentation","category":"plugin-manifest","format":"markdown","content":"# openzeppelin-contracts Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/README.md)","tokens":300,"sizeBytes":291},{"name":"README.md","path":"Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md","title":"upgradeable Documentation","category":"plugin-manifest","format":"markdown","content":"# upgradeable Documentation\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/scripts/upgradeable/README.md)","tokens":300,"sizeBytes":320},{"name":"readme.md","path":"Topics/Tools/TOOL07_Foundry/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/readme.md","title":"TOOL07_Foundry Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity 极简入门-工具篇 7：Foundry，以 Solidity 为中心的开发工具包\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity 极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy\\_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n---\n\n## 什么是 Foundry?\n来自 Foundry [官网 (getfoundry.sh) ](https://getfoundry.sh) 对该工具的介绍：\n\n> Foundry是 一个用 Rust编写的用于以太坊应用程序开发的极快、可移植和模块化的工具包 ( Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.)\n\n项目设施：\n- 官网：[https://getfoundry.sh](https://getfoundry.sh)\n- Github 仓库：[https://github.com/foundry-rs/foundry](https://github.com/foundry-rs/foundry)\n- 文档：[https://book.getfoundry.sh](https://book.getfoundry.sh)\n\n介绍的解释：\n- **用 Rust 语言编写**： Foundry 完全采用 Rust 语言开发， [Github 上的源代码仓库](https://github.com/foundry-rs/foundry) 是一个 Rust 语言工程。我们可以通过获取 [Release 的二进制文件](https://github.com/foundry-rs/foundry/releases)，也可以通过 Rust 语言的 cargo 包管理[工具编译&构建安装](https://github.com/foundry-rs/foundry#installing-from-source);\n- **用于以太坊应用程序开发**： Foundry 作为 以太坊（Solidity语言）项目/应用程序开发的 “工程化” 工具，提供专业 Solidity 开发环境与“工具链”。**通过它你可以快速、方便的完成依赖项管理、编译、运行测试、部署，并可以通过命令行和 Solidity 脚本与链进行交互**;\n- **极快**： Foundry 利用 [ethers-solc](https://github.com/gakonst/ethers-rs/tree/master/ethers-solc/) 比较于传统通过 Node.js 辅助完成的测试用例/工程，Foundry 构建、测试的执行速度很快（创建一个工程，写一些测试用例跑一下会感受到震撼）;\n- **可移植**: Foundry 工程支持与其他类型的工程集成（如：[与 Hardhat 集成](https://book.getfoundry.sh/config/hardhat)）;\n- **模块化**：通过 git submodule & 构建目录映射，快速方便的引入依赖;\n\n<!--👆TODO: some 🔗 LINKS can be added when our Hardhat tutorial is complete -->\n\n## 为什么选择 Foundry？\n\n如果你满足以下条件或有过类似体验，你一定要试试 Foundry：\n\n- ~~如果你有 Rust “语言信仰”~~，如果你是个专业的 以太坊（Solidity语言）应用开发者；\n- 你曾经用过类似 Hardhat.js 这样的工具；\n- 你厌倦了大量测试用例的等待，需要有工具**更加快速**的跑完你的测试用例；\n- 你觉得处理 BigNumber 稍微有一点点🤏麻烦;\n- 有过**通过 Solidity 语言本身完成测试用例**（或测试合约的合约）的需求；\n- 你觉得通过 git submodule 的方式管理依赖更加方便（而不是 npm）；\n- ···\n\n\n如果有以下情况 Foundry 可能不适合你：\n- Solidity 初学者；\n- 你的项目不需要写测试用例、不需要过多在 Solidity 工程方面的自动化操作；\n\n\n## Foundry 的主要功能\n> 该部分源于 Foundry book ([https://book.getfoundry.sh](https://book.getfoundry.sh))，让章节的理解更容易。\n\n- [创建以太坊（Solidity）智能合约应用开发项目](https://book.getfoundry.sh/projects/creating-a-new-project)，[开发已有的项目](https://book.getfoundry.sh/projects/working-on-an-existing-project);\n- [管理以太坊(Solidity)智能合约的依赖项目](https://book.getfoundry.sh/projects/dependencies);\n- [创建由 Solidity 语言编写的测试用例（并且能很快速的执行测试用例）](https://book.getfoundry.sh/forge/writing-tests): 并且支持[模糊测试](https://book.getfoundry.sh/forge/fuzz-testing)与[差异测试](https://book.getfoundry.sh/forge/differential-ffi-testing)等方便、专业的测试方式;\n- 通过 [Cheatcodes（作弊码）](https://book.getfoundry.sh/forge/cheatcodes) 在 Solidity语言 编写的测试用例中**进行 “EVM环境之外” 的 vm 功能进行交互与断言**：更换测试用例语句执行者的钱包地址（更换 `msg.sender`）、对 EVM 外的 Event 事件进行断言；\n- 执行过程与错误追踪：[“函数堆栈”级的错误追踪（Traces）](https://book.getfoundry.sh/forge/traces)；\n- [部署合约和自动化的完成scan上合约的开源验证](https://book.getfoundry.sh/forge/deploying)；\n- 在项目中支持[完整的gas使用情况追踪](https://book.getfoundry.sh/forge/gas-tracking)：包括合约测试细节的gas用量和gas报告；\n- 交互式[调试器](https://book.getfoundry.sh/forge/debugger)；\n\n## Foundry 的组成\n\nFoundry 项目由 `Forge`, `Cast`, `Anvil` 几个部分（命令行工具）组成\n\n- Forge: Foundry 项目中**执行初始化项目、管理依赖、测试、构建、部署智能合约**的命令行工具;\n- Cast: Foundry 项目中**与 RPC 节点交互**的命令行工具。可以进行智能合约的调用、发送交易数据或检索任何类型的链上数据;\n- Anvil:  Foundry 项目中**启动的本地测试网/节点**的命令行工具。可以使用它配合测试前端应用与部署在该测试网的合约或通过 RPC 进行交互; \n\n## 快速使用 --- 创建一个 Foundry 项目\n\n> 内容出自 Foundry book 的 Getting Start 部分\n\n即将完成的过程：\n1. 安装 Foundry;\n2. 初始化一个 Foundry 项目;\n3. 理解初始化过程中添加的智能合约、测试用例；\n4. 执行构建&测试;\n  \n  \n### 安装 Foundry\n\n对于不同的环境：\n- MacOS / Linux （等 Unix like 系统）：\n  - 通过 `foundryup` 安装（👈Foundry 项目首页推荐的方式）;\n  - 通过 源代码构建 安装;\n- Windows\n  - 通过 源代码构建 安装;\n- Docker 环境\n  - 参考 Foundry Package: [ https://github.com/gakonst/foundry/pkgs/container/foundry](https://github.com/gakonst/foundry/pkgs/container/foundry)\n- Github Action： 用于构建完整的 Action 流程\n  - 参考 [https://github.com/foundry-rs/foundry-toolchain](https://github.com/foundry-rs/foundry-toolchain)\n\n---\n\n#### 通过[脚本](https://raw.githubusercontent.com/foundry-rs/foundry/master/foundryup/install)快速安装\n通过有`bash`的（或者类Unix环境）快速安装\n```shell\n$ curl -L https://foundry.paradigm.xyz | bash\n```\n执行后将会安装 `foundryup`，在此后执行它\n```shell\n$ foundryup\n```\n如果一切顺利，您现在可以使用三个二进制文件：`forge`、`cast` 和 `anvil`。\n\n\n<!--\n\n---\n\n#### [通过源代码构建安装（需要你了解一点 Rust 环境）](https://book.getfoundry.sh/getting-started/installation#building-from-source)\n\n要从源代码构建，您需要获取 `Rust` 和 `Cargo`。获得两者的最简单方法是使用 `rustup`。\n\n```shell\n# clone 项目目录至本地\ngit clone https://github.com/foundry-rs/foundry\n\n# 进入项目目录\ncd foundry\n\n# 安装 cast + forge\ncargo install --path ./cli --profile local --bins --locked --force\n\n# 安装 anvil\ncargo install --path ./anvil --profile local --locked --force\n```\n-->\n### 初始化一个 Foundry 项目\n\n通过 `forge` 的 `forge init` 初始化项目 \"hello_wtf\"\n```shell\n$ forge init hello_wtf\n\nInitializing /Users/username/hello_wtf...\nInstalling forge-std in \"/Users/username/hello_wtf/lib/forge-std\" (url: Some(\"https://github.com/foundry-rs/forge-std\"), tag: None)\n    Installed forge-std\n    Initialized forge project.\n```\n该过程通过安装依赖`forge-std`初始化了一个 Foundry 项目\n\n在项目目录中看到\n\n```shell\n$ tree -L 2 \n.\n├── foundry.toml        # Foundry 的 package 配置文件\n├── lib                 # Foundry 的依赖库\n│   └── forge-std       # 工具 forge 的基础依赖\n├── script              # Foundry 的脚本\n│   └── Counter.s.sol   # 示例合约 Counter 的脚本\n├── src                 # 智能合约的业务逻辑、源代码将会放在这里\n│   └── Counter.sol     # 示例合约\n└── test                # 测试用例目录\n    └── Counter.t.sol   # 示例合约的测试用例\n```\n提示：\n- 依赖项作为 git submodule 在 `./lib` 目录中\n- 关于 Foundry 的 package 配置文件请详细参考: [https://github.com/foundry-rs/foundry/blob/master/config/README.md#all-options](https://github.com/foundry-rs/foundry/blob/master/config/README.md#all-options)\n\n\n### 理解初始化过程中添加的智能合约、测试用例\n\n#### src 目录\n\n主要由业务逻辑构成\n`src` 目录中的 `./src/Counter.sol`:\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {          // 一个很简单的 Counter 合约\n    uint256 public number;  // 维护一个 public 的 uint256 数字\n\n    // 设置 number 变量的内容\n    function setNumber(uint256 newNumber) public { \n        number = newNumber;\n    }\n\n    // 让 number 变量的内容自增\n    function increment() public {\n        number++;\n    }\n}\n```\n\n#### script 目录\n\n参考 Foundry 项目文档中的 [Solidity-scripting](https://book.getfoundry.sh/tutorials/solidity-scripting) 该目录主要由“部署”脚本构成（也可通过该脚本调用 Foundry 提供的 `vm` 功能实现应用业务逻辑之外的高级功能，等同于 Hardhat.js 中的 scripts）。\n\n详见script 目录中的 `./script/Counter.s.sol`：\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13; // 许可 和 Solidity版本标识\n\nimport \"forge-std/Script.sol\"; // 引入foundry forge中的Script库\nimport \"../src/Counter.sol\"; // 引入要部署的Counter合约\n\n// 部署脚本继承了Script合约\ncontract CounterScript is Script {\n    // 可选函数，在每个函数运行之前被调用\n    function setUp() public {}\n\n    // 部署合约时会调用run()函数\n    function run() public {\n        vm.startBroadcast(); // 开始记录脚本中合约的调用和创建\n        new Counter(); // 创建合约\n        vm.stopBroadcast(); // 结束记录\n    }\n}\n```\n\nFoundry的部署脚本是一个用Solidity写的智能合约，虽然它不会被部署，但符合Solidity的规范。你可以用`forge script`运行脚本并部署合约。\n\n```shell\nforge script script/Counter.s.sol:CounterScript\n```\n\n\n#### test 目录\n\n主要由合约的测试用例构成\n\ntest 目录中的 `./test/Counter.t.sol`\n\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";        // 引入 forge-std 中用于测试的依赖\nimport \"../src/Counter.sol\";        // 引入用于测试的业务合约\n\n// 基于 forge-std 的 test 合约依赖实现测试用例\ncontract CounterTest is Test {      \n    Counter public counter;\n\n    // 初始化测试用例\n    function setUp() public { \n       counter = new Counter();\n       counter.setNumber(0);\n    }\n\n    // 基于初始化测试用例\n    // 断言测试自增后的 counter 的 number 返回值 同等于 1\n    function testIncrement() public {\n        counter.increment();\n        assertEq(counter.number(), 1);\n    }\n\n    // 基于初始化测试用例\n    // 执行差异测试测试\n    // forge 测试的过程中\n    // 为 testSetNumber 函数参数传递不同的 unit256 类型的 x\n    // 达到测试 counter 的 setNumber 函数 为不同的 x 设置不同的数\n    // 断言 number() 的返回值等同于差异测试的 x 参数\n    function testSetNumber(uint256 x) public {\n        counter.setNumber(x);\n        assertEq(counter.number(), x);\n    }\n\n    // 差异测试：参考 https://book.getfoundry.sh/forge/differential-ffi-testing\n}\n```\n\n### 执行构建&测试\n\n在项目目录中通过执行 `forge build` 完成构建\n```shell\n$ forge build\n\n[⠒] Compiling...\n[⠢] Compiling 10 files with 0.8.17\n[⠰] Solc 0.8.17 finished in 1.06s\nCompiler run successful\n```\n\n完成构建后 通过 `forge test` 完成测试\n```shell\n$ forge test\n\n[⠢] Compiling...\nNo files changed, compilation skipped\n\nRunning 2 tests for test/Counter.t.sol:CounterTest\n[PASS] testIncrement() (gas: 28312)\n[PASS] testSetNumber(uint256) (runs: 256, μ: 27609, ~: 28387)\nTest result: ok. 2 passed; 0 failed; finished in 9.98ms\n```\n\n至此，您已完成上手使用 Foundry 并且初始化一个项目。\n\n<!--\n\n  TODO: For foundry advanced usage ...\n\n  We need cover: \n  \n  - cli forge `test` : reference https://book.getfoundry.sh/forge/writing-tests\n  - cheatcode.\n  - Logs and traces levels.\n\n... etc.\n\n-->\n\n\n\n## Foundry Cast的进阶使用\n主要介绍Foundry Cast的使用，使用Cast在命令行下达到[Ethereum (ETH) Blockchain Explorer](https://etherscan.io/) 的效果。\n\n练习如下目标\n* 查询区块\n* 查询交易\n* 交易解析\n* 账户管理\n* 合约查询\n* 合约交互\n* 编码解析\n* 本地模拟链上交易\n\n\n\n## 区块相关\n\n### 查询区块\n\n```shell\n# $RPC_MAIN 替换成需要的RPC地址\ncast block-number --rpc-url=$RPC_MAIN\n```\n\n输出结果：\n\n```\n15769241\n```\n> 将环境变量的ETH_RPC_URL设置为 --rpc-url 你就不需要在每个命令行后面增加 --rpc-url=$RPC_MAIN 我这里直接设置为主网\n\n### 查询区块信息\n\n```shell\n# cast block <BLOCK> --rpc-url=$RPC_MAIN\n\ncast block 15769241 --rpc-url=$RPC_MAIN\n\n# 格式化\n\ncast block 15769241 --json --rpc-url=$RPC_MAIN\n\n\n```\n\n输出结果：\n\n```shell \nbaseFeePerGas        22188748210\ndifficulty           0\nextraData            0x\ngasLimit             30000000\ngasUsed              10595142\nhash                 0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nlogsBloom            0x1c6150404140580410990400a61d01e30030b00100c2a6310b11b9405d012980125671129881101011501d399081855523a106443aef3ab07148626315f721550290981058030b2af90b213961204c6103d2002a076c9e12d0800475b8231f0d06a20100da57c60aa0c008280128284418503340087c8650104c34500c18aa1c2070878008c21c64207d1424000244811415afc507640448122060644c181204ba412f0af11365020880508105551226004c0801c1840183003a42062a5a2444c13266020c00081440008038492740a8204a0c6c050a29d52405b92e4b20f028a97a604c6b0849ca81c4d06009258b4206217803a168824484deb8513242f082\nminer                0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263\nmixHash              0x09b7a94ef1d6c93caaff49ca8bf387652e0e33e116076b61f4d5ee79f0b91f92\nnonce                0x0000000000000000\nnumber               15769241\nparentHash           0x95c60d89f2275a6a7b1a9545cf1fb6d8c614402cd7311c82bc7972c177f7812d\nreceiptsRoot         0xe0240d60c448387123e412114cd0165b2af7b926d34bb824f8c544b022aa76f9\nsealFields           []\nsha3Uncles           0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\nsize                 149912\nstateRoot            0xaa3e9d839e99c4791827c81df9c9129028a320432920205f191e3fb261d0951c\ntimestamp            1666026803\ntotalDifficulty      58750003716598352816469\ntransactions:        [\n\t0xc4f5c10e4419698edaf7431df464340b389e4b79db959d58f42e82e8d1ed18ae\n\t0xb90edeacf833ac6cb91a326c775ed86d8047a467404bd8c69782d2260983eaad\n\t0x6f280650e35238ab930c9a0f3163443fffe2efedc5b553f408174d4bcd89cd8d\n\t0x2e0eafea64aaf2f53240a16b11a4f250ba74ab9ca5a1a90e6f2a6e92185877d2\n\t0x34f41d22ed8209da379691640cec5bfb8bf9404ad0f7264709b7959d61532343\n\t0x7569ab5ce2d1ca13a0c65ad52cc901dfc186e8ff8800793550b97760cbe34db2\n\t0xcdeef0ffe859fcf96fb52e22a9789295c6f1a94280df9faf0ebb9d52abefb3e7\n\t0x00d6793f3dbdd616351441b9e3da9a0de51370174e0d9383b4aae5c3c9806c2a\n\t0xff3daf63a431af021351d3da5f2f39a894352328d7f3df96afab1888f5a7093f\n\t0x7938399bee5293c384831c8e5aa698cdb491d568f9ebfb6d5c946f4ef7bf7e51\n\t0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\n\t0x0435d78a1b62484fbe3a7680d68ba4bdf0d692f087f4a6b70eb377421c58a5dd\n\t0xe16d1fa4d60cca7447850337c63cdf7b888318cc1bbb893b115f262dc01132d7\n\t0x44af4f696dcfedee682d7e511ad2469780443052565eea731b86b652a175c05e\n\t0xe88732f92ac376efb6e7517e66fc586447e0d065b8686556f2c1a7c3b7a519ce\n\t0x7ee890b096e97fc0c7e3cf74e0f0402532e0f3b8fa0e0c494d3d691d031f57e7\n\t...]\n```\n\n## 交易相关\n\n### 查询交易\n\n```shell\n# 跟ethersjs中的 provider.getTransaction 类似\n# cast tx <HASH> [FIELD] --rpc-url=$RPC\n\n# 跟ethersjs中的 provider.getTransactionReceipt类似\n# cast receipt <HASH> [FIELD] --rpc-url=$RPC \n\ncast tx 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 --rpc-url=$RPC \n\ncast receipt 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 --rpc-url=$RPC\n\n# 只获取logs\n\ncast receipt 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 logs --rpc-url=$RPC\n\n```\n\n第一条命令行结果：\n\n```shell\nblockHash            0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nblockNumber          15769241\nfrom                 0x9C0649d7325990D98375F7864eA167B5EAdCD46a\ngas                  313863\ngasPrice             35000000000\nhash                 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\ninput                0x38ed173900000000000000000000000000000000000000000000000332ca1b67940c000000000000000000000000000000000000000000000000000416b4849e6ba1475000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a00000000000000000000000000000000000000000000000000000000634d91c1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\nnonce                14\nr                    0x288aef25af73a4d1916f8d37107ef5f24729a423f23acc38920829c4180fe794\ns                    0x7644d26a91da02ff1e774cc821febf6387b8ee9f3e3085140b781819d0d8ede0\nto                   0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D\ntransactionIndex     10\nv                    38\nvalue                0\n```\n\n第二行命令行结果：\n\n```shell\nblockHash               0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\nblockNumber             15769241\ncontractAddress\ncumulativeGasUsed       805082\neffectiveGasPrice       35000000000\ngasUsed                 114938\nlogs                    [{\"address\":\"0x97be09f2523b39b835da9ea3857cfa1d3c660cbb\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\"],\"data\":\"0x00000000000000000000000000000000000000000000000332ca1b67940c0000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x2\",\"removed\":false},{\"address\":\"0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb\",\"topics\":[\"0x06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x0000000000000000000000000000000000000000000000044b0a580cbdcfc0d90000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x3\",\"removed\":false},{\"address\":\"0x1bbf25e71ec48b84d773809b4ba55b6f4be946fb\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x000000000000000000000000f848e97469538830b0b147152524184a255b9106\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x0000000000000000000000000000000000000000000000044b0a580cbdcfc0d9\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x4\",\"removed\":false},{\"address\":\"0xf848e97469538830b0b147152524184a255b9106\",\"topics\":[\"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1\"],\"data\":\"0x00000000000000000000000000000000000000000000213ebfba613ffdcdd6ad0000000000000000000000000000000000000000000018b4b7f855bdcaac3b14\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x5\",\"removed\":false},{\"address\":\"0xf848e97469538830b0b147152524184a255b9106\",\"topics\":[\"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822\",\"0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d\",\"0x0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\"],\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000332ca1b67940c00000000000000000000000000000000000000000000000000044b0a580cbdcfc0d90000000000000000000000000000000000000000000000000000000000000000\",\"blockHash\":\"0x016e71f4130bac96a20761acbc0ba82a77c26f85513f1661adfd406d1c809543\",\"blockNumber\":\"0xf09e99\",\"transactionHash\":\"0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\",\"transactionIndex\":\"0xa\",\"logIndex\":\"0x6\",\"removed\":false}]\nlogsBloom               0x00200000000000000000000080000000000000000000000000010000000008000000000000800000000000000000000000000000002000000000000000000000000000000000000000000008000000200000000000000000000000400000100000000000800000002000000000000000000000400000000000000010000000000000000000000000005000000000040000000000000000080000004004000000000000084100000000000000000000000000000040000000000000000000040000000002000000000000000000000000000000000000001000002000000020000000000000000000000000000000000000004000000000000000000000000000\nroot\nstatus                  1\ntransactionHash         0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\ntransactionIndex        10\ntype                    0\n\n```\n\n### 交易解析\n\nCast 会从 [Ethereum Signature Database](https://sig.eth.samczsun.com.) 解析对应的方法名称\n\n```shell\n# cast 4byte <SELECTOR> 解析交易的名称\ncast 4byte 0x38ed1739\n```\n\n输出结果：\n\n```shell\nswapExactTokensForTokens(uint256,uint256,address[],address,uint256)\n```\n\n### 交易签名 \n\n> 使用 Keccak-256 能够计算出方法名\n> 函数名为被调函数原型[1]的Keccak-256哈希值的前4个字节。这允许EVM准确无误地识别被调函数。\n\n交易签名：\n\n```shell\n# cast sig <SIG>\n\ncast sig \"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)\"\n\n```\n\n输出结果：\n\n```shell\n0x38ed1739\n```\n\n所以你可以看到最终都是 `0x38ed1739`\n\n有些方法名称可能没有，你可以通过`cast upload-signature <SIG> `上传给 [Ethereum Signature Database](https://sig.eth.samczsun.com) \n\n### 交易解码\n\n```shell\n# 获得calldata\ncast tx 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0 input --rpc-url=$RPC\n\n# 可以通过该方法decode交易的数据，类似etherscan中的decode方法\n# cast pretty-calldata <CALLDATA>\ncast pretty-calldata 0x38ed173900000000000000000000000000000000000000000000000332ca1b67940c000000000000000000000000000000000000000000000000000416b4849e6ba1475000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a00000000000000000000000000000000000000000000000000000000634d91c1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\n```\n\n输出结果：\n\n```shell\n Possible methods:\n - swapExactTokensForTokens(uint256,uint256,address[],address,uint256)\n ------------\n [0]:  00000000000000000000000000000000000000000000000332ca1b67940c0000\n [1]:  00000000000000000000000000000000000000000000000416b4849e6ba14750\n [2]:  00000000000000000000000000000000000000000000000000000000000000a0\n [3]:  0000000000000000000000009c0649d7325990d98375f7864ea167b5eadcd46a\n [4]:  00000000000000000000000000000000000000000000000000000000634d91c1\n [5]:  0000000000000000000000000000000000000000000000000000000000000002\n [6]:  00000000000000000000000097be09f2523b39b835da9ea3857cfa1d3c660cbb\n [7]:  0000000000000000000000001bbf25e71ec48b84d773809b4ba55b6f4be946fb\n```\n\n### 模拟运行\n\n```\n# Usage: cast run --rpc-url <URL> <TXHASH>\n\ncast run 0x20e7dda515f04ea6a787f68689e27bcadbba914184da5336204f3f36771f59f0\n```\n\n运行结果：\n\n![cast-run](./img/1.png)\n\n可以在结果中看到运行消耗的gas，以及方法顺序调用的过程，以及释放的emit的事件。通过这个可以了解一个hash的内在过程。类似 [BlockSec Building BlockChain Security Infrastructure](https://blocksec.com/) 和 [Tenderly | Ethereum Developer Platform](https://tenderly.co/) 可以结合使用。\n\n## 账户管理\n\n### 新建账户\n\n```shell\n# 新建一个账号\n# cast wallet new [OUT_DIR] \ncast wallet new\n\n# 新建一个keystore的账号，带有密码\n# cast wallet new <PATH>\ncast wallet new  ~/Downloads\n```\n\n第一条命令行结果输出：\n\n```shell\nSuccessfully created new key pair.\nAddress: 0xDD20b18E001A80d8b27B8Caa94EeAC884D1c****\nPrivate Key: edb4444199bddea91879c0214af27c0c7f99****bf18e46ba4078a39ccdbe0bc\n```\n\n第二条命令行结果输出：\n\n```shell\nEnter secret:\nCreated new encrypted keystore file: `/Users/EasyPlux/Downloads/b5832df5-21e9-4959-8c85-969eec9c0***`\\nPublic Address of the key: 0x58c1C8f6A7D92A9b20A5343949cd624570Ab****\n```\n\n### 账户签名\n\n```shell\n# 两种方法都可以使用签名，第一种载入刚才生成的keystore私钥，第二种直接输入自己的私钥。\ncast wallet sign <MESSAGE> --keystore=<PATH> \ncast wallet sign <MESSAGE> -i\n```\n\n### 账户验证\n\n```shell\ncast wallet verify --address <ADDRESS> <MESSAGE> <SIGNATURE> \n```\n\n## 合约交互\n\n### 获取合约\n\n```shell\ncast etherscan-source <contract address>\n\ncast etherscan-source 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --etherscan-api-key='key'\n\n```\n\n### 下载合约\n\n```shell\n#cast etherscan-source -d <path>\n# 我这里已经将$WETH的地址写入环境变量，如果没写入的，可以写成合约地址\ncast etherscan-source $WETH -d ~/Downloads\n```\n\n### 调用合约(读数据)\n\n`cast call` 用于从区块链上读取数据（调用只读函数），该操作不会改变区块链状态，也不需要支付 Gas 费用。下面我们调用 `WETH` 合约的`balanceOf`方法,查看 `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2` 账号的余额\n\n```shell\n#cast call [OPTIONS] [TO] [SIG] [ARGS]... [COMMAND] --rpc-url=$RPC\n\ncast call $WETH \"balanceOf(address)\" 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url=$RPC\n\n# 输出\n# 0x0000000000000000000000000000000000000000000000230d12770f2845219c\n\n# 格式化输出 在参数后面加一个返回值的格式\n\ncast call $WETH \"balanceOf(address)(uint256)\" 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 --rpc-url=$RPC\n\n# 输出\n# 646577988758891995548\n\n```\n\n### 调用合约(写数据)\n\n`cast send` 用于发送交易并修改区块链状态（调用改变状态的函数），该操作会消耗 Gas 费用，需要签名并发送交易。\n\n```shell\n#cast send [OPTIONS] [TO] [SIG] [ARGS]... [COMMAND] --rpc-url=$RPC\n\ncast send 0x... \"deposit(address,uint256)\" 0x... 1 --rpc-url=$RPC\n\n```\n\n\n### 解析ABI\n\n可以根据ABI反向解析出solidity代码\n```shell\n# cast interface [OPTIONS] <PATH_OR_ADDRESS>\ncast interface ./weth.abi\n```\n\n## 编码解码\n\n```shell\ncast --to-hex \n\ncast --to-dec \n\ncast --to-unit \n\ncast --to-wei \n\ncast --to-rlp \n\ncast --from-rlp\n\n```\n\n## Tips\n\n### 设置ETH_RPC_URL\n将环境变量的`ETH_RPC_URL`设置为 `--rpc-url`的值，这样你就不需要在每个命令行后面增加 `--rpc-url=$RPC_MAIN`，我这里直接设置为主网，如下：\n``` shell\nexport ETH_RPC_URL=your_rpc_url\nsource ~/.bashrc  # 如果你使用的是 Bash\nsource ~/.zshrc   # 如果你使用的是 Zsh\ncast block-number # 不用再配置 --rpc-url 参数\n```\n\n### 设置ETHERSCAN_API_KEY\n设置`ETHERSCAN_API_KEY`环境变量可以直接代替 `--etherscan-api-key`\n\n### JSON格式化\n\n加上 `--json`  可以格式化输出\n\n```shell\ncast block 15769241 --json --rpc-url=$RPC_MAIN\n```\n\n## Anvil本地节点的使用\n\n### 基本命令行\n\nanvil 跟 hardhat 还有 truffle中的ganache都是一样的，是一个本地的eth节点，同样拥有各种fork的功能。\n\n```shell\nanvil \nanvil --accounts=<NUM> --balance=<NUM> \nanvil --mnemonic=<MNEMONIC> \nanvil --fork-url=$RPC --fork-block-number=<BLOCK>\n```\n\n### RPC的使用\n\n```shell\nanvil_* -> hardhat_* \n\nanvil_impersonateAccount \n\nanvil_setStorageAt\n```\n\n## Forge命令行进阶的使用\n\n代码存放在`WTFSolidity/Topics/Tools/TOOL07_Foundry/hello_wtf`\n\n代码目录树如下：\n\n```shell\n.\n├── broadcast\n│   └── Counter.s.sol \n├── foundry.toml        # foundry配置文件\n├── lib\n│   └── forge-std\n├── node_modules        # 使用npm依赖包目录，你也可以直接使用forge install\n│   └── @openzeppelin\n├── package-lock.json\n├── package.json\n├── script\n│   └── Counter.s.sol   # 脚本合约\n├── src\n│   └── Counter.sol\n└── test\n    ├── Counter.t.sol\n    └── Test.t.sol      # 测试合约\n```\n\n### 初始化项目\n```shell\n\nforge init <dir_name> \n\n# 使用模板初始化项目\nforge init --template <template_path> <dir_name>\n\n```\n\n## 热更新\n\n```shell\nforge build -w\n```\n\n\n### 测试\n\n```shell\n# 三个v会现实详细的log信息，还显示失败测试的堆栈跟踪\nforge test -vvv\n# 四个v显示所有测试的堆栈跟踪，并显示失败测试的设置（setup）跟踪。\nforge test -vvvv\n# 热更新模式\nforge test -vvv -w\n\n# log打印 需要 - vv 2个v以上才可以\n```\n\n使用 console2.log(\"test\") 来打印\n\n```js\n\n\nfunction testSetNumber(uint256 x) public {\n        console2.log(\"testNumber: %s==============\", x);\n        counter.setNumber(x);\n        assertEq(counter.number(), x);\n    }\n```\n\n\n使用 emit log 来打印\n\n```js\nfunction testNumberIs42() public {\n        emit log(\"test\");\n        assertEq(testNumber, 42);\n    }\n```\n\n改变 block.timestamp\n\n```js\n\nfunction testCheatCode()public {\n  console2.Log(\"before:\"block.timestamp);\n  vm.warp(1000);\n  console2.log(\"after:\"block.timestamp);\n}\n\n```\n\n改变msg.sender 【可以模拟管理员账户】\n\n```js\n// 只有第一次有影响\nvm.prank(address)\n\n\n// 多次影响\nvm.startPrank(address)\n...code\nvm.stopPrank()\n\n```\n\n\n改变账户余额（也可以用于改变大多数ERC20代币余额）\n\n```js\nfunction testCheatCode()public{\n\tconsole2.Log(\"before:\"alice.balance);\n\tvm.deal(alice,1 ether);\n\tconsole2.Log(\"after:\"alice.balance);\n}\n\n```\n\n## 安装插件\n\n### 使用forge安装插件\n\n```shell\nforge install [OPTIONS] <github username>/<github project>@<tag>\n```\n\n### 使用npm安装插件\n\n```shell\nnpm init -y\nnpm i @openzeppelin/contracts \n// yarn add @openzeppelin/contracts\n```\n\n安装完成之后需要配置`foundry.toml`方法，在libs中添加 `node_modules`文件夹。\n\n```toml\n[profile.default]\nsrc = 'src'\nout = 'out'\nlibs = ['lib','node_modules']\n```\n\n\n## 测试一\n\n新建`test/Test.t.sol`\n\n```js\n// SPDX-License-Identifier: SEE LICENSE IN LICENSE\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/Counter.sol\";\n// 导入IERC20的接口，通过该接口可以调用对应的方法\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract IERC20Test is Test {\n  // 声明Counter合约对象变量\n  Counter public counter;\n  // 声明一个地址变量\n  address public alice;\n  // 声明一个msgSender\n  address public msgSender;\n  // 声明帮助合约函数\n  Helper public h;\n\n  //定义一个IERC20 合约对象\n  IERC20 public dai;\n\n  function setUp() public {\n    // new测试合约对象\n    counter = new Counter();\n    // 调用对象方法\n    counter.setNumber(0);\n    // new helper对象\n    h = new Helper();\n\n    alice = address(10086);\n    console2.log(alice);\n    dai = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);\n  }\n\n  // 测试给合约地址转账\n  function testCheatCode() public {\n    console2.log(\"before:\", dai.balanceOf(alice));\n    deal(address(dai), alice,1 ether);\n    console2.log(\"after:\", dai.balanceOf(alice));\n  }\n  // 测试改变合约msg.sender\n  function testCheatAddress() public {\n    console2.log(\"before:\", h.whoCalled());\n    vm.prank(address(1));\n    console2.log(\"after:\", h.whoCalled());\n  }\n}\n\n\ncontract Helper {\n  function whoCalled() public view returns (address) {\n    return msg.sender;\n  }\n}\n```\n\n\n运行测试：\n\n因为本地没有dai的部署合约，所以我们直接fork主网， -vvv可以显示console2.log，-w表示watch模式。\n\n```shell\nforge test -vvv --fork-url=$ETH_RPC_URL -w\n```\n\n输出结果：\n\n```shell\nRunning 2 tests for test/Test.t.sol:IERC20Test\n[PASS] testCheatAddress() (gas: 12873)\nLogs:\n  0x0000000000000000000000000000000000002766\n  before: 0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84\n  after: 0x0000000000000000000000000000000000000001\n\n[PASS] testCheatCode() (gas: 153596)\nLogs:\n  0x0000000000000000000000000000000000002766\n  before: 0\n  after: 1000000000000000000\n\nTest result: ok. 2 passed; 0 failed; finished in 5.61s\n```\n\n### 代码中fork网络\n\n```js\nfunction testCodeFork() public {\n    console2.log(address(dai));\n    string memory rpc = vm.envString(\"ETH_RPC_URL\");\n    uint256 mainnet = vm.createFork(rpc);\n    vm.selectFork(mainnet);\n    // 这边下面开始就是直接fork网络了\n    console2.log(\"before:\",dai.balanceOf(alice));\n    deal(address(dai),alice,1 ether);\n    console2.log(\"after:\",dai.balanceOf(alice));\n  }\n```\n\n### 从代码中读取环境变量\n\n```js\n// 通过 vm.envAddress 获取环境变量中的地址\n    dai = IERC20(vm.envAddress(\"DAI\"));\n```\n\n### 完整代码\n\n```js\n// SPDX-License-Identifier: SEE LICENSE IN LICENSE\npragma solidity ^0.8.13;\n\nimport \"forge-std/Test.sol\";\nimport \"../src/Counter.sol\";\n// 导入IERC20的接口，通过该接口可以调用对应的方法\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ncontract IERC20Test is Test {\n  // 声明Counter合约对象变量\n  Counter public counter;\n  // 声明一个地址变量\n  address public alice;\n  // 声明一个msgSender\n  address public msgSender;\n  // 声明帮助合约函数\n  Helper public h;\n\n  //定义一个IERC20 合约对象\n  IERC20 public dai;\n\n  function setUp() public {\n    // new测试合约对象\n    counter = new Counter();\n    // 调用对象方法\n    counter.setNumber(0);\n    // new helper对象\n    h = new Helper();\n\n    alice = address(10086);\n    console2.log(alice);\n    // 通过 vm.envAddress 获取环境变量中的地址\n    dai = IERC20(vm.envAddress(\"DAI\"));\n  }\n\n\n  // 测试给合约地址转账\n  function testCheatCode() public {\n    console2.log(\"before:\", dai.balanceOf(alice));\n    deal(address(dai), alice,1 ether);\n    console2.log(\"after:\", dai.balanceOf(alice));\n  }\n  // 测试改变合约msg.sender\n  function testCheatAddress() public {\n    console2.log(\"before:\", h.whoCalled());\n    vm.prank(address(1));\n    console2.log(\"after:\", h.whoCalled());\n  }\n\n  function testCodeFork() public {\n    console2.log(address(dai));\n    string memory rpc = vm.envString(\"ETH_RPC_URL\");\n    uint256 mainnet = vm.createFork(rpc);\n    vm.selectFork(mainnet);\n    // 这边下面开始就是直接fork网络了\n    console2.log(\"before:\",dai.balanceOf(alice));\n    deal(address(dai),alice,1 ether);\n    console2.log(\"after:\",dai.balanceOf(alice));\n  }\n\n}\n\n\ncontract Helper {\n  function whoCalled() public view returns (address) {\n    return msg.sender;\n  }\n}\n```\n\n### vm.sol\n\n`vm.sol` 中还有很多封装好的方法可以直接使用\n\n```js\n// Sets the *next* call's msg.sender to be the input address\n    function prank(address) external;\n    // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called\n    function startPrank(address) external;\n    // Sets the *next* call's msg.sender to be the input address, and the tx.origin to be the second input\n    function prank(address,address) external;\n    // Sets all subsequent calls' msg.sender to be the input address until `stopPrank` is called, and the tx.origin to be the second input\n    function startPrank(address,address) external;\n    // Resets subsequent calls' msg.sender to be `address(this)`\n    function stopPrank() external;\n    // Sets an address' balance, (who, newBalance)\n    function deal(address, uint256) external;\n    // Sets an address' code, (who, newCode)\n    function etch(address, bytes calldata) external;\n    // Expects an error on next call\n    function expectRevert(bytes calldata) external;\n    function expectRevert(bytes4) external;\n    function expectRevert() external;\n    // Records all storage reads and writes\n    function record() external;\n    // Gets all accessed reads and write slot from a recording session, for a given address\n    function accesses(address) external returns (bytes32[] memory reads, bytes32[] memory writes);\n```\n\n\n##  运行脚本\n\n```shell\nforge script [OPTIONS] <PATH> [ARGS]...\nforge script script/Counter.s.sol:CounterScript\n```\n\n`script/Counter.s.sol` 脚本代码\n\n```js\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Script.sol\";\n\ncontract CounterScript is Script {\n// 每次初始化会运行\n    function setUp() public {\n        console2.log(\"setup \");\n    }\n\n    function run() public {\n        vm.broadcast();\n        console2.log(\"run\");\n    }\n\n    function someFunction(uint256 x) public {\n        console2.log(\"some other func\");\n        console2.log(x);\n    }\n}\n\n```\n\n指定方法，带参数的测试运行\n\n```shell\nforge script script/Counter.s.sol --sig=\"someFunction(uint256 x)\" 10\n```\n\n## 脚本部署合约\n\n编写部署脚本：\n```solidity\n// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport \"forge-std/Script.sol\";\n// 引入合约\nimport \"../src/Counter.sol\";\n\ncontract CounterScript is Script {\n  function setUp() public {\n    console2.log(\"setup \");\n  }\n\n  function run() public {\n    // 开始记录脚本中合约的调用和创建\n    vm.startBroadcast();\n    //生成合约对象\n    Counter c = new Counter();\n    // 结束记录\n    vm.stopBroadcast();\n  }\n}\n\n```\n\n测试部署：\n\n```shell\nforge script script/Counter.s.sol -vvvv --rpc-url=http://127.0.0.1:8545\n```\n\n正式部署：\n\n```\nforge script script/Counter.s.sol -vvvv --rpc-url=$RPC_MAIN --broadcast --private-key=privete_key\n```\n\n部署完成之后会多一个broadcast文件夹，查看该文件夹有`run-latest.json`可以看到部署的相应信息。\n\n### 部署多个网络\n\n使用fork代码可以部署多个网络\n\n\n```js\nuint256 mainnet = vm.createFork(rpc);\n```\n\n## 命令行部署合约\n\n部署并开源合约，其中 `--etherscan-api-key` 为以太坊浏览器（或其他 EVM 浏览器）中申请的 API key，`--verify` 为部署后开源合约。\n```solidity\n# forge create --rpc-url <your_rpc_url> --private-key <your_private_key> --etherscan-api-key <KEY> --verify src/YourContract.sol:YourContract --constructor-args <constructor_args>\n  forge create --rpc-url $RPC_MAIN \\ \n   --private-key privete_key  \\ \n   --etherscan-api-key xxxx  \\ \n   --verify \\\n   src/Counter.sol:Counter\n```\n\n## Tips： \n\n```shell\nforge test --gas-report\n\n# 获取合约相关信息，例如abi、bytecode等等\nforge inspect <CONTRACT> <FIELD>\n\n# 生成gas快照\nforge snapshot\n\n# 当前快照文件与最新更改进行比较，对比gas是否减少\nforge snapshot --diff \n\n# 交互式Debugger\nforge script script/Counter.s.sol --debug\n\n# 链上交易debugger\nforge run --debug\n\n```\n\n\n\n## 总结\n\n这一讲我们介绍了以Solidity为中心的开发工具，并介绍了如何利用Foundry编译，部署，测试智能合约。由于Foundry的部署和测试脚本都是用Solidity编写，免去了开发者学习javascript的时间成本，并提供了更多练习Solidity的机会，推荐大家使用。\n\n\n## 参考\n[使用 foundry 框架加速智能合约开发](https://www.youtube.com/watch?v=EXYeltwvftw) \n[cast Commands - Foundry Book](https://book.getfoundry.sh/reference/cast/)\n[https://twitter.com/wp__lai](https://twitter.com/wp__lai)\n","isInternal":false,"tokens":14057,"sizeBytes":40999},{"name":"readme.md","path":"Topics/Tools/TOOL08_ZAN/readme.md","rawUrl":"https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL08_ZAN/readme.md","title":"TOOL08_ZAN Documentation","category":"plugin-manifest","format":"markdown","content":"# WTF Solidity 极简入门-工具篇 8：ZAN，节点服务和合约审计等 Web3 技术服务\n\n我最近在重新学 Solidity，巩固一下细节，也写一个“WTF Solidity 极简入门”，供小白们使用（编程大佬可以另找教程），每周更新 1-3 讲。\n\n推特：[@0xAA_Science](https://twitter.com/0xAA_Science)｜[@WTFAcademy\\_](https://twitter.com/WTFAcademy_)\n\n社区：[Discord](https://discord.gg/5akcruXrsk)｜[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)｜[官网 wtf.academy](https://wtf.academy)\n\n所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)\n\n---\n\n## ZAN 是什么\n\n[ZAN](https://zan.top?chInfo=wtf) 是一家 Web3 技术服务提供商，是蚂蚁集团下的一个技术品牌。它提供多种技术服务，有类似 Infura 和 Alchemy 提供的节点服务，包括各种链的 JSON-RPC 支持，以及其他高级的链 API。还有安全相关的合约审计、链上数据分析、KYC 等服务。另外还提供 toB 的解决方案，包括 RWA 资产的链上发行、零知识证明加速以及提供安全和可定制的区块链等。\n\n接下来会针对开发者常用的节点服务、合约审计和链上数据分析（KNOW YOUR TRANSACTION）功能做介绍。在学习之前你可以先访问 [https://zan.top](https://zan.top?chInfo=wtf) 并完成注册和登录。\n\n## 节点服务\n\n### 创建 API Key\n\n之后进入到节点服务的控制台 [https://zan.top/service/apikeys](https://zan.top/service/apikeys?chInfo=wtf) 创建一个 Key，每个 Key 都有默认的免费额度，对于小项目来说够用了。\n\n创建成功后你会看到如下的页面：\n\n![](./img/zan-service.png)\n\n接下来你就可以直接点击网站上的 Copy 按钮复制获取 API Key 了，但是大部分情况我们都是直接复制你需要的链的 RPC 地址，然后在你的 DApp 中使用。\n\n### 使用 RPC 地址\n\n不同的区块链通常都会有自己的基础的 JSON-RPC 的接口规范，比如以太坊的 JSON-RPC 接口规范，你可以在 [https://ethereum.org/en/developers/docs/apis/json-rpc/](https://ethereum.org/en/developers/docs/apis/json-rpc/) 获取。\n\nZAN 提供的接口自然也遵循这样的规范，比如你可以通过访问 `https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}` 来访问以太坊上的数据。当然，我们通常可以直接使用链官方或者生态提供的 SDK 来调用接口。下面我们会介绍如何使用以太坊常用的一些 SDK 来调用 ZAN 提供的节点服务。\n\n需要注意上面代码中的 `YourZANApiKey` 需要替换成你自己的 Key。另外在实际的项目中，为了避免你的 Key 被滥用，建议你将 Key 放到后端服务中，然后通过后端服务来调用节点服务，或者在 ZAN 的控制台中设置域名白名单来降低被滥用的风险。\n\n#### 使用 ethers\n\n在 ethers.js 中，我们可以利用 ZAN 提供的 API Key 来创建 JsonRpcProvider，与链上交互。\n\n```javascript\nimport { ethers } from \"ethers\";\n\nconst provider = new ethers.providers.JsonRpcProvider(\n  \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n);\n\nprovider.getBlockNumber().then((blockNumber) => {\n  console.log(\"Current block number: \" + blockNumber);\n});\n```\n\n如上所示，我们可以通过 ethers.js 提供的 JsonRpcProvider 来访问 ZAN 提供的节点服务，获取当前区块的高度。更多的 ethers.js 的使用方法可以参考 ethers.js 官方文档：[ethers V5](https://docs.ethers.org/v5/api/providers/jsonrpc-provider/) | [ethers V6](https://docs.ethers.org/v6/api/providers/jsonrpc/#JsonRpcProvider)。\n\n#### 使用 web3.js\n\n在 web3.js 中，我们可以利用 ZAN 提供的 API Key 来创建 Web3Provider，与链上交互。\n\n```javascript\nimport Web3 from \"web3\";\n\nconst web3 = new Web3(\n  \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n);\nweb3.eth.getBlockNumber().then((blockNumber) => {\n  console.log(\"Current block number: \" + blockNumber);\n});\n```\n\n如上所示，我们可以通过 web3.js 提供的 Web3Provider 来访问 ZAN 提供的节点服务，获取当前区块的高度。更多的 web3.js 的使用方法可以参考 [web3.js 官方文档](https://web3js.readthedocs.io/)\n\n#### 使用 wagmi\n\n在 ZAN 的控制台中选择以太坊主网的节点服务地址复制，复制后的地址添加到 wagmi 的 `http()` 方法中，如下：\n\n```jsx\nimport { createConfig, http, WagmiProvider } from \"wagmi\";\nimport { mainnet } from \"wagmi/chains\";\n\nconst config = createConfig({\n  chains: [mainnet],\n  transports: {\n    [mainnet.id]: http(\n      \"https://api.zan.top/node/v1/eth/mainnet/{YourZANApiKey}\"\n    ),\n  },\n});\n\nexport default function App() {\n  return <WagmiProvider config={config}>{/** ... */}</WagmiProvider>;\n}\n```\n\n如上，在 `WagmiProvider` 包裹的组件中你就可以使用 wagmi 提供的各种 hook 来访问以太坊的数据了。\n\n### 安全设置\n\n如果你在生产环境中使用，为了避免你的 API Key 被滥用或者攻击，你可以在 ZAN 的控制台中设置域名白名单，这样只有在白名单中的域名才能使用你的 API Key。\n\n![setting](./img/service-setting.png)\n\n还有其他设置你也可以在 ZAN 的控制台中找到，比如你可以设置每个 Key 的访问频率限制，这样可以避免你的 Key 被滥用。也可以查看每个 Key 的使用情况，设置团队共同管理 Key 等。\n\n### 测试网代币水龙头\n\n在开发中，我们经常需要获取测试网的代币，你可以通过水龙头获取测试代币，ZAN 也提供了测试网代币的水龙头服务，你可以在 [https://zan.top/faucet](https://zan.top/faucet?chInfo=wtf) 中获取测试代币。\n\n## 合约安全审计\n\n合约安全审计是一个非常重要的环节，尤其是在 DeFi 项目中，合约的安全性直接关系到用户的资金安全。ZAN 提供了合约安全审计服务，你可以在 [https://zan.top/home/contract-review](https://zan.top/home/contract-review) 中提交你的合约进行审计。ZAN 提供了免费版和专家版，专家版是有人工介入，需要收费。我们以免费版为例，说明如何在 ZAN 中提交合约审计任务。你有两种方法，一种是在网站上提交，另外一种是通过 VSCode 插件提交。\n\n### 通过 ZAN 网站提交\n\n你可以在 [https://zan.top/review/reports/apply](https://zan.top/review/reports/apply?chInfo=wtf) 提交一个合约审计任务：\n\n![create](./img/scr-new.png)\n\n有多种提交方式，提交后会进入到自动化的程序进行审计，如下图所示，你需要等待几分钟。\n\n![waiting](./img/scr-wait.png)\n\n需要注意的是，这种方式是自动化的审计，只能检测一些常见的漏洞，并无法保障合约的逻辑正确性，如果你的合约比较复杂，还是需要人工介入审计的。\n\n### 通过 VSCode 插件提交\n\nZAN 提供了一个 [VSCode 插件](https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review)，你可以在你的 VSCode 中安装该插件，直接在 VSCode 中提交合约审计任务。\n\n首先方案插件地址 [https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review](https://marketplace.visualstudio.com/items?itemName=zantop.zan-smart-contract-review) 点击 Install 唤起 VSCode 安装插件。\n\n安装成功后左侧会有一个 ZAN 的图标，点击图标后可以看到一个 `Config Access Key` 的按钮。\n\n![config-vscode](./img/config-vscode.png)\n\n点击按钮后配置你的 Access Key，Key 需要在 ZAN 的合约审计控制台中获取：\n\n![getkey](./img/vscode-key.png)\n\n获取 Key 后填入 VSCode 插件配置中，然后你就可以在 VSCode 中提交合约审计任务了。\n\n### 合约报告查看\n\n合约分析完成后你可以在网站上查看报告：\n\n![src-report](./img/scr-report.png)\n\n比如上图是对一个简单的 ERC721 的[合约](https://github.com/ourmetaverse/our-metaverse-contract)的分析结果，你可以通过[https://zan.top/review/reports/public/b82c9992-bfce-4986-baff-5bb4e76e1eb9](https://zan.top/review/reports/public/b82c9992-bfce-4986-baff-5bb4e76e1eb9?chInfo=wtf)查看报告。\n\n对于专家服务，会有多轮 AI + 专家人工审计后得到一个 PDF 报告，你可以访问[该链接](https://mdn.alipayobjects.com/huamei_hsbbrh/afts/file/A*tl-PR5pIIt4AAAAAAAAAAAAADiOMAQ/hebao_v3_20240313.pdf) 查看一个示例。\n\n![pdf](./img/scr-pdf.png)\n\n## 链上数据分析（KNOW YOUR TRANSACTION）\n\n区块链上的数据都是公开透明的，然而要在浩瀚的链上数据中分析问题，查找线索也不是那么容易的事情。ZAN 提供了链上数据分析服务，你可以在 [https://zan.top/kyt/controller](https://zan.top/kyt/controller?chInfo=wtf) 中提交你的地址，查看交易的详细信息。\n\n![kyt](./img/kyt-submit.png)\n\n提交的内容可以是一个地址，也可以是一笔交易，如下图所示，你可以看到资金的流动情况，还会标记出有风险的地址：\n\n![kyt-demo](./img/kyt-demo.png)\n\n可以用于资金追踪、巨鲸监控、反洗钱等等服务。对于专业用户，你可以使用 API 来调用，如下图你可以在控制台中获取你的 API Key：\n\n![kyt-key](./img/kyt-key.png)\n\n```sh\n## Replace {apiKey} with the API key you obtained from the ZAN dashboard.\n## You can also replace the \"eth\" and \"mainnet\" with any other supported networks.\ncurl https://api.zan.top/kyt/v1/score \\\n     -H \"Content-Type: application/json\" \\\n     -H \"Authorization:Bearer {apiKey}\" \\\n     -X POST \\\n     -d \"{\\\"objectId\\\":\\\"0xA160cdAB225685dA1d56aa342Ad8841c3b53f291\\\",\\\"objectType\\\":\\\"address\\\",\\\"analysisType\\\":\\\"\\\",\\\"chainShortName\\\":\\\"eth\\\",\\\"depth\\\":\\\"\\\"}\"\n```\n\n如上面示例代码，你可以通过访问 `https://api.zan.top/kyt/v1/score` 来获取某一个地址的相关数据。\n\n## 总结\n\n这一讲，我们介绍了如何使用 ZAN 提供的各种 Web3 技术服务。ZAN 提供了丰富的服务，有面向 DApp 开发者的，也有面向商业机构，安全团队，研究机构等的服务，你可以根据自己的需求选择合适的服务。\n","isInternal":false,"tokens":3281,"sizeBytes":10245}],"systemPromptSnippet":"<yakaai_skills repo=\"AmazingAng/WTF-Solidity\">\n<!-- File: Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json (Tokens: ~300 | Category: anthropic-skill) -->\n# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package-lock.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# TOOL06_Hardhat Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL06_Hardhat/package.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json (Tokens: ~300 | Category: anthropic-skill) -->\n# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json (Tokens: ~300 | Category: anthropic-skill) -->\n# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json (Tokens: ~300 | Category: anthropic-skill) -->\n# 1 Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Forge-std Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Fixtures Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package-lock.json)\n\n<!-- File: Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Hello_wtf Skill\n\nPath: `Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Languages/pt-br/Topics/Tools/TOOL07_Foundry/hello_wtf/package.json)\n\n<!-- File: out/extensions/IERC721Metadata.sol/IERC721Metadata.json (Tokens: ~6169 | Category: anthropic-skill) -->\n{\"abi\":[{\"type\":\"function\",\"name\":\"approve\",\"inputs\":[{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"balanceOf\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"getApproved\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"isApprovedForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"name\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"ownerOf\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"owner\",\"type\":\"address\",\"internalType\":\"address\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"safeTransferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"data\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"setApprovalForAll\",\"inputs\":[{\"name\":\"operator\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"supportsInterface\",\"inputs\":[{\"name\":\"interfaceId\",\"type\":\"bytes4\",\"internalType\":\"bytes4\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"symbol\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"tokenURI\",\"inputs\":[{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"internalType\":\"string\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"transferFrom\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"event\",\"name\":\"Approval\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ApprovalForAll\",\"inputs\":[{\"name\":\"owner\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"operator\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false,\"internalType\":\"bool\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"Transfer\",\"inputs\":[{\"name\":\"from\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"to\",\"type\":\"address\",\"indexed\":true,\"internalType\":\"address\"},{\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true,\"internalType\":\"uint256\"}],\"anonymous\":false}],\"bytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"deployedBytecode\":{\"object\":\"0x\",\"sourceMap\":\"\",\"linkReferences\":{}},\"methodIdentifiers\":{\"approve(address,uint256)\":\"095ea7b3\",\"balanceOf(address)\":\"70a08231\",\"getApproved(uint256)\":\"081812fc\",\"isApprovedForAll(address,address)\":\"e985e9c5\",\"name()\":\"06fdde03\",\"ownerOf(uint256)\":\"6352211e\",\"safeTransferFrom(address,address,uint256)\":\"42842e0e\",\"safeTransferFrom(address,address,uint256,bytes)\":\"b88d4fde\",\"setApprovalForAll(address,bool)\":\"a22cb465\",\"supportsInterface(bytes4)\":\"01ffc9a7\",\"symbol()\":\"95d89b41\",\"tokenURI(uint256)\":\"c87b56dd\",\"transferFrom(address,address,uint256)\":\"23b872dd\"},\"rawMetadata\":\"{\\\"compiler\\\":{\\\"version\\\":\\\"0.8.34+commit.80d5c536\\\"},\\\"language\\\":\\\"Solidity\\\",\\\"output\\\":{\\\"abi\\\":[{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Approval\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":false,\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"ApprovalForAll\\\",\\\"type\\\":\\\"event\\\"},{\\\"anonymous\\\":false,\\\"inputs\\\":[{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"indexed\\\":true,\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"Transfer\\\",\\\"type\\\":\\\"event\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"approve\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"balanceOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"balance\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"getApproved\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"}],\\\"name\\\":\\\"isApprovedForAll\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"name\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"ownerOf\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"owner\\\",\\\"type\\\":\\\"address\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"},{\\\"internalType\\\":\\\"bytes\\\",\\\"name\\\":\\\"data\\\",\\\"type\\\":\\\"bytes\\\"}],\\\"name\\\":\\\"safeTransferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"operator\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"approved\\\",\\\"type\\\":\\\"bool\\\"}],\\\"name\\\":\\\"setApprovalForAll\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"bytes4\\\",\\\"name\\\":\\\"interfaceId\\\",\\\"type\\\":\\\"bytes4\\\"}],\\\"name\\\":\\\"supportsInterface\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"bool\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"bool\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[],\\\"name\\\":\\\"symbol\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"tokenURI\\\",\\\"outputs\\\":[{\\\"internalType\\\":\\\"string\\\",\\\"name\\\":\\\"\\\",\\\"type\\\":\\\"string\\\"}],\\\"stateMutability\\\":\\\"view\\\",\\\"type\\\":\\\"function\\\"},{\\\"inputs\\\":[{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"from\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"address\\\",\\\"name\\\":\\\"to\\\",\\\"type\\\":\\\"address\\\"},{\\\"internalType\\\":\\\"uint256\\\",\\\"name\\\":\\\"tokenId\\\",\\\"type\\\":\\\"uint256\\\"}],\\\"name\\\":\\\"transferFrom\\\",\\\"outputs\\\":[],\\\"stateMutability\\\":\\\"nonpayable\\\",\\\"type\\\":\\\"function\\\"}],\\\"devdoc\\\":{\\\"details\\\":\\\"See https://eips.ethereum.org/EIPS/eip-721\\\",\\\"events\\\":{\\\"Approval(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables `approved` to manage the `tokenId` token.\\\"},\\\"ApprovalForAll(address,address,bool)\\\":{\\\"details\\\":\\\"Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\\"},\\\"Transfer(address,address,uint256)\\\":{\\\"details\\\":\\\"Emitted when `tokenId` token is transferred from `from` to `to`.\\\"}},\\\"kind\\\":\\\"dev\\\",\\\"methods\\\":{\\\"approve(address,uint256)\\\":{\\\"details\\\":\\\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\\\"},\\\"balanceOf(address)\\\":{\\\"details\\\":\\\"Returns the number of tokens in ``owner``'s account.\\\"},\\\"getApproved(uint256)\\\":{\\\"details\\\":\\\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"isApprovedForAll(address,address)\\\":{\\\"details\\\":\\\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\\\"},\\\"name()\\\":{\\\"details\\\":\\\"Returns the token collection name.\\\"},\\\"ownerOf(uint256)\\\":{\\\"details\\\":\\\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\\\"},\\\"safeTransferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"safeTransferFrom(address,address,uint256,bytes)\\\":{\\\"details\\\":\\\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\\\"},\\\"setApprovalForAll(address,bool)\\\":{\\\"details\\\":\\\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\\\"},\\\"supportsInterface(bytes4)\\\":{\\\"details\\\":\\\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\\\"},\\\"symbol()\\\":{\\\"details\\\":\\\"Returns the token collection symbol.\\\"},\\\"tokenURI(uint256)\\\":{\\\"details\\\":\\\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\\"},\\\"transferFrom(address,address,uint256)\\\":{\\\"details\\\":\\\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\\\"}},\\\"title\\\":\\\"ERC-721 Non-Fungible Token Standard, optional metadata extension\\\",\\\"version\\\":1},\\\"userdoc\\\":{\\\"kind\\\":\\\"user\\\",\\\"methods\\\":{},\\\"version\\\":1}},\\\"settings\\\":{\\\"compilationTarget\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":\\\"IERC721Metadata\\\"},\\\"evmVersion\\\":\\\"prague\\\",\\\"libraries\\\":{},\\\"metadata\\\":{\\\"bytecodeHash\\\":\\\"ipfs\\\"},\\\"optimizer\\\":{\\\"enabled\\\":false,\\\"runs\\\":200},\\\"remappings\\\":[\\\":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\\\",\\\":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\\\",\\\":forge-std/=lib/forge-std/src/\\\",\\\":halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\\\",\\\":openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\\\"]},\\\"sources\\\":{\\\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\\\":{\\\"keccak256\\\":\\\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\\\",\\\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\\\"]},\\\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\":{\\\"keccak256\\\":\\\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\\\",\\\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\\\"]},\\\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\\\":{\\\"keccak256\\\":\\\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\\\",\\\"license\\\":\\\"MIT\\\",\\\"urls\\\":[\\\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\\\",\\\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\\\"]}},\\\"version\\\":1}\",\"metadata\":{\"compiler\":{\"version\":\"0.8.34+commit.80d5c536\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"approved\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Approval\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\",\"indexed\":false}],\"type\":\"event\",\"name\":\"ApprovalForAll\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\",\"indexed\":true},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\",\"indexed\":true}],\"type\":\"event\",\"name\":\"Transfer\",\"anonymous\":false},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"approve\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"getApproved\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"ownerOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"safeTransferFrom\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"approved\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"setApprovalForAll\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}]},{\"inputs\":[],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\",\"name\":\"tokenURI\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}]},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"tokenId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\",\"name\":\"transferFrom\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"approve(address,uint256)\":{\"details\":\"Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.\"},\"balanceOf(address)\":{\"details\":\"Returns the number of tokens in ``owner``'s account.\"},\"getApproved(uint256)\":{\"details\":\"Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.\"},\"isApprovedForAll(address,address)\":{\"details\":\"Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}\"},\"name()\":{\"details\":\"Returns the token collection name.\"},\"ownerOf(uint256)\":{\"details\":\"Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.\"},\"safeTransferFrom(address,address,uint256)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC-721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must have been allowed to move this token by either {approve} or   {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"safeTransferFrom(address,address,uint256,bytes)\":{\"details\":\"Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon   a safe transfer. Emits a {Transfer} event.\"},\"setApprovalForAll(address,bool)\":{\"details\":\"Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the address zero. Emits an {ApprovalForAll} event.\"},\"supportsInterface(bytes4)\":{\"details\":\"Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] to learn more about how these ids are created. This function call must use less than 30 000 gas.\"},\"symbol()\":{\"details\":\"Returns the token collection symbol.\"},\"tokenURI(uint256)\":{\"details\":\"Returns the Uniform Resource Identifier (URI) for `tokenId` token.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"Transfers `tokenId` token from `from` to `to`. WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"remappings\":[\"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/\",\"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/\",\"forge-std/=lib/forge-std/src/\",\"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/\",\"openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/\"],\"optimizer\":{\"enabled\":false,\"runs\":200},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"compilationTarget\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":\"IERC721Metadata\"},\"evmVersion\":\"prague\",\"libraries\":{}},\"sources\":{\"lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol\":{\"keccak256\":\"0xf78f05f3b8c9f75570e85300d7b4600d7f6f6a198449273f31d44c1641adb46f\",\"urls\":[\"bzz-raw://e28b872613b45e0e801d4995aa4380be2531147bfe2d85c1d6275f1de514fba3\",\"dweb:/ipfs/QmeeFcfShHYaS3BdgVj78nxR28ZaVUwbvr66ud8bT6kzw9\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"keccak256\":\"0xf46268c37522320bb2119a5a394bc5c739a95c0c574c8d08e8c643f4d06e5c76\",\"urls\":[\"bzz-raw://517e4b295f35b9947c72ad7379a6089439ece7bb6f4a2ea0a159da13046c039e\",\"dweb:/ipfs/QmZXzkSfLUbvujig3zVbpDHykpHhqLpvQtdiN3B5j4TA3u\"],\"license\":\"MIT\"},\"lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol\":{\"keccak256\":\"0x8891738ffe910f0cf2da09566928589bf5d63f4524dd734fd9cedbac3274dd5c\",\"urls\":[\"bzz-raw://971f954442df5c2ef5b5ebf1eb245d7105d9fbacc7386ee5c796df1d45b21617\",\"dweb:/ipfs/QmadRjHbkicwqwwh61raUEapaVEtaLMcYbQZWs9gUkgj3u\"],\"license\":\"MIT\"}},\"version\":1},\"id\":28}\n\n<!-- File: Topics/Tools/TOOL06_Hardhat/package-lock.json (Tokens: ~19981 | Category: anthropic-skill) -->\n{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"lockfileVersion\": 2,\n  \"requires\": true,\n  \"packages\": {\n    \"\": {\n      \"name\": \"tool06_hardhat\",\n      \"version\": \"1.0.0\",\n      \"license\": \"ISC\",\n      \"devDependencies\": {\n        \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n        \"hardhat\": \"^2.22.2\"\n      }\n    },\n    \"node_modules/@adraffy/ens-normalize\": {\n      \"version\": \"1.10.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz\",\n      \"integrity\": \"sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@cspotcode/source-map-support\": {\n      \"version\": \"0.8.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\n      },\n      \"engines\": {\n        \"node\": \">=12\"\n      }\n    },\n    \"node_modules/@ethersproject/abi\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abi/-/abi-5.7.0.tgz\",\n      \"integrity\": \"sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/hash\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-provider\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz\",\n      \"integrity\": \"sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/networks\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/transactions\": \"^5.7.0\",\n        \"@ethersproject/web\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/abstract-signer\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz\",\n      \"integrity\": \"sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-provider\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/address\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/address/-/address-5.7.0.tgz\",\n      \"integrity\": \"sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/base64\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/base64/-/base64-5.7.0.tgz\",\n      \"integrity\": \"sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/bignumber\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz\",\n      \"integrity\": \"sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\"\n      }\n    },\n    \"node_modules/@ethersproject/bytes\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/bytes/-/bytes-5.7.0.tgz\",\n      \"integrity\": \"sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/constants\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/constants/-/constants-5.7.0.tgz\",\n      \"integrity\": \"sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bignumber\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/hash\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/hash/-/hash-5.7.0.tgz\",\n      \"integrity\": \"sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/abstract-signer\": \"^5.7.0\",\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/keccak256\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz\",\n      \"integrity\": \"sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"js-sha3\": \"0.8.0\"\n      }\n    },\n    \"node_modules/@ethersproject/logger\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/logger/-/logger-5.7.0.tgz\",\n      \"integrity\": \"sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==\",\n      \"dev\": true\n    },\n    \"node_modules/@ethersproject/networks\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/networks/-/networks-5.7.1.tgz\",\n      \"integrity\": \"sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/properties\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/properties/-/properties-5.7.0.tgz\",\n      \"integrity\": \"sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/rlp\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/rlp/-/rlp-5.7.0.tgz\",\n      \"integrity\": \"sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/signing-key\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz\",\n      \"integrity\": \"sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"bn.js\": \"^5.2.1\",\n        \"elliptic\": \"6.5.4\",\n        \"hash.js\": \"1.1.7\"\n      }\n    },\n    \"node_modules/@ethersproject/strings\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/strings/-/strings-5.7.0.tgz\",\n      \"integrity\": \"sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/transactions\": {\n      \"version\": \"5.7.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/transactions/-/transactions-5.7.0.tgz\",\n      \"integrity\": \"sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/address\": \"^5.7.0\",\n        \"@ethersproject/bignumber\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/constants\": \"^5.7.0\",\n        \"@ethersproject/keccak256\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/rlp\": \"^5.7.0\",\n        \"@ethersproject/signing-key\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@ethersproject/web\": {\n      \"version\": \"5.7.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@ethersproject/web/-/web-5.7.1.tgz\",\n      \"integrity\": \"sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@ethersproject/base64\": \"^5.7.0\",\n        \"@ethersproject/bytes\": \"^5.7.0\",\n        \"@ethersproject/logger\": \"^5.7.0\",\n        \"@ethersproject/properties\": \"^5.7.0\",\n        \"@ethersproject/strings\": \"^5.7.0\"\n      }\n    },\n    \"node_modules/@fastify/busboy\": {\n      \"version\": \"2.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@fastify/busboy/-/busboy-2.1.1.tgz\",\n      \"integrity\": \"sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=14\"\n      }\n    },\n    \"node_modules/@jridgewell/resolve-uri\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz\",\n      \"integrity\": \"sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">=6.0.0\"\n      }\n    },\n    \"node_modules/@jridgewell/sourcemap-codec\": {\n      \"version\": \"1.4.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz\",\n      \"integrity\": \"sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@jridgewell/trace-mapping\": {\n      \"version\": \"0.3.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\n      }\n    },\n    \"node_modules/@metamask/eth-sig-util\": {\n      \"version\": \"4.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz\",\n      \"integrity\": \"sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"ethereumjs-abi\": \"^0.6.8\",\n        \"ethereumjs-util\": \"^6.2.1\",\n        \"ethjs-util\": \"^0.1.6\",\n        \"tweetnacl\": \"^1.0.3\",\n        \"tweetnacl-util\": \"^0.15.1\"\n      },\n      \"engines\": {\n        \"node\": \">=12.0.0\"\n      }\n    },\n    \"node_modules/@noble/curves\": {\n      \"version\": \"1.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/curves/-/curves-1.2.0.tgz\",\n      \"integrity\": \"sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"1.3.2\"\n      }\n    },\n    \"node_modules/@noble/curves/node_modules/@noble/hashes\": {\n      \"version\": \"1.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.3.2.tgz\",\n      \"integrity\": \"sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 16\"\n      }\n    },\n    \"node_modules/@noble/hashes\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/hashes/-/hashes-1.1.2.tgz\",\n      \"integrity\": \"sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==\",\n      \"dev\": true\n    },\n    \"node_modules/@noble/secp256k1\": {\n      \"version\": \"1.6.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@noble/secp256k1/-/secp256k1-1.6.3.tgz\",\n      \"integrity\": \"sha512-T04e4iTurVy7I8Sw4+c5OSN9/RkPlo1uKxAomtxQNLq8j1uPAqnsqG1bqvY3Jv7c13gyr6dui0zmh/I3+f/JaQ==\",\n      \"dev\": true\n    },\n    \"node_modules/@nodelib/fs.scandir\": {\n      \"version\": \"2.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.stat\": \"2.0.5\",\n        \"run-parallel\": \"^1.1.9\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.stat\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nodelib/fs.walk\": {\n      \"version\": \"1.2.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@nodelib/fs.scandir\": \"2.1.5\",\n        \"fastq\": \"^1.6.0\"\n      },\n      \"engines\": {\n        \"node\": \">= 8\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr/-/edr-0.3.2.tgz\",\n      \"integrity\": \"sha512-HGWtjibAK1mo4I2A7nJ/fXqe/J9G54OrSPJnnkY2K8TiXotYLShGd9GvHkae3PuFjTJKm6ZgBy7tveJj5yrCfw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 18\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/edr-darwin-arm64\": \"0.3.2\",\n        \"@nomicfoundation/edr-darwin-x64\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-arm64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-gnu\": \"0.3.2\",\n        \"@nomicfoundation/edr-linux-x64-musl\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-arm64-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-ia32-msvc\": \"0.3.2\",\n        \"@nomicfoundation/edr-win32-x64-msvc\": \"0.3.2\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-arm64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.2.tgz\",\n      \"integrity\": \"sha512-l6wfSBUUbGJiCENT6272CDI8yoMuf0sZH56H5qz3HnAyVzenkOvmzyF6/lar54m986kdAQqWls4cLvDxiOuLxg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-darwin-x64\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.2.tgz\",\n      \"integrity\": \"sha512-OboExL7vEw+TRJQl3KkaEKU4K7PTdZPTInZ0fxMAtOpcWp7EKR+dQo68vc/iAOusB3xszHKxt7t+WpisItfdcg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-xtEK+1eg++3pHi6405NDXd80S3CGOFEGQIyVGCwjMGQFOLSzBGGCsrb/0GB4J19zd1o/8ftCd/HjZcbVAWWTLQ==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-arm64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-3cIsskJOXQ1yEVsImmCacY7O03tUTiWrmd54F05PnPFrDLkjbzodQ3b2gUWzfbzUZWl67ZTJd1CvVSzpe7XGzw==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-gnu\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.2.tgz\",\n      \"integrity\": \"sha512-ouPdphHNsyO7wqwa4hwahC5WqBglK/fIvMmhR/SXNZ9qruIpsA8ZZKIURaHMOv/2h2BbNGcyTX9uEk6+5rK/MQ==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-linux-x64-musl\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.2.tgz\",\n      \"integrity\": \"sha512-sRhwhiPbkpJMOUwXW1FZw9ks6xWyQhIhM0E8o3TXEXKSPKTE6whQLEk1R37iFITaI36vb6rSwLKTU1cb32gCoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-arm64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-IEwVealKfumu1HSSnama26yPuQC/uthRPK5IWtFsQUOGwOXaS1r9Bu7cGYH2jBHl3IT/JbxD4xzPq/2pM9uK0A==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-ia32-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-jYMnf6SFgguqROswwdsjJ1wvneD/5c16pVu9OD4DxNqhKNP5bHEw6L2N4DcJ89tpXMpJ6AlOpc0QuwzddiZ3tA==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/edr-win32-x64-msvc\": {\n      \"version\": \"0.3.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.2.tgz\",\n      \"integrity\": \"sha512-Byn4QuWczRy/DUUQM3WjglgX/jGVUURVFaUsmIhnGg//MPlCLawubBGRqsrMuvaYedlIIJ4I2rgKvZlxdgHrqg==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-common\": {\n      \"version\": \"4.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz\",\n      \"integrity\": \"sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-rlp\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz\",\n      \"integrity\": \"sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==\",\n      \"dev\": true,\n      \"bin\": {\n        \"rlp\": \"bin/rlp.cjs\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx\": {\n      \"version\": \"5.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz\",\n      \"integrity\": \"sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-common\": \"4.0.4\",\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"@nomicfoundation/ethereumjs-util\": \"9.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-tx/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util\": {\n      \"version\": \"9.0.4\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz\",\n      \"integrity\": \"sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@nomicfoundation/ethereumjs-rlp\": \"5.0.4\",\n        \"ethereum-cryptography\": \"0.1.3\"\n      },\n      \"engines\": {\n        \"node\": \">=18\"\n      },\n      \"peerDependencies\": {\n        \"c-kzg\": \"^2.1.2\"\n      },\n      \"peerDependenciesMeta\": {\n        \"c-kzg\": {\n          \"optional\": true\n        }\n      }\n    },\n    \"node_modules/@nomicfoundation/ethereumjs-util/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-chai-matchers\": {\n      \"version\": \"2.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.6.tgz\",\n      \"integrity\": \"sha512-Te1Uyo9oJcTCF0Jy9dztaLpshmlpjLf2yPtWXlXuLjMt3RRSmJLm/+rKVTW6gfadAEs12U/it6D0ZRnnRGiICQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai-as-promised\": \"^7.1.3\",\n        \"chai-as-promised\": \"^7.1.1\",\n        \"deep-eql\": \"^4.0.1\",\n        \"ordinal\": \"^1.0.3\"\n      },\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-ethers\": {\n      \"version\": \"3.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.5.tgz\",\n      \"integrity\": \"sha512-RNFe8OtbZK6Ila9kIlHp0+S80/0Bu/3p41HUpaRIoHLm6X3WekTd83vob3rE54Duufu1edCiBDxspBzi2rxHHw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"debug\": \"^4.1.1\",\n        \"lodash.isequal\": \"^4.5.0\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers\": {\n      \"version\": \"1.0.6\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.6.tgz\",\n      \"integrity\": \"sha512-a35iVD4ycF6AoTfllAnKm96IPIzzHpgKX/ep4oKc2bsUKFfMlacWdyntgC/7d5blyCTXfFssgNAvXDZfzNWVGQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"ethereumjs-util\": \"^7.1.4\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.9.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereum-cryptography\": {\n      \"version\": \"0.1.3\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz\",\n      \"integrity\": \"sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/pbkdf2\": \"^3.0.0\",\n        \"@types/secp256k1\": \"^4.0.1\",\n        \"blakejs\": \"^1.1.0\",\n        \"browserify-aes\": \"^1.2.0\",\n        \"bs58check\": \"^2.1.2\",\n        \"create-hash\": \"^1.2.0\",\n        \"create-hmac\": \"^1.1.7\",\n        \"hash.js\": \"^1.1.7\",\n        \"keccak\": \"^3.0.0\",\n        \"pbkdf2\": \"^3.0.17\",\n        \"randombytes\": \"^2.1.0\",\n        \"safe-buffer\": \"^5.1.2\",\n        \"scrypt-js\": \"^3.0.0\",\n        \"secp256k1\": \"^4.0.1\",\n        \"setimmediate\": \"^1.0.5\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-network-helpers/node_modules/ethereumjs-util\": {\n      \"version\": \"7.1.5\",\n      \"resolved\": \"https://registry.npmmirror.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz\",\n      \"integrity\": \"sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/bn.js\": \"^5.1.0\",\n        \"bn.js\": \"^5.1.2\",\n        \"create-hash\": \"^1.1.2\",\n        \"ethereum-cryptography\": \"^0.1.3\",\n        \"rlp\": \"^2.2.4\"\n      },\n      \"engines\": {\n        \"node\": \">=10.0.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-toolbox\": {\n      \"version\": \"4.0.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz\",\n      \"integrity\": \"sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA==\",\n      \"dev\": true,\n      \"peerDependencies\": {\n        \"@nomicfoundation/hardhat-chai-matchers\": \"^2.0.0\",\n        \"@nomicfoundation/hardhat-ethers\": \"^3.0.0\",\n        \"@nomicfoundation/hardhat-network-helpers\": \"^1.0.0\",\n        \"@nomicfoundation/hardhat-verify\": \"^2.0.0\",\n        \"@typechain/ethers-v6\": \"^0.5.0\",\n        \"@typechain/hardhat\": \"^9.0.0\",\n        \"@types/chai\": \"^4.2.0\",\n        \"@types/mocha\": \">=9.1.0\",\n        \"@types/node\": \">=16.0.0\",\n        \"chai\": \"^4.2.0\",\n        \"ethers\": \"^6.4.0\",\n        \"hardhat\": \"^2.11.0\",\n        \"hardhat-gas-reporter\": \"^1.0.8\",\n        \"solidity-coverage\": \"^0.8.1\",\n        \"ts-node\": \">=8.0.0\",\n        \"typechain\": \"^8.3.0\",\n        \"typescript\": \">=4.5.0\"\n      }\n    },\n    \"node_modules/@nomicfoundation/hardhat-verify\": {\n      \"version\": \"2.0.5\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.5.tgz\",\n      \"integrity\": \"sha512-Tg4zu8RkWpyADSFIgF4FlJIUEI4VkxcvELsmbJn2OokbvH2SnUrqKmw0BBfDrtvP0hhmx8wsnrRKP5DV/oTyTA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@ethersproject/abi\": \"^5.1.2\",\n        \"@ethersproject/address\": \"^5.0.2\",\n        \"cbor\": \"^8.1.0\",\n        \"chalk\": \"^2.4.2\",\n        \"debug\": \"^4.1.1\",\n        \"lodash.clonedeep\": \"^4.5.0\",\n        \"semver\": \"^6.3.0\",\n        \"table\": \"^6.8.0\",\n        \"undici\": \"^5.14.0\"\n      },\n      \"peerDependencies\": {\n        \"hardhat\": \"^2.0.4\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz\",\n      \"integrity\": \"sha512-1LMtXj1puAxyFusBgUIy5pZk3073cNXYnXUpuNKFghHbIit/xZgbk0AokpUADbNm3gyD6bFWl3LRFh3dhVdREg==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">= 12\"\n      },\n      \"optionalDependencies\": {\n        \"@nomicfoundation/solidity-analyzer-darwin-arm64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-darwin-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-freebsd-x64\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-arm64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-gnu\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-linux-x64-musl\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": \"0.1.1\",\n        \"@nomicfoundation/solidity-analyzer-win32-x64-msvc\": \"0.1.1\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz\",\n      \"integrity\": \"sha512-KcTodaQw8ivDZyF+D76FokN/HdpgGpfjc/gFCImdLUyqB6eSWVaZPazMbeAjmfhx3R0zm/NYVzxwAokFKgrc0w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-darwin-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-XhQG4BaJE6cIbjAVtzGOGbK3sn1BO9W29uhk9J8y8fZF1DYz0Doj8QDMfpMu+A6TjPDs61lbsmeYodIDnfveSA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"darwin\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-freebsd-x64\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.1.tgz\",\n      \"integrity\": \"sha512-GHF1VKRdHW3G8CndkwdaeLkVBi5A9u2jwtlS7SLhBc8b5U/GcoL39Q+1CSO3hYqePNP+eV5YI7Zgm0ea6kMHoA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"freebsd\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-g4Cv2fO37ZsUENQ2vwPnZc2zRenHyAxHcyBjKcjaSmmkKrFr64yvzeNO8S3GBFCo90rfochLs99wFVGT/0owpg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-WJ3CE5Oek25OGE3WwzK7oaopY8xMw9Lhb0mlYuJl/maZVo+WtP36XoQTb7bW/i8aAdHW5Z+BqrHMux23pvxG3w==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.1.tgz\",\n      \"integrity\": \"sha512-5WN7leSr5fkUBBjE4f3wKENUy9HQStu7HmWqbtknfXkkil+eNWiBV275IOlpXku7v3uLsXTOKpnnGHJYI2qsdA==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.1.tgz\",\n      \"integrity\": \"sha512-KdYMkJOq0SYPQMmErv/63CwGwMm5XHenEna9X9aB8mQmhDBrYrlAOSsIPgFCUSL0hjxE3xHP65/EPXR/InD2+w==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"linux\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-arm64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-VFZASBfl4qiBYwW5xeY20exWhmv6ww9sWu/krWSesv3q5hA0o1JuzmPHR4LPN6SUZj5vcqci0O6JOL8BPw+APg==\",\n      \"cpu\": [\n        \"arm64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==\",\n      \"cpu\": [\n        \"ia32\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc\": {\n      \"version\": \"0.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz\",\n      \"integrity\": \"sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==\",\n      \"cpu\": [\n        \"x64\"\n      ],\n      \"dev\": true,\n      \"optional\": true,\n      \"os\": [\n        \"win32\"\n      ],\n      \"engines\": {\n        \"node\": \">= 10\"\n      }\n    },\n    \"node_modules/@scure/base\": {\n      \"version\": \"1.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/base/-/base-1.1.1.tgz\",\n      \"integrity\": \"sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==\",\n      \"dev\": true\n    },\n    \"node_modules/@scure/bip32\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip32/-/bip32-1.1.0.tgz\",\n      \"integrity\": \"sha512-ftTW3kKX54YXLCxH6BB7oEEoJfoE2pIgw7MINKAs5PsS6nqKPuKk1haTF/EuHmYqG330t5GSrdmtRuHaY1a62Q==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@noble/secp256k1\": \"~1.6.0\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@scure/bip39\": {\n      \"version\": \"1.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@scure/bip39/-/bip39-1.1.0.tgz\",\n      \"integrity\": \"sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@noble/hashes\": \"~1.1.1\",\n        \"@scure/base\": \"~1.1.0\"\n      }\n    },\n    \"node_modules/@sentry/core\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/core/-/core-5.30.0.tgz\",\n      \"integrity\": \"sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/hub\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/hub/-/hub-5.30.0.tgz\",\n      \"integrity\": \"sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/minimal\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/minimal/-/minimal-5.30.0.tgz\",\n      \"integrity\": \"sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/node\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/node/-/node-5.30.0.tgz\",\n      \"integrity\": \"sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/core\": \"5.30.0\",\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/tracing\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"cookie\": \"^0.4.1\",\n        \"https-proxy-agent\": \"^5.0.0\",\n        \"lru_map\": \"^0.3.3\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/tracing\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/tracing/-/tracing-5.30.0.tgz\",\n      \"integrity\": \"sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/hub\": \"5.30.0\",\n        \"@sentry/minimal\": \"5.30.0\",\n        \"@sentry/types\": \"5.30.0\",\n        \"@sentry/utils\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/types\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/types/-/types-5.30.0.tgz\",\n      \"integrity\": \"sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==\",\n      \"dev\": true,\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@sentry/utils\": {\n      \"version\": \"5.30.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@sentry/utils/-/utils-5.30.0.tgz\",\n      \"integrity\": \"sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@sentry/types\": \"5.30.0\",\n        \"tslib\": \"^1.9.3\"\n      },\n      \"engines\": {\n        \"node\": \">=6\"\n      }\n    },\n    \"node_modules/@solidity-parser/parser\": {\n      \"version\": \"0.14.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@solidity-parser/parser/-/parser-0.14.3.tgz\",\n      \"integrity\": \"sha512-29g2SZ29HtsqA58pLCtopI1P/cPy5/UAzlcAXO6T/CNJimG6yA8kx4NaseMyJULiC+TEs02Y9/yeHzClqoA0hw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"antlr4ts\": \"^0.5.0-alpha.4\"\n      }\n    },\n    \"node_modules/@tsconfig/node10\": {\n      \"version\": \"1.0.9\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.9.tgz\",\n      \"integrity\": \"sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node12\": {\n      \"version\": \"1.0.11\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz\",\n      \"integrity\": \"sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node14\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz\",\n      \"integrity\": \"sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@tsconfig/node16\": {\n      \"version\": \"1.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.3.tgz\",\n      \"integrity\": \"sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@typechain/ethers-v6\": {\n      \"version\": \"0.5.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz\",\n      \"integrity\": \"sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"lodash\": \"^4.17.15\",\n        \"ts-essentials\": \"^7.0.1\"\n      },\n      \"peerDependencies\": {\n        \"ethers\": \"6.x\",\n        \"typechain\": \"^8.3.2\",\n        \"typescript\": \">=4.7.0\"\n      }\n    },\n    \"node_modules/@typechain/hardhat\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@typechain/hardhat/-/hardhat-9.1.0.tgz\",\n      \"integrity\": \"sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"fs-extra\": \"^9.1.0\"\n      },\n      \"peerDependencies\": {\n        \"@typechain/ethers-v6\": \"^0.5.1\",\n        \"ethers\": \"^6.1.0\",\n        \"hardhat\": \"^2.9.9\",\n        \"typechain\": \"^8.3.2\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/fs-extra\": {\n      \"version\": \"9.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz\",\n      \"integrity\": \"sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"at-least-node\": \"^1.0.0\",\n        \"graceful-fs\": \"^4.2.0\",\n        \"jsonfile\": \"^6.0.1\",\n        \"universalify\": \"^2.0.0\"\n      },\n      \"engines\": {\n        \"node\": \">=10\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/jsonfile\": {\n      \"version\": \"6.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz\",\n      \"integrity\": \"sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"universalify\": \"^2.0.0\"\n      },\n      \"optionalDependencies\": {\n        \"graceful-fs\": \"^4.1.6\"\n      }\n    },\n    \"node_modules/@typechain/hardhat/node_modules/universalify\": {\n      \"version\": \"2.0.1\",\n      \"resolved\": \"https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz\",\n      \"integrity\": \"sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"engines\": {\n        \"node\": \">= 10.0.0\"\n      }\n    },\n    \"node_modules/@types/bn.js\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/bn.js/-/bn.js-5.1.1.tgz\",\n      \"integrity\": \"sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/chai\": {\n      \"version\": \"4.3.14\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai/-/chai-4.3.14.tgz\",\n      \"integrity\": \"sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/chai-as-promised\": {\n      \"version\": \"7.1.8\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz\",\n      \"integrity\": \"sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/chai\": \"*\"\n      }\n    },\n    \"node_modules/@types/concat-stream\": {\n      \"version\": \"1.6.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/concat-stream/-/concat-stream-1.6.1.tgz\",\n      \"integrity\": \"sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/form-data\": {\n      \"version\": \"0.0.33\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/form-data/-/form-data-0.0.33.tgz\",\n      \"integrity\": \"sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/glob\": {\n      \"version\": \"7.2.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/glob/-/glob-7.2.0.tgz\",\n      \"integrity\": \"sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==\",\n      \"dev\": true,\n      \"peer\": true,\n      \"dependencies\": {\n        \"@types/minimatch\": \"*\",\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/lru-cache\": {\n      \"version\": \"5.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/lru-cache/-/lru-cache-5.1.1.tgz\",\n      \"integrity\": \"sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/minimatch\": {\n      \"version\": \"5.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/minimatch/-/minimatch-5.1.2.tgz\",\n      \"integrity\": \"sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/mocha\": {\n      \"version\": \"9.1.1\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/mocha/-/mocha-9.1.1.tgz\",\n      \"integrity\": \"sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/node\": {\n      \"version\": \"18.15.13\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/node/-/node-18.15.13.tgz\",\n      \"integrity\": \"sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==\",\n      \"dev\": true\n    },\n    \"node_modules/@types/pbkdf2\": {\n      \"version\": \"3.1.0\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz\",\n      \"integrity\": \"sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@types/prettier\": {\n      \"version\": \"2.7.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.3.tgz\",\n      \"integrity\": \"sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/qs\": {\n      \"version\": \"6.9.7\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/qs/-/qs-6.9.7.tgz\",\n      \"integrity\": \"sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==\",\n      \"dev\": true,\n      \"peer\": true\n    },\n    \"node_modules/@types/secp256k1\": {\n      \"version\": \"4.0.3\",\n      \"resolved\": \"https://registry.npmmirror.com/@types/secp256k1/-/secp256k1-4.0.3.tgz\",\n      \"integrity\": \"sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==\",\n      \"dev\": true,\n      \"dependencies\": {\n        \"@types/node\": \"*\"\n      }\n    },\n    \"node_modules/@ungap/promise-all-settled\": {\n      \"version\": \"1.1.2\",\n      \"resolved\": \"https://registry.npmmirror.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz\",\n      \"integrity\": \"sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsm\n\n<!-- File: Topics/Tools/TOOL06_Hardhat/package.json (Tokens: ~179 | Category: anthropic-skill) -->\n{\n  \"name\": \"tool06_hardhat\",\n  \"version\": \"1.0.0\",\n  \"description\": \"我最近在重新学solidity，巩固一下细节，也写一个“WTF Solidity极简入门”，供小白们使用），每周更新1-3讲。\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@nomicfoundation/hardhat-toolbox\": \"^4.0.0\",\n    \"hardhat\": \"^2.22.2\"\n  },\n  \"directories\": {\n    \"test\": \"test\"\n  }\n}\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json (Tokens: ~300 | Category: anthropic-skill) -->\n# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193264.json)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json (Tokens: ~300 | Category: anthropic-skill) -->\n# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-1666193265.json)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json (Tokens: ~300 | Category: anthropic-skill) -->\n# 1 Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/broadcast/Counter.s.sol/1/run-latest.json)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Forge-std Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/package.json)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json (Tokens: ~300 | Category: anthropic-skill) -->\n# Fixtures Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/forge-std/src/test/fixtures/broadcast.log.json)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/better-tires-pull.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/blue-jars-lay.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/bright-cooks-brush.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/config.json)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/curly-pandas-flow.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/flat-flies-hear.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/fruity-coats-smash.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/gentle-apples-dance.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/happy-pants-decide.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/smooth-cows-notice.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/spicy-seals-bake.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/sweet-houses-cheer.md)\n\n<!-- File: Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md (Tokens: ~300 | Category: anthropic-skill) -->\n# .changeset Skill\n\nPath: `Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/AmazingAng/WTF-Solidity/HEAD/Topics/Tools/TOOL07_Foundry/hello_wtf/lib/openzeppelin-contracts/.changeset/tangy-jokes-begin.md)\n\n<!-- ... +56 more modular skills available via /api/skills/AmazingAng/WTF-Solidity?path={path} -->\n</yakaai_skills>"}