| Слой | Поле ответа | Роль |
|---|---|---|
| Static | transaction.message.accountKeys | Ключи, записанные в самом message; здесь находятся signers |
| Loaded writable | meta.loadedAddresses.writable | Разрешённые через ALT accounts с правом записи |
| Loaded readonly | meta.loadedAddresses.readonly | Разрешённые через ALT accounts только для чтения |
| Lookup recipe | message.addressTableLookups | Адрес каждой ALT и индексы элементов внутри неё |
- Слой
- Static
- Поле ответа
- transaction.message.accountKeys
- Роль
- Ключи, записанные в самом message; здесь находятся signers
- Слой
- Loaded writable
- Поле ответа
- meta.loadedAddresses.writable
- Роль
- Разрешённые через ALT accounts с правом записи
- Слой
- Loaded readonly
- Поле ответа
- meta.loadedAddresses.readonly
- Роль
- Разрешённые через ALT accounts только для чтения
- Слой
- Lookup recipe
- Поле ответа
- message.addressTableLookups
- Роль
- Адрес каждой ALT и индексы элементов внутри неё
Сначала запросите версию, которую действительно умеете читать
У метода getTransaction укажите encoding json или jsonParsed и maxSupportedTransactionVersion: 0. Без допустимой версии RPC-клиент может отклонить ответ с v0. Поле version должно подтвердить 0; для legacy алгоритм ALT не нужен. Обычные Solana-транзакции по-прежнему требуют отдельной проверки signature, slot, meta.err, fee и account deltas: восстановленный список accounts не доказывает успешное исполнение.
Ответ null означает лишь, что транзакция не найдена или не подтверждена при выбранном commitment. Он не доказывает, что подписи никогда не было: проверьте cluster, подпись, commitment, archival coverage и второй RPC-узел. Не смешивайте mainnet-beta с devnet и не переносите ответ между разными genesis hash.
Полный порядок строится из трёх последовательных массивов
Для raw json соберите orderedAccountKeys как конкатенацию static accountKeys, meta.loadedAddresses.writable и meta.loadedAddresses.readonly — именно в этом порядке. Затем programIdIndex и каждый индекс из instruction.accounts разрешаются по единому массиву. Индекс внутри addressTableLookups относится не к compiled instruction, а к позиции публичного ключа в конкретной ALT; это два разных пространства индексов.
В jsonParsed RPC уже возвращает message.accountKeys объектами с pubkey, signer, writable и source. source=transaction отличает static key, source=lookupTable — загруженный. Это удобная независимая сверка, но parsed instruction может быть частичной или отсутствовать для неизвестной программы. Для аудита сохраняйте и raw json: в нём видны исходные compiled indices и lookup recipe.
| Наблюдение | Что известно | Следующий шаг |
|---|---|---|
| version=0, loadedAddresses заполнен | Исторические resolved keys доступны | Собрать ordered list и разрешить indices |
| version=0, jsonParsed содержит source | RPC уже приложил lookup keys | Сверить число, порядок и writable с raw ответом |
| addressTableLookups есть, loadedAddresses отсутствует | Известен рецепт, но не итоговый список | Запросить full metadata у archival RPC; не гадать по explorer UI |
| Текущая ALT закрыта или не читается | Live table не даёт исторического state | Искать сохранённый transaction metadata или block response |
| Индекс выходит за ordered list | Декодирование или response неполны | Остановить атрибуцию accounts и перепроверить encoding/version |
- Наблюдение
- version=0, loadedAddresses заполнен
- Что известно
- Исторические resolved keys доступны
- Следующий шаг
- Собрать ordered list и разрешить indices
- Наблюдение
- version=0, jsonParsed содержит source
- Что известно
- RPC уже приложил lookup keys
- Следующий шаг
- Сверить число, порядок и writable с raw ответом
- Наблюдение
- addressTableLookups есть, loadedAddresses отсутствует
- Что известно
- Известен рецепт, но не итоговый список
- Следующий шаг
- Запросить full metadata у archival RPC; не гадать по explorer UI
- Наблюдение
- Текущая ALT закрыта или не читается
- Что известно
- Live table не даёт исторического state
- Следующий шаг
- Искать сохранённый transaction metadata или block response
- Наблюдение
- Индекс выходит за ordered list
- Что известно
- Декодирование или response неполны
- Следующий шаг
- Остановить атрибуцию accounts и перепроверить encoding/version
Воспроизводимая проверка сохраняет и рецепт, и результат
- 1Закрепите контекст
Запишите cluster/genesis, signature, commitment, endpoint, slot и время ответа.
- 2Получите две формы
Запросите json и jsonParsed с maxSupportedTransactionVersion 0; сохраните исходные ответы.
- 3Проверьте message
Зафиксируйте version, static keys и каждый addressTableLookup с table key, writableIndexes и readonlyIndexes.
- 4Соберите ordered list
Добавьте к static keys сначала все loaded writable, затем все loaded readonly в возвращённом порядке.
- 5Разрешите instructions
Для каждой instruction сопоставьте programIdIndex и account indices с полными публичными ключами.
- 6Проверьте результат
Отдельно сопоставьте meta.err, logs, inner instructions и pre/post balances с нужными accounts.
Адрес найден — роль ещё надо доказать
Полный account list отвечает, какой публичный ключ стоял за индексом и был ли он signer/writable. Он не объясняет бизнес-роль автоматически: ATA, PDA и token account различают по owner program, derivation и состоянию конкретного account. Название в эксплорере, метка проекта или присутствие ключа в ALT не доказывают владение, получателя перевода или одобрение операции.
Stop-сигналы
- инструмент показывает только static accountKeys, но декодирует все instruction indices как полные адреса;
- текущую ALT выдают за снимок её состояния в историческом slot;
- writable account называют signer, хотя lookup accounts не подписывают transaction;
- успех объявляют по красивому parsed action без meta.err и account deltas;
- ответы двух RPC относятся к разным cluster, commitment или encoding;
- неизвестный program ID заменяют догадкой по метке эксплорера.
Закрытый результат — это сохранённые raw/parsed ответы, точный ordered list, таблица index → pubkey → source → writable/signer и отдельное подтверждение перевода по state deltas. Если loadedAddresses нельзя получить, не подписывайте роль неизвестным индексам: запросите archival block/transaction у другого провайдера или оставьте вывод как unknown.
Источники
Мы используем прямые ссылки и фиксируем дату проверки. Полный текст чужих материалов не перепечатывается.
- Solana Docs — Versioned transactions Solana Foundation · Проверено 23 августа 2026 г. в 19:59 GMT+5
- Solana Docs — RPC JSON structures Solana Foundation · Проверено 23 августа 2026 г. в 19:59 GMT+5
- Solana RPC — getTransaction Solana Foundation · Проверено 23 августа 2026 г. в 19:59 GMT+5
- Solana Cookbook — Address Lookup Tables Solana Foundation · Проверено 23 августа 2026 г. в 19:59 GMT+5
