---
title: 只读账户
---

这个设计涵盖了[runtime](../validator/runtime.md)对只读和可写账户的处理。 修改同一账户的多个事务必须串行处理，以便它们总是以相同的顺序重放。 否则，这可能会给账本引入非确定性。 然而，有些事务只需要读取，而不需要修改特定账户的数据。 由于重放顺序并不重要，因此可以并行处理多个只读取同一账户的事务，从而提供性能优势。

为了识别只读账户，事务MessageHeader结构包含`num_readonly_signed_accounts`和`num_readonly_unsigned_accounts`。 指令`program_ids`作为只读、无符号账户包含在账户向量中，因为可执行账户同样不能在指令处理过程中被修改。

## Runtime处理

Runtime的交易处理规则需要稍微更新。 程序仍然不能写入或花费不属于自己的账户。 但新的runtime规则保证了只读账户不能被修改，即使是拥有这些账户的程序也不能修改。

只读账户具有以下属性。

- 只读访问所有账户字段，包括lamports(不能贷记或借记) 和账户数据。

贷记、借记或修改只读账户的指令将失败。

## 账户锁定优化

账户模块在runtime跟踪当前锁定的账户，从而将只读账户和可写账户分开。 默认的账户锁给一个账户赋予了 "可写 "的称号，并且一次只能由一个处理线程访问。 只读账户由一个单独的机制锁定，允许并行读取。

虽然还没有实现，但只读账户可以缓存在内存中，并由所有执行事务的线程共享。 一个理想的设计是，当一个只读账户被任何在runtime移动的事务引用时，保持这个缓存，并在最后一个事务退出runtime释放缓存。

只读账户也可以作为引用传入处理器，保存一个额外的副本。
