【问题标题】:Borrowing confusion in rust on the NEAR protocol借用 NEAR 协议中的 rust 混淆
【发布时间】:2022-01-08 23:52:48
【问题描述】:

我正在 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` 

我还没有生锈的基础,还不知道问题的解决方案。任何想法都欣然接受。

【问题讨论】:

  • 你的 75% 和 25% 是 1) 错误 2) 真的不是你处理金钱的方式。

标签: rust nearprotocol near


【解决方案1】:

您当前的合同设计存在几个问题。

首先是你在内存中使用的数据结构。这意味着当你的合约启动时,它必须将整个状态加载到内存中。想为一个乐透抽奖,但要付钱加载所有乐透。这不会扩展。您应该使用持久性集合,请参阅https://www.near-sdk.io/contract-structure/collections

至于你的类型问题。

let mut lotto = &self.lotteries[lotto_id as usize];

这一行创建了一个可变引用,&amp;NearLotto

self.lotteries[lotto_id as usize] = lotto;

然后你尝试在它期望NearLotto时设置一个引用。

由于您正在更新对向量中某个位置的可变引用,因此您无需将其写回,因为您已对其进行了变异。因此不需要这条线。

【讨论】:

  • 感谢您重新使用 UnorderedMap 帮助解决了这个问题。
【解决方案2】:

我认为

self.lotteries[lotto_id as usize] = lotto;

应该是

self.lotteries[lotto_id as usize] = *lotto;

您想使用乐透参考持有的值更新彩票

【讨论】:

    猜你喜欢
    • 2020-09-26
    • 1970-01-01
    • 2011-07-31
    • 2021-01-12
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多