har*_*rkl 8 javascript rust blockchain solana
我正在尝试处理我的 solana 合约中的交易。我应该这样做的方式是使用createAccountWithSeed生成程序(8DqELvN5TFeMtNJciUYvGqso2CyG5M6XNWxh3HRr3Vjv)和付款人拥有的转账帐户。因此,我创建新的转账帐户以发送到 solana 程序处理器以执行交易。但是,当我将转账帐户传递给我的 Rust 程序时,check_account_owner该帐户由系统程序 (11111111111111111111111111111111) 而不是我的程序拥有。
所以我的问题有两个:
这是客户端的 JS createAccountWithSeed。
const transferAcc = await PublicKey.createWithSeed(
payer.publicKey,
"payer",
PROGRAM_ID,
);
await connection.requestAirdrop(transferAcc, 100000);
SystemProgram.createAccountWithSeed({
basePubkey: payer.publicKey,
fromPubkey: payer.publicKey,
lamports: 100000,
newAccountPubkey: transferAcc,
programId: PROGRAM_ID,
seed: "payer",
space: 1024,
});
const accInfo = await connection.getAccountInfo(transferAcc);
console.log(
`Paying from acc: ${transferAcc.toBase58()}, Owned by: ${accInfo?.owner.toBase58()}`
);
Run Code Online (Sandbox Code Playgroud)
这是尝试进行传输的 Rust 代码。
pub fn process_payment(
program_id: &Pubkey,
accounts: &[AccountInfo],
payment_fee: u64,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let token_program = next_account_info(account_info_iter)?;
let payer_acc = next_account_info(account_info_iter)?;
let transfer_acc = next_account_info(account_info_iter)?;
let receiver_acc = next_account_info(account_info_iter)?;
if !payer_acc.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
if *token_program.key != id() {
return Err(SosolError::IncorrectTokenProgramId.into());
}
check_account_owner(payer_payment_acc, &program_id)?;
msg!("Calling the token program to transfer tokens to the receiver...");
token_transfer(
token_program.clone(),
transfer_acc.clone(),
receiver_account_key.clone(),
payer_acc.clone(),
payment_fee,
)?;
Ok(())
}
/// Issue a spl_token `Transfer` instruction.
#[allow(clippy::too_many_arguments)]
fn token_transfer<'a>(
token_program: AccountInfo<'a>,
source: AccountInfo<'a>,
destination: AccountInfo<'a>,
authority: AccountInfo<'a>,
amount: u64,
) -> Result<(), ProgramError> {
let ix = transfer(
token_program.key,
source.key,
destination.key,
authority.key,
&[],
amount,
)?;
invoke(&ix, &[source, destination, authority, token_program])
}
Run Code Online (Sandbox Code Playgroud)
错误日志状态:
Program log: Expected account to be owned by program 8DqELvN5TFeMtNJciUYvGqso2CyG5M6XNWxh3HRr3Vjv, received 11111111111111111111111111111111
Program log: CUSTOM-ERROR: The account did not have the expected program id
Run Code Online (Sandbox Code Playgroud)
好的,那么转账账户之所以归系统程序而不是我的程序所有,是因为我是在交易之外创建账户的。关键是将createAccountWithSeed(或者实际上只是createAccount为了我,因为我实际上想要为每笔交易创建一个新帐户)方法添加到您的交易链中,如下所示:
const transaction = new Transaction();
const transferAcc = new Keypair();
const transferAccPubKey = transferAcc.publicKey;
transaction.add(
SystemProgram.createAccount({
fromPubkey: payerAccount.publicKey,
newAccountPubkey: transferAccPubKey,
lamports: paymentFee,
space: dataLayout.span,
programId: PROGRAM_ID,
})
);
Run Code Online (Sandbox Code Playgroud)
runloop是一个非常好的合作伙伴资源,可以提供这方面的帮助。将所有交易项目添加到交易项目后,您将使用以下方式发送它:
return await sendAndConfirmTransaction(connection, transaction, [
payerAccount, transferAcc
]);
Run Code Online (Sandbox Code Playgroud)
因此,如果您正在为在哪里插入该transaction.add方法而烦恼,请寻找该方法。
我花了很长时间才弄清楚这一点,所以希望它对某人有所帮助。
| 归档时间: |
|
| 查看次数: |
3306 次 |
| 最近记录: |