Skip to main content

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

https://polkadot.subscan.io/account/5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6ZCheck it out on Subscan:

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we dontdon't use any cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

https://polkadot.subscan.io/account/5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we dont use any cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we don't use any cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)

added 1 character in body
Source Link
Bruno
  • 8.5k
  • 1
  • 13
  • 37

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

https://polkadot.subscan.io/account/5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we dont use anany cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

https://polkadot.subscan.io/account/5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we dont use an cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

https://polkadot.subscan.io/account/5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we dont use any cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)

Source Link
Shawn Tabrizi
  • 16.3k
  • 2
  • 24
  • 64

I would like to understand how treasury accounts are created and used under the hood

You can see here for a similar explanation on sub-accounts.

To walk through the specific steps here:

  1. Here is the function defined in the Treasury pallet for generating the account id:

    /// The account ID of the treasury pot.
    ///
    /// This actually does computation. If you need to keep using it, then make sure you cache the
    /// value and only call this once.
    pub fn account_id() -> T::AccountId {
        T::PalletId::get().into_account()
    }
    
  2. T::PalletId::get() is defined as:

    pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
    
  3. into_account() is defined as:

    /// Convert into an account ID. This is infallible.
    fn into_account(&self) -> AccountId {
        self.into_sub_account(&())
    }
    
    fn into_sub_account<S: Encode>(&self, sub: S) -> T {
        (Id::TYPE_ID, self, sub)
            .using_encoded(|b| T::decode(&mut TrailingZeroInput(b)))
            .expect("`AccountId` type is never greater than 32 bytes; qed")
    }
    
  4. Id::TYPE_ID is defined as:

    impl TypeId for PalletId {
        const TYPE_ID: [u8; 4] = *b"modl";
    }
    

So to generate the account, we just need to take the raw bytes of "modl" + "py/trsry" and stick that into an account:

as_bytes("modl") = 0x6d6f646c
as_bytes("py/trsry") = 0x70792f7472737279

So the Account Id is:

0x6d6f646c70792f74727372790000000000000000000000000000000000000000

Which maps to Substrate Address:

5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

Check it out on Subscan:

https://polkadot.subscan.io/account/5EYCAe5ijiYfyeZ2JJCGq56LmPyNRAKzpG4QkoQkkQNB5e6Z

This public key has no known private key since it is just generated from raw bytes as shown above. When accessing funds from this account, we dont use an cryptography. The low level runtime has direct access to modify this account in any way without authorization.

If you want to look for the private key, you can try, and if you succeed, you will get access to all the treasury funds across all Substrate chains.

A pretty nice bounty, so do let me know when you find it :)