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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
use casper_types::CLValue;

use crate::call_def::CallDef;
use crate::casper_types::bytesrepr::Bytes;
use crate::casper_types::U512;
use crate::{Address, OdraError, OdraResult};

/// Trait representing the context of a smart contract.
#[cfg_attr(test, allow(unreachable_code))]
#[cfg_attr(test, mockall::automock)]
pub trait ContractContext {
    /// Retrieves from the storage the value associated with the given key.
    ///
    /// # Arguments
    ///
    /// * `key` - The key to retrieve the value for.
    ///
    /// # Returns
    ///
    /// An `Option` containing the value associated with the key, or `None` if the key is not found.
    fn get_value(&self, key: &[u8]) -> Option<Bytes>;

    /// Writes to the storage the value associated with the given key.
    ///
    /// # Arguments
    ///
    /// * `key` - The key to set the value for.
    /// * `value` - The value to be set.
    fn set_value(&self, key: &[u8], value: Bytes);

    /// Retrieves the value behind a named key.
    ///
    /// # Arguments
    ///  
    /// * `name` - The name of the key.
    fn get_named_value(&self, name: &str) -> Option<Bytes>;

    /// Sets the value behind a named key.
    ///
    /// # Arguments
    ///
    /// * `name` - The name of the key.
    /// * `value` - The value to set.
    fn set_named_value(&self, name: &str, value: CLValue);

    /// Retrieves the key value behind a named dictionary.
    ///
    /// # Arguments
    ///
    /// * `dictionary_name` - The name of the dictionary.
    /// * `key` - The key to retrieve the value for.
    fn get_dictionary_value(&self, dictionary_name: &str, key: &[u8]) -> Option<Bytes>;

    /// Sets the key value behind a named dictionary.
    ///
    /// # Arguments
    ///
    /// * `dictionary_name` - The name of the dictionary.
    /// * `key` - The key to set the value for.
    /// * `value` - The value to set.
    fn set_dictionary_value(&self, dictionary_name: &str, key: &[u8], value: CLValue);

    /// Removes the named key from the storage.
    ///
    /// # Arguments
    /// * `dictionary_name` - The name of the dictionary.
    fn remove_dictionary(&self, dictionary_name: &str);

    /// Retrieves the address of the caller.
    fn caller(&self) -> Address;

    /// Retrieves the address of the current contract.
    fn self_address(&self) -> Address;

    /// Calls another contract at the specified address with the given call definition.
    ///
    /// # Arguments
    ///
    /// * `address` - The address of the contract to call.
    /// * `call_def` - The call definition specifying the method and arguments to call.
    ///
    /// # Returns
    ///
    /// The result of the contract call as a byte array.
    fn call_contract(&self, address: Address, call_def: CallDef) -> Bytes;

    /// Retrieves the current block time.
    ///
    /// # Returns
    ///
    /// The current block time as a `u64` value.
    fn get_block_time(&self) -> u64;

    /// Retrieves the value attached to the call.
    ///
    /// # Returns
    ///
    /// The attached value as a `U512` value.
    fn attached_value(&self) -> U512;

    /// Retrieves the balance of the current contract.
    ///
    /// # Returns
    /// The balance of the current contract in U512
    fn self_balance(&self) -> U512;

    /// Emits an event with the specified event data.
    ///
    /// # Arguments
    ///
    /// * `event` - The event data to emit.
    fn emit_event(&self, event: &Bytes);

    /// Transfers tokens to the specified address.
    ///
    /// # Arguments
    ///
    /// * `to` - The address to transfer the tokens to.
    /// * `amount` - The amount of tokens to transfer.
    fn transfer_tokens(&self, to: &Address, amount: &U512);

    /// Reverts the contract execution with the specified error.
    ///
    /// # Arguments
    ///
    /// * `error` - The error to revert with.
    ///
    /// # Panics
    ///
    /// This function will panic and abort the contract execution.
    fn revert(&self, error: OdraError) -> !;

    /// Retrieves the value of the named argument as a byte array.
    ///
    /// # Arguments
    ///
    /// * `name` - The name of the argument.
    ///
    /// # Returns
    ///
    /// The value of the named argument as a byte array.
    fn get_named_arg_bytes(&self, name: &str) -> OdraResult<Bytes>;

    /// Similar to `get_named_arg_bytes`, but returns `None` if the named argument is not present.
    fn get_opt_named_arg_bytes(&self, name: &str) -> Option<Bytes>;

    /// Handles the value attached to the call. Sets the value in the contract context.
    fn handle_attached_value(&self);

    /// Clears the value attached to the call.
    fn clear_attached_value(&self);

    /// Computes the hash of the given byte array.
    ///
    /// # Arguments
    ///
    /// * `bytes` - The byte array to compute the hash for.
    ///
    /// # Returns
    ///
    /// The computed hash as a fixed-size byte array of length 32.
    fn hash(&self, bytes: &[u8]) -> [u8; 32];
}