Учетные записи (Аккаунты)
Сохранение состояния между транзакциями
Если программе необходимо сохранить состояние между транзакциями, она делает это с помощью accounts. Учетные записи аналогичны файлам в таких операционных системах, как Linux, в том смысле, что они могут содержать произвольные данные, которые сохраняются после завершения жизненного цикла программы. Как и файл, учетная запись включает метаданные, которые сообщают среде выполнения, кому и как разрешен доступ к данным.
В отличие от файла учетная запись включает метаданные на протяжении всего времени существования файла. Это время жизни выражается количеством дробных нативных токенов, называемых lampports. Аккаунты хранятся в памяти валидатора и платят "rent", чтобы оставаться там. Каждый валидатор периодически сканирует все аккаунты и взимает арендную плату. Любая учетная запись, которая падает до нуля, очищается. Аккаунты также могут быть помечены как rent-exempt, если они содержат достаточное количество лампортов.
Точно так же, как пользователь Linux использует путь для поиска файла, клиент Solana использует адрес для поиска учетной записи. Адрес представляет собой 256-битный открытый ключ.
Подписанты
Транзакции могут включать цифровые подписи, соответствующие открытым ключам учетных записей, на которые ссылается транзакция. Такие подписи означают, что владелец закрытого ключа учетной записи подписал и, таким образом, «санкционировал» транзакцию. В этом случае учетная запись называется signer. Информация о том, является ли учетная запись подписывающей стороной, передается программе как часть метаданных учетной записи. Затем программы могут использовать эту информацию для принятия авторитетных решений.
Только для чтения
Транзакции могут указывать, что некоторые учетные записи, на которые она ссылается, должны рассматриваться как учетные записи только для чтения, чтобы обеспечить параллельную обработку учетных записей между транзакциями. Среда выполнения позволяет нескольким программам одновременно читать учетные записи только для чтения. Если программа пытается изменить учетную запись только для чтения, транзакция отклоняется средой выполнения.
Исполняемый файл
Если учетная запись помечена как «исполняемая» в своих метаданных, то она считается программой, которую можно запустить, включив открытый ключ учетной записи в инструкцию идентификатор программы. Учетные записи помечаются как исполняемые во время успешного процесса развертывания программы загрузчиком, которому принадлежит учетная запись. Когда программа развертывается в механизме выполнения (развертывание BPF), загрузчик определяет, что байт-код в данных учетной записи является допустимым. Если это так, загрузчик постоянно помечает учетную запись программы как исполняемый файл.
Если программа помечена как окончательная (не подлежащая обновлению), среда выполнения обеспечивает неизменяемость данных учетной записи (программы). С помощью обновляемого загрузчика можно загрузить совершенно новую программу на существующий программный адрес.
Создание
Чтобы создать учетную запись, клиент создает keypair и регистрирует свой открытый ключ с помощью инструкции SystemProgram::CreateAccount
с предварительно выделенным фиксированным размером хранилища в байтах. Текущий максимальный размер данных учетной записи составляет 10 мегабайт.
Адрес учетной записи может быть любым произвольным 256-битным значением, и для опытных пользователей существуют механизмы для создания производных адресов (SystemProgram::CreateAccountWithSeed
, [Pubkey::CreateProgramAddress
](calling-between-programs.md#program-derived -адреса)).
Учетные записи, которые никогда не создавались с помощью системной программы, также могут быть переданы программам. Когда инструкция ссылается на учетную запись, которая не была создана ранее, программе будет передана учетная запись без данных и с нулевыми лампами, которая принадлежит системной программе.
Такие вновь созданные учетные записи отражают, подписывают ли они транзакцию, и поэтому могут использоваться в качестве полномочий. В этом контексте власти сообщают программе, что владелец закрытого ключа, связанного с открытым ключом учетной записи, подписал транзакцию. Открытый ключ учетной записи может быть известен программе или записан в другой учетной записи, что означает какое-то владение или полномочия в отношении актива или операции, которую программа контролирует или выполняет.
Право собственности и присвоение программ
Созданная учетная запись инициализируется встроенной программой, называемой Системной программой, и называется системной учетной записью. Учетная запись включает метаданные «владельца». Владелец - это идентификатор программы. Среда выполнения предоставляет программе доступ на запись к учетной записи, если ее идентификатор совпадает с владельцем. В случае системной программы среда выполнения позволяет клиентам передавать лампы и, что важно, назначать владельца учетной записи, что означает смену владельца на другой идентификатор программы. Если учетная запись не принадлежит программе, программе разрешено только считывать ее данные и кредитовать учетную запись.
Проверка достоверности немодифицированных учетных записей только для справки
В целях безопасности рекомендуется, чтобы программы проверяли действительность любой учетной записи, которую они считывают, но не изменяют.
Это связано с тем, что злоумышленник может создавать учетные записи с произвольными данными, а затем передавать эти учетные записи программе вместо действительных учетных записей. Произвольные данные могут быть созданы таким образом, что это приведет к неожиданному или вредному поведению программы.
Модель безопасности предусматривает, что данные учетной записи могут быть изменены только программой «Владелец» учетной записи. Это позволяет программе доверять тому, что данные передаются им через принадлежащие им учетные записи. Среда выполнения обеспечивает это, отклоняя любую транзакцию, содержащую программу, пытающуюся выполнить запись в учетную запись, которой она не владеет.
Если бы программа не проверяла достоверность учетной записи, она могла бы прочитать учетную запись, которая, по ее мнению, принадлежит ей, но на самом деле это не так. Любой может давать инструкции программе, и среда выполнения не знает, что эти учетные записи должны принадлежать программе.
Чтобы проверить действительность учетной записи, программа должна либо сверить адрес учетной записи с известным значением, либо убедиться, что учетная запись действительно принадлежит правильно (обычно принадлежит самой программе).
Например, когда программы используют учетную запись sysvar. Если программа не проверит адрес или владельца учетной записи, невозможно быть уверенным, что это настоящая и действительная учетная запись sysvar, просто путем успешной десериализации данных учетной записи.
Соответственно, Solana SDK проверяет действительность учетной записи sysvar во время десериализации.
Альтернативный и более безопасный способ прочитать sysvar — использовать функцию sysvar [get()
](https://github.com/solana-labs/solana/blob/64bfc14a75671e4ec3fe969ded01a599645080eb/sdk/program/src/sysvar/mod. rs#L73), который не требует этих проверок.
Если программа всегда изменяет рассматриваемую учетную запись, проверка адреса/владельца не требуется, потому что изменение не принадлежащей учетной записи будет отклонено средой выполнения, а содержащая транзакция будет отброшена.
Аренда
Поддержание учетных записей в Solana требует затрат на хранение, называемых rent, поскольку кластер блокчейна должен активно поддерживать данные для обработки любых будущих транзакций. Это отличается от Биткойна и Эфириума, где хранение учетных записей не требует никаких затрат.
В настоящее время все новые аккаунты должны быть освобождены от арендной платы.
Освобождение от арендной платы
Аккаунт считается освобожденным от арендной платы, если он содержит арендную плату не менее 2 лет. Это проверяется каждый раз, когда баланс счета уменьшается, и транзакции, которые уменьшат баланс ниже минимальной суммы, не пройдут.
Среда выполнения требует, чтобы исполняемые учетные записи программы были освобождены от арендной платы, чтобы избежать очистки.
Примечание. Используйте конечную точку RPC getMinimumBalanceForRentExemption
для расчета минимального баланса для определенного размера учетной записи. Следующий расчет является иллюстративным.
Например, исполняемый файл программы размером 15 000 байт требует баланса в 105 290 880 лэмпортов (=~ 0,105 SOL), чтобы быть освобожденным от арендной платы:
105,290,880 = 19.055441478439427 (fee rate) * (128 + 15_000)(account size including metadata) * ((365.25/2) * 2)(epochs in 2 years)
Арендную плату также можно оценить с помощью подкоманды командной строки solana rent
$ solana rent 15000
Rent per byte-year: 0.00000348 SOL
Rent per epoch: 0.000288276 SOL
Rent-exempt minimum: 0.10529088 SOL
Примечание. Будьте уверены, что, если в какой-то момент в будущем арендная ставка потребуется увеличить, будут предприняты шаги для обеспечения того, чтобы учетные записи, освобожденные от арендной платы до повышения, оставались освобожденными от арендной платы впоследствии.