Running into an issue while working on a NEAR contract. Facing multiple errors, including traits not being implemented for UnorderedSet<AccountId>
and mismatched types.
error[E0277]: the trait bound `UnorderedSet<AccountId>: Default` is not satisfied
--> src/lib.rs:38:55
|
38 | #[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone)]
| ^^^^^^^^^^^ the trait `Default` is not implemented for `UnorderedSet<AccountId>`
|
= note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `UnorderedSet<AccountId>: Clone` is not satisfied
--> src/lib.rs:48:5
|
38 | #[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone)]
| ----- in this derive macro expansion
...
48 | voters: UnorderedSet<AccountId>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `UnorderedSet<AccountId>`
|
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0308]: mismatched types
--> src/lib.rs:85:25
|
85 | self.tokens.get(account_id).map(|token| token.metadata.clone())
| --- ^^^^^^^^^^ expected `&_`, found `AccountId`
| |
| arguments to this method are incorrect
|
= note: expected reference `&_`
found struct `AccountId`
note: method defined here
--> /home/akash/.cargo/registry/src/index.crates.io-6f17d22bba15001f/near-sdk-5.5.0/src/store/lookup_map/mod.rs:242:12
|
242 | pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
| ^^^
help: consider borrowing here
|
85 | self.tokens.get(&account_id).map(|token| token.metadata.clone())
| +
error[E0308]: mismatched types
--> src/lib.rs:144:44
|
144 | self.proposals.insert(proposal_id, &proposal);
| ------ ^^^^^^^^^ expected `Proposal`, found `&&Proposal`
| |
| arguments to this method are incorrect
|
help: the return type of this call is `&&Proposal` due to the type of the argument passed
--> src/lib.rs:144:9
|
144 | self.proposals.insert(proposal_id, &proposal);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------^
| |
| this argument influences the return type of `insert`
note: method defined here
--> /home/akash/.cargo/registry/src/index.crates.io-6f17d22bba15001f/near-sdk-5.5.0/src/store/unordered_map/mod.rs:487:12
|
487 | pub fn insert(&mut self, k: K, value: V) -> Option<V>
| ^^^^^^
error[E0308]: mismatched types
--> src/lib.rs:148:9
|
147 | pub fn get_proposal(&self, proposal_id: u64) -> Option<Proposal> {
| ---------------- expected `std::option::Option<Proposal>` because of return type
148 | self.proposals.get(&proposal_id)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<Proposal>`, found `Option<&Proposal>`
|
= note: expected enum `std::option::Option<Proposal>`
found enum `std::option::Option<&Proposal>`
help: use `std::option::Option::cloned` to clone the value inside the `std::option::Option`
|
148 | self.proposals.get(&proposal_id).cloned()
| +++++++++
error[E0277]: a value of type `Vec<Proposal>` cannot be built from an iterator over elements of type `&Proposal`
--> src/lib.rs:152:33
|
152 | self.proposals.values().collect()
| ^^^^^^^ value of type `Vec<Proposal>` cannot be built from `std::iter::Iterator<Item=&Proposal>`
|
= help: the trait `FromIterator<&Proposal>` is not implemented for `Vec<Proposal>`
= help: the trait `FromIterator<Proposal>` is implemented for `Vec<Proposal>`
= help: for that trait implementation, expected `Proposal`, found `&Proposal`
note: the method call chain might not have had the expected associated types
--> src/lib.rs:152:24
|
152 | self.proposals.values().collect()
| -------------- ^^^^^^^^ `Iterator::Item` is `&Proposal` here
| |
| this expression has type `UnorderedMap<u64, Proposal>`
note: required by a bound in `collect`
--> /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/iter/traits/iterator.rs:2001:5
error[E0382]: use of moved value: `account_id`
--> src/lib.rs:81:34
|
72 | pub fn mint(&mut self, account_id: AccountId, metadata: TokenMetadata) {
| ---------- move occurs because `account_id` has type `AccountId`, which does not implement the `Copy` trait
...
80 | self.tokens.insert(account_id, token);
| ---------- value moved here
81 | self.token_owners.insert(account_id);
| ^^^^^^^^^^ value used here after move
|
help: consider cloning the value if the performance cost is acceptable
|
80 | self.tokens.insert(account_id.clone(), token);
| ++++++++
warning: variable does not need to be mutable
--> src/lib.rs:103:13
|
103 | let mut proposal = Proposal {
| ----^^^^^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default
contarct code →
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::store::{LookupMap, UnorderedMap, UnorderedSet};
use near_sdk::serde::{Deserialize, Serialize};
use near_sdk::{env, near_bindgen, require, AccountId, BorshStorageKey, PanicOnDefault, NearToken};
#[derive(BorshStorageKey, BorshSerialize)]
enum StorageKey {
Tokens,
TokenOwners,
Proposals,
ProposalVoters { proposal_id: u64 },
}
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct Contract {
tokens: LookupMap<AccountId, Token>,
token_owners: UnorderedSet<AccountId>,
proposals: UnorderedMap<u64, Proposal>,
next_proposal_id: u64,
}
#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone)]
#[serde(crate = "near_sdk::serde")]
pub struct Token {
owner_id: AccountId,
metadata: TokenMetadata,
}
#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone)]
#[serde(crate = "near_sdk::serde")]
pub struct TokenMetadata {
title: Option<String>,
description: Option<String>,
governance_role: String,
}
#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, Clone)]
#[serde(crate = "near_sdk::serde")]
pub struct Proposal {
id: u64,
title: String,
description: String,
proposer: AccountId,
votes_for: NearToken,
votes_against: NearToken,
#[serde(skip)]
voters: UnorderedSet<AccountId>,
status: ProposalStatus,
}
#[derive(BorshDeserialize, BorshSerialize, Serialize, Deserialize, PartialEq, Clone)]
#[serde(crate = "near_sdk::serde")]
pub enum ProposalStatus {
Active,
Passed,
Rejected,
}
#[near_bindgen]
impl Contract {
#[init]
pub fn new() -> Self {
Self {
tokens: LookupMap::new(StorageKey::Tokens),
token_owners: UnorderedSet::new(StorageKey::TokenOwners),
proposals: UnorderedMap::new(StorageKey::Proposals),
next_proposal_id: 0,
}
}
pub fn mint(&mut self, account_id: AccountId, metadata: TokenMetadata) {
require!(!self.tokens.contains_key(&account_id), "Token already exists for this account");
let token = Token {
owner_id: account_id.clone(),
metadata,
};
self.tokens.insert(account_id, token);
self.token_owners.insert(account_id);
}
pub fn token_metadata(&self, account_id: AccountId) -> Option<TokenMetadata> {
self.tokens.get(account_id).map(|token| token.metadata.clone())
}
pub fn is_token_owner(&self, account_id: AccountId) -> bool {
self.token_owners.contains(&account_id)
}
pub fn governance_role(&self, account_id: AccountId) -> Option<String> {
self.tokens.get(&account_id).map(|token| token.metadata.governance_role.clone())
}
pub fn create_proposal(&mut self, title: String, description: String) -> u64 {
let account_id = env::predecessor_account_id();
require!(self.is_token_owner(account_id.clone()), "Only holders can create proposals");
let proposal_id = self.next_proposal_id;
self.next_proposal_id += 1;
let mut proposal = Proposal {
id: proposal_id,
title,
description,
proposer: account_id,
votes_for: NearToken::from_near(0),
votes_against: NearToken::from_near(0),
voters: UnorderedSet::new(StorageKey::ProposalVoters { proposal_id }),
status: ProposalStatus::Active,
};
self.proposals.insert(proposal_id, proposal);
proposal_id
}
pub fn vote(&mut self, proposal_id: u64, vote: bool) {
let account_id = env::predecessor_account_id();
require!(self.is_token_owner(account_id.clone()), "Only holders can vote");
let mut proposal = self.proposals.get(&proposal_id).expect("Proposal not found");
require!(proposal.status == ProposalStatus::Active, "Proposal is not active");
require!(!proposal.voters.contains(&account_id), "Account has already voted");
if vote {
proposal.votes_for = proposal.votes_for.saturating_add(NearToken::from_near(1));
} else {
proposal.votes_against = proposal.votes_against.saturating_add(NearToken::from_near(1));
}
proposal.voters.insert(account_id);
let total_votes = proposal.votes_for.as_near() + proposal.votes_against.as_near();
if total_votes >= (self.token_owners.len() / 2 + 1) as u128 {
if proposal.votes_for > proposal.votes_against {
proposal.status = ProposalStatus::Passed;
} else {
proposal.status = ProposalStatus::Rejected;
}
}
self.proposals.insert(proposal_id, &proposal);
}
pub fn get_proposal(&self, proposal_id: u64) -> Option<Proposal> {
self.proposals.get(&proposal_id)
}
pub fn get_all_proposals(&self) -> Vec<Proposal> {
self.proposals.values().collect()
}
pub fn transfer(&mut self, _from: AccountId, _to: AccountId) {
//the transfer function
}
}
Any tips on resolving these errors?