- It runs all on-chain calls in a simulated environment first, which allows the effects of on-chain calls to be validated before they cost gas.
- It exposes Foundry cheatcodes, which allow for deep instrumentation and customization of the EVM environment. These cheatcodes in turn allow OP Deployer to call into Solidity scripts.
- Easy integration with existing Solidity-based tooling.
- Detailed stack traces when deployments fail.
- Fast feedback loops that prevent sending on-chain transactions that may fail.
- Live chain forking.
vm.broadcast to signal a transaction that should be sent on-chain.
Why Use Solidity Scripts?
Solidity scripts are much more ergonomic than Go code for complex on-chain interactions. They allow for:- Easy integration with existing Solidity-based tooling and libraries.
- Simple ABI encoding/decoding.
- Clear separation of concerns between inter-contract calls, and the underlying RPC calls that drive them.
Engine Implementation
The scripting engine is implemented in theop-chain-ops/script package. It extends Geth’s EVM implementation with
Forge cheatcodes, and defines some tools that allow Go structs to be etched into the EVM’s memory. Geth exposes
hooks that drive most of the engine’s behavior. The best way to understand these further is to read the code.
Using the Engine
OP Deployer uses the etching tooling described above to communicate between OP Deployer and the scripting engine. Most Solidity scripts define an input contract, an output contract, and the script itself. The script reads data from fields on the input contract, then sets fields on the output contract as it runs. OP Deployer defines the input and output contracts as Go structs, like this:evm: struct tag to customize the behavior of these getters and setters.
Finally, the script itself gets etched into the EVM’s memory and executed, like this: