Solana:在链上创建 PDA 账户
Solana: Create PDA account on chain
我正在尝试编写一个 Solana 程序,在链上为我创建一个 PDA 帐户。我无法让它工作,老实说,不知道我做错了什么:/
我的 Solana 程序中有以下代码:
let account_info_iter = &mut accounts.iter();
let initializer = next_account_info(account_info_iter)?;
if !initializer.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
let (pda, bump_seed) = Pubkey::find_program_address(&[b"admin_account"], program_id);
let admin_account = next_account_info(account_info_iter)?;
if admin_account.key != &pda {
return Err(CustomError::InvalidAdminAccount.into());
}
// we are checking if the account is rent exempt. In case it is, the account is already initialized
if **admin_account.try_borrow_lamports()? > 0 {
msg!("This account is already initialised. skipping");
return Ok(())
}
let lamports = Rent::default().minimum_balance(1);
let ix = solana_program::system_instruction::create_account(
initializer.key,
admin_account.key,
lamports,
1,
program_id,
);
// Sign and submit transaction
invoke_signed(
&ix,
&[initializer.clone(), admin_account.clone()],
&[&[b"admin_account"], &[&[bump_seed]]]
)?;
这是我的 Python 脚本:
pda_account, nonce = PublicKey.find_program_address([b"admin_account"], PROGRAM_ID)
init_ix = TransactionInstruction(
data=bytes(1),
keys=[
AccountMeta(pubkey=ADMIN_KEYPAIR.public_key, is_signer=True, is_writable=False),
AccountMeta(pubkey=pda_account, is_signer=False, is_writable=True),
],
program_id=PROGRAM_ID,
)
transaction = Transaction()
transaction.add(init_pantos_token_ix)
utils.send_and_confirm_tx(CLIENT, transaction, ADMIN_KEYPAIR)
每当我执行交易时,我都会收到以下错误消息:
Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing
但是缺少什么帐户?我尝试使用系统程序,但这给了我另一个错误:/
有人有什么想法吗?
确实需要在top-level处传入系统程序,然后在invoke_signed
处传入是可选的。所以你的 python 脚本应该做:
init_ix = TransactionInstruction(
data=bytes(1),
keys=[
AccountMeta(pubkey=ADMIN_KEYPAIR.public_key, is_signer=True, is_writable=True),
AccountMeta(pubkey=pda_account, is_signer=False, is_writable=True),
AccountMeta(pubkey=solana.system_program.SYS_PROGRAM_ID, is_signer=False, is_writable=False)
],
program_id=PROGRAM_ID,
)
请注意,您的 ADMIN_KEYPAIR
也需要可写才能将 lamports 从它移动到 pda 帐户。 client-side 上的这些更改应该可以工作。
我正在尝试编写一个 Solana 程序,在链上为我创建一个 PDA 帐户。我无法让它工作,老实说,不知道我做错了什么:/
我的 Solana 程序中有以下代码:
let account_info_iter = &mut accounts.iter();
let initializer = next_account_info(account_info_iter)?;
if !initializer.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
let (pda, bump_seed) = Pubkey::find_program_address(&[b"admin_account"], program_id);
let admin_account = next_account_info(account_info_iter)?;
if admin_account.key != &pda {
return Err(CustomError::InvalidAdminAccount.into());
}
// we are checking if the account is rent exempt. In case it is, the account is already initialized
if **admin_account.try_borrow_lamports()? > 0 {
msg!("This account is already initialised. skipping");
return Ok(())
}
let lamports = Rent::default().minimum_balance(1);
let ix = solana_program::system_instruction::create_account(
initializer.key,
admin_account.key,
lamports,
1,
program_id,
);
// Sign and submit transaction
invoke_signed(
&ix,
&[initializer.clone(), admin_account.clone()],
&[&[b"admin_account"], &[&[bump_seed]]]
)?;
这是我的 Python 脚本:
pda_account, nonce = PublicKey.find_program_address([b"admin_account"], PROGRAM_ID)
init_ix = TransactionInstruction(
data=bytes(1),
keys=[
AccountMeta(pubkey=ADMIN_KEYPAIR.public_key, is_signer=True, is_writable=False),
AccountMeta(pubkey=pda_account, is_signer=False, is_writable=True),
],
program_id=PROGRAM_ID,
)
transaction = Transaction()
transaction.add(init_pantos_token_ix)
utils.send_and_confirm_tx(CLIENT, transaction, ADMIN_KEYPAIR)
每当我执行交易时,我都会收到以下错误消息:
Transaction simulation failed: Error processing Instruction 0: An account required by the instruction is missing
但是缺少什么帐户?我尝试使用系统程序,但这给了我另一个错误:/ 有人有什么想法吗?
确实需要在top-level处传入系统程序,然后在invoke_signed
处传入是可选的。所以你的 python 脚本应该做:
init_ix = TransactionInstruction(
data=bytes(1),
keys=[
AccountMeta(pubkey=ADMIN_KEYPAIR.public_key, is_signer=True, is_writable=True),
AccountMeta(pubkey=pda_account, is_signer=False, is_writable=True),
AccountMeta(pubkey=solana.system_program.SYS_PROGRAM_ID, is_signer=False, is_writable=False)
],
program_id=PROGRAM_ID,
)
请注意,您的 ADMIN_KEYPAIR
也需要可写才能将 lamports 从它移动到 pda 帐户。 client-side 上的这些更改应该可以工作。