4

I don't know how can I write an onchain program in Solana that after executing the logic, returns an array of integers, strings, etc ... to the client, and how can I fetch it using web3?

2 Answers 2

2

Solana instruction handlers don't return data, they write to accounts and return a rust OK (showing the instruction has completed successfully).

So store the integers or string in an account. Then use the web3 library to read the contents of the account (this is easier when you use Anchor)

In Rust(Using Anchor)

pub struct StoreStuffInAccount<'info>
{
// The necessary accounts needed to store data on the Blockchain

    #[account(mut)]
    pub payer: Signer<'info>,// account that pays transaction fees
    
    
    #[account(init, payer = user, space = 8 + 4 + 32 + 4 + 32 + 1)]// space represents size in bytes you want to store on the blockchain
    pub stuff_account: Account<'info, Stuff>,

    pub system_program: Program<'info, System>,
}

pub struct Stuff
{
  // The data(String, Integer) you plan to store on the Blockchain
   firstname: String,//32 bytes
   lastname: String,// 32 bytes
   birthday: u8, // 1 byte
}

pub fn store_stuff_in_account(ctx: Context<StoreStuffInAccount>, first_name: String, last_name: String, birthday: u8) -> Result<()>
{
// This tells the smart contract to store information on the blockchain
  let stuff = &mut ctx.accounts.stuff_account;

  stuff.firstname = first_name;
  stuff.lastname = last_name;
  stuff.birthday = birthday;
  Ok(())
} 

You can learn more about the space calculation

In Client Side

  import * as anchor from "@project-serum/anchor";
  anchor.setProvider(anchor.AnchorProvider.env());
  const provider =  anchor.getProvider() as anchor.AnchorProvider;// local wallet for testing
  const program = anchor.workspace.StoreStuff as Program<StoreStuff>;// the deployed smart contract information exists here including address
  const stuffAccount = anchor.web3.Keypair.generate();// Create a new Account that we will use to store information
      
      await program.initialize("first_name", "last_name", "24092022" ) // calls the smart contract to store information on the blockchain
        .accounts({
        {        
          payer: provider.wallet.publicKey,
          stuffAccount: stuffAccount.publicKey,
          systemProgram: SystemProgram.programId
        })
        .signers: [stuffAccount]
        .rpc()


// Retrieve an account from the blockchain so that you can read its contents(anchor deserializes it for you)
      const account = await program.account.stuffAccount.fetch(stuffAccount.publicKey);
      console.log("firstname ", account.firstName);
      console.log("lastname ", account.lastName);
      console.log("birthday ", account.birthday);

To learn more on how on how to start writing smart contracts on solana. You can start from here

0

There's a syscall available to on-chain programs called set_return_data, which puts data into a buffer that can be read by the higher-level programs using get_return_data. This all mediated through opaque byte buffers, so you'll need to know how to decode the response.

If you want to fetch the data from the client side, you can simulate the transaction and read the data back from the return_data field in the response: https://edge.docs.solana.com/developing/clients/jsonrpc-api#results-50

The RPC support in simulated transactions is very new in version 1.11, but the return data is available in earlier versions.

Source code for set_return_data at https://github.com/solana-labs/solana/blob/658752cda710cb358d7ccbbc2cee06bf8009c2d4/sdk/program/src/program.rs#L102

Source code for get_return_data at https://github.com/solana-labs/solana/blob/658752cda710cb358d7ccbbc2cee06bf8009c2d4/sdk/program/src/program.rs#L117

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.