【问题标题】:Is it possible to corrupt Solana Smart Contract from client side?是否有可能从客户端破坏 Solana 智能合约?
【发布时间】:2021-10-30 12:09:48
【问题描述】:

我正在关注this tutorial 在本地网络上创建智能合约。一切正常,但是当我修改客户端智能合约时最终处于“损坏”状态。我无法理解发生了什么。这是合同:

use anchor_lang::prelude::*;
 
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
 
#[program]
mod mysolanaapp {
    use super::*;
 
    pub fn create(ctx: Context<Create>) -> ProgramResult {
        let base_account = &mut ctx.accounts.base_account;
        base_account.count = 0;
        Ok(())
    }
 
    pub fn increment(ctx: Context<Increment>) -> ProgramResult {
        let base_account = &mut ctx.accounts.base_account;
        base_account.count += 1;
        Ok(())
    }
}
 
// Transaction instructions
#[derive(Accounts)]
pub struct Create<'info> {
    #[account(init, payer = user, space = 16 + 16)]
    pub base_account: Account<'info, BaseAccount>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program <'info, System>,
}
 
// Transaction instructions
#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut)]
    pub base_account: Account<'info, BaseAccount>,
}
 
// An account that goes inside a transaction instruction
#[account]
pub struct BaseAccount {
    pub count: u64,
}

并且工作的客户端代码是:

const anchor = require('@project-serum/anchor');
const { SystemProgram } = anchor.web3;
 
 
(async () => {
 
    const provider = anchor.Provider.local();
    anchor.setProvider(provider);
 
    // The Account to create.
    const myAccount = anchor.web3.Keypair.generate();
 
    // Read the generated IDL.
    const idl = JSON.parse(require('fs').readFileSync('./hello.json', 'utf8'));
 
    // Address of the deployed program.
    const programId = new anchor.web3.PublicKey('GrfgF4vWfVEDsLKHxiB5Q6yfYhziubLY9M8VVxyTEc6o');
 
    // Generate the program client from IDL.
    const program = new anchor.Program(idl, programId);
 
    // Execute the RPC.
    await program.rpc.create({
        accounts: {
            baseAccount: myAccount.publicKey,
            user: provider.wallet.publicKey,
            systemProgram: SystemProgram.programId,
        },
        signers: [myAccount],
    });
 
    /* Fetch the account and check the value of count */
    let account = await program.account.baseAccount.fetch(myAccount.publicKey);
    console.log('Count 0: ', account.count.toString())
 
    await program.rpc.increment({
        accounts: {
            baseAccount: myAccount.publicKey,
        },
    });
 
    account = await program.account.baseAccount.fetch(myAccount.publicKey);
    console.log('Count 1: ', account.count.toString())
 
})();

但是,此代码每次调用时都会生成新帐户。由于我想保持数据的持久性,我尝试用加载我用来部署合约的本地密钥对来替换帐户生成:

const secKey = JSON.parse(require('fs').readFileSync('/home/username/.config/solana/id.json', 'utf8'));
const arr = Uint8Array.from(secKey)

const myAccount = anchor.web3.Keypair.fromSecretKey(arr);

但是这会导致错误:

SendTransactionError: 发送交易失败: 交易模拟失败: 此账户可能无法用于支付交易费用

对我来说更奇怪的是,还原更改无济于事,而且客户端一直在失败。令我惊讶的是,由于锚点返回以下错误,甚至不再可能再次部署合约:

升级权限:/home/username/.config/solana/id.json 正在部署 程序“mysolanaapp”...程序路径: /home/username/workspace/solana/mysolanaapp/target/deploy/mysolanaapp.so... ==================================================== ================== 恢复中间账户的临时密钥对文件 solana-keygen recover 和以下 12 个字的助记词: ==================================================== ================== 完全体现演员侧舌荷兰人铺路作物对病案 ==================================================== ================== 要恢复部署,请将恢复的密钥对作为 [PROGRAM_ADDRESS_SIGNER] 参数到solana deploy 或作为 [BUFFER_SIGNER] 到 solana program deploysolana write-buffer'. Or to recover the account's lamports, pass it as the [BUFFER_ACCOUNT_ADDRESS] argument to solana 程序关闭`。 ==================================================== ================== 错误:帐户分配失败:RPC响应错误-32002: 交易模拟失败:此账户可能无法用于支付 交易费用部署出现问题:输出{状态: 退出状态(退出状态(256)),标准输出:“”,标准错误:“”}。

非常感谢您的提示。发生了什么?我是否设法破坏了客户的合同?

【问题讨论】:

    标签: anchor smartcontracts solana


    【解决方案1】:

    这是所有预期的行为。错误:

    SendTransactionError:发送交易失败:交易模拟失败:此账户可能无法用于支付交易费用

    提供所有最重要的信息。在 Solana 中,当您向网络发送交易时,系统程序 (https://docs.solana.com/developing/runtime-facilities/programs#system-program) 拥有的某个帐户必须签署交易,以扣除费用。当您使用您的程序在myAccount 上运行create 指令时,该帐户将被分配给您的程序,因此它不再属于系统程序,因此无法签署交易。有关帐户模型的更多信息,特别是有关所有权的信息,请访问 https://docs.solana.com/developing/programming-model/accounts#ownership-and-assignment-to-programs

    说了这么多,要解决您的问题,您需要使用不同的帐户签署交易。您可以使用solana-keygen new -o new_account.json 然后solana airdrop .1 new_account.json 使其有资金,然后根据需要将其用作签名者。

    【讨论】:

      猜你喜欢
      • 2021-11-06
      • 2022-08-04
      • 2019-08-12
      • 2022-08-15
      • 1970-01-01
      • 2023-01-15
      • 2019-05-04
      • 2022-08-16
      • 2022-12-06
      相关资源
      最近更新 更多