Search code examples
blockchainsolanaanchor-solana

Make a Solana program pay for the transaction


I'm not sure that is possible, but what I would like to do is to make the program pay for the transaction cost and make the user use the program for free.

In my mind the process would be:

  1. I send some Solana to the account of the program to handle future transactions.
  2. A user interact with the function SaveData
  3. (Inside this function in the future will be some sort of mechanism to check if the user can interact with the function without paying)
  4. The program would pay for the transaction, so the user don't have to pay even a single Lamport.

My code is:

#[derive(Accounts)]
pub struct SaveData<'info> {
    #[account(init, payer = system_program, space = 8 + 50 + 32 )]
    pub data_account: Account<'info, DataState>,

    #[account(mut)]
    pub authority: Signer<'info>,

    pub system_program: Program<'info, System>,
}
#[account]
pub struct DataState {
    pub authority: Pubkey,
    content: String
}

I tried setting system_program as the payer, but if I try to build the program with anchor it gives me this error:

error[E0599]: no method named `exit` found for struct `SaveData` in the current scope
  --> programs/test-smart-contract/src/lib.rs:5:1
   |
5  | #[program]
   | ^^^^^^^^^^ method not found in `SaveData<'_>`
...
61 | pub struct SaveData<'info> {
   | -------------------------- method `exit` not found for this

How can I achieve what I want to do?


Update

In order to manage this problem, I started developing this service: cowsigner.com


Solution

  • Unfortunately every transaction has a fee payer which is specified and needs to sign on the transaction and be a signer account.

    System program is a native program on Solana and you're misusing it in your case. This is the official definition for it:

    Create new accounts, allocate account data, assign accounts to owning programs, transfer lamports from System Program owned accounts and pay transaction fees.

    If you wish to pay for the fees then you would need a dedicated account, that is specified as the feePayer on each transaction and signs on each transaction as well.