【发布时间】: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 deploy或solana write-buffer'. Or to recover the account's lamports, pass it as the [BUFFER_ACCOUNT_ADDRESS] argument tosolana 程序关闭`。 ==================================================== ================== 错误:帐户分配失败:RPC响应错误-32002: 交易模拟失败:此账户可能无法用于支付 交易费用部署出现问题:输出{状态: 退出状态(退出状态(256)),标准输出:“”,标准错误:“”}。
非常感谢您的提示。发生了什么?我是否设法破坏了客户的合同?
【问题讨论】:
标签: anchor smartcontracts solana