I tried to deploy my Solana smart contract, but I encountered the following error:
"Error: Deploying program failed: Error processing
Instruction 1: invalid account data for instruction"
May I have your help to take a look at this failed deployment
https://solscan.io/tx/c8VBq8sE5XP2Q75pvLXsyGhehC3Utj1zS9fatunHuvgVDdGobKhupvFUXBTb7DxPfeneSskmEZhszrdPqpXSsyg?cluster=devnet?
Thanks!
This one is subtle, but the error is contained in the logs of your transaction if you look at the "Raw" Program Logs.
It says: ELF error: Found writable section (.bss._ZN5ahash12random_state11RAND_SOURCE17h85a33855e0b029fbE) in ELF, read-write data not supported
Solana programs can't have writable static data, and if your program has a bss section, it means there is some writable static data. It could be from a Hasher or randomizer. More info at https://docs.solana.com/developing/on-chain-programs/overview#static-writable-data
If you need a form of mapping, use BTreeMap which is currently supported. Here is a small example Anchor program:
use anchor_lang::prelude::*;
use std::collections::BTreeMap;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
mod basic_0 {
use super::*;
pub fn initialize(_ctx: Context<Initialize>) -> ProgramResult {
let mut map = BTreeMap::new();
map.insert("key1", "value1");
map.insert("key2", "value2");
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize {}
Related
In #solana/web3.js when you create a transaction instruction, you specify pubkeys of your accounts, program id, and just raw bytes of your "data" parameter. In anchor program you declare your module to be a program with corresponding attribute, and now your pub functions become instructions. I could not find in the anchor book, how specifically they serialize their instruction name. How do I specify for my JavaScript frontend which instruction do I want it to execute?
How do I specify for my JavaScript frontend which instruction I want it to execute?
Anchor uses IDL(Interface Description Language) for this purpose. whenever you complete your Solana program you can build it(anchor build). With this command, you have exported idl in root/target/idl folder. You can deploy this file to Solana network and fetch it and make a program in any client like ts(typescript) because of its mapping. You can open up one of the IDL.json files for better understanding. with this file, you can call instructions or use accounts of your Solana program.
Also, you have another file with ts extension inside root/target/types. We use this file inside anchor test for creating a program with that and also for specifying which instruction or account we want to use. Also, this file is useful for creating anchor programs inside clients. Because this file contains "export const IDL.....". So, we can use this file for creating program like this:
import { PROGRAM_ID } from "./constants";//program account public key
import { IDL } from "./your_directory_of_programs";// directory of copy/paste types/your_program.ts file
export function getProgramInstance(connection, wallet) {
if (!wallet.publicKey) return;
const provider = new anchor.AnchorProvider(
connection,
wallet,
anchor.AnchorProvider.defaultOptions()
);
// Read the generated IDL.
const idl = IDL;
// Address of the deployed program.
const programId = PROGRAM_ID;
// Generate the program client from IDL.
const program = new anchor.Program(idl, programId, provider);
return program;
}
and call any instruction like this:
await program.methods
.yourInstruction()
.accounts({
})
.signers()
.rpc();
Read this part of the Solana Cookbook for more details of what's going on when we want to call instruction of program from TS or any other clients.
I have been trying to run the execute_sale ix from the mpl-auction-house package but I get this error in the logs I have got the sellInstruction and buyInstruction working
This is my Code
const executeSellInstructionAccounts:ExecuteSaleInstructionAccounts = {
buyer:buyerwallet.publicKey,
seller:Sellerwallet.publicKey,
tokenAccount:tokenAccountKey,
tokenMint:mint,
metadata:await getMetadata(mint),
treasuryMint:new anchor.web3.PublicKey(AuctionHouse.mint),
auctionHouse:new anchor.web3.PublicKey(AuctionHouse.address),
auctionHouseFeeAccount:new anchor.web3.PublicKey(AuctionHouse.feeAccount),
authority:new anchor.web3.PublicKey(AuctionHouse.authority),
programAsSigner:programAsSigner,
auctionHouseTreasury:new anchor.web3.PublicKey(AuctionHouse.treasuryAccount),
buyerReceiptTokenAccount:buyerATA.address,
sellerPaymentReceiptAccount:Sellerwallet.publicKey,
buyerTradeState:BuyertradeState,
escrowPaymentAccount:escrowPaymentAccount,
freeTradeState:freeTradeState,
sellerTradeState:SellertradeState,
}
const executeSellInstructionArgs:ExecuteSaleInstructionArgs = {
escrowPaymentBump:escrowBump,
freeTradeStateBump:freeTradeBump,
programAsSignerBump:programAsSignerBump,
buyerPrice:buyPriceAdjusted,
tokenSize:tokenSizeAdjusted,
}
const execute_sale_ix = createExecuteSaleInstruction(
executeSellInstructionAccounts,executeSellInstructionArgs
)
const execute_sale_tx = new anchor.web3.Transaction(
{
recentBlockhash: blockhash,
feePayer: Sellerwallet.publicKey,
}
)
execute_sale_tx.add(execute_sale_ix);
const execute_sale_res = await sprovider.sendAndConfirm(execute_sale_tx);
There is currently a discrepancy between the published AuctionHouse SDK and the underlying Rust program.
The console reference implementation is here: https://github.com/metaplex-foundation/metaplex/blob/master/js/packages/cli/src/auction-house-cli.ts
The console reference implementation works because it loads the idl directly from the chain and is therefore up to date. It bypasses the AuctionHouse SDK completely.
However, if you're doing this in the browser, you probably don't want to load the IDL from the chain. You'd need things like a decompression library and that would blow up your package size quite a bit.
To work around this, I've forked metaplex repo here: https://github.com/neftworld/metaplex
The fork above has the following changes:
Including the IDL definition as a typescript src file (correct as at 30 May 2022)
Fetching auctionHouse program from local IDL definition instead getting it from the chain
Hence, you can use this as a base for your web implementation. To make this work on the web, you will need to remove references to keypair - console uses a key pair file - and use the browser wallet to sign the transaction before sending.
I'm trying to retrieve with Rust the unique identifier of the MSV authentication package. For that, i'm trying to use the Windows API function LsaLookupAuthenticationPackage, but it is returning the NTSTATUS constant 0xC00000FE (STATUS_NO_SUCH_PACKAGE), which acording to the official documentation it means "A specified authentication package is unknown".
To call LsaLookupAuthenticationPackage, I'm using the official crate to access the Windows API. Below I detail the activities that I perform before calling LsaLookupAuthenticationPackage:
1.- I run my code as System.
2.- I successfully enable SeTcbPrivilege using the function RtlAdjustPrivilege.
3.- I successfully call LsaRegisterLogonProcess to open a handle to start the interaction with the LSA.
4.- I use this handle to call LsaLookupAuthenticationPackage. Below, I show the code that I'm using to call LsaLookupAuthenticationPackage:
let package:[char;20]= ['M','S','V','1','_','0','_','P','A','C','K','A','G','E','_','N','A','M','E','\0'];
let auth_package: STRING = STRING {Length:19, MaximumLength:19, Buffer:transmute(package.as_ptr())};
let auth_package_ptr: *const STRING = transmute(&auth_package);
let auth_id: *mut u32 = transmute(&u32::default());
let ret = LsaLookupAuthenticationPackage(handle,auth_package_ptr,auth_id);
I also tried to use an &str instead of the char array to store the auth package name, but it didn't work either.
For me it's obvious that the function is working, so the problem seems to be that I'm not passing correctly the auth package name.
I'm trying to test a program on localnet which makes numerous cross-program invocations (CPIs).
Is there an easy way to initialize a localnet cluster with all the accounts copied over from mainnet-beta?
I know there is a clone flag on the solana-test-validator command however it would be impractical to use clone for all the accounts I need copied over.
It is impractical to invoke solana-test-validator from the command line to do this.
The approach I've taken is to use solana account to get the accounts to local files, then use "in code" initialization of the solana test validator to load those accounts and then test.
For the first part, you could rig up a script to invoke:
solana account -o LOCALFILE.json --output json-compact PUBLIC_KEY where it will fetch account associated with PUBLIC_KEY and put in LOCALFILE.json
Then, in rust (just an example using 2 accounts but it could be many more. More than likely you'd want to walk a well known directory to load from and just loop that to build the input Vec:
fn load_stored(tvg: &mut TestValidatorGenesis) -> &mut TestValidatorGenesis {
let mut avec = Vec::<AccountInfo>::new();
for i in 0..2 {
let akp = get_keypair(USER_ACCOUNT_LIST[i]).unwrap();
avec.push(AccountInfo {
address: akp.pubkey(),
filename: USER_STORED_LIST[i],
});
}
tvg.add_accounts_from_json_files(&avec)
}
/// Setup the test validator with predefined properties
pub fn setup_validator() -> Result<(TestValidator, Keypair), Box<dyn error::Error>> {
let vwallet = get_keypair(WALLET_ACCOUNT).unwrap();
std::env::set_var("BPF_OUT_DIR", PROG_PATH);
let mut test_validator = TestValidatorGenesis::default();
test_validator.ledger_path(LEDGER_PATH);
test_validator.add_program(PROG_NAME, PROG_KEY);
load_stored(&mut test_validator);
// solana_logger::setup_with_default("solana=error");
let test_validator =
test_validator.start_with_mint_address(vwallet.pubkey(), SocketAddrSpace::new(true))?;
Ok((test_validator, vwallet))
}
You can launch the validator with -um -c ADDRESS to preload accounts with the content of mainnet-beta. In practice that's often not feasible, as you simply would need to many accounts, but for small programs it does work.
As another alternative, you can try using this fork of the Solana monorepo, which aims to clone the entire state of the ledger from mainnet, and spins up a validator from it: https://github.com/DappioWonderland/solana
Note that I haven't used it and haven't audited it to be sure it doesn't do anything shady, but if it lives up to the promise, it should be exactly what you need!
When working on Parity Substrate runtime development, how can I print out debug message for tracing and inspecting my variables?
Both of the above answers are correct in their own sense/time. Here's a more accurate overview:
runtime_io::print("..."); has been moved. You can now use the same function from sp-runtime::print(). These will be visible in a log target named runtime. So you'd have to do RUST_LOG=runtime=debug. You are still calling into sp_io under the hood though. Also, note that frame_support is re-exporting this for you. Most pallets need frame_support anyhow and this maeks the usage easier.
If you want to compile for wasm and native, and want prints only for native execution, use sp_std::if_std!{} macro.
Finally, you can use frame_support::debug module. This module provides wrappers around the above two to make the usage easier and more rust-like. Similar to a normal logger, you can use debug::native::warn!(...) etc.
A final useful tip is to: when possible, you can just bloat your code with println! and do SKIP_WASM_BUILD=1 cargo run [xxx]. This is helpful when you are developing and want quick debug prints without any of the setup explained above.
You can also use the if_std! macro included with sp-std:
https://github.com/paritytech/substrate/pull/2979
if_std! is a feature gate that should only be run when std feature is enabled.
Example
sp_std::if_std! {
// This code is only being compiled and executed when the `std` feature is enabled.
println!("Hello native world");
}
This is better because you can println variables and stuff rather than simply printing a string.
As a newcomer to Substrate development, the most direct way I found is with runtime_io::print().
Example:
use runtime_io::{ self };
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn deposit_event<T>() = default;
pub fn my_func(origin) -> Result {
runtime_io::print("Hello World");
Ok(());
}
}
}
The message will then appear in the console. Pay quick attention to it as it is constantly scrolling.
For a complete example, refer to the TCR tutorial example in github.
you can use the log crate, add it to your cargo.toml and use it like this:
log::info!("hello {}",substrate);
source : https://docs.substrate.io/test/debug/