Bittensor · Multisig Guide
Bittensor Key Security · Worked Examples
Every multisig on Bittensor leaves the same event trail — NewMultisig → approvals → MultisigExecuted (or MultisigCancelled). Here are four real operations pulled from Finney, each with its live extrinsic data on Taostats, so you can see exactly how a signed transaction moves from proposal to execution — and how it gets abandoned.
as_multi puts the full call on-chain from the start (every signer reads it from the chain); approve_as_multi puts only the hash on-chain (the call is transported off-chain and hash-matched).Three signers, all three required. The proposer opened the operation with as_multi, so the entire call — a 0.01 TAO transfer — was written on-chain in the opening extrinsic. Every co-signer could read the exact transaction straight from the chain before approving. This is the complete three-signature chain, start to finish.
Signer A composes the transfer and opens the multisig with the full call on-chain. This emits NewMultisig. Approvals so far: 1 of 3 — nothing moves yet.
signer: 5DXoaFJyg…MPWcSMwc
→ extrinsic 8638931-0015 · block 8,638,931
Signer B reads the call from the chain, confirms it, and approves against the same call_hash. This emits MultisigApproval. Approvals: 2 of 3 — still one short, still nothing executes.
signer: 5EcWJipQv…kaAwibV
→ extrinsic 8638934-0038 · block 8,638,934
The third signature reaches the threshold. On the same extrinsic, the runtime dispatches the inner transfer from the multisig account. This emits MultisigExecuted with result: Ok. The 0.01 TAO moves. Done.
signer: 5FPCUBpEB…hmXZ29s
→ extrinsic 8638955-0042 · block 8,638,955
Three separate blocks, three separate signers, one transaction. The funds moved only when the third approval landed — no single signer could have moved them alone. Because it was opened with as_multi, signers B and C read the exact call from the chain; no off-chain trust required.
The simplest real case: two signers, both required. Only two signatures exist in the whole lifecycle — the open and the execute. There's no middle "approval" step at all, because the second signature is the threshold. Notice how much shorter the event trail is than the 3-of-3.
Signer A opens with the full call on-chain. NewMultisig emitted. Approvals: 1 of 2.
signer: 5Gn81EQTZ…GwaxZvCd
→ extrinsic 8637827-0015 · block 8,637,827
The second and final signature reaches the 2-of-2 threshold and dispatches the transfer in the same extrinsic. MultisigExecuted with result: Ok. Two signatures, two blocks, done — no separate approval round.
signer: 5CgQDQRQ8…TWYmCj6
→ extrinsic 8637848-0020 · block 8,637,848
A 2-of-N multisig has no intermediate MultisigApproval events — the second signature is the threshold, so it goes straight from NewMultisig to MultisigExecuted. Fewer signers = a shorter ceremony, but also less redundancy: in a 2-of-2, losing either key locks the account forever.
This is the case that trips people up. The multisig reached its threshold and dispatched — the outer extrinsic succeeded. But the inner call it dispatched returned an error, so MultisigExecuted carries result: Err. The multisig machinery worked perfectly; the thing it tried to do did not. These are two different outcomes, and reading them as one is a classic mistake.
It was opened with approve_as_multi, so only the hash of the call went on-chain at open time — the signers verified the call off-chain against that hash before the final signer supplied the full call at execution.
Signer A opens the op supplying just the call_hash — the call body is not on-chain yet. NewMultisig emitted. Approvals: 1 of 2.
signer: 5GRCukV2r…ZdaQXDXo
→ extrinsic 8636095-0030 · block 8,636,095
The second signer reaches the 2-of-3 threshold and provides the full call, which the runtime dispatches. The outer extrinsic succeeds (the multisig did its job) but the dispatched call returns an error — so the event is MultisigExecuted with result: Err. Nothing the inner call intended actually took effect.
signer: 5E7RCRrPV…y3L7AgirGJ
→ extrinsic 8636130-0010 · block 8,636,130
An extrinsic that shows success on Taostats only means the multisig call was accepted and dispatched. Whether the inner transaction succeeded is a separate signal — the result field inside MultisigExecuted (Ok vs Err). A tool built for signers should surface both: "threshold reached ✅" is not the same as "your transaction did what you wanted ✅."
Not every multisig op completes. Here the proposer opened an operation, it sat pending without reaching threshold, and the original depositor cancelled it with cancel_as_multi — clearing the pending entry and reclaiming the reserved deposit. Only the person who opened the op (the depositor) can cancel it.
The depositor opens a pending op (hash-only) and reserves the multisig deposit. NewMultisig emitted. Approvals: 1 of 2 — it now waits for a co-signer.
signer: 5FYk9u3v8…BTNht1m
→ extrinsic 8622170-0018 · block 8,622,170
Roughly 34 blocks later, instead of a second approval, the depositor withdrew the operation entirely. cancel_as_multi references the original op's timepoint and call_hash, removes the pending entry, and returns the reserved deposit. This emits MultisigCancelled. The transaction never executed and never will — it's gone.
signer: 5FYk9u3v8…BTNht1m (same depositor)
→ extrinsic 8622204-0016 · block 8,622,204
A pending multisig op isn't permanent. The depositor can abandon it with cancel_as_multi — useful if a co-signer disappears, the details were wrong, or the transaction is no longer wanted. Only the depositor can cancel, and doing so reclaims the reserved deposit. A signer tool should offer this as a clear "abandon" action, not leave stale ops hanging.
Whatever the threshold or the call, every multisig op walks the same state machine — and every step is a real event you can query on Taostats:
| Example | Threshold | Opened with | Outcome | Signatures |
|---|---|---|---|---|
| 3-of-3 transfer | 3-of-3 | as_multi (call on-chain) | Executed · Ok | 3 |
| 2-of-2 transfer | 2-of-2 | as_multi (call on-chain) | Executed · Ok | 2 |
| Inner failed | 2-of-3 | approve_as_multi (hash only) | Executed · Err | 2 |
| Cancelled | 2-of-2 | approve_as_multi (hash only) | Cancelled | 1 + cancel |
/api/event/v1 and /api/extrinsic/v1) and linked to their live extrinsic pages. Addresses are SS58-encoded (network prefix 42) from the on-chain public keys. Amounts converted from RAO (1 TAO = 10⁹ RAO). Every extrinsic link resolves to its Taostats page — verify the raw call data there.