1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::{
num_bigint::{BigInt, Sign},
tx_mock::TxPanic,
DebugApi,
};
use alloc::vec::Vec;
use elrond_wasm::api::{
BigIntApi, ManagedBufferApi, StorageReadApi, StorageReadApiImpl, StorageWriteApi,
StorageWriteApiImpl,
};
impl StorageReadApi for DebugApi {
type StorageReadApiImpl = DebugApi;
fn storage_read_api_impl() -> Self::StorageReadApiImpl {
DebugApi::new_from_static()
}
}
impl DebugApi {
fn storage_load_vec_u8(&self, key: &[u8]) -> Vec<u8> {
self.with_contract_account(|account| match account.storage.get(&key.to_vec()) {
None => Vec::with_capacity(0),
Some(value) => value.clone(),
})
}
}
impl StorageReadApiImpl for DebugApi {
fn storage_load_len(&self, key: &[u8]) -> usize {
self.storage_load_vec_u8(key).len()
}
fn storage_load_to_heap(&self, key: &[u8]) -> Box<[u8]> {
self.storage_load_vec_u8(key).into_boxed_slice()
}
fn storage_load_big_uint_raw(&self, key: &[u8], dest: Self::ManagedBufferHandle) {
let bytes = self.storage_load_vec_u8(key);
let bi = BigInt::from_bytes_be(Sign::Plus, bytes.as_slice());
self.bi_overwrite(dest, bi);
}
fn storage_load_managed_buffer_raw(
&self,
key_handle: Self::ManagedBufferHandle,
dest: Self::ManagedBufferHandle,
) {
let key_bytes = self.mb_to_boxed_bytes(key_handle);
let bytes = self.storage_load_vec_u8(key_bytes.as_slice());
self.mb_overwrite(dest, bytes.as_slice());
}
fn storage_load_from_address(
&self,
address_handle: Self::ManagedBufferHandle,
key_handle: Self::ManagedBufferHandle,
dest: Self::ManagedBufferHandle,
) {
let address = elrond_wasm::types::heap::Address::from_slice(
self.mb_to_boxed_bytes(address_handle).as_slice(),
);
let key_bytes = self.mb_to_boxed_bytes(key_handle);
self.with_account(&address, |account| {
match account.storage.get(key_bytes.as_slice()) {
None => self.mb_overwrite(dest, &[]),
Some(value) => self.mb_overwrite(dest, value.as_slice()),
}
})
}
}
impl StorageWriteApi for DebugApi {
type StorageWriteApiImpl = DebugApi;
fn storage_write_api_impl() -> Self::StorageWriteApiImpl {
DebugApi::new_from_static()
}
}
impl StorageWriteApiImpl for DebugApi {
fn storage_store_slice_u8(&self, key: &[u8], value: &[u8]) {
if key.starts_with(&b"ELROND"[..]) {
std::panic::panic_any(TxPanic {
status: 10,
message: "cannot write to storage under Elrond reserved key".to_string(),
});
}
self.with_contract_account_mut(|account| {
account.storage.insert(key.to_vec(), value.to_vec());
});
}
fn storage_store_big_uint_raw(&self, key: &[u8], handle: Self::BigIntHandle) {
self.storage_store_slice_u8(key, self.bi_get_signed_bytes(handle).as_slice());
}
fn storage_store_managed_buffer_raw(
&self,
key_handle: Self::ManagedBufferHandle,
value_handle: Self::ManagedBufferHandle,
) {
let key_bytes = self.mb_to_boxed_bytes(key_handle);
let value_bytes = self.mb_to_boxed_bytes(value_handle);
self.storage_store_slice_u8(key_bytes.as_slice(), value_bytes.as_slice());
}
fn storage_store_managed_buffer_clear(&self, key_handle: Self::ManagedBufferHandle) {
let key_bytes = self.mb_to_boxed_bytes(key_handle);
self.storage_store_slice_u8(key_bytes.as_slice(), &[]);
}
}