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
//! This module implements traits for the contract interface. //! This allows setting-up mock objects for testing individual //! contract invocations. #[cfg(not(feature = "std"))] use alloc::vec::Vec; use concordium_contracts_common::*; /// Objects which can access parameters to contracts. /// /// This trait has a Read supertrait which means that structured parameters can /// be directly deserialized by using `.get()` function from the `Get` trait. /// /// The reuse of `Read` methods is the reason for the slightly strange choice of /// methods of this trait. pub trait HasParameter: Read { /// Get the size of the parameter to the method. fn size(&self) -> u32; } /// Objects which can access chain metadata. pub trait HasChainMetadata { /// Get time in milliseconds at the beginning of this block. fn slot_time(&self) -> SlotTime; /// Get block height of the current block. fn block_height(&self) -> BlockHeight; /// Get the height of the last finalized block, i.e., block to which the /// current block has a finalized pointer to. fn finalized_height(&self) -> FinalizedHeight; /// Get the slot number of the current block. fn slot_number(&self) -> SlotNumber; } /// Types which can act as init contexts. pub trait HasInitContext<Error: Default> where Self::ParamType: Read, { /// Data needed to open the context. type InitData; type ParamType: HasParameter; type MetadataType: HasChainMetadata; /// Open the init context for reading and accessing values. fn open(data: Self::InitData) -> Self; /// Who invoked this init call. fn init_origin(&self) -> AccountAddress; /// Get the cursor to the parameter. fn parameter_cursor(&self) -> Self::ParamType; /// Get the reference to chain metadata fn metadata(&self) -> &Self::MetadataType; } /// Types which can act as receive contexts. pub trait HasReceiveContext<Error: Default> where Self::ParamType: Read, { type ReceiveData; type ParamType: HasParameter; type MetadataType: HasChainMetadata; /// Open the receive context for reading and accessing values. fn open(data: Self::ReceiveData) -> Self; /// Who is the account that initiated the top-level transaction this /// invocation is a part of. fn invoker(&self) -> AccountAddress; /// The address of the contract being invoked. fn self_address(&self) -> ContractAddress; /// Balance on the contract before the call was made. fn self_balance(&self) -> Amount; /// The immediate sender of the message. In general different from the /// invoker. fn sender(&self) -> Address; /// Account which created the contract instance. fn owner(&self) -> AccountAddress; /// Get the cursor to the parameter. fn parameter_cursor(&self) -> Self::ParamType; /// Get the reference to chain metadata fn metadata(&self) -> &Self::MetadataType; } /// A type that can serve as the contract state type. pub trait HasContractState<Error: Default> where Self: Read, Self: Write<Err = Error>, Self: Seek<Err = Error>, { type ContractStateData; /// Open the contract state. Only one instance can be opened at the same /// time. fn open(_: Self::ContractStateData) -> Self; /// Get the current size of contract state. fn size(&self) -> u32; /// Truncate the state to the given size. If the given size is more than the /// current state size this operation does nothing. The new position is at /// most at the end of the stream. fn truncate(&mut self, new_size: u32); /// Make sure that the memory size is at least that many bytes in size. /// Returns true iff this was successful. The new bytes are initialized as /// 0. fn reserve(&mut self, len: u32) -> bool; } /// Objects which can serve as loggers. /// /// Logging functionality can be used by smart contracts to record events that /// might be of interest to external parties. These events are not used on the /// chain, and cannot be observed by other contracts, but they are stored by the /// node, and can be queried to provide information to off-chain actors. pub trait HasLogger { /// Initialize a logger. fn init() -> Self; /// Log the given bytes as-is. fn log_bytes(&mut self, event: &[u8]); #[inline(always)] /// Log a serializable event by serializing it with a supplied serializer. fn log<S: Serial>(&mut self, event: &S) { let mut out = Vec::new(); if event.serial(&mut out).is_err() { crate::trap(); // should not happen } self.log_bytes(&out) } } /// An object that can serve to construct actions. /// /// The actions that a smart contract can produce as a /// result of its execution. These actions form a tree and are executed by /// the scheduler in the predefined order. pub trait HasActions { /// Default accept action. fn accept() -> Self; /// Send a given amount to an account. fn simple_transfer(acc: &AccountAddress, amount: Amount) -> Self; /// Send a message to a contract. fn send(ca: &ContractAddress, receive_name: &str, amount: Amount, parameter: &[u8]) -> Self; /// If the execution of the first action succeeds, run the second action /// as well. fn and_then(self, then: Self) -> Self; /// If the execution of the first action fails, try the second. fn or_else(self, el: Self) -> Self; }