Giter Site home page Giter Site logo

anchor-book's People

Contributors

0xdeepmehta avatar acheroncrypto avatar armaniferrante avatar drseu55 avatar fanatid avatar fletchertyler914 avatar gabrielepicco avatar githubpang avatar harshkn avatar hiroyukikumazawa avatar joemccann avatar kennethcassel avatar lucasig11 avatar omahs avatar paul-schaaf avatar polarisiota avatar sohrab- avatar svendowideit avatar tanmaymunjal avatar tomlinton avatar trungbaotran1701 avatar tudorpintea999 avatar u32luke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

anchor-book's Issues

multiple book versions at the same time

updating the book because of a new version shouldn't remove the old book version so we need a way to display multiple versions of the book.

alternatively, tag book commits that update to a new anchor version and give instruction in readme on how to run a different version locally

TicTacToe example: trying to use ctx inside Game

Following the TicTacToe example, I'm trying to pass ctx to a public method flip of Game:

// instructions/play.rs
pub fn play(ctx: Context<Play>, data: FlipArgs) -> Result<()> {
    ctx.accounts.game.flip(&ctx, data)
}
pub fn flip(&mut self, ctx: Context<Play>, data: FlipArgs) -> Result<()> {
    self.charge_fee(ctx);

    match data.heads_or_tails {
        true => self.play_heads(ctx),
        false => self.play_tails(ctx),
    }
}

fn charge_fee(&self, ctx: Context<Play>) -> Result<()> {
    let player = &ctx.accounts.player;

    if **player.try_borrow_lamports()? < self.static_amount {
        return Err(CoinflipError::InsufficientFunds.into());
    }

    let fee = self.calculate_fee();

    **player.try_borrow_mut_lamports()? -= fee as u64;

    Ok(())
}

However, this results in an error:

anchor_lang::context::Context<instructions::play::Play>
ctx: Context<Play>
anchor_lang::context::Context<instructions::play::Play>
ctx: Context<Play>
mismatched types

expected struct `anchor_lang::context::Context`, found reference

So, how to make ctx work from inside Game in order to access the ctx.accounts.player?

Syntax Error Due to Missing Semicolon in PDAs.md

Hello,

I've encountered a syntax error in the game module within the anchor_in_depth/PDAs.md file. Specifically, the issue arises from a missing semicolon at the end of the line where user_stats.bump is assigned. Here's the relevant code snippet:

use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod game {
    use super::*;
    // handler function
    pub fn create_user_stats(ctx: Context<CreateUserStats>, name: String) -> Result<()> {
        let user_stats = &mut ctx.accounts.user_stats;
        user_stats.level = 0;
        if name.as_bytes().len() > 200 {
            // proper error handling omitted for brevity
            panic!();
        }
        user_stats.name = name;
        user_stats.bump = ctx.bumps.user_stats // Missing semicolon here

Issue:
The line user_stats.bump = ctx.bumps.user_stats is missing a semicolon at the end. This omission could lead to a compilation error, affecting developers who are trying to compile or run this example.

Expected Correction:
The line should end with a semicolon, as shown below:

user_stats.bump = ctx.bumps.user_stats;

Recommendation:
Please add the missing semicolon to ensure the code snippet compiles without errors. This small fix will help improve the documentation's accuracy and usability for developers exploring Anchor.

Thank you for your attention to this matter.

bug about "Tic-Tac-Toe" project.

When i code flow this example Milestone Project - Tic-Tac-Toe.

I got an error " Error: AnchorError caused by account: game. Error Code: AccountDidNotSerialize. Error Number: 3004. Error Message: Failed to serialize the account." at anchor test.

I also see the notice.

(What about using mem::size_of()? This almost works but not quite. The issue is that borsh will always serialize an option as 1 byte for the variant identifier and then additional x bytes for the content if it's Some. Rust uses null-pointer optimization to make Option's variant identifier 0 bytes when it can, so an option is sometimes just as big as its contents. This is the case with Sign. This means the MAXIMUM_SIZE could also be expressed as mem::size_of() + 9.)

but it seems like lose 4 bit of borsh space. Maybe the MAXIMUM_SIZE need change to pub const MAXIMUM_SIZE: usize = 4 + (32 * 2) + 1 + (9 * (1 + 1)) + (32 + 1);

use ts builder api

adjust all client code in the book and the /programs folder to use the new program.methods API.

The PDA inference is still behind a feature gate and should not be included in the book yet.

error[E0107]: populated from the Tic-Tac-Toe and CPA examples when followed explicitly

Same error code populated from the Tic-Tac-Toe and CPA examples when followed explicitly.
error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
--> programs/tic-tac-toe/src/lib.rs:58:67
|
58 | pub fn setup_game(ctx: Context, player_two: Pubkey) -> Result<()> {
| ^^^^^^ -- supplied 1 generic argument
| |
| expected 2 generic arguments
|
note: enum defined here, with 2 generic parameters: T, E
help: add missing generic argument
|
58 | pub fn setup_game(ctx: Context, player_two: Pubkey) -> Result<(), E> {
| +++

For more information about this error, try rustc --explain E0107.

Testing a game that transfer lamports: "sum of account balances before and after instruction do not match"

instructions::play is defined like this:

use crate::state::game::*;
use anchor_lang::prelude::*;

pub fn play(ctx: Context<Play>, data: FlipArgs) -> Result<()> {
    let game = &mut ctx.accounts.game;
    game.flip(&ctx.accounts.player, data)
}

#[derive(Accounts)]
pub struct Play<'info> {
    #[account(mut)]
    pub game: Account<'info, Game>,
    #[account(init, payer = payer, space = Game::MAXIMUM_SIZE + 8)]
    /// CHECK: insecure
    pub player: AccountInfo<'info>,
    #[account(mut)]
    pub payer: Signer<'info>,
    pub system_program: Program<'info, System>,
}

game.flip will then attempt to charge the player a fee:

pub fn flip(&mut self, player: &AccountInfo, data: FlipArgs) -> Result<()> {
        match self.charge_fee(player) {
            Err(e) => return Err(e),
            _ => match data.heads_or_tails {
                true => self.play_heads(player),
                false => self.play_tails(player),
            },
        }
    }

    fn charge_fee(&self, player: &AccountInfo) -> Result<()> {
        if **player.try_borrow_lamports()? < self.static_amount {
            return Err(CoinflipError::InsufficientFunds.into());
        }

        let fee = self.calculate_fee();

        **player.try_borrow_mut_lamports()? -= fee as u64;

        Ok(())
    }

Typescript chai tests try to setup the game, airdrop balance to the player and then flip:

it("play: heads", async () => {
    const gameKeypair = anchor.web3.Keypair.generate();
    await setupGame(gameKeypair);

    const playerKeypair = anchor.web3.Keypair.generate();
    const signature = await programProvider.connection.requestAirdrop(
      playerKeypair.publicKey,
      anchor.web3.LAMPORTS_PER_SOL,
    );
    await programProvider.connection.confirmTransaction(signature);
    const balance = await programProvider.connection.getBalance(playerKeypair.publicKey);

    console.log(balance);

    await program.methods
      .flip({ headsOrTails: true })
      .accounts({
        game: gameKeypair.publicKey,
        player: playerKeypair.publicKey,
      })
      .signers([playerKeypair])
      .rpc();

    // ...
  });

But fails with:

2) solana-anchor-coinflip
       play: heads:
     Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: sum of account balances before and after instruction do not match
      at Connection.sendEncodedTransaction (node_modules/@solana/web3.js/src/connection.ts:4068:13)
      at processTicksAndRejections (internal/process/task_queues.js:93:5)
      at Connection.sendRawTransaction (node_modules/@solana/web3.js/src/connection.ts:4030:20)
      at sendAndConfirmRawTransaction (node_modules/@project-serum/anchor/src/provider.ts:284:21)
      at AnchorProvider.sendAndConfirm (node_modules/@project-serum/anchor/src/provider.ts:144:14)
      at MethodsBuilder.rpc [as _rpcFn] (node_modules/@project-serum/anchor/src/program/namespace/rpc.ts:29:16)

I think the problem lies in the pub struct Play definition:

#[derive(Accounts)]
pub struct Play<'info> {
    #[account(mut)]
    pub game: Account<'info, Game>,
    #[account(init, payer = payer, space = Game::MAXIMUM_SIZE + 8)]
    /// CHECK: insecure
    pub player: AccountInfo<'info>,
    #[account(mut)]
    pub payer: Signer<'info>,
    pub system_program: Program<'info, System>,
}

Initial test fails

Seems it doesnt work. Simply did a build and deploy. Followed by a test and got this:

Error: failed to get recent blockhash: FetchError: request to http://localhost:8899/ failed, reason: connect ECONNREFUSED ::1:8899

validator is running locally

Splitting program into multiple files failed

I am success in this tic_tac_toe project,But when i try to split program into multiple files. the program doesn't work. the error message is unresolved import crate,but i think my program is same to this example.
image

require! macro

I see that Anchor is suggesting the use of the require! macro, which produces code like this:

    pub fn is_active(&self) -> bool {
        self.state == GameState::Active
    }
    pub fn play(&mut self, tile: &Tile) -> Result<()> {
        require!(self.is_active(), TicTacToeError::GameAlreadyOver);
        ...
    }

However this is not idiomatic Rust. Normally in Rust you would see something like this:

     fn is_active(&self) -> Result<()> {
         match self.state.eq(&GameState::Active) {
             false => Err(TicTacToeError::GameAlreadyOver),
             true => Ok(()),
         }
     }


     pub fn play(&mut self, tile: &Tile) -> Result<()> {
         self.is_active()?;
         ...
     }

I feel like this is an attempt to bring the Solidity coding style into Rust. Is there a technical reason to this, or is this popular just because a lot of smart contract devs are transitioning from Solidity to Rust?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.