A developer auditing a smart contract on Solana encounters a transaction with an unverified program call. The instruction data is present, but the program’s ABI is not registered on Solscan. The raw bytes show a four-byte signature followed by encoded parameters, but without knowing the exact function schema, determining what the contract actually did requires manual decoding. This is the practical problem facing auditors, security researchers, and developers who encounter unfamiliar or newly deployed programs: how to extract meaningful information from instruction signatures and parameter data when standard verification sources are unavailable.
The challenge is not academic. Solana’s architecture allows any program to accept any instruction, and many contracts—whether experimental, proprietary, or intentionally obscure—do not submit their ABIs for public verification. Understanding instruction signatures and parameter layout is therefore essential for anyone responsible for transaction analysis, security audits, or forensic review. Solscan provides the raw data; reverse-engineering it into actionable information requires knowledge of how Solana encodes instructions, how to identify common patterns, and where to find additional context.
Instruction structure and the role of signatures
Every Solana instruction consists of three mandatory components: the program address, a list of account metadata, and instruction data. The instruction data itself begins with a discriminator (often called a signature), which is typically an eight-byte value derived from a hash of the program and function name. Some programs use shorter discriminators, and a few use variable-length identifiers, but the eight-byte standard is most common in Anchor-based contracts and follows a predictable pattern.
The discriminator serves as a routing mechanism. When the program receives an instruction, it reads the first eight bytes, matches them against its known function list, and branches to the corresponding handler. If the program is closed-source or unverified, Solscan cannot automatically display the function name; it shows the hex value instead. However, the discriminator itself is deterministic. A given function name, when hashed with the program’s name using a specific algorithm (typically SHA-256 truncated to eight bytes in Anchor), always produces the same discriminator. This means that reverse-engineering is possible: if you suspect a program is using Anchor conventions, you can generate candidate discriminators and compare them against what Solscan shows.
The bytes following the discriminator are the actual function parameters. Their layout and interpretation depend entirely on the function’s schema. Solana does not enforce a standard serialization format; programs can use Borsh (the Anchor default), bincode, a custom format, or even raw bytes. Without the schema, interpreting these bytes requires either finding the program’s source code, reconstructing it from similar programs, or testing against known inputs and observing outputs.
Solscan’s role in this process is to display the raw instruction data clearly and provide context. When you view a transaction on the platform, the instruction panel shows the program address, the parsed accounts (if the program is verified), and the hex-encoded instruction data. By copying this data and analyzing it offline, you can begin the reverse-engineering process. For developers with access to developer tools and API access through Solscan’s interface, querying historical transactions can help you identify patterns across multiple calls to the same program.
Identifying Anchor programs and standard discriminators
Anchor is a framework that standardizes much of Solana program development. Programs built with Anchor use consistent discriminator generation: the function name and program name are concatenated, hashed with SHA-256, and the first eight bytes are used as the discriminator. This regularity is invaluable for reverse-engineering. If you suspect a program uses Anchor, you can write a small utility to hash candidate function names and see if any match the observed discriminator.
Common Anchor function names follow patterns such as “initialize,” “deposit,” “withdraw,” “swap,” “mint,” “burn,” “transfer,” “claim,” and “stake.” If a program’s discriminator matches the expected hash of one of these names combined with the program name, you have likely identified the function. Tools such as the Anchor CLI can compute discriminators, and online hash calculators can verify your work. The process is straightforward: concatenate the program name (with no spaces) and the function name, hash with SHA-256, and take the first eight bytes. If it matches, you have found the right function.
Not all programs use Anchor, and some use Anchor but with custom discriminator schemes. However, the standard is widespread enough that it covers a large fraction of public programs. By checking a few candidate names, you can often narrow down the function quickly. Solscan’s display of the program’s GitHub repository (when available) can also help: if the source code is public, you can look up the exact discriminator directly from the codebase.
Programs that do not follow Anchor conventions may use shorter or longer discriminators, or route instructions differently. In these cases, pattern matching becomes more important. By examining multiple transactions to the same program, you can identify which bytes remain constant (likely the function identifier) and which vary (likely parameters). This is slower but still feasible for well-documented programs or those with visible on-chain behavior (such as token transfers or NFT mints) that you can correlate with the instruction data.
Parsing parameters after the discriminator
Once you have identified the function, interpreting the parameters requires understanding the serialization format. Borsh, Anchor’s standard serializer, encodes data in a predictable way: integers are little-endian, booleans are single bytes, strings are length-prefixed, and structs are concatenated without padding. If you know the function signature (the input types), you can manually parse the bytes step by step.
For example, if a function takes a u64 amount and a string memo, the instruction data after the eight-byte discriminator would contain eight bytes for the amount (little-endian), followed by a four-byte length prefix for the string, followed by the string bytes. By carefully reading the bytes in order, you can extract each parameter. Solscan’s raw data view (usually accessible by clicking “Details” or a similar button) provides the hex representation; converting to decimal or ASCII as needed is then a manual process.
Account lists are another critical parameter. Every Solana instruction specifies which accounts it will read or write. Solscan shows this in the transaction’s account metadata section. For unverified programs, the accounts are listed by address and signer status, but their roles are not labeled. By comparing the accounts across multiple transactions to the same program, you can infer roles: if an account is always the same and is a signer, it may be the program authority. If it changes between transactions and receives tokens, it may be a destination. By cross-referencing the accounts with on-chain data (checking token balances, NFT ownership, or transaction outputs), you can often determine what the accounts represent.
Some parameters are themselves public keys or token mint addresses, embedded within the instruction data. These are typically 32 bytes each in the byte stream. If you spot patterns of 32-byte sequences, they are likely addresses. You can paste these addresses back into Solscan to see what they are: token mints, associated token accounts, or other known programs. This cross-referencing is often faster than manual parsing and provides immediate context.
Using transaction logs and program outputs
Instruction data alone is incomplete. What a program actually did is recorded in its logs and in changes to on-chain state. Solscan displays program logs in the transaction details, and these logs often include human-readable messages or data fields that the program itself emitted. Many programs log their inputs or state changes using Solana’s log functions, which produce text output visible in the transaction history.
By examining the logs alongside the instruction data, you can often infer what parameters were used. A log message such as “Transfer: 1000 tokens from account A to account B” directly documents the action, even if the instruction itself is unverified. The logs are a form of on-chain documentation created by the program. While they are not cryptographically guaranteed to be accurate (a buggy or malicious program can log false information), they are your best clue to what the program intended to do.
Token transfer events are another source of information. When a Solana program modifies a token account balance, it appears on-chain and can be traced. Solscan’s token tab and associated token account views show transfers and ownership changes. If you see a token instruction followed by an account balance change visible on Solscan, you can correlate them. A program’s instruction may not be labeled, but its effect on token accounts is undeniable.
For NFT operations, Solscan’s NFT analytics provide transaction history and metadata. If an instruction results in an NFT being transferred or minted, the NFT’s page on Solscan will show the transaction. This is often easier than parsing the instruction bytes directly: you can see the NFT, view its trading history, and observe when specific instruction patterns coincide with transfers.
Reconstructing schema from multiple transactions
When a single transaction is not enough, a sample of transactions to the same program can reveal its schema. By gathering several instruction calls to the same unverified function and overlaying them, you can identify which bytes change and which remain constant. Bytes that are always the same are likely fixed headers or flags. Bytes that vary in a structured way (e.g., a block of 32 bytes that always matches a known address) are likely parameters.
Solscan’s advanced search and filters allow you to find all transactions to a specific program within a date range or sorted by account. By exporting or copying several of these instructions, you can perform differential analysis. A simple approach is to write the instruction bytes into a spreadsheet, color-code identical bytes across transactions, and look for the boundaries where consistency breaks down. These boundaries mark parameter fields.
Once you have identified a likely field, you can test your hypothesis by checking whether the values make sense. If you think bytes 8–15 contain a token amount, convert them to decimal and check whether they match account balance changes visible elsewhere in the transaction. If you think bytes 16–47 contain an address, look up that address on Solscan and see whether it is related to the instruction’s purpose. This iterative validation is slower than having a verified ABI, but it works.
Documentation from the program’s creators (even if incomplete) can accelerate this process. Many programs publish function descriptions in blog posts, GitHub wikis, or Discord announcements. A simple description such as “the deposit function takes an amount and a mint address” is enough to let you identify the correct fields. Solscan itself does not provide this documentation, but by combining the explorer’s data with external research, you can piece together the schema.
Smart contract verification and when to trust sources
When a program is verified on Solscan, the explorer can automatically decode instructions and display human-readable function names and parameters. This is a significant convenience, but it also creates a trust boundary. Verification on Solscan means that the program’s ABI has been registered, but it does not mean that the on-chain code matches the published source. A malicious actor could submit an ABI for one program while the actual deployed code is different, tricking users into misinterpreting transactions.
In practice, the leading explorer for Solana transactions uses a verification process that checks the on-chain code against a published source repository, such as GitHub. If the code matches, Solscan displays a verified badge. However, this verification is only as trustworthy as the source repository and the uploader’s identity. For security-critical audits, verifying the source code independently (by reviewing the repository yourself or comparing it to known security standards) is important.
For unverified programs, the absence of a verified badge does not mean the code is malicious; it often means the program’s owner has not gone through the registration process. Many legitimate programs remain unverified. Conversely, a verified badge does not guarantee safety. The right approach is to treat verification as a convenience tool for parsing, not as a security stamp. Always examine the actual behavior: does the transaction do what you expect? Do the logs make sense? Does the on-chain state change align with the instruction? These questions should guide your interpretation, not a badge.
Using Solscan’s API and developer tools for automation
Manual inspection of one transaction is feasible; analyzing thousands is not. Solscan offers API access that allows developers to query transactions, accounts, and program data programmatically. By leveraging the API, you can automate the collection and analysis of instruction data across many transactions, apply pattern-matching algorithms, and build tools to decode unknown instructions at scale.
The API returns transaction data in a structured JSON format, including all instruction details. By writing a script to fetch transactions for a program and extract instruction data, you can build a database of all calls. Tools such as Python’s struct module or JavaScript libraries can parse the bytes according to a schema you construct. For frequently-called functions, this automation is essential: it can identify parameter ranges, detect anomalies, and support forensic analysis far beyond what manual review allows.
Some developers also publish decoding tools on GitHub specifically for their programs, reverse-engineered or official. By searching for the program address alongside terms like “decoder,” “parser,” or “instruction,” you may find community-created tools. These are not always maintained, but they can provide a starting point for your own analysis. Solscan’s integration with GitHub (showing repositories associated with programs) can direct you to these resources.
The developer tools available through Solscan emphasize transparency and accessibility. No private key or wallet connection is required; all data is public blockchain information. This makes the platform suitable for security researchers and auditors who need to analyze suspicious transactions without risk. The combination of a clear UI for one-off inspections and API access for bulk analysis makes Solscan a practical foundation for reverse-engineering work.
Common pitfalls and practical tips
One frequent mistake is assuming that instruction data is always valid or correctly interpreted. A program may encode data in a non-standard way, use padding or alignment that breaks your assumptions, or have evolved its format over time. Always validate your interpretation against multiple data points: logs, account changes, and transaction outcomes. If your parsing produces nonsensical results (negative amounts, invalid addresses, or state changes that do not match the decoded parameters), reconsider your schema.
Another pitfall is conflating instruction intent with actual effect. A malicious or buggy program might claim in its logs to perform one action while doing another. The authoritative record is the on-chain state: which accounts changed, which tokens moved, which NFTs transferred. By examining Solscan’s transaction tree (showing all accounts modified), you can verify that the instruction’s effect matches the claimed behavior. If there is a discrepancy, the actual state change is the truth.
Time is also important. Program code can be updated, especially if the program has upgrade authority. An instruction that worked correctly three months ago might behave differently today if the program was upgraded. Solscan shows the program’s current deployed code; it does not show historical versions. For forensic analysis or attribution, knowing when the program was last upgraded is critical. Check Solscan’s program details page for upgrade history if it is available.
Finally, document your findings. If you successfully reverse-engineer a function’s schema, share it in comments, documentation, or open-source tools. The Solana community benefits when knowledge is pooled. A GitHub repository with decoded instruction formats, even if incomplete, accelerates future analysis and reduces duplication of effort. Solscan’s transparency model depends on shared understanding, and contributing to that understanding is part of responsible ecosystem participation.
Frequently asked questions
How can I find the discriminator of an unknown Anchor program?
If the program uses Anchor conventions, concatenate the program name and function name without spaces, hash with SHA-256, and take the first eight bytes. Convert to hex and compare against the instruction data shown on Solscan. If they match, you have found the function. Alternatively, check the program’s GitHub repository for the source code, which will list the exact discriminators.
Can I parse instruction parameters without the program’s ABI?
Yes, but it requires manual effort. By examining the hex bytes after the discriminator and understanding the serialization format (usually Borsh), you can decode integers, strings, addresses, and other types. Comparing multiple transactions to the same function helps identify which bytes represent which parameters. Program logs and on-chain state changes also provide context to validate your interpretation.
What should I do if a program is unverified on Solscan?
An unverified program is not necessarily unsafe; it simply means the ABI has not been registered. You can still analyze its instructions by examining the raw data, logs, and on-chain effects. For security-critical decisions, verify the program’s behavior independently by reviewing its source code, checking multiple transactions, and confirming the on-chain outcomes match the instructions. Solscan’s data is sufficient for this analysis even without verification.