prompt
签名
function prompt(string calldata promptText) external returns (string memory input);
function promptSecret(string calldata promptText) external returns (string memory input);
function promptSecretUint(string calldata promptText) external returns (uint256);
描述
向用户显示一个交互式提示,以插入任意数据。
vm.prompt
显示一个交互式输入,而 vm.promptSecret
和 vm.promptSecretUint
显示一个隐藏输入,用于密码和其他不应泄露到终端的秘密信息。
ℹ️ 注意
此作弊码旨在用于脚本中——而不是测试中。还建议遵循以下最佳实践,以测试使用
vm.prompt
的脚本并处理超时,因为脚本可能会挂起或回滚。此作弊码在非交互式 shell 中运行时会回滚。
配置
为了防止不必要的挂起,vm.prompt
有一个超时配置。
在你的 foundry.toml
中:
prompt_timeout = 120
默认值为 120
,单位为秒。
最佳实践
测试使用 vm.prompt
的脚本
在测试包含 vm.prompt
的脚本时,建议使用以下模式:
contract Script {
function run() public {
uint256 myUint = vm.parseUint(vm.prompt("enter uint"));
run(myUint);
}
function run(uint256 myUint) public {
// actual logic
}
}
这样,我们可以保持用户体验的提升(在运行脚本时不必提供 --sig
参数),但测试可以将任何值设置为 myUint
,而不仅仅是硬编码的默认值。
处理超时
当用户未能在超时到期之前提供输入时,vm.prompt
作弊码会回滚。如果需要,可以通过使用 try/catch
来处理超时:
string memory input;
try vm.prompt("Username") returns (string memory res) {
input = res;
}
catch (bytes memory) {
input = "Anonymous";
}
示例
选择 RPC 端点
提供选择要运行的 RPC/链的选项。
在你的 foundry.toml
文件中:
[rpc_endpoints]
mainnet = "https://eth.llamarpc.com"
polygon = "https://polygon.llamarpc.com"
在你的脚本中:
string memory rpcEndpoint = vm.prompt("RPC endpoint");
vm.createSelectFork(rpcEndpoint);
将用户输入解析为原生类型
我们可以使用字符串解析作弊码来解析用户的响应:
uint privateKey = vm.promptSecretUint("Private key");
address to = vm.parseAddress(vm.prompt("Send to"));
uint amount = vm.parseUint(vm.prompt("Amount (wei)"));
vm.broadcast(privateKey);
payable(to).transfer(amount);