Строковый атрибут, установленный в методе init, всегда возвращает пустую строку - PullRequest
3 голосов
/ 01 ноября 2019

У меня есть следующая структура с impl:

#[near_bindgen]
#[derive(Default, Serialize, Deserialize, BorshDeserialize, BorshSerialize, Debug)]
pub struct MyStruct {
    owner: String
}

#[near_bindgen(init => new)]
impl MyStruct {
    fn new() -> Self {
        Self {
             owner: "bob".to_string()
        }
    }

    fn get_owner(&self) -> String {
         return self.owner;
    }
}

Затем я развертываю контракт, используя near deploy my_contract --masterAccount myAccount

Если я вызываю get_owner с использованием Near-Shell: near call my_contract get_owner --accountId=myAccount Он всегда возвращает"" вместо ожидаемого "bob".

Похоже, новый метод может не вызываться при развертывании.

Ответы [ 2 ]

4 голосов
/ 01 ноября 2019

Инициализатор не вызывается автоматически при развертывании. deploy просто развертывает код и ничего не вызывает в контракте. Вероятно, мы должны добавить новый метод для оболочки, который делает deploy_and_call. Но сейчас просто вызовите new вручную.

Причина, по которой мы не инициализируем автоматически, заключается в том, что initializer может принимать дополнительные аргументы. Вы можете передать владельца методу new. Вот пример того, как использовать инициализатор с пользовательскими аргументами, а также как убедиться, что контракт не может быть вызван без инициализации:

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize)]
pub struct FunToken {
    /// AccountID -> Account details.
    pub accounts: Map<AccountId, Account>,

    /// Total supply of the all token.
    pub total_supply: Balance,
}

impl Default for FunToken {
    fn default() -> Self {
        env::panic(b"Not initialized");
        unreachable!();
    }
}

#[near_bindgen(init => new)]
impl FunToken {
    pub fn new(owner_id: AccountId, total_supply: Balance) -> Self {
        let mut ft = Self { accounts: Map::new(b"a".to_vec()), total_supply };
        let mut account = ft.get_account(&owner_id);
        account.balance = total_supply;
        ft.accounts.insert(&owner_id, &account);
        ft
    }
}

Отсюда: https://github.com/nearprotocol/near-bindgen/blob/master/examples/fun-token/src/lib.rs#L52-L77

В основном это паника во время вызова по умолчанию, поэтому не инициализированный контракт не может быть вызван.

2 голосов
/ 01 ноября 2019

Функции инициализатора обычно используются, когда вам нужно параметризовать инициализацию контракта. Если параметров нет, просто добавьте Default trait:

impl Default for MyStruct {
  fn default() -> Self {
    Self {
      owner: "bob".to_string()
    }
}}
...