NEAR 智能合约承诺使用
NEAR SmartContract promises usage
在 NEAR 协议中开发 SmartConract 时应该使用 Promises 并不是一件显而易见的事情。当它是多余的。
例如,我有一些逻辑可以完成某些 public 方法:
#[private]
fn record_data(&mut self, key: &Vec<u8>) -> Balance {
let initial_storage = env::storage_usage();
assert!(
!self.used_events.contains(&key),
"Proof event cannot be reused. Proof already exist."
);
self.used_events.insert(&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(&mut self, amount: Balance) {
// ...some logic
self.record_data(&data)
}
所以有了 Promises,我可以用 async
的方式调用 record_data
。
但是不清楚我什么时候必须使用那种方式(Promise 调用)。当我可以以非常简单的方式调用时:
self.record_data(&data)
这是一个显而易见的事实,跨合约调用总是通过 Promises。
但是同一个合约调用了特定的内部合约函数——我们不清楚什么时候应该使用 Promises。
所以我需要很好地说明什么时候必须使用 Promises 以及什么时候它会多余。
您可以异步调用 record_data
,但需要付出一定的代价。您要支付基本费用以进行另一笔交易 + 运行 代码的 gas 成本 + 与主机调用交互的 gas(例如 env::*
)。所以使内部调用异步的原因是为了利用并发性:参见 rust-sdk's merge sort
pub fn merge_sort(&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, &account_id, 0, prepaid_gas / 4)
.and(ext::merge_sort(arr1, &account_id, 0, prepaid_gas / 4))
.then(ext::merge(&account_id, 0, prepaid_gas / 4))
.into()
}
在 NEAR 协议中开发 SmartConract 时应该使用 Promises 并不是一件显而易见的事情。当它是多余的。
例如,我有一些逻辑可以完成某些 public 方法:
#[private]
fn record_data(&mut self, key: &Vec<u8>) -> Balance {
let initial_storage = env::storage_usage();
assert!(
!self.used_events.contains(&key),
"Proof event cannot be reused. Proof already exist."
);
self.used_events.insert(&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(&mut self, amount: Balance) {
// ...some logic
self.record_data(&data)
}
所以有了 Promises,我可以用 async
的方式调用 record_data
。
但是不清楚我什么时候必须使用那种方式(Promise 调用)。当我可以以非常简单的方式调用时:
self.record_data(&data)
这是一个显而易见的事实,跨合约调用总是通过 Promises。 但是同一个合约调用了特定的内部合约函数——我们不清楚什么时候应该使用 Promises。
所以我需要很好地说明什么时候必须使用 Promises 以及什么时候它会多余。
您可以异步调用 record_data
,但需要付出一定的代价。您要支付基本费用以进行另一笔交易 + 运行 代码的 gas 成本 + 与主机调用交互的 gas(例如 env::*
)。所以使内部调用异步的原因是为了利用并发性:参见 rust-sdk's merge sort
pub fn merge_sort(&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, &account_id, 0, prepaid_gas / 4)
.and(ext::merge_sort(arr1, &account_id, 0, prepaid_gas / 4))
.then(ext::merge(&account_id, 0, prepaid_gas / 4))
.into()
}