I have the following code, using the anchor framework (version 0.23.0):
use anchor_lang::prelude::*;
#[account]
#[derive(Default, Debug)]
pub struct Raffle {
// ... fields
}
#[account(zero_copy)]
pub struct Participant {
// ... fields
}
#[derive(Accounts)]
pub struct BuyTicket<'info>{
#[account(has_one = participants)]
pub raffle: Account<'info, Raffle>,
#[account(mut)]
pub participants: AccountLoader<'info, Participant>,
// ... others fields
}
Then, when I run anchor build, I get the following error:
BPF SDK: ~/.local/share/solana/install/releases/1.9.13/solana-release/bin/sdk/bpf
cargo-build-bpf child: rustup toolchain list -v
cargo-build-bpf child: cargo +bpf build --target bpfel-unknown-unknown --release
Compiling project v0.1.0 (~/programs/project)
error[E0609]: no field `participants` on type `anchor_lang::prelude::Account<'_, structs::Raffle>`
--> programs/project/src/structs.rs:136:25
|
136 | #[account(has_one = participants)]
| ^^^^^^^^^^^^ unknown field
For more information about this error, try `rustc --explain E0609`.
error: could not compile `nft2raffle` due to previous error
Now, rustc --explain E0609 defines the error of accessing a nonexistent field within a struct; but the participant field inside the structure does exist.
How can fix the error?
has_one checks the target_account field participant on the account raffle matches the key of the target_account participant field in the Accounts struct.
You have to put participants: Pubkey in struct Raffle
Related
I am working with a course on coatings with the Solana Spotify Project and studying on YouTube. Please tell me the code produces such errors, but everything is written correctly and clearly. I don't know where I forgot.
use anchor_lang::prelude::*;
use anchor_lang::solana_program::entrypoint::ProgramResult;
use anchor_spl::token::{self,Token};
use std::mem::size_of;
// This is your program's public key and it will update
// automatically when you build the project.
declare_id!("11111111111111111111111111111111");
#[program]
mod spotify_clone {
use super::*;
pub fn accept_payment(ctx: Context<PayerContext>, data: u64) -> ProgramResult {
let payer_wallet = &mut ctx.accounts.payer_wallet;
payer_wallet.wallet = ctx.accounts.authority.key();
let ix = anchor_lang::solana_program::system_instruction::transfer(
&ctx.accounts.authority.key(),
&ctx.accounts.receiver.key(),
100000000,
);
anchor_lang::solana_program::program::invoke(
&ix,
&[
ctx.accounts.authority.to_account_info(),
ctx.accounts.receiver.to_account_info(),
],
)
}
}
#[derive(Accounts)]
pub struct PayerContext<'info> {
#[account(
init,
seeds = [b"payer".as_ref(), authority.key().as_ref()],
bump,
payer = authority,
space = size_of::<PayerAccount>() + 8,
)]
pub payer_wallet: Account<'info, PayerAccount>,
//Specific param to object
#[account(mut)]
pub receiver: AccountInfo<'info>,
//Specific param to object
//Authority[this is signer who paid transaction fee]
#[account(mut)]
pub authority: Signer<'info>,
pub system_programm: UncheckedAccount <'info>,
//Token Programm
#[account(constraint = token_program.key == &token::ID)]
pub token_program: Program<'info, Token>,
//Clock to the Save Your Time
pub clock: Sysvar<'info,Clock>,
}
#[account]
pub struct PayerAccount{
pub wallet: Pubkey,
}
Error appears here. The main problem in the code i think is here:
pub payer_wallet: Account<'info, PayerAccount>,
Code of error E0277:
error[E0277]: the trait bound `PayerContext<'_>: anchor_lang::Accounts<'_>` is not satisfied
--> /src/lib.rs:10:1
|
10 | #[program]
| ^^^^^^^^^^ the trait `anchor_lang::Accounts<'_>` is not implemented for `PayerContext<'_>`
|
note: required by `anchor_lang::context::Context::<'a, 'b, 'c, 'info, T>::new`
Second error E0432:
error[E0432]: unresolved import `crate`
--> /src/lib.rs:10:1
|
10 | #[program]
| ^^^^^^^^^^ could not find `__client_accounts_payer_context` in the crate root
|
= note: this error originates in the attribute macro `program` (in Nightly builds, run with -Z macro-backtrace for more info)
Third error E0599:
error[E0599]: no method named `exit` found for struct `PayerContext` in the current scope
--> /src/lib.rs:10:1
|
10 | #[program]
| ^^^^^^^^^^ method not found in `PayerContext<'_>`
...
34 | pub struct PayerContext<'info> {
| ------------------------------ method `exit` not found for this
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `exit`, perhaps you need to implement it:
candidate #1: `anchor_lang::AccountsExit`
= note: this error originates in the attribute macro `program` (in Nightly builds, run with -Z macro-backtrace for more info)
Try adding
#[derive(Accounts)] to PayerContext
Like this
#[derive(Accounts)]
pub struct PayerContext<'info> {}
I am using rust diesel diesel = { version = "1.4.8", features = ["postgres","64-column-tables","chrono","serde_json"] } to do the group by query follow the docs like this:
fpub fn get_bill_book_account_sum(){
use crate::diesel::GroupByDsl;
use diesel::dsl::max;
use crate::model::diesel::dict::dict_schema::test as bill_record_table;
let source_query = bill_record_table::table
.group_by(bill_record_table::id)
.select((max(bill_record_table::tags),bill_record_table::id))
.filter(bill_record_table::dsl::tags.eq(9));
}
then compile this code, shows error like this:
error[E0277]: the trait bound `aggregate_ordering::max::max<BigInt, columns::tags>: NonAggregate` is not satisfied
--> src/main.rs:19:17
|
19 | .select((max(bill_record_table::tags),bill_record_table::id))
| ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonAggregate` is not implemented for `aggregate_ordering::max::max<BigInt, columns::tags>`
| |
| required by a bound introduced by this call
|
= note: required because of the requirements on the impl of `diesel::Expression` for `(aggregate_ordering::max::max<BigInt, columns::tags>, columns::id)`
note: required by a bound in `diesel::QueryDsl::select`
--> /Users/xiaoqiangjiang/.cargo/registry/src/mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd/diesel-1.4.8/src/query_dsl/mod.rs:291:20
|
291 | Selection: Expression,
| ^^^^^^^^^^ required by this bound in `diesel::QueryDsl::select`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `rust-learn` due to previous error
where am I doing wrong? what should I do to fixed this problem? this is the schema define(I have removed all the columns just using 2 columns to make a minimal reproduce example):
table! {
test (id) {
id -> Int8,
tags -> Int8,
}
}
and this is the model define:
// Generated by diesel_ext
#![allow(unused)]
#![allow(clippy::all)]
use std::io::Write;
use diesel::deserialize::FromSql;
use diesel::pg::Pg;
use diesel::serialize::{Output, ToSql};
use diesel::sql_types::Jsonb;
use rocket::serde::Serialize;
use serde::Deserialize;
use crate::model::diesel::dict::dict_schema::*;
#[derive(Queryable,Debug,Serialize,Deserialize,Default)]
pub struct Test {
pub id: i64,
pub tags: i64,
}
this is the minimal main.rs entrypoint:
#[macro_use]
extern crate diesel;
mod model;
use diesel::{ ExpressionMethods, QueryDsl};
fn main() {
get_bill_book_account_sum();
}
pub fn get_bill_book_account_sum(){
use crate::diesel::GroupByDsl;
use diesel::dsl::max;
use crate::model::diesel::dict::dict_schema::test as bill_record_table;
let source_query = bill_record_table::table
.group_by(bill_record_table::id)
.select((max(bill_record_table::tags),bill_record_table::id))
.filter(bill_record_table::dsl::tags.eq(9));
}
change the aggregate query like this fixed this problem:
pub fn get_bill_book_account_sum(request: &BillAccountRequest) -> Result<Vec<(i64, i32)>, diesel::result::Error>{
use crate::diesel::GroupByDsl;
use crate::model::diesel::fortune::fortune_schema::bill_record as bill_record_table;
let source_query = bill_record_table::table
.group_by(bill_record_table::account_id)
.select((diesel::dsl::sql::<diesel::sql_types::BigInt>("SUM(CAST(amount AS Integer))"),bill_record_table::account_id))
.filter(bill_record_table::dsl::bill_book_id.eq(request.bill_book_id));
let result = source_query.load::<(i64,i32)>(&get_connection());
return result;
}
the solution come from this issue. This is the answer come from the maintainer that shows diesel 1.x did not support group by official.
I'm working on a pallet and after switching to the newest node template it stopped building. Here is declaration
#[derive(Encode, Decode, Clone)]
pub struct VendorData<T :Config>
{
pub vendor : VendorId,
pub owner_account_id : T::AccountId,
}
impl<T:Config> Default for VendorData<T> {
fn default() -> Self {
Self {
vendor : Default::default(),
owner_account_id : Default::default(),
}
}
}
#[pallet::storage]
pub(super) type Vendors<T: Config> = StorageMap<_, Blake2_128Concat, VendorId, VendorData<T>, ValueQuery>;
The cargo build error:
error[E0277]: the trait bound `VendorData<T>: TypeInfo` is not satisfied
...
#[pallet::storage]
^^^^^^^ the trait `TypeInfo` is not implemented for `VendorData<T>`
I've tried declaring struct in a different ways, for example by adding TypeInfo:
#[derive(Encode, Decode, Default, Eq, PartialEq, TypeInfo)]
but every time another errors arise, like this:
error: cannot find macro `format` in this scope
--> /home/psu/.cargo/git/checkouts/substrate-7e08433d4c370a21/352c46a/primitives/consensus/aura/src/lib.rs:50:3
|
50 | app_crypto!(ed25519, AURA);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider importing this macro:
scale_info::prelude::format
= note: this error originates in the macro `$crate::app_crypto_public_common_if_std` (in Nightly builds, run with -Z macro-backtrace for more info)
There is another storage item which does not cause errors
pub type Cid = Vec<u8>;
#[pallet::storage]
pub(super) type VendorModels<T: Config> = StorageMap<_, Blake2_128Concat, VendorId, Vec<Cid>, ValueQuery>;
So it seems it's only about storing VendorData struct. Please assist, after hours of experiments and googling I'm lost
UPDATE: after adding TypeInfo to all storage structs declaration the pallet is compiled but a lot of errors like below arised:
error: cannot find macro `format` in this scope
error: cannot find macro `vec` in this scope
You will need to either make sure that all your generic types implement TypeInfo or skip the types explicitly.
Based on this example code in Substrate you could write:
#[derive(Encode, Decode, Clone, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct VendorData<T :Config>
{
pub vendor : VendorId,
pub owner_account_id : T::AccountId,
}
Or alternatively the following should work:
#[derive(Encode, Decode, Clone, TypeInfo)]
pub struct VendorData<AccountId>
{
pub vendor : VendorId,
pub owner_account_id : AccountId,
}
I currently trying to implement abstract function which will update a few meta fields for any table in the database, but getting problems with Identifiable.
I have a database where every table has meta-fields:
....
pub updu: Option<Uuid>, // ID of a user who changed it
pub updt: Option<NaiveDateTime>, //updated with current date/time on every change
pub ver: Option<i32>, //Version increases on every change
.....
I want to implement a function which would make update for every entity. Currently I have this implementation:
pub fn update<Model>(
conn: &PgConnection,
old_model: Model,
mut updated_model: Model,
user_id: Uuid,
) -> Result<Model, diesel::result::Error>
where
Model: MetaFields + AsChangeset<Target = <Model as HasTable>::Table> + IntoUpdateTarget,
Update<Model, Model>: LoadQuery<PgConnection, Model>
{
updated_model.update_fields(user_id);
Ok(
diesel::update(old_model)
.set(updated_model)
.get_result(conn).unwrap()
)
When I am trying to call it it shows this error:
error[E0277]: the trait bound `Marking: Identifiable` is not satisfied
--> src/service/marking_service.rs:116:24
|
116 | web::block(move || common::dao::update(&conn2, real_marking1[0].clone(), marking2_to_update, jwt_token.user_id))
| ^^^^^^^^^^^^^^^^^^^ the trait `Identifiable` is not implemented for `Marking`
|
= help: the following implementations were found:
<&'ident Marking as Identifiable>
= note: required because of the requirements on the impl of `IntoUpdateTarget` for `Marking`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `testapi` due to previous error
An entity which I am trying to update in this example is:
use chrono::{NaiveDateTime, Utc};
use common::model::MetaFields;
use common::utils::constants::DEL_MARK_AVAILABLE;
use serde::{Deserialize, Serialize};
use serde_json;
use uuid::Uuid;
use crate::schema::marking;
#[derive(
Clone,
Serialize,
Deserialize,
Debug,
Queryable,
Insertable,
AsChangeset,
Identifiable,
QueryableByName,
Default,
)]
#[primary_key(uuid)]
#[table_name = "marking"]
pub struct Marking {
pub uuid: Uuid,
pub updt: Option<NaiveDateTime>,
pub ver: Option<i32>,
pub updu: Option<Uuid>,
pub comment: Option<String>,
pub status: Option<String>,
}
impl MetaFields for Marking {
fn update_fields(&mut self, user_id: Uuid) {
self.updu = Option::from(user_id);
self.ver = Option::from(self.ver.unwrap() + 1);
self.updt = Option::from(Utc::now().naive_local());
}
}
As you can see Identifiable is defined for this entity, but for some reason update cannot see it. Could someone suggest what I am missing here?
Update, schema:
table! {
marking (uuid) {
uuid -> Uuid,
updt -> Nullable<Timestamp>,
ver -> Nullable<Int4>,
updu -> Nullable<Uuid>,
comment -> Nullable<Varchar>,
status -> Nullable<Varchar>,
}
}
diesel = { version = "1.4.6", features = ["postgres", "uuid", "chrono", "uuidv07", "serde_json"] }
r2d2 = "0.8"
r2d2-diesel = "1.0.0"
diesel_json = "0.1.0"
Your code is almost correct. The error message already mentions the issue:
#[derive(Identifiable)] does generate basically the following impl: impl<'a> Identifiable for &'a struct {}, which means that trait is only implemented for a reference to self. Depending on your other trait setup you can try the following things:
Pass a reference as old_model common::dao::update
Change the definition of common::dao::update to take a reference as second argument. Then you can separate the trait bounds for Model so that you bound IntoUpdateTarget on &Model instead.
(It's hard to guess which one will be the better solution as your question is missing a lot of important context. Please try to provide a complete minimal example in the future.)
I'm using a type from the web3 crate, web3::contract::Contract<web3::transports::Http>. The compiler is complaining with E0277:
$ cargo run
Compiling proj v0.1.0 (/home/user/proj)
error[E0277]: the trait bound `web3::contract::Contract<web3::transports::Http>: Default` is not satisfied
--> src/book.rs:38:5
|
38 | / #[serde(skip)]
39 | | abi: web3::contract::Contract<OMETransport>,
| |_______________________________________________^ the trait `Default` is not implemented for `web3::contract::Contract<web3::transports::Http>`
|
= note: required by `std::default::Default::default`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `proj`
To learn more, run the command again with --verbose.
How can this error originate from std::default::Default::default?
The definition for the relevant type (i.e., the struct containing the web3 type) is:
/// Represents an order book for a particular market
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Book {
market: Address, /* the address of the market */
bids: BTreeMap<U256, VecDeque<Order>>, /* buy-side */
asks: BTreeMap<U256, VecDeque<Order>>, /* sell-side */
#[serde(serialize_with = "from_hex_se", deserialize_with = "from_hex_de")]
ltp: U256, /* last traded price */
depth: (usize, usize), /* depth */
crossed: bool, /* is book crossed? */
#[serde(serialize_with = "from_hex_se", deserialize_with = "from_hex_de")]
spread: U256, /* bid-ask spread */
#[serde(skip)]
abi: web3::contract::Contract<web3::transports:Http>,
}
the serde documentation for #[serde(skip)] says:
When deserializing, Serde will use Default::default() or the function given by default = "..." to get a default value for this field.