Confusión de préstamos en Rust en el protocolo NEAR.
Estoy desarrollando un contrato inteligente en la plataforma NEAR que es una lotería. La estructura que tengo es un contrato principal que tiene un Vec de loterías.
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct LottoList {
owner_id: AccountId,
lotteries: Vec<nearlotto>,
}
Cada lotería está representada por la siguiente structura.
#[derive(BorshDeserialize, BorshSerialize)]
pub struct NearLotto {
lotto_id: u32,
owner_id: AccountId,
entries: Vector<accountid>, //UnorderedMap<u64, accountid="">,
entry_fee: Balance,
prize_pool: Balance,
climate_pool: Balance,
winner: AccountId,
closed: bool,
rand: u128
}
El init crea una matriz vacía y después de eso podemos comenzar a agregar nuevas loterías.
#[init]
pub fn new(owner_id: AccountId) -> Self {
assert!(env::is_valid_account_id(owner_id.as_bytes()), "Invalid owner account");
assert!(!env::state_exists(), "Already initialized");
Self {
owner_id,
lotteries: Vec::new()
}
}
pub fn add_lotto(&mut self, owner_id: AccountId, entry_fee:u128, start_pool:u128){
assert!(self.owner_id == env::signer_account_id(), "Only account owner can make more lottos");
let lotto = NearLotto {
lotto_id: self.lotteries.len() as u32,
owner_id,
entries: Vector::new(b'e'), //UnorderedMap::new(b"entries".to_vec()),
entry_fee: entry_fee,
prize_pool: start_pool,
climate_pool:0,
winner: "".to_string(),
closed: false,
rand: 78
};
self.lotteries.push(lotto);
}
El problema que tengo es con la función para ingresar al sorteo. Que es como sigue.
#[payable]
pub fn enter_draw(&mut self, lotto_id:u32){
// charge some storage fee
let mut lotto = &self.lotteries[lotto_id as usize];
let attached = env::attached_deposit();
assert!(attached >= lotto.entry_fee, "Entry fee not enough");
assert!(lotto.entries.len() < MAX_ENTRIES, "Entries are full");
env::log(format!("money matches, add entry").as_bytes());
lotto.prize_pool = lotto.prize_pool + (env::attached_deposit()/4)*3; // 75% of entries fees goes into prize pool
lotto.climate_pool = lotto.climate_pool + (env::attached_deposit()/4)*3; //25% of entries go to climate change
lotto.entries.push(&env::signer_account_id()); //self.entries.insert(&k, &near_sdk::env::signer_account_id());
env::log(format!("{} Entering the lottery", env::signer_account_id()).as_bytes());
self.lotteries[lotto_id as usize] = lotto;
}
La última línea me da el error.
mismatched types
expected struct NearLotto, found &NearLotto
No tengo la base en Rust todavía para saber la solución al problema. ¿Alguna idea será agradecida?</u64,>
davy.ai
El problema parece ser porque la variable
lotto
en la funciónenter_draw
se declara como una referencia mutable (&mut
) a una estructuraNearLotto
. Sin embargo, cuando se recupera el valor de esta variable del vectorself.lotteries
, se devuelve como una referencia (&
) a la estructuraNearLotto
.Para resolver este problema, simplemente podemos cambiar el tipo de
lotto
aNearLotto
en lugar de&mut NearLotto
. Esto hará una copia de la estructuraNearLotto
del vector, que luego se puede modificar y asignar de vuelta al vector.Aquí está el código actualizado para la función
enter_draw
:En este código actualizado, primero creamos una copia de la estructura
NearLotto
usandoclone()
, y modificamos esta copia. Finalmente, asignamos la copia modificada de vuelta al vectorself.lotteries
.