Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When querying all storages from System.Account, all storage values are the same #374

Open
AstaFrode opened this issue Mar 29, 2024 · 0 comments

Comments

@AstaFrode
Copy link

AstaFrode commented Mar 29, 2024

Hello, I have a requirement to query all account information from System.Account, but the results I get are the same. I hope to get your help, thank you very much.
My block explorer address is: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Ftestnet-rpc2.cess.cloud%2Fws%2F#/chainstate
Here is my code and the results I get:

package main

import (
	"errors"
	"fmt"
	"log"

	gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4"
	"github.com/centrifuge/go-substrate-rpc-client/v4/types"
	"github.com/centrifuge/go-substrate-rpc-client/v4/types/codec"
	"github.com/centrifuge/go-substrate-rpc-client/v4/xxhash"
	"github.com/decred/base58"
	"golang.org/x/crypto/blake2b"
)

var RPC_ADDRS = []string{
	//testnet
	"wss://testnet-rpc0.cess.cloud/ws/",
	"wss://testnet-rpc1.cess.cloud/ws/",
	"wss://testnet-rpc2.cess.cloud/ws/",
}

func main() {
	accounts, err := GetAllAccountInfoFromBlock(1)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(accounts), " : ", accounts)
}

func GetAllAccountInfoFromBlock(block int) ([]types.AccountInfo, error) {
	var (
		err error
		c   *gsrpc.SubstrateAPI
	)
	for i := 0; i < len(RPC_ADDRS); i++ {
		c, err = gsrpc.NewSubstrateAPI(RPC_ADDRS[i])
		if err == nil {
			break
		}
	}
	if c == nil {
		log.Fatal("all rpc addresses are unavailable")
	}

	defer c.Client.Close()

	var data []types.AccountInfo

	key := createPrefixedKey("System", "Account")

	// get all account information from the latest block
	if block < 0 {
		keys, err := c.RPC.State.GetKeysLatest(key)
		if err != nil {
			return nil, err
		}
		set, err := c.RPC.State.QueryStorageAtLatest(keys)
		if err != nil {
			return nil, err
		}
		for _, elem := range set {
			for _, change := range elem.Changes {
				var storageData types.AccountInfo
				if err := codec.Decode(change.StorageData, &storageData); err != nil {
					fmt.Println("Decode StorageData:", err)
					continue
				}
				var storageKey types.AccountID
				if err := codec.Decode(change.StorageKey, &storageKey); err != nil {
					fmt.Println("Decode StorageKey:", err)
					continue
				}
				fmt.Println(encodePublicKeyAsAccount(storageKey[:]))
				data = append(data, storageData)
			}
		}
		return data, nil
	}

	// get all account information from the block

	blockhash, err := c.RPC.Chain.GetBlockHash(uint64(block))
	if err != nil {
		return data, err
	}

	keys, err := c.RPC.State.GetKeys(key, blockhash)
	if err != nil {
		return nil, err
	}
	set, err := c.RPC.State.QueryStorageAt(keys, blockhash)
	if err != nil {
		return nil, err
	}
	for _, elem := range set {
		for _, change := range elem.Changes {
			if change.HasStorageData {
				var storageData types.AccountInfo
				if err := codec.Decode(change.StorageData, &storageData); err != nil {
					fmt.Println("Decode StorageData err:", err)
					continue
				}
				var storageKey types.AccountID
				if err := codec.Decode(change.StorageKey, &storageKey); err != nil {
					fmt.Println("Decode StorageKey err:", err)
					continue
				}
				fmt.Println(encodePublicKeyAsAccount(storageKey[:]))
				data = append(data, storageData)
			}
		}
	}
	return data, nil
}

func createPrefixedKey(pallet, method string) []byte {
	return append(xxhash.New128([]byte(pallet)).Sum(nil), xxhash.New128([]byte(method)).Sum(nil)...)
}

func encodePublicKeyAsAccount(publicKey []byte) (string, error) {
	if len(publicKey) != 32 {
		return "", errors.New("invalid public key")
	}
	payload := appendBytes([]byte{0x50, 0xac}, publicKey)
	input := appendBytes([]byte{0x53, 0x53, 0x35, 0x38, 0x50, 0x52, 0x45}, payload)
	ck := blake2b.Sum512(input)
	checkum := ck[:2]
	address := base58.Encode(appendBytes(payload, checkum))
	if address == "" {
		return address, errors.New("public key encoding failed")
	}
	return address, nil
}

func appendBytes(data1, data2 []byte) []byte {
	if data2 == nil {
		return data1
	}
	return append(data1, data2...)
}

result:

cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
cXfrMc9SvviCksFEYikLXJZRAZp3S5VtjgVTAPccddWWizroz <nil>
24  :  [{0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 4 1 0 {100000000000000000000000000 0 3000000000000000000000000 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 4 1 0 {100000000000000000000000000 0 3000000000000000000000000 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 4 1 0 {100000000000000000000000000 0 3000000000000000000000000 170141183460469231731687303715884105728}} {0 0 1 0 {1000000000000000000 0 0 170141183460469231731687303715884105728}} {0 4 1 0 {100000000000000000000000000 0 3000000000000000000000000 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 4 1 0 {100000000000000000000000000 0 3000000000000000000000000 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}} {0 0 1 0 {100000000000000000000000000 0 0 170141183460469231731687303715884105728}}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant