How to customize ArbOS on your Orbit chain
Customizations require expertise
Customizing your chain is a core benefit of building with Arbitrum Orbit. We strongly recommend that teams interested in customizations work alongside a partner with ArbOS and Nitro software expertise, such as a Rollup-as-a-Service team.
Working alongside an experienced Orbit operator can help your team navigate the complex tradeoff space of rollup customizations, which can include performance, security, and cost considerations. Offchain Labs is positioned to train and enable Rollup-as-a-Service in their work with clients to scale support to the Orbit ecosystem as a whole. As such, Offchain Labs does not necessarily have the capacity to review code changes made by individual Orbit chains.
We encourage you to leverage your in-house expertise, collaborate with expert partners, and allocate appropriate resources for both an initial implementation (including an audit) and ongoing maintenance and security management of your customization.
Cases where you may want to consider customizing your own ArbOS upgrade
-
When you want to make changes to your Nitro code that affect the State Transition Function, or STF (you may refer to the Customize STF docs), and
-
If your desired changes need to be made to a live and operational Orbit chain
If your changes meet both those 2 points, then you will need a custom ArbOS upgrade.
Also, if you made changes to a live and operational chain and want to upgrade them later in the future, then you will likely need an ArbOS upgrade to facilitate the upgrade.
Where should I insert ArbOS Upgrade related code?
Below, you will find 4 examples of ArbOS-related code changes and, generally, how to make them:
1. Add a new method to exsiting precompile on a specific ArbOS version:
After you add sayHi()
to ArbSys.go
according to the guide in customize precompile option 1,
you need continue to modify precompile.go.
For example, the original code is:
ArbSys := insert(MakePrecompile(pgen.ArbSysMetaData, &ArbSys{Address: types.ArbSysAddress}))
arbos.ArbSysAddress = ArbSys.address
arbos.L2ToL1TransactionEventID = ArbSys.events["L2ToL1Transaction"].template.ID
arbos.L2ToL1TxEventID = ArbSys.events["L2ToL1Tx"].template.ID
You need to append the following code to it:
ArbSys := insert(MakePrecompile(pgen.ArbSysMetaData, &ArbSys{Address: types.ArbSysAddress}))
arbos.ArbSysAddress = ArbSys.address
arbos.L2ToL1TransactionEventID = ArbSys.events["L2ToL1Transaction"].template.ID
arbos.L2ToL1TxEventID = ArbSys.events["L2ToL1Tx"].template.ID
// The arbos version control logic
ArbOwner.methodsByName["SayHi"].arbosVersion = ${The arbos version you want to activate this method}
In this way, this method will be executed normally and return results only after you update ArbOS to the target version.
2. Create a new precompile contract on a specific ArbOS version
After you add a new precompile named ArbHi
according to the guide in customize precompile option 2 and make changes to precompile.go,
you also need to make the following changes:
ArbHi := insert(MakePrecompile(pgen.ArbHiMetaData, &ArbHi{Address: types.ArbHiAddress})) // types.ArbHiAddress here is an example address
// Set activate version to the precompile
ArbHi.arbosVersion = ${The arbos version you want to activate this precompile}
// Set activate version to all method
for _, method := range ArbHi.methods {
method.arbosVersion = ${The arbos version you want to activate this precompile}
}
In this way, ArbHi and all its methods will be activated after the ArbOS version you set.