cheatcode:prompt —— 为Script提供交互式输入
首先,我们先了解一下prompt
cheatcode
prompt
Signature
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);
Description
向用户显示插入任意数据的交互式提示。
vm.prompt
显示一个交互式输入,而vm.promptSecret
和vm.promptSecretUint
显示一个隐藏的输入,用于密码和其他不应泄漏到中断的秘密信息。
Note:
此 cheatcode 旨在用于脚本,而并非测试。
对于该 cheatcode,为了防止不必要的挂断,vm.prompt
有一个超时配置:
在 Foundry.toml 中:
prompt_timeout = 120
默认值为 120
,单位为秒
一个简单的例子
对于 Foundry init 后附带的三个默认合约,我们对Counter.s.sol
进行如下的修改:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
contract CounterScript is Script {
Counter public counter;
function setUp() public {}
function run() public {
vm.startBroadcast();
counter = new Counter();
uint256 number = vm.parseUint(vm.prompt("Set Number: "));
counter.setNumber(number);
vm.stopBroadcast();
}
}
其中:parseUint
cheatcode 的作用是将prompt
从命令行捕获的数据转换为 uint256
类型
我们运行一下:
可以看到,Foundry 为我们给出了一个交互的输入。我们在这里传入我们要设置的 number
即可。
使用这个 cheatcode,大大方便了我们在后续过程中多次修改 script 的问题。
不过有一点需要注意:该 cheatcode 在非交互式 shell 中运行时回滚。
这就引出了一个问题:如果我们按照这个例子的方式书写我们的 script 的话,我们这个脚本将无法在后续的 test 中集成。所以,这就可以展示我们的最佳实践了。
最佳实践
在 test 中集成包含vm.prompt
的脚本时,可以使用这样的模式:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import {Script, console} from "forge-std/Script.sol";
import {Counter} from "../src/Counter.sol";
contract CounterScript is Script {
Counter public counter;
function setUp() public {}
function run() public {
uint256 number = vm.parseUint(vm.prompt("Number: "));
run(number);
}
function run(uint256 myUint) public {
vm.startBroadcast();
counter = new Counter();
counter.setNumber(myUint);
vm.stopBroadcast();
}
}
这样,我们直接运行该脚本时,他会为我们提供可交互的环境来获取数据;当我们想要将其集成到 test 时,直接调用 run(uint256)
这个函数签名的 run
函数就可以了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Q1ngying!