#smartcontracts #nearprotocol
#smartcontracts #nearprotocol
Вопрос:
Это не очевидно, когда я должен использовать обещания при разработке SmartConract в NEAR Protocol. И когда это избыточно.
Например, у меня есть некоторая логика, которая завершает некоторые общедоступные методы:
#[private]
fn record_data(amp;mut self, key: amp;Vec<u8>) -> Balance {
let initial_storage = env::storage_usage();
assert!(
!self.used_events.contains(amp;key),
"Proof event cannot be reused. Proof already exist."
);
self.used_events.insert(amp;key);
let current_storage = env::storage_usage();
let attached_deposit = env::attached_deposit();
let required_deposit =
Balance::from(current_storage - initial_storage) * STORAGE_PRICE_PER_BYTE;
attached_deposit - required_deposit
}
И в том же контракте у меня есть функция:
#[payable]
fn deposit(amp;mut self, amount: Balance) {
// ...some logic
self.record_data(amp;data)
}
Итак, с помощью Promises я могу позвонить record_data
in async
way.
Но неясно, когда я должен использовать этот способ (вызов обещания). И когда я могу позвонить очень простым способом:
self.record_data(amp;data)
Это очевидный факт, что вызов кросс-контракта всегда выполняется через Promises.
Но тот же контракт вызывает определенные функции внутреннего контракта — неясно, когда мы должны использовать обещания.
Поэтому мне нужно хорошее разъяснение, когда я должен использовать Promises и когда оно будет избыточным.
Ответ №1:
Вы можете выполнить вызов record_data
async, но за это приходится платить. Вы платите базовую плату за совершение другой транзакции стоимость газа для запуска кода газ для взаимодействия с вызовами хоста (например env::*
). Таким образом, причина асинхронности внутренних вызовов заключается в том, чтобы воспользоваться преимуществами параллелизма: см. Сортировку слиянием rust-sdk
pub fn merge_sort(amp;self, arr: Vec<u8>) -> PromiseOrValue<Vec<u8>> {
if arr.len() <= 1 {
return PromiseOrValue::Value(arr);
}
let pivot = arr.len() / 2;
let arr0 = arr[..pivot].to_vec();
let arr1 = arr[pivot..].to_vec();
let prepaid_gas = env::prepaid_gas();
let account_id = env::current_account_id();
ext::merge_sort(arr0, amp;account_id, 0, prepaid_gas / 4)
.and(ext::merge_sort(arr1, amp;account_id, 0, prepaid_gas / 4))
.then(ext::merge(amp;account_id, 0, prepaid_gas / 4))
.into()
}
Комментарии:
1. 1. Итак, преимущества обещаний только для подхода параллелизма? 2. Объяснил немного больше, как это будет выполняться. Потому что он создаст квитанцию, чтобы она могла выполняться на любом другом хосте (узле) в блокчейне (это означает, что это не тот же хост выполнения)? 3. Что означает конкретная формула: prepaid_gas / 4, как я решаю разделить на число 4?
2. 1. Это также для взаимодействия между контрактами; у вас может быть
then
обещание, которое использует обратный вызов для внутреннего метода, который затем позволяет вам проверить успешность вызова.3. 2. В этом примере результатом начального вызова контракта будет значение, возвращаемое последним вызовом в цепочке. Квитанции отслеживают это, и это обрабатывается средой выполнения. 3. Необходимо обеспечить достаточное количество газа для покрытия расходов.
4
В этой формуле исходят из четырех транзакций, текущей транзакции и трех обещаний. Однако первоначальная транзакция, вероятно, переплачивается. Существует такжеenv::used_gas