I'm trying to programmatically (via ethers.js) submit a tx to a multisig--specifically a a DAO proposal--and the ABI for the deployed multisig on etherscan (https://etherscan.io/address/0xd9db270c1b5e3bd161e8c8503c55ceabee709552#code) only has execTransaction but not submitTransaction like some of the examples I've seen on Github, and I know execTransaction is for executing a previously approved transaction. How do I submit a tx for multisig approval from a script?

  • You seem to be confusing the Safe Core SDK and Safe Contract methods. For submitting a transaction through a script, please refer to the SDK docs.
    – mikheevm
    Commented May 30, 2023 at 18:33

1 Answer 1


Submitting a tx via the multi-sig has basically several stages:

  1. Create the transaction data, for example, to call some method in your DAO contract
  2. Use some transport to collect all confirmations off-chain. Usually, this is the Safe Transaction Service, but you could even use a JSON file, which you send somehow to every participant, and collect the confirmations. Safe Service is much more convenient as the transaction is visible and can be signed with metamask at https://app.safe.global/transactions/queue?safe=eth:0x...

But we prefer raw JSONs, as we have multiple backends to validate and sign the transaction, which means one instance creates the transaction, sends the JSON to the 2. backend instance, and gets the response back with the confirmation.

  1. Send the transaction data with the confirmations to the blockchain.

You could use safe core SDK and ethers to create-sign-collect-send, but using 0xweb is much easier. How it could look like:

  1. Install, and add your safe with one owner
npm i 0xweb -g
0xweb init
0xweb accounts add --key 0x<key> --name foo --pin *****
0xweb safe add --address 0x<safe_address> --owner foo  --name safe/mysafe --pin *****
  1. Install the DAO contract
0xweb i 0x<contract_address> --chain eth --name MyDao
  1. Contract interaction with confirmations via the Safe Service
import { MyDao } from './0xweb/eth/MyDao/MyDao';
import { Config } from '@dequanto/Config';

await Config.fetch();

let contract = new MyDao();
// Creates the transaction, submits to Safe Transaction Service
let writer = await contract.myComplexMethod(`safe/mysafe`, someComplexArg, otherArg);

// Waits for confirmations and automatically submits to the blockchain
let receipt = await writer.wait();
  • Thank you but I am trying to do this entirely programmatically with no CLI stuff going on. Can I sign with Safe Transaction Service? No luck yet. I'm using a forked version of mainnet because it would be mind-bogglingly complex to deploy this particular DAO (Compound), and keep erroring out on the impersonated signature: Unknown account: <Owner_1/Deployer Impersonated Address>
    – Morgan W
    Commented Jun 13, 2023 at 15:42
  • The CLI is just for the Contract Class generation and adding one owner's address. Signing and submitting are entirely programmatically (P3).
    – tenbits
    Commented Jun 16, 2023 at 13:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.