I am trying to fetch all the programs deployed by a given address. I went through the Solana documentation but I could not figure out how I can do it. I am considering to use solscan.io to fetch the transactions but I do not know how to process that data. It is very different than Ethereum. Does anyone know how I can achieve this?
1 Answer
Question could be what is the end goal. The programs are upgradable (by default https://medium.com/coinmonks/solana-internals-part-2-how-is-a-solana-deployed-and-upgraded-d0ae52601b99) in Solana and if you say "deployed by a given address" then you will quite probably need to search the history of transactions and check what account was the fee payer or considered as upgradable authority at the time of deployment.
If you search the programs that belongs to particular upgradable authority then you can use the general getProgramAccounts
call (https://docs.solana.com/api/http#getprogramaccounts, with more details at https://solanacookbook.com/guides/get-program-accounts.html#facts).
As Solana uses the account model (https://docs.solana.com/developing/programming-model/accounts) then we know the program is an account with specific owner.
Owner of all standard programs is the address of BPFLoaderUpgradeab1e11111111111111111111111
.
The program BPFLoaderUpgradeab1e11111111111111111111111
works with several states: Uninitialized, Buffer, Program, Data (https://github.com/solana-labs/solana/blob/v1.15.0/sdk/program/src/bpf_loader_upgradeable.rs#L29).
Let's check an example of Marinade Staking program
https://explorer.solana.com/address/MarBmsSgKXdrN1egZf5sqe1TMai9K1rChYNDJgjq7aD
We can see the "Program Account" (Program), having associated "Program Executable Data Account" (ProgramData).
The upgrade authority is "551FBXSXdhcRDDkdcb3ThDRg84Mwe5Zs6YjJ1EEoyzBp
" (considered as an owner or who deployed).
The structure of the Account with executable data (i.e., the ProgramData
) owned by the BPFLoader
program can be observed in source code
https://github.com/solana-labs/solana/blob/v1.15.0/sdk/program/src/bpf_loader_upgradeable.rs#L29
ProgramData {
slot: u64,
upgrade_authority_address: Option<Pubkey>,
},
From that we can calculate the offset and data for the filter.
The data structure of the ProgramData
is:
4 bytes for type,
8 bytes for slot
1 byte for `Option`
32 bytes for Pubkey
The type ProgramData
is fourth in the enum thus on index 3.
Getting the base58
of [3,0,0,0]
we get 5Sxr3
.
Then the offset for the searching upgradable authority key is 4 + 8 + 1.
With following call we can get account of type ProgramData where upgradable authority is the given Pubkey.
curl https://api.mainnet-beta.solana.com -X POST -H "Content-Type: application/json" -d '
{
"jsonrpc": "2.0",
"id": 1,
"method": "getProgramAccounts",
"params": [
"BPFLoaderUpgradeab1e11111111111111111111111",
{
"encoding": "base64",
"filters": [
{
"memcmp": {
"offset": 0,
"bytes": "5Sxr3"
}
},
{
"memcmp": {
"offset": 13,
"bytes": "551FBXSXdhcRDDkdcb3ThDRg84Mwe5Zs6YjJ1EEoyzBp"
}
}
]
}
]
}
'
-
Thank you for your detailed answer. It helped a lot. I have a few questions regarding your answer: 1. I guess this only works for programs that have update authority. What about the programs that does not contain this? 2. I guess the call you attached at the end of your response fetches only one program where upgradable authority is the given Pubkey. What should I do if there are more than one programs related to the given Pubkey? 3. How do you calculate base58 of [0, 0, 0, 3] Commented Feb 9, 2023 at 13:02
-
1ad 1) That's what I'm not sure 100% but I think you would need to fallback to search the blockchain history. In fact when the program is deployed with
BPFLoaderUpgradeab1e11111111111111111111111
but even it s not upgradable (solana program deploy --final ...
, see stackoverflow.com/questions/69884904/…) then it seems (I did just quick check which could not be covering all) still the offset13
contains the pubkey of the "owner/deployer".– chaldaCommented Feb 10, 2023 at 8:03 -
1a trouble seems could be rather when the program is deployed with
BPFLoader2111111111111111111111111111111111
(solana deploy ...
) where there is no such info involved.– chaldaCommented Feb 10, 2023 at 8:05 -
1ad 2) the fetch should show all the accounts that matches the filter. While I'm not sure when, how, if could be limited by some RPC nodes settings (like size of transfered data to client is limited) (like if you try to remove the second part of the filter you should get program data of all programs at Solana which is un-probable to me)– chaldaCommented Feb 10, 2023 at 8:06
-
1ad 3) I jsut use a simple python script for this gist.github.com/ochaloup/58ceee3ed436766ba7c444bf3fbc8545– chaldaCommented Feb 10, 2023 at 8:08