I am trying to understand this code comment here from pallet_multisig

    /// Derive a multi-account ID from the sorted list of accounts and the threshold that are
    /// required.
    /// NOTE: `who` must be sorted. If it is not, then you'll get the wrong answer.
    pub fn multi_account_id(who: &[T::AccountId], threshold: u16) -> T::AccountId {
        let entropy = (b"modlpy/utilisuba", who, threshold).using_encoded(blake2_256);
        Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
            .expect("infinite length input; no invalid inputs for type; qed")

Sorted by what?

1 Answer 1


AccountIds, like all types, are represented with bytes.

We require that the user submit the list of other accounts in the multisig in an sorted list by the byte representation of each account.

This ensures that each unique set of users creates only a single multisig account. For example, a multisig with users (B, A, C) would not be accepted as the accounts are not sorted. But (A, B, C) would be, and it is the only order set of these users which would be accepted.

The logic which handles checking the sorting is here:

/// Check that signatories is sorted and doesn't contain sender, then insert sender.
fn ensure_sorted_and_insert(
    other_signatories: Vec<T::AccountId>,
    who: T::AccountId,
) -> Result<Vec<T::AccountId>, DispatchError> {
    let mut signatories = other_signatories;
    let mut maybe_last = None;
    let mut index = 0;
    for item in signatories.iter() {
        if let Some(last) = maybe_last {
            ensure!(last < item, Error::<T>::SignatoriesOutOfOrder);
        if item <= &who {
            ensure!(item != &who, Error::<T>::SenderInSignatories);
            index += 1;
        maybe_last = Some(item);
    signatories.insert(index, who);

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.