> For the complete documentation index, see [llms.txt](https://docs.xft.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xft.finance/bitnet/accounts/multisig.md).

# Multisig

n is the number of independent signing keys

m is the number those keys that must sign in order to authorize a transaction

\---

<table><thead><tr><th width="190">Account Type</th><th width="135">Multisig</th><th>Use case</th></tr></thead><tbody><tr><td>Shared</td><td>1-of-2</td><td>both husband and wife individually have full access to their funds</td></tr><tr><td>Consensus</td><td>2-of-2</td><td>both husband and wife must agree to spend their funds</td></tr><tr><td>Threshold</td><td>2-of-3</td><td>an escrow service is involved as an independent 3rd party, to co-sign with either the seller, or with the buyer, if seller and buyer do not agree</td></tr><tr><td>Secure</td><td>2-of-3</td><td>a single owner controls all 3 keys but secures them via different means to diversify risks</td></tr><tr><td>Arbitrary Threshold</td><td>M-of-N</td><td>full flexibility on the number of signers</td></tr><tr><td></td><td>N-of-N</td><td><p>all parties sign with their unique private keys for the </p><p>transaction to be considered valid</p></td></tr></tbody></table>

\---

TECHNICAL IMPLEMENTATION&#x20;

-Submit a transaction

-Approve and revoke approval of pending transactions

-Execute a transaction after enough owners have approved it.

{% code overflow="wrap" expandable="true" %}

```
PUBLIC AND EXTERNAL FUNCTIONS
constructor(address[] owners_, uint256 required_): Sets owners and threshold M.
receive(): Accepts native deposits.
submitTransaction(address to, uint256 value, bytes data): Queues any call, returns txIndex.
submitERC20Transfer(address token, address to, uint256 amount): Queues ERC20/Dollar transfer, returns txIndex.
confirmTransaction(uint256 txIndex): Owner approves pending tx.
revokeConfirmation(uint256 txIndex): Owner removes approval before execute.
executeTransaction(uint256 txIndex): Executes once confirmations >= M.
getOwners(): Returns owner list.
getTransactionCount(): Returns tx count.
getTransaction(uint256 txIndex): Returns to, value, data, executed, numConfirmations.
isOwner(address account): Checks if account is owner.
isConfirmed(uint256 txIndex, address owner): Checks if owner confirmed tx.
numConfirmationsRequired(): Returns threshold M.

PRIVATE AND INTERNAL FUNCTIONS
_setOwners(address[] owners_, uint256 required_): Validates non-zero unique owners, 0 < M <= N.
_submit(address to, uint256 value, bytes data): Stores tx, emits SubmitTransaction.
_execute(uint256 txIndex): Checks threshold, marks executed, calls target.
_verifyTransfer(uint256 txIndex, address target, bytes data, bytes ret): Reverts if ERC20 transfer returns false.
_bubble(uint256 txIndex, bytes ret): Passes target revert reason through.
_requireOwner(address account): Reverts if not owner.
_requireTxExists(uint256 txIndex): Reverts if index out of range.
_requireNotExecuted(uint256 txIndex): Reverts if already executed.
_requireNotConfirmed(uint256 txIndex, address owner): Reverts if owner already confirmed.

MODIFIERS
onlyOwner, txExists, notExecuted, notConfirmed

EVENTS
Deposit(address indexed sender, uint256 amount, uint256 balance)
SubmitTransaction(address indexed owner, uint256 indexed txIndex, address indexed to, uint256 value, bytes data)
ConfirmTransaction(address indexed owner, uint256 indexed txIndex)
RevokeConfirmation(address indexed owner, uint256 indexed txIndex)
ExecuteTransaction(address indexed owner, uint256 indexed txIndex)

ROLES
OWNER: submit, confirm, revoke, execute
ANYONE: deposit native, read state
```

{% endcode %}

XFTMultiSigWallet 0x5Ca0E0Fc171dF83f8Bc4467c12ae0102892F0AFd

FLOWS

```
DOLLAR TRANSFER FLOW
1. Owner calls submitERC20Transfer(DOLLAR, receiver, amount)
2. M owners call confirmTransaction(txIndex)
3. Owner calls executeTransaction(txIndex)
4. Dollar debits wallet
5. Dollar credits receiver
```

\---

It has no time limit; once a transaction is signed, it allows you to withdraw all funds immediately.

It has no daily limit on the number of transactions: you can create thousands of transactions per minute.

It has no notifications; you don't get an SMS or email when the account status has changed.
