I’ve made a tool to deploy Safe contracts on a blockchain based on the presigned trasaction from this repo.

Multi-sig wallets are a great way to secure your funds, they are also a safe way to interact with your smart contract to call some sensitive functions. This post will show you how to deploy Safe contracts to enable multi-sig for a blockchain.

To deploy a Safe multi-sig contract on a blockchain, several Safe contracts are necessary to be deployed first. They are:

  • GnosisSafeProxyFactory
  • GnosisSafe and GnosisSafeL2
  • DefaultCallbackHandler and CompatibilityFallbackHandler
  • MultiSend and MultiSendCallOnly
  • CreateCall
  • SignMessageLib
  • SimulateTxAccessor

Three Repositories

Safe (privious Gnosis Safe) provides three different repositories to deploy Safe contracts on a blockchains:

Deploy Safe Single Factory

Through a contract which can call create2 opcode to deploy contracts, we can deploy a contract with a deterministic address, due to

new_contract_address = hash(0xFF, single_factory_address, salt, bytecode)

That means no matter when the transaction is issued, as long as the singleton factory address and the salt are fixed, the address is only determined by the bytecode of the deployed contract. Therefore, we can deploy the same contract on different blockchains with the same address.

To ensure that the Safe contracts on different blockchains have the same address, the Safe Singleton Factory is deployed on each blockchain firstly with the same nonce through a normal contract deployment transaction. Then the Safe contracts are deployed through the Safe Singleton Factory by calling create2 opcode on each blockchain .

There are two ways to deploy the Safe Singleton Factory on a blockchain:

  • Deploy the Safe Singleton Factory with the help from Safe team, they can issue a transction on each blockchain to deploy the Safe Singleton Factory with the same address (the same nonce and bytecode);
  • Deploy the Safe Singleton Factory by yourself. You can deploy the Safe Singleton Factory on a blockchain by using a presigned transaction without chain ID included, which is provided in this repo https://github.com/Arachnid/deterministic-deployment-proxy.

Entrance A: Safe Preisgned Transaction

To get a presigned transaction from Safe team to deploy the Safe Singleton Factory on a blockchain, an issue should be opened on the Safe Singleton Factory repo and provide necessary information to publish a presigned transaction for a given blockchain.

Safe team requires the following information to publish a presigned transaction:

  • The blockchain name
  • The blockchain ID
  • The link to chainlist.org for the blockchain
  • RPC url for the blockchain
  • Explorer url for the blockchain
  • Necessary native token transfer to the signer address 0xE1CB04A0fA36DdD16a06ea828007E35e1a3cBC37

The presigned transaction issued by Safe team is obeying EIP-155, which requires the chain ID to be signed within transaction to protect replay attck. The chain ID is the ID of the target blockchain, which can be found on chainlist.org.

Safe team will periodically publish a presigned transaction on the artifacts folder in the Safe Singleton Factory repo for the given blockchain. For example, the presigned transaction for the base blockchain is published as

{
	"gasPrice": 200000000,
	"gasLimit": 100000,
	"signerAddress": "0xE1CB04A0fA36DdD16a06ea828007E35e1a3cBC37",
	"transaction": "0xf8a680840bebc200830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf382422ea08dd745c4f66575e8d66550978dd6fd6d7f15236dc7bcc0360cfa2abd090c6a82a06b53e59bc854a90820624342e9aaa6b9fac224f1efe90a8466ce6e03d65c9bb1",
	"address": "0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7"
}

The presigned transaction can be submitted to deploy the Safe Singleton Factory contract on the target blockchain. The signer of this transaction is 0xE1CB04A0fA36DdD16a06ea828007E35e1a3cBC37, and this presigned transaction is always the very first transaction of this account on the target blockchain, that means nonce=0.

Before you can submit the transaction successfully, amount of native gas token on the target blockchain must be transfered to the signer address. Usually, 0.001 is enough to execute this presigned transaction.

After token transfered, please set a proper RPC url for the target blockchain in the .env file

RPC="an available RPC url for the target blockchain"

And run yarn submit to relay the presigned transaction to the RPC node of the target blockchain. The Safe Singleton Factory contract will be deployed on the target blockchain with the same address as other blockchains.

Bingo, you got the entry point to deploy Safe contracts deterministically on your chain.

Entrance B: Universal Preisgned Transaction

For some reason, the Safe team cannot always respose quickly to the request for deploying the Safe Singleton Factory on a blockchain. In this case, you can deploy the Safe Singleton Factory by yourself, which is called here as Universal Presigned Transaction.

Before EIP-155, the chain ID is not included in the transaction signature, which means the same transaction can be replayed on different blockchains. This is a security issue, because the transaction on one blockchain can be replayed on another blockchain, which may cause unexpected result, such as stealing token. And the Safe team also decide to sign transaction with chain ID included, but there is an open Singleton Facotry contract can be deployed on different blockchains with the same address

To do so, we need a presigned transaction without chainID included, which is published on this repository. You can create a deployment.json file under the /artifacts/<chainID>/ folder and paste the presigned transaction into it. For example, the deployment.json file for the Orderly mainnet is under /artifacts/291/

{
	"gasPrice": 100,
	"gasLimit": 100000,
	"signerAddress": "0x3fab184622dc19b6109349b94811493bf2a45362",
	"transaction": "0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",
	"address": "0x4e59b44847b379578588920ca78fbf26c0b4956c"
}

Through this presigned transaction, we can deploy the Safe Singleton Factory on the target blockchain with the address = 0x4e59b...4956c. And of course, you should transfer some native token to the signer address 0x3fab1...45362 and set proper RPC url in .env file before you can submit this transaction.

Some RPC provider doesn’t support transaction without chain ID included, you need choose a proper one, or you can set a local node to submit the transaction.

Deploy Safe Contracts

After the Singleton Factory is deployed on the target blockchain, we can deploy Safe contracts through it. All Safe contracts are included in this repo, and the version 1.3.0 is most popular one. You should first checkout to the v1.3.0-libs.0 branch, and then run yarn install to install the dependencies.

If you request a presigned transaction from Safe team, the deployment.json file is downloaded automatically into node_modules/@gnosis.pm/safe-singleton-factory/artifacts/<chainID>/ folder after yarn install. If you deployed the singleton factory by yourself, you should copy the deployment.json file into the node_modules/@gnosis.pm/safe-singleton-factory/artifacts/<Target chainID>/.

And set the private key in .evn file and proper network configuration into network filed of hardhat.config.ts, such as

network: {
	 orderly:{
      ...sharedNetworkConfig,
      url: "https://rpc.orderly.network"
    }
}

Then, execute the following command to deploy Safe contracts on the target blockchain

yarn deploy-all <network>

If you are lucky, you will get the following output

Verification status for SimulateTxAccessor: FAILURE
Verification status for GnosisSafeProxyFactory: SUCCESS
Verification status for DefaultCallbackHandler: SUCCESS
Verification status for CompatibilityFallbackHandler: SUCCESS
Verification status for CreateCall: SUCCESS
Verification status for MultiSend: FAILURE
Verification status for MultiSendCallOnly: SUCCESS
Verification status for SignMessageLib: SUCCESS
Verification status for GnosisSafeL2: SUCCESS
Verification status for GnosisSafe: SUCCESS

Now, you can find the deployed Safe contracts on the target blockchain and the addresses are the same as other blockchains, if both Singleton Factory contracts are deployed with the same way (Entrance A or Entrance B). For Entrance B, the addresses are listed here below:

Contract Name Contract Address
GnosisSafeProxyFactory 0xa6B71E26C5e0845f74c812102Ca7114b6a896AB2
GnosisSafe 0xd9Db270c1B5E3Bd161E8c8503c55cEABeE709552
GnosisSafeL2 0x3E5c63644E683549055b9Be8653de26E0B4CD36E
DefaultCallbackHandler 0x1AC114C2099aFAf5261731655Dc6c306bFcd4Dbd
CompatibilityFallbackHandler 0xf48f2B2d2a534e402487b3ee7C18c33Aec0Fe5e4
MultiSend 0xA238CBeb142c10Ef7Ad8442C6D1f9E89e07e7761
MultiSendCallOnly 0x40A2aCCbd92BCA938b02010E17A5b8929b49130D
CreateCall 0x7cbB62EaA69F79e6873cD1ecB2392971036cFAa4
SignMessageLib 0xA65387F16B013cf2Af4605Ad8aA5ec25a2cbA3a2
SimulateTxAccessor 0x59AD6735bCd8152B84860Cb256dD9e96b85F69Da

Publish Safe Contracts

Once the ten contracts are deployed on the target blockchain, you should publish the addresses of them on the Safe Deployments repo through a PR request.

Becuase there are two ways to deploy the Singleton Factory contract, so you can find there are two different addresses for each Safe contract, such as this ProxyFactory address file due to the deterministica deployment.

safe_contract_address = hash(0xFF, singleton_factory_address, salt, bytecode)

Once your PR has been merged into this repo, other projects now can deploy Safe multi-sig contracts through these Safe contracts on the your blockchain.

Good luck and happy building!

Summary

In this article, we explained how to deploy Safe contracts on a blockchain. The entry point Signleton Factory contract is most critical part to deploy Safe contracts deterministically on a blockchain. There are two ways to deploy the Singleton Factory contract on a blockchain, one is to request a presigned transaction from Safe team, and the other is to deploy the Singleton Factory contract by yourself. After the Singleton Factory contract is deployed, you can deploy Safe contracts through it. Finally, you should publish the addresses of deployed Safe contracts on the Safe Deployments repo.

Next article, we will show you how to deploy Safe multi-sig contracts on a blockchain through the deployed Safe contracts, and introduce how to interact with Safe multi-sig contract to execute onchain actions.