关于Solana 中 transfer SOL的一点理解

核心,只有owner才能转移所属账号的SOL,这与只有owner才能写数据的道理是一样的。

一、账号的owner种类

一个账号的owner有以下几种:

系统程序: 11111111111111111111111111111111

不可升级程序:BPFLoader2111111111111111111111111111111111

可升级程序: BPFLoaderUpgradeab1e11111111111111111111111

用户自己的程序(例如):6QL77rHaAKzmNYnmHfrCK1N4bN6fy8dK3CKh623FeUYF

二、转移账号

首先是转移账号:

执行转移时,执行的上下文环境必须是转移账号的owner。因此有如下几点:

  • 外部账号可以直接使用solana transfer来转移

  • 不可升级程序及可升级程序不可转移

  • 程序拥有的账号可以在程序内进行转移(通过 **source_info.try_borrow_mut_lamports()? -= 10; 的形式)

  • 只读账号无法进行转移(因为转移其实要写数据,当前所有可执行程序均是只读的)

因此不存在玩家(外部账号)通过一个程序转移自己的sol(因为程序只能转移自己拥有的账号的sol)。

三、接收账号

根据接收账号是否可写/只读,有如下几点:

  • 外部账号可以接收,如果外部账号不存在,使用命令行转移时会有提示需要添加 --allow-unfunded-recipient 选项,使用脚本转移时同时会创建账号,该账号的owner为系统程序:11111111111111111111111111111111,这个要注意,如果你使用seed计算了一个本应该程序拥有的账号地址,而使用脚本直接向其转移lamp,最终会导致该账号的owner为11111111111111111111111111111111,而不是预期中的程序。同样,使用脚本创建账号时不指定owner,也会导致新创建的地址的owner为系统程序11111111111111111111111111111111,即使是你计算的某个程序拥有的地址。
  • owner为通用程序的账号是可以接收的,例如owner为token_program_id或者自定义程序ID的。
  • 用户自己的程序或者系统程序(owner为 BPFLoaderUpgradeab1e11111111111111111111111 或者 BPFLoader2111111111111111111111111111111111)是无法接收的,因为程序都是只读的。

四、其它注意事项

如果在程序内部使用 **source_info.try_borrow_mut_lamports()? -= 10; 的形式,注意所有账号的余额变化必须相符(不相符会报错:sum of account balances before and after instruction do not match

猜你喜欢

转载自blog.csdn.net/weixin_39430411/article/details/121855048