在 NEAR 协议上借用 rust 的混乱
Borrowing confusion in rust on the NEAR protocol
我正在 NEAR 平台上开发智能合约,这是一种彩票。我的结构是一个主合约,它持有一个 Vec 彩票。
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct LottoList{
owner_id: AccountId,
lotteries: Vec<NearLotto>,
}
每个彩票由以下结构表示。
#[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
}
init 创建一个空数组,之后我们可以开始添加新彩票。
#[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 cna 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);
}
我遇到的问题是进入抽奖的功能。具体如下。
#[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;
}
最后一行给出了错误。
mismatched types
expected struct `NearLotto`, found `&NearLotto`
我还没有生锈的基础,不知道问题的解决方案。任何想法感激地接受。
我觉得
self.lotteries[lotto_id as usize] = lotto;
应该是
self.lotteries[lotto_id as usize] = *lotto;
您想用乐透参考值更新彩票
您当前的合约设计存在几个问题。
首先是您在内存中使用数据结构。这意味着当您的合约启动时,它必须将整个状态加载到内存中。想为单个乐透做抽奖,但需要支付加载所有乐透的费用。这不会扩展。您应该使用持久性集合,请参阅 https://www.near-sdk.io/contract-structure/collections.
关于你的类型问题。
let mut lotto = &self.lotteries[lotto_id as usize];
这一行创建了一个可变引用,&NearLotto
。
self.lotteries[lotto_id as usize] = lotto;
然后您尝试在它期望 NearLotto
.
时设置引用
由于您正在更新对向量中某个位置的可变引用,因此您无需将其写回,因为您已就地对其进行了变异。因此不需要这一行。
我正在 NEAR 平台上开发智能合约,这是一种彩票。我的结构是一个主合约,它持有一个 Vec 彩票。
#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct LottoList{
owner_id: AccountId,
lotteries: Vec<NearLotto>,
}
每个彩票由以下结构表示。
#[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
}
init 创建一个空数组,之后我们可以开始添加新彩票。
#[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 cna 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);
}
我遇到的问题是进入抽奖的功能。具体如下。
#[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;
}
最后一行给出了错误。
mismatched types
expected struct `NearLotto`, found `&NearLotto`
我还没有生锈的基础,不知道问题的解决方案。任何想法感激地接受。
我觉得
self.lotteries[lotto_id as usize] = lotto;
应该是
self.lotteries[lotto_id as usize] = *lotto;
您想用乐透参考值更新彩票
您当前的合约设计存在几个问题。
首先是您在内存中使用数据结构。这意味着当您的合约启动时,它必须将整个状态加载到内存中。想为单个乐透做抽奖,但需要支付加载所有乐透的费用。这不会扩展。您应该使用持久性集合,请参阅 https://www.near-sdk.io/contract-structure/collections.
关于你的类型问题。
let mut lotto = &self.lotteries[lotto_id as usize];
这一行创建了一个可变引用,&NearLotto
。
self.lotteries[lotto_id as usize] = lotto;
然后您尝试在它期望 NearLotto
.
由于您正在更新对向量中某个位置的可变引用,因此您无需将其写回,因为您已就地对其进行了变异。因此不需要这一行。