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
// Note: Simple macros cannot be placed in dharitri-wasm-derive,
// because Rust "cannot export macro_rules! macros from a `proc-macro` crate type currently".
/// Getting all imports needed for a smart contract.
#[macro_export]
macro_rules! imports {
() => {
use core::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
SubAssign,
};
use dharitri_wasm::{
api::{
BigIntApi, BlockchainApi, CallValueApi, CryptoApi, EllipticCurveApi, ErrorApi,
LogApi, ManagedTypeApi, PrintApi, SendApi,
},
contract_base::{ContractBase, ProxyObjBase},
dharitri_codec::{DecodeError, NestedDecode, NestedEncode, TopDecode},
err_msg,
dct::*,
io::*,
non_zero_usize,
non_zero_util::*,
only_owner, require, sc_error,
storage::mappers::*,
types::{
SCResult::{Err, Ok},
*,
},
Box, Vec,
}; // TODO: remove at some point, they shouldn't be public
};
}
/// Imports required for deriving serialization and TypeAbi.
#[macro_export]
macro_rules! derive_imports {
() => {
use dharitri_wasm::{
derive::TypeAbi,
dharitri_codec,
dharitri_codec::dharitri_codec_derive::{
NestedDecode, NestedEncode, TopDecode, TopDecodeOrDefault, TopEncode,
TopEncodeOrDefault,
},
};
};
}
/// Compact way of returning a static error message.
#[macro_export]
macro_rules! sc_error {
($s:expr) => {
dharitri_wasm::types::SCResult::Err(dharitri_wasm::types::StaticSCError::from($s)).into()
};
}
/// Equivalent to the `?` operator for SCResult.
#[deprecated(
since = "0.16.0",
note = "The `?` operator can now be used on `SCResult`, please use it instead."
)]
#[macro_export]
macro_rules! sc_try {
($s:expr) => {
match $s {
dharitri_wasm::types::SCResult::Ok(t) => t,
dharitri_wasm::types::SCResult::Err(e) => {
return dharitri_wasm::types::SCResult::Err(e);
},
}
};
}
/// Allows us to write Solidity style `require!(<condition>, <error_msg>)` and avoid if statements.
///
/// It can only be used in a function that returns `SCResult<_>` where _ can be any type.
///
/// ```rust
/// # use dharitri_wasm::*;
/// # use dharitri_wasm::api::BlockchainApi;
/// # use dharitri_wasm::types::{*, SCResult::Ok};
/// # pub trait ExampleContract: dharitri_wasm::contract_base::ContractBase
/// # {
/// fn only_callable_by_owner(&self) -> SCResult<()> {
/// require!(self.blockchain().get_caller() == self.blockchain().get_owner_address(), "Caller must be owner");
/// Ok(())
/// }
/// # }
/// ```
#[macro_export]
macro_rules! require {
($expression:expr, $error_msg:expr) => {
if (!($expression)) {
return sc_error!($error_msg);
}
};
}
/// Very compact way of not allowing anyone but the owner to call a function.
///
/// It can only be used in a function that returns `SCResult<_>` where _ can be any type.
///
/// ```rust
/// # use dharitri_wasm::*;
/// # use dharitri_wasm::api::BlockchainApi;
/// # use dharitri_wasm::types::{*, SCResult::Ok};
/// # pub trait ExampleContract: dharitri_wasm::contract_base::ContractBase
/// # {
/// fn only_callable_by_owner(&self) -> SCResult<()> {
/// only_owner!(self, "Caller must be owner");
/// Ok(())
/// }
/// # }
/// ```
#[macro_export]
macro_rules! only_owner {
($trait_self: expr, $error_msg:expr) => {
if ($trait_self.blockchain().get_caller() != $trait_self.blockchain().get_owner_address()) {
return sc_error!($error_msg);
}
};
}
/// Converts usize to NonZeroUsize or returns SCError.
#[macro_export]
macro_rules! non_zero_usize {
($input: expr, $error_msg:expr) => {
if let Some(nz) = NonZeroUsize::new($input) {
nz
} else {
return sc_error!($error_msg);
}
};
}