1

Hi I am creating a split bill and pay smart contract. I have written a small piece of code to begin with here it is:

use anchor_lang::prelude::*;

declare_id!("BpvN4cCL5RxjxQk2ikVbXAA2bskMZgH4eveiy41Wg3FV");

#[program]
pub mod split_bill {
    use super::*;

    pub fn initialize_split(ctx: Context<InitializeSplit>, name: String, total_amount: u64,) -> Result<()> {

        let split_bill = &mut ctx.accounts.bill;
        split_bill.authority = ctx.accounts.initializer.key();
        split_bill.bill_name = name;
        split_bill.total_amount = total_amount;
        split_bill.contributors = Vec::new();
        Ok(())
    }
}

#[account]
#[derive(InitSpace)]
pub struct SplitBill {
    pub authority: Pubkey,

    #[max_len(50)]
    pub bill_name: String,
    pub total_amount: u64,

    #[max_len(10, 40)]
    pub contributors: Vec<Contributor>,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone, InitSpace)]
pub struct Contributor{
    pub address: Pubkey,
    pub amount: u64,
}

#[derive(Accounts)]
#[instruction(authority:Pubkey, bill_name: String)]
pub struct InitializeSplit<'info> {
    #[account(mut)]
    pub initializer: Signer<'info>,

    #[account(
        init,
        space = 8 + SplitBill::INIT_SPACE,
        payer = initializer,
        seeds = [authority.key().as_ref(), bill_name.as_ref(), ],
        bump,    
    )]
    pub bill: Account<'info, SplitBill>,

    /// CHECK: This account is not loaded in this instruction and serves only as a destination for the final transfer.
    pub receiver: AccountInfo<'info>,
    pub system_program: Program<'info, System>,
}

I wrote a test script to test it:

import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { SplitBill } from "../target/types/split_bill";
import { startAnchor } from "solana-bankrun";
import { BankrunProvider } from "anchor-bankrun";
import {PublicKey} from '@solana/web3.js';
import { expect } from "chai";

const IDL = require("../target/idl/split_bill.json");
const programId = new PublicKey("BpvN4cCL5RxjxQk2ikVbXAA2bskMZgH4eveiy41Wg3FV");

describe("split-bill", () => {
  
  let context;
  let provider;
  let program: Program<SplitBill>;

  before(async () => {
    context = await startAnchor("", [{name:"split_bill", programId: programId}], []);
    provider = new BankrunProvider(context);
    program = new Program<SplitBill>(IDL, provider);
  });

  it("Initialize a split bill", async () => {

    console.log("initialize split");

    const [splitBillAddress] = await PublicKey.findProgramAddressSync(
      [provider.wallet.publicKey.toBuffer(), Buffer.from("test"), ],
      programId);

    console.log("splitBillAddress", splitBillAddress.toBase58());

    const tx = await program.methods.initializeSplit("test", new anchor.BN(1000)).accountsPartial({
      bill: splitBillAddress,
      receiver: provider.wallet.publicKey,
    }).rpc();

    console.log("initialize split done");
  });
});

And I am getting this error:

1) split-bill
       Initialize a split bill:
     Error: AnchorError occurred. Error Code: InstructionDidNotDeserialize. Error Number: 102. Error Message: The program could not deserialize the given instruction.
      at Function.parse (node_modules/@coral-xyz/anchor/src/error.ts:136:14)
      at translateError (node_modules/@coral-xyz/anchor/src/error.ts:277:35)
      at MethodsBuilder.rpc [as _rpcFn] (node_modules/@coral-xyz/anchor/src/program/namespace/rpc.ts:35:29)

Please Help Thanks.

1 Answer 1

1

In your instruction macro, #[instruction(authority: Pubkey, bill_name: String)] you are using authority but aren't passing in this address in your initialize_split function.

initialize_split(ctx: Context<InitializeSplit>, authority: Pubkey, name: String, total_amount: u64,)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.