文章详细解释了Solana中'owner'和'authority'的区别,'owner'是程序,'authority'是钱包,程序只能修改其拥有的账户数据,而'authority'通过发送签名交易来请求程序修改数据。文章结构清晰,包含代码示例和图片,适合中级开发者阅读。
新来者在 Solana 中常常对“owner”和“authority”之间的区别感到困惑。本文力图尽可能简洁地澄清这种混淆。
只有程序可以向账户写入数据——具体而言,只有向它们拥有的账户写入。程序不能随意向任意账户写入数据。
当然,程序不能自发地向账户写入数据。它们需要从一个钱包接收指令。然而,程序通常只会从特权钱包接受特定账户的写入指令:即 authority。
账户的拥有者是一个程序。Authority 是一个钱包。Authority 发送一个交易到程序,该程序可以向账户写入数据。
Solana 中所有账户都有以下字段,这些字段大多不言自明:
我们可以通过在终端运行 solana account <我们的钱包地址>
来查看这些(在背景中运行 Solana 验证器):
注意一些有趣的事情:我们不是我们钱包的拥有者! 地址 111...111
是 system program。
为什么系统程序拥有钱包,而不是钱包自己拥有自己?
只有账户的拥有者可以修改其中的数据。
这意味着我们无法直接修改我们的余额。只有系统程序可以做到这一点。要将 SOL 从我们的账户转出,我们发送一个签名交易到系统程序。系统程序验证我们拥有该账户的私钥,然后代表我们修改余额。
这是你在 Solana 中经常会看到的模式:只有账户的拥有者可以修改该账户中的数据。如果程序看到来自一个预定地址的有效签名,它就会修改账户中的数据:即 authority。
Authority 是一个地址,程序将在看到有效签名时接受该地址的指令。Authority 不能直接修改账户。它需要通过拥有它正在尝试修改的账户的程序来进行操作。
然而,拥有者始终是一个程序,而该程序将在交易的签名有效时代表其他人修改账户。
例如,在我们关于 使用不同签名者修改账户 的教程中,我们看到了这一点。
练习:创建一个程序来初始化存储账户。你将需要方便地记录程序和存储账户的地址。考虑将以下代码添加到测试中:
console.log(`program: ${program.programId.toBase58()}`);
console.log(`storage account: ${myStorage.toBase58()}`);
然后在被初始化的账户上运行 solana account <存储账户>
。你应该看到拥有者是程序。
这里是运行练习的截图:
当我们查看存储账户的元数据时,我们看到程序是拥有者。
因为程序拥有存储账户,所以它能够写入数据。用户无法直接写入存储账户,他们需要签署交易并请求程序写入数据。
在 Solidity 中,我们通常将拥有者称为对智能合约拥有管理权限的特殊地址。“拥有者”并不是以太坊运行级别存在的概念,而是应用于 Solidity 合约的一种设计模式。Solana 中的拥有者则更为根本。在以太坊中,智能合约只能写入自己的存储插槽。想象一下我们有一种机制,可以让以太坊智能合约能够写入其他存储插槽。在 Solana 术语中,它将成为这些存储插槽的 owner。
Authority 可以是程序级别的一个构造。在我们关于 Anchor 签名者 的教程中,我们制作了一个程序,允许Alice从她的账户中扣除积分并转给其他人。为了知道只有Alice可以发送该账户的扣除交易,我们在账户中存储了她的地址:
##[account]
pub struct Player {
points: u32,
authority: Pubkey
}
Solana 使用类似的机制来记住谁部署了一个程序。在我们关于 Anchor 部署 的教程中,我们提到部署程序的钱包也能够升级它。
“升级”一个程序与向其写入新的数据——即新的字节码是一样的。只有程序的拥有者可以向其写入(该程序是 BPFLoaderUpgradeable
,我们将很快看到)。
那么,Solana 怎样知道如何将升级权限赋予部署某个程序的钱包呢?
在我们部署程序之前,让我们通过在终端运行 solana address
来查看 anchor 正在使用哪个钱包:
请注意我们的地址是 5jmi...rrTj
。现在让我们创建一个程序。
确保 solana-test-validator
和 solana logs
在后台运行,然后部署 Solana 程序:
anchor init owner_authority
cd owner_authority
anchor build
anchor test --skip-local-validator
当我们查看日志时,我们看到刚刚部署的程序的地址:
记住,在 Solana 中,一切都是账户,包括程序。现在让我们使用 solana account 6Ye7CgrwJxH3b4EeWKh54NM8e6ZekPcqREgkrn7Yy3Tg
来检查这个账户。我们得到以下结果:
注意 authority 字段缺失,因为“authority” 并不是 Solana 账户所拥有的字段。如果你滚动到本文顶部,你会看到控制台中的键与我们在文章顶部列出的字段匹配。
在这里,“owner” 是 BPFLoaderUpgradeable111...111
,这是所有 Solana 程序的拥有者。
现在让我们运行 solana program show 6Ye7CgrwJxH3b4EeWKh54NM8e6ZekPcqREgkrn7Yy3Tg
,其中 6Ye7...y3TG
是我们的程序地址:
在上述绿色框中,我们看到我们的钱包地址——即用于部署程序的地址,以及我们之前用 solana address
打印的地址:
但这引出了一个重要问题…
它并不是账户中的一个字段,所以它一定是在某个 Solana 账户的 data
字段中。“authority” 存储在 ProgramData Address
中,该位置存储着程序的字节码:
在继续之前,将 ProgramData Address
的 base58 编码转换为十六进制表示将是有帮助的。完成此操作的代码在文章末尾提供,但是现在我们请读者接受下面这句话,即我们的 Solana 钱包地址 5jmigjgt77kAfKsHri3MHpMMFPo6UuiAMF19VdDfrrTj
的十六进制表示为:
4663b48dfe92ac464658e512f74a8ee0ffa99fffe89fb90e8d0101a0c3c7767a
我们可以使用 solana account
查看 ProgramData
地址账户,但我们也将其发送到临时文件以避免在终端转储太多数据。
solana account FkYygT7X7qjifdxfBVWXTHpj87THJGmtmKUyU4SamfQm > tempfile
head -n 10 tempfile
上面命令的输出显示我们钱包(十六进制)嵌入到 data
中。请注意,黄色下划线的十六进制代码与我们钱包(authority)的十六进制编码匹配:
这一点从上面的命令序列中应能隐含得出,但重申是值得的。尽管程序是一个标记为可执行的账户,但字节码并不存储在它自己的数据字段中,而是在另一个账户中(这个账户有点令人困惑地不是可执行的,它仅仅存储字节码)。
练习:你能找到程序将存储字节码的账户地址吗?本文的附录中包含可能有用的代码。
只有程序的拥有者可以更改其数据。Solana 程序的拥有者是 BPFLoaderUpgradeable
系统程序,因此按照默认设置,部署程序的钱包无法更改存储在账户中的数据(字节码)。
为了启用程序的升级,Solana 运行时将部署者的钱包嵌入到程序的字节码中。它将这个字段称为“authority”。
当部署钱包尝试升级字节码时,Solana 运行时将检查事务签名者是否为 authority。如果事务签名者与 authority 匹配,则 BPFLoaderUpgradeable
将代表 authority 更新程序的字节码。
以下 Python 代码将完成转换。此代码由一个聊天机器人生成,因此仅供参考:
def decode_base58(bc, length):
base58_digits = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
n = 0
for char in bc:
n = n * 58 + base58_digits.index(char)
return n.to_bytes(length, 'big')
def find_correct_length_for_decoding(base58_string):
for length in range(25, 50): # 尝试从 25 到 50 的长度
try:
decoded_bytes = decode_base58(base58_string, length)
return decoded_bytes.hex()
except OverflowError:
continue
return None
## 要转换的 Base58 字符串
base58_string = "5jmigjgt77kAfKsHri3MHpMMFPo6UuiAMF19VdDfrrTj"
## 转换并获取十六进制字符串
hex_string = find_correct_length_for_decoding(base58_string)
print(hex_string)
请查阅我们的 Solana 开发课程 以了解更多 Solana 主题!如需其他区块链主题,请查看我们的 区块链训练营。
原发布于 2024 年 3 月 11 日
- 原文链接: rareskills.io/post/solan...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!