如何在 Serum Anchor 中签署代币交易

har*_*rkl 5 anchor rust solana

我有一个使用 Serum Anchor(在 Solana 上)的简单合约,将代币从一方转移到另一方。目前它失败了:

Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account

以下片段的完整代码:https://gist.github.com/h4rkl/700400f515ab0736fd6d9318d44b2dca

我正在为交易设置 4 个账户:

  let mint = null; // key for token mint
  let god = null; // main program account to pay from and sign
  let creatorAcc = anchor.web3.Keypair.generate(); // account to pay to
  let creatorTokenAcc = null; // token account for payment
Run Code Online (Sandbox Code Playgroud)

我将它们设置如下:

const [_mint, _god] = await serumCmn.createMintAndVault(
      program.provider,
      new anchor.BN(MINT_TOKENS),
      undefined,
      MINT_DECIMALS
    );
    mint = _mint;
    god = _god;

    creatorTokenAcc =await serumCmn.createTokenAccount(
      program.provider,
      mint,
      creatorAcc.publicKey
    );
Run Code Online (Sandbox Code Playgroud)

然后我用以下方法付款:

const INTERACTION_FEE = 200000000000000;
await program.rpc.interaction(new anchor.BN(INTERACTION_FEE), {
      accounts: {
        from: god,
        to: creatorTokenAcc,
        owner: program.provider.wallet.publicKey,
        tokenProgram: TOKEN_PROGRAM_ID,
      },
    });
Run Code Online (Sandbox Code Playgroud)

在合约中该方法触发我的交互过程如下:

pub fn interaction(ctx: Context<Interaction>, interaction_fee: u64) -> ProgramResult {
        let cpi_accounts = Transfer {
            from: ctx.accounts.from.to_account_info().clone(),
            to: ctx.accounts.to.to_account_info().clone(),
            authority: ctx.accounts.owner.clone(),
        };
        let cpi_program = ctx.accounts.token_program.clone();
        let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
        token::transfer(cpi_ctx, interaction_fee)?;
       
        Ok(())
    }
Run Code Online (Sandbox Code Playgroud)

pub struct我已经使用以下参数设置了交互:

#[derive(Accounts)]
pub struct Interaction<'info> {
    #[account(mut, has_one = owner)]
    from: CpiAccount<'info, TokenAccount>,
    #[account("from.mint == to.mint")]
    to: CpiAccount<'info, TokenAccount>,
    #[account(signer)]
    owner: AccountInfo<'info>,
    token_program: AccountInfo<'info>,
}
Run Code Online (Sandbox Code Playgroud)

据我所知,参数是正确的,并且该god帐户作为付款人拥有钱包并且是签名人。为什么会失败,我错过了什么?我完全没有主意了。

har*_*rkl 3

传奇人物阿玛尼·费兰特 (Armani Ferrante) 的回答是:

您的 to帐户未标记为可变。