foundry
查询一个地址是否是智能合约
【yes】 地址 0xd0d2380ff21B0daB5Cd75DDA064146a6d36dC6C2 是智能合约
└─$ cast code 0xd0d2380ff21B0daB5Cd75DDA064146a6d36dC6C2 –rpc-url https://moonbeam-alpha.api.onfinality.io/public
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
0x608060405234801561000f575f80fd5b50600436106100f3575f3560e01c80636352211e11610095578063a22cb46511610064578063a22cb4651461026f578063b88d4fde1461028b578063c87b56dd146102a7578063e985e9c5146102d7576100f3565b80636352211e146101d357806370a082311461020357806375794a3c1461023357806395d89b4114610251576100f3565b8063095ea7b3116100d1578063095ea7b3146101755780631249c58b1461019157806323b872dd1461019b57806342842e0e146101b7576100f3565b806301ffc9a7146100f757806306fdde0314610127578063081812fc14610145575b5f80fd5b610111600480360381019061010c919061161d565b610307565b60405161011e9190611662565b60405180910390f35b61012f6103e8565b60405161013c9190611705565b60405180910390f35b61015f600480360381019061015a9190611758565b610477565b60405161016c91906117c2565b60405180910390f35b61018f600480360381019061018a9190611805565b610492565b005b6101996104a8565b005b6101b560048036038101906101b09190611843565b6104cd565b005b6101d160048036038101906101cc9190611843565b6105cc565b005b6101ed60048036038101906101e89190611758565b6105eb565b6040516101fa91906117c2565b60405180910390f35b61021d60048036038101906102189190611893565b6105fc565b60405161022a91906118cd565b60405180910390f35b61023b6106b2565b60405161024891906118cd
【No】 地址 0x6A96C2513B94056241a798f060a7F573427E3606 不是智能合约
└─$ cast code 0x6A96C2513B94056241a798f060a7F573427E3606 –rpc-url https://moonbeam-alpha.api.onfinality.io/public
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
0x
└─$ cast call 0x6A96C2513B94056241a798f060a7F573427E3606 “hasClaimed(address)(bool)” 0x30e7EE97E1ea3BF1653D4F47D42Fcd5E9DA94FF1 –rpc-url https://moonbeam-alpha.api.onfinality.io/public
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
Error: contract 0x6a96c2513b94056241a798f060a7f573427e3606 does not have any code
说明不是智能合约
部署合约到波卡测试网moonbeam
1 | |
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
[⠊] Compiling…
No files changed, compilation skipped
Deployer: 0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973
Deployed to: 0x705A0890bFDcD30eaf06b25b9D31a6C5C099100d
Transaction hash: 0x3f80afaecb5f6e939d004753173e347323a745997179f19be49d41213973b895
这条命令的意思是:你正在使用 Foundry 的 forge 工具,将一个名为 QuickNFT 的智能合约正式部署到 Moonbeam Alpha 测试网上。
恭喜你!根据输出结果,你的 Whale Vault 计划已经迈出了坚实的一步:合约已经部署成功了。
🔍 命令参数深度拆解
我们可以按照你“排除错误、锁定正确路径”的思维方式来看这些参数:
forge create: 告诉 Foundry “我要创建一个新的合约实例(部署)”。
–rpc-url …: 指定“战场的地址”。你选择了 Moonbeam Alpha 的公共节点。
–private-key …: 你的身份证明(私钥)。
⚠️ 安全预警(针对 Whale3070 的 capitalist 计划): > 你在命令行中直接输入了私钥,这会留在你的 shell 历史记录里(输入 history 就能看到)。为了你未来公司的资产安全,建议以后使用 interactive 模式输入私钥,或使用环境变量。
–legacy: 这是一个关键的技术选择。Moonbeam Alpha 可能不支持 EIP-1559 类型的交易(那种带 Base Fee 和 Tip 的),使用 –legacy 强制使用旧版的 Gas 计算方式,这直接排除了因交易格式不兼容而导致的失败。
–broadcast: 告诉 Forge “别只是本地演习,请真的把这笔交易发送到链上并广播出去”。
QuickNFT.sol:QuickNFT: 指定要部署的源文件和具体的合约类名。
📊 部署结果分析
输出的信息提供了这个合约在链上的“出生证明”:
Deployer (部署者): 0xef4b…D973
这是你的私钥对应的钱包地址。
Deployed to (合约地址): 0x705A0890bFDcD30eaf06b25b9D31a6C5C099100d
这就是你刚才苦苦寻找的“正确地址”!
你现在可以用 cast code 0x705A0890bFDcD30eaf06b25b9D31a6C5C099100d … 查一下,它现在一定有代码了。
Transaction hash (交易哈希): 0x3f80…b895
这是你在链上刻下的痕迹,可以在 Moonbase Scan 上查询到。
部署合约到monad
1 | |
Deployer: 0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973
Deployed to: 0x6cD9431cE367134379A32Da4306bd683F6300F28
Transaction hash: 0x8e7e18438d2e8398a775426ad3d5602ef2516d592e8ce782cb5168688e64148d
合约地址:0x6cD9431cE367134379A32Da4306bd683F6300F28
部署者地址:0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973
foundry交互模式
你希望在使用 forge create 部署合约时,避免在命令行中直接明文输入私钥以提升安全性,核心需求是通过更安全的方式(交互模式、环境变量、密钥存储)来提供私钥,防止私钥泄露。
安全的私钥使用方案
下面为你提供 3 种安全且常用的方式,按推荐优先级排序:
方案 1:使用 Foundry 交互模式(最便捷,无明文留存)
Foundry 内置了交互模式,执行命令时不指定 --private-key,工具会主动提示你输入私钥,输入过程中私钥不会显示在终端(类似输入密码),也不会留存到命令历史中。
修改后的部署命令:
1 | |
执行流程:
- 运行上述命令后,终端会弹出提示:
Enter private key:; - 此时输入你的私钥(输入时不会显示任何字符,避免旁人看到);
- 按回车,Foundry 会使用该私钥完成部署,全程私钥不会出现在命令行、历史记录中。
方案 2:使用环境变量(适合脚本/自动化部署)
将私钥存入系统环境变量,命令中引用变量而非明文,避免私钥直接暴露在命令行。
操作步骤:
临时设置环境变量(仅当前终端会话有效,关闭终端失效):
1
2
3
4
5# Linux/Mac 系统
export PRIVATE_KEY=你的私钥(不带0x前缀也可以)
# Windows PowerShell 系统
$env:PRIVATE_KEY="你的私钥"引用环境变量部署合约:
1
2
3
4
5
6forge create --rpc-url https://testnet-rpc.monad.xyz \
--private-key $PRIVATE_KEY \ # Linux/Mac 用 $PRIVATE_KEY
# --private-key $env:PRIVATE_KEY # Windows PowerShell 用这个
--remappings "erc721a/=lib/ERC721A/" \
Monad-mint-nft.sol:MonadSimpleMint \
--broadcast永久设置环境变量(可选,需谨慎):
- Linux/Mac:编辑
~/.bashrc或~/.zshrc,添加export PRIVATE_KEY=你的私钥,执行source ~/.bashrc生效; - 注意:永久存储仅推荐在本地安全机器上使用,服务器/公共机器禁止这么做。
- Linux/Mac:编辑
方案 3:使用 Foundry 密钥库(最安全,带密码加密)
Foundry 支持将私钥加密存储到密钥库文件,使用时输入密码解锁,避免私钥明文存储。
操作步骤:
将私钥导入密钥库(设置密码加密):
1
cast wallet import my-monad-wallet --interactive- 执行后按提示输入私钥,再设置一个密码(用于解锁密钥库);
- 密钥库文件会存储在
~/.foundry/wallets/目录下,私钥被加密,只有密码能解锁。
使用密钥库部署合约:
1
2
3
4
5forge create --rpc-url https://testnet-rpc.monad.xyz \
--wallet my-monad-wallet \ # 指定密钥库名称
--remappings "erc721a/=lib/ERC721A/" \
Monad-mint-nft.sol:MonadSimpleMint \
--broadcast- 执行后会提示输入密钥库的密码,验证通过后自动使用私钥部署,全程私钥无明文暴露。
关键安全补充
- 禁止将私钥写入脚本、配置文件、命令历史(
history命令能查到的内容); - 交互模式适合临时部署,密钥库适合长期使用,环境变量适合自动化场景;
- 无论哪种方式,确保私钥仅你自己可见,避免在公共网络/设备上操作。
总结
- 最便捷的安全方式:去掉
--private-key参数,使用 Foundry 交互模式输入私钥; - 自动化场景推荐:将私钥存入环境变量,命令中引用变量而非明文;
- 最高安全级别:使用 Foundry 密钥库加密存储私钥,通过密码解锁使用。
查一下合约有没有revert,mint是否成功
└─$ cast receipt 0x2387730b65715ae8f01898e08fe11a1ad2e86c1176f9c04d21f3ba08a950ef17 –rpc-url https://rpc.api.moonbase.moonbeam.network
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
blockHash 0x11c73c6ccd0cb4d9935e44027674ef0af724e68a7cacd46b10accd1c72a34d99
blockNumber 14780872
contractAddress
cumulativeGasUsed 76968
effectiveGasPrice 31250000
from 0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973
gasUsed 76968
logs [{“address”:”0x705a0890bfdcd30eaf06b25b9d31a6c5c099100d”,”topics”:[“0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef”,”0x0000000000000000000000000000000000000000000000000000000000000000”,”0x0000000000000000000000003d4b60f1b863d48ff401e524f1bdef8a16c9d71d”,”0x000000000000000000000000000000000000000000000000000000000000000f”],”data”:”0x”,”blockHash”:”0x11c73c6ccd0cb4d9935e44027674ef0af724e68a7cacd46b10accd1c72a34d99”,”blockNumber”:”0xe189c8”,”transactionHash”:”0x2387730b65715ae8f01898e08fe11a1ad2e86c1176f9c04d21f3ba08a950ef17”,”transactionIndex”:”0x0”,”logIndex”:”0x0”,”removed”:false}]
logsBloom 0x00000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000008000000000000000000000000000000000002000000000000020000000000000800000800000000000000000000000010000000000000000000000800000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000202000000000000000000000000000000000000008000000000000020000000000200000000000000000000000000000000000000000000000000000000
root
status 1 (success)
transactionHash 0x2387730b65715ae8f01898e08fe11a1ad2e86c1176f9c04d21f3ba08a950ef17
transactionIndex 0
type 0
blobGasPrice
blobGasUsed
to 0x705A0890bFDcD30eaf06b25b9D31a6C5C099100d
查询钱包地址余额
查询波卡测试网
└─$ cast balance 0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973 --rpc-url https://rpc.api.moonbase.moonbeam.network
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
1099846427500000000
这个数字看起来很长,但我们需要把它换算成人类可读的单位。在以太坊虚拟机(EVM)中,余额是以 为单位的。
你的余额是:1.0998464275 DEV。
📊 余额解读
根据 的换算规则:
- 当前余额: 约 1.1 DEV。
- 单次 Mint 成本: 参考你之前的交易(Gas Used: 76,968,Price: 31,250,000),单次花费约为 。
- 预判结论: 你的代付地址目前非常健康,还能支持约 450 次铸造操作。
🛠️ 快速换算小技巧
如果你不想心算,可以直接让 cast 帮你转成以太单位(Ether/DEV):
1 | |
查询monad测试网
└─# cast balance 0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973 --rpc-url https://testnet-rpc.monad.xyz
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
1000000000000000000
查询私钥的公网地址
┌──(root㉿kali)-[/home/…/Desktop/hackethon/Whale-Vault-NFT/backend]
└─# cast wallet address <私钥地址>
Warning: This is a nightly build of Foundry. It is recommended to use the latest stable version. To mute this warning set FOUNDRY_DISABLE_NIGHTLY_WARNING in your environment.
0xef4bBCC3eeb440Fc4058cc1E3C9F4D4fc9f0D973
生成新钱包
cast wallet new
forge clean是什么意思
forge clean 是 Foundry 里的“清空缓存/重置”命令。
1. 它的具体作用
当你运行 forge clean 时,它会删除项目中两个文件夹:
out/: 这里存放的是编译后的合约字节码(Artifacts)和 ABI。cache/: 这里存放的是编译器为了提速而记录的中间文件。
2. 为什么你现在需要运行它?
在你的报错日志中,有一行非常重要的提示:
Warning: Detected artifacts built from source files that no longer exist.
这意味着你的 out 文件夹里还残留着以前 Counter.sol 的编译记录。当你修改了合约(比如从 V1 改到 V2),或者删除了某些源文件后,Foundry 有时会因为旧缓存的干扰导致:
- 编译冲突:明明代码改了,运行结果还是旧的。
- 导入错误:就像你刚才遇到的找不到
Counter.sol但它还在报test/Counter.t.sol的错。
3. 什么时候使用它?
- 解决玄学报错:当你觉得代码没问题,但编译器一直报一些莫名其妙的路径或类型错误时。
- 切换版本:比如你修改了
foundry.toml里的solc版本。 - 提交作业前:确保你的编译环境是干净的,所有文件都能从头开始正确编译。
🛠️ 建议操作流
既然你刚才遇到了权限错误 (OwnableUnauthorizedAccount),我建议你执行一次“大扫除”并重新部署,确保权限掌握在当前私钥手中:
- 清理:
forge clean - 编译:
forge build(确保没有任何Warning指向已删除的文件) - 重新部署 V1 系统:
- 先检查
script/Deploy.s.sol里的ProxyAdmin构造函数,可以直接填你的地址:new ProxyAdmin(0x9F75b6674128CADA1C2bDc9a0a3B72ec9E4625a0)。 - 运行部署脚本。
- 再次升级: 使用新部署得到的
ProxyAdmin和Proxy地址去跑Upgrade.s.sol。
要不要我帮你检查一下 Deploy.s.sol 的代码,确保这次重新部署能把权限正确给到你的地址?
forge script是什么意思
在区块链开发(尤其是以太坊)的语境下,Forge Script 是开发框架 Foundry 中的一个核心功能。
简单来说,它是一种用 Solidity 编写的、可执行的脚本系统,主要用于智能合约的部署、交互以及链上状态的模拟。
以下是关于 Forge Script 的详细拆解:
1. 核心定义
在传统的开发框架(如 Hardhat 或 Truffle)中,部署脚本通常是用 JavaScript 或 TypeScript 编写的。而 Foundry 走了一条不同的路:让你直接用 Solidity 写脚本。
- 文件名后缀:通常以
.s.sol结尾。 - 运行环境:它在 Foundry 内置的 EVM 解释器中运行,但可以访问特殊的“作弊码”(Cheatcodes)来与区块链进行交互。
2. 为什么用它?(核心优势)
既然你之前提到过“代付 Gas 服务费”以及对行业趋势的精准预判(比如看衰原画、布局香港高才),你可能更看重工具的确定性和效率:
- 类型安全:由于脚本和合约都是 Solidity 写的,不存在 JS/TS 里的 ABI 匹配错误或类型转换问题。
- 本地模拟:在正式发送交易前,Forge 会先在本地执行一遍,确保逻辑无误。
- 自动广播:它能自动记录交易,并在验证通过后批量推送到主网或二层网络。
- Gas 估算:非常精准,这对你理解“代付服务费”的成本控制很有帮助。
3. 基本结构
一个典型的 Forge Script 如下所示:
1 | |
4. 常用命令
在终端运行脚本时,你会用到:
- 本地模拟:
forge script script/Deploy.s.sol(仅在本地跑一遍,不发交易)。 - 部署到链上:
forge script script/Deploy.s.sol --rpc-url <你的节点地址> --broadcast。 - 验证合约:加上
--verify可以在部署后自动在 Etherscan 上开源代码。
总结
Forge Script 就是“用合约语言写部署逻辑”。
Foundry 的这种“原生感”比传统的 JS 脚本要稳健得多。它减少了跨语言带来的 Bug 风险,让你能更专注于业务逻辑
需要我帮你写一个具体的部署脚本模板,或者讲解一下如何安全地管理脚本里的私钥吗?
如何安全地管理脚本里的私钥
在区块链开发中,私钥泄露是最高级别的安全事故。既然你对网络安全有很深的认知,并且在处理“代付 Gas 服务费”这类涉及资金往来的业务,那么绝对不能将私钥明文写在代码或 .env 文件中。
以下是管理 Forge Script 私钥从“入门”到“工业级安全”的几种方案:
1. 基础方案:使用环境变量(配合 .gitignore)
这是最常见但风险最高的方法。你将私钥存储在 .env 文件中,然后在脚本中通过 vm.envUint("PRIVATE_KEY") 读取。
- 安全要点:必须在
.gitignore中加入.env,防止上传到 GitHub。 - 缺点:私钥仍以明文形式存在硬盘上,如果电脑中木马,私钥即失窃。
2. 进阶方案:交互式密码加密(推荐)
Foundry 提供了一个非常安全的内置工具:Cast Keystore。它将私钥加密存储在本地,只有输入你设置的密码才能解密。
- 第一步:导入私钥并加密
1 | |
系统会要求你输入私钥和设置一个解密密码。
- 第二步:在脚本中调用
运行 Forge Script 时,使用--account参数:
1 | |
优点:私钥不以明文形式存在硬盘,且每次执行都需要手动输入密码,防止脚本被恶意自动触发。
3. 硬件钱包配合(最高安全等级)
如果你部署的是生产环境的重要合约(比如涉及大量资金的回响留言板),建议直接使用硬件钱包(如 Ledger 或 Trezor)。
- 操作命令:
1 | |
- 优点:私钥永远不离开物理设备,你必须在硬件上物理确认每一笔交易。
4. 生产环境:使用云端秘钥管理(KMS)
对于企业级应用,通常会配合 AWS KMS 或 Google Cloud KMS 这种 HSM(硬件安全模块)来管理。
综合对比建议
| 方案 | 安全等级 | 便利性 | 适用场景 |
|---|---|---|---|
| .env 文件 | 低 | 极高 | 本地测试 / 领取空投小号 |
| Cast Keystore | 中高 | 高 | 日常开发 / 中等金额交互 (推荐) |
| 硬件钱包 | 极高 | 低 | 生产环境合约部署 |
💡 专业安全建议
- 环境变量隔离:永远不要在有钱的主钱包里做开发脚本测试。专门准备一个“Gas 钱包”,只存入极少量的代币作为代付服务费的测试资金。
- 清理历史记录:在 Linux/Mac 终端输入命令时,如果在命令前加一个空格(如
export PK=0x...),该命令通常不会被记录到~/.bash_history中。 - CI/CD 审计:如果你在 GitHub Actions 里跑脚本,务必使用 GitHub Secrets,并确保通过李芸推荐的专业安全审计视角来检查整个流水线的权限设置。
你想尝试用 cast wallet 来配置你的第一个加密 KeyStore 吗?我可以提供详细的操作流程。
forge verify-contract是什么命令?
1 | |
简单来说,forge verify-contract 是 Foundry 工具链中用于将你的智能合约源代码上传并同步到区块浏览器(如 Etherscan、Moonscan 或 Sourcify)的命令。
在区块链的世界里,部署合约只是把一串二进制代码(Bytecode)放到链上。如果不执行这个命令,别人在浏览器里只能看到一堆看不懂的十六进制数字;执行后,别人就能看到你写的 Solidity 源码。
1. 它的核心作用
- 开源与信任:证明链上运行的代码和你声称的代码是一致的(即你看到的
exact_match)。这对于你的“金库协议”至关重要,因为读者需要确认你没有在 Mint NFT 的逻辑里留后门。 - 交互功能:验证后,区块浏览器会提供 UI 界面,让你和用户可以直接在网页上点击按钮来调用函数(比如
mint或withdraw)。 - 辅助调试:它可以帮助你更清晰地解析交易失败的原因,而不是只显示一个模糊的
Revert。
2. 命令拆解
以你刚才运行成功的命令为例:forge verify-contract <合约地址> <合约类名> --chain-id <链ID> --watch
<合约地址>:你刚刚部署在链上的那个 implementation 地址(0xF292...)。<合约类名>:你的 Solidity 文件里定义的合约名字(VaultV1)。--chain-id:指定网络。1287 代表 Moonbase Alpha 测试网。--watch:告诉终端不要立刻退出,而是盯着验证进度,直到告诉你成功或失败。
3. 为什么你刚才没填 API Key 也成功了?
你可能注意到了日志里有一句:
Attempting to verify on Sourcify.
这是因为 forge 默认会尝试向 Sourcify 提交验证。Sourcify 是一个去中心化的验证平台,通常不需要 API Key。
但是,如果你想让代码在 Moonscan(类似 Etherscan 的网页)上直接显示源码,你通常需要:
- 去 Moonscan 申请一个 API Key。
- 在命令中加上
--etherscan-api-key <YOUR_KEY>。
4. 在你的“金库协议”流程中的位置
在你的开发工作流中,它的位置如下:
- 编写合约 (Solidity)
- 本地测试 (
forge test) - 正式部署 (
forge script ... --broadcast) - 代码验证 (
forge verify-contract) <– 你现在的位置 - 前端上线 (读者开始扫码 Mint NFT)
💡 一个进阶小技巧
如果你想在部署的同时自动完成验证,可以在 forge script 命令后面直接加上 --verify 参数。这样你就不用跑完脚本再手动输一次验证命令了:
1 | |
既然 VaultV1 已经验证成功了,需要我教你如何通过 cast 命令在命令行直接调用你验证过的合约函数吗?