Solana: Smart Contract Runs Fine on Solana Playground, but Fails on Local Machine
As a smart contract developer, especially those built on popular platforms like Ethereum and Solana, it is essential to ensure that your code compiles and runs correctly on different environments. In this article, we will explore what went wrong with a simple voting contract written in Rust that worked fine on the Solana Playground, but failed to launch on my local machine.
The Contract
Our smart contract is designed to create an interactive polling application where users can vote for their preferred outcome of a scenario. The contract uses the Solana SDK (Software Development Kit) and relies on several libraries, including Solana-Program
, Solana-Client
, and Solana-Rust-SDK
. It is written in Rust, with most of the functionality implemented using the Solana-Program
API.
Here is a quick overview of the contract:
`Rust
Use only_program :: {
account_info :: next_account_info,
EntryPoint :: {get_event_address, Invoke},
MSG,
Program_error :: {ProgramError, Result as ProgramResult},
pubkey :: pubkey,
};
Use solana_sdk :: {
Error :: Error as SolanaError,
KEYPAIR :: KEYPAIR,
transaction :: { self , commit , preparetransactionError },
};
// Function to create a new poll
pub fn create_poll (
pubkey: & pubkey,
Result: string,
) -> ProgramResult < imprint > {
// Create a new poll instance
Let Pool = Pool :: new ();
pool.set_outcome(result);
// Get the following account information for the user’s vote
let user_account_info = pool.get_next_account_info().
Let Account_keypair = user_account_info.key;
// Invoke the create_poll
function
invoke(
& account_keypair,
create_poll_callback,
&pool,
& [
account_keypair,
next_account_info(),
],
Commit::final,
)
} }
// Function to update the poll results
pub fn update_poll(result: string) -> ProgramResult
// Update the poll instance with the new result
Let Pool = Pool::new();
pool . set_outcome ( result ) ;
// Get the following account information for the user’s vote
let user_account_info = pool.get_next_account_info().
Let Account_keypair = user_account_info.key;
// Invoke the update_poll
function
invoke(
&cont_keypair,
update_poll_callback,
&pool,
& [
cont_keypair,
next_account_info(),
],
Commit::final,
)
} }
// Callback functions for poll creation and updates
pub fn create_poll_callback (
cont_info: &continfo,
pool: &pool,
) -> ProgramResult
// Create a new poll instance
Let Pool = Pool::new();
pool.set_outcome(cont_info.data.borrow().as_str())?;
OK (commit::final)
} }
pub fn update_poll_callback (
cont_info: &continfo,
pool: &pool,
) -> ProgramResult < pricing > {
// Update the poll instance with the new result
Let Pool = Pool::new();
pool.set_outcome(cont_info.data.borrow().as_str())?;
OK (commit::final)
} }
`
Problem
On my local machine, I encountered an error that prevented me from running the contract. The error message was quite cryptic:
`
ERROR: Undefined type ProgramResult
not found in this scope
Upon closer inspection of the code, we can see that the create_poll_callback
and update_poll_callback
functions return a ProgramResult
, which is defined by the Solana SDK. However, there is no explicit type definition for it.
Solution
To resolve the issue, I made two changes to my contract:
1.