diff --git a/framework/base/src/api/managed_types/const_handles.rs b/framework/base/src/api/managed_types/const_handles.rs
index bd92bcc1db..1657d18e67 100644
--- a/framework/base/src/api/managed_types/const_handles.rs
+++ b/framework/base/src/api/managed_types/const_handles.rs
@@ -22,6 +22,9 @@ pub const CALLBACK_CLOSURE_ARGS_BUFFER: RawHandle = -23;
pub const MBUF_TEMPORARY_1: RawHandle = -25;
pub const MBUF_TEMPORARY_2: RawHandle = -26;
+pub const ADDRESS_CALLER: RawHandle = -30;
+pub const ADDRESS_SELF: RawHandle = -31;
+
pub const NEW_HANDLE_START_FROM: RawHandle = -100; // > -100 reserved for APIs
/// Used as a flag. Do not use as a regular handle.
diff --git a/framework/base/src/contract_base/wrappers/send_wrapper.rs b/framework/base/src/contract_base/wrappers/send_wrapper.rs
index b55e486241..83972d0b28 100644
--- a/framework/base/src/contract_base/wrappers/send_wrapper.rs
+++ b/framework/base/src/contract_base/wrappers/send_wrapper.rs
@@ -12,6 +12,7 @@ use crate::{
},
codec,
esdt::ESDTSystemSmartContractProxy,
+ proxy_imports::{ReturnsRaw, ToSelf},
types::{
BigUint, ContractCall, ContractCallNoPayment, EgldOrEsdtTokenIdentifier, EsdtTokenPayment,
ManagedAddress, ManagedArgBuffer, ManagedBuffer, ManagedType, ManagedVec, TokenIdentifier,
@@ -380,11 +381,31 @@ where
pub fn call_local_esdt_built_in_function(
&self,
gas: u64,
- endpoint_name: &ManagedBuffer,
- arg_buffer: &ManagedArgBuffer,
+ endpoint_name: ManagedBuffer,
+ arg_buffer: ManagedArgBuffer,
) -> ManagedVec> {
- self.send_raw_wrapper()
- .call_local_esdt_built_in_function(gas, endpoint_name, arg_buffer)
+ Tx::new_tx_from_sc()
+ .to(ToSelf)
+ .with_gas_limit(gas)
+ .raw_call()
+ .function_name(endpoint_name)
+ .arguments_raw(arg_buffer)
+ .returns(ReturnsRaw)
+ .sync_call()
+ }
+
+ fn call_local_esdt_built_in_function_minimal(
+ &self,
+ function_name: &str,
+ arg_buffer: ManagedArgBuffer,
+ ) {
+ Tx::new_tx_from_sc()
+ .to(ToSelf)
+ .with_gas_limit(A::blockchain_api_impl().get_gas_left())
+ .raw_call()
+ .function_name(function_name)
+ .arguments_raw(arg_buffer)
+ .sync_call()
}
/// Allows synchronous minting of ESDT/SFT (depending on nonce). Execution is resumed afterwards.
@@ -410,11 +431,7 @@ where
arg_buffer.push_arg(amount);
- let _ = self.call_local_esdt_built_in_function(
- A::blockchain_api_impl().get_gas_left(),
- &ManagedBuffer::from(func_name),
- &arg_buffer,
- );
+ self.call_local_esdt_built_in_function_minimal(func_name, arg_buffer);
}
/// Allows synchronous minting of ESDT/SFT (depending on nonce). Execution is resumed afterwards.
@@ -456,11 +473,7 @@ where
arg_buffer.push_arg(amount);
- let _ = self.call_local_esdt_built_in_function(
- A::blockchain_api_impl().get_gas_left(),
- &ManagedBuffer::from(func_name),
- &arg_buffer,
- );
+ self.call_local_esdt_built_in_function_minimal(func_name, arg_buffer);
}
/// Allows synchronous burning of ESDT/SFT/NFT (depending on nonce). Execution is resumed afterwards.
@@ -549,8 +562,8 @@ where
let output = self.call_local_esdt_built_in_function(
A::blockchain_api_impl().get_gas_left(),
- &ManagedBuffer::from(ESDT_NFT_CREATE_FUNC_NAME),
- &arg_buffer,
+ ManagedBuffer::from(ESDT_NFT_CREATE_FUNC_NAME),
+ arg_buffer,
);
if let Some(first_result_bytes) = output.try_get(0) {
@@ -770,11 +783,7 @@ where
arg_buffer.push_arg(uri);
}
- let _ = self.call_local_esdt_built_in_function(
- A::blockchain_api_impl().get_gas_left(),
- &ManagedBuffer::from(ESDT_NFT_ADD_URI_FUNC_NAME),
- &arg_buffer,
- );
+ self.call_local_esdt_built_in_function_minimal(ESDT_NFT_ADD_URI_FUNC_NAME, arg_buffer);
}
/// Changes attributes of an NFT, via a synchronous builtin function call.
@@ -789,10 +798,9 @@ where
arg_buffer.push_arg(nft_nonce);
arg_buffer.push_arg(new_attributes);
- let _ = self.call_local_esdt_built_in_function(
- A::blockchain_api_impl().get_gas_left(),
- &ManagedBuffer::from(ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME),
- &arg_buffer,
+ self.call_local_esdt_built_in_function_minimal(
+ ESDT_NFT_UPDATE_ATTRIBUTES_FUNC_NAME,
+ arg_buffer,
);
}
}
diff --git a/framework/base/src/types/interaction/tx_to.rs b/framework/base/src/types/interaction/tx_to.rs
index 13c78b5da6..6d964bd0b5 100644
--- a/framework/base/src/types/interaction/tx_to.rs
+++ b/framework/base/src/types/interaction/tx_to.rs
@@ -1,6 +1,8 @@
mod tx_to_caller;
+mod tx_to_self;
pub use tx_to_caller::ToCaller;
+pub use tx_to_self::ToSelf;
use crate::types::{heap::Address, ManagedAddress};
diff --git a/framework/base/src/types/interaction/tx_to/tx_to_caller.rs b/framework/base/src/types/interaction/tx_to/tx_to_caller.rs
index 5c1668d38d..1e3b59db73 100644
--- a/framework/base/src/types/interaction/tx_to/tx_to_caller.rs
+++ b/framework/base/src/types/interaction/tx_to/tx_to_caller.rs
@@ -1,7 +1,7 @@
use crate::{
- api::{BlockchainApi, CallTypeApi},
+ api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi},
contract_base::BlockchainWrapper,
- types::{AnnotatedValue, ManagedAddress, ManagedBuffer, TxScEnv},
+ types::{AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv},
};
use super::{TxTo, TxToSpecified};
@@ -9,23 +9,16 @@ use super::{TxTo, TxToSpecified};
/// Indicates that transaction should be sent to the caller (the sender of the current transaction).
pub struct ToCaller;
-fn get_caller() -> ManagedAddress
-where
- Api: CallTypeApi + BlockchainApi,
-{
- BlockchainWrapper::::new().get_caller()
-}
-
impl AnnotatedValue, ManagedAddress> for ToCaller
where
Api: CallTypeApi + BlockchainApi,
{
fn annotation(&self, env: &TxScEnv) -> ManagedBuffer {
- get_caller::().hex_expr()
+ self.with_address_ref(env, |addr_ref| addr_ref.hex_expr())
}
fn into_value(self, _env: &TxScEnv) -> ManagedAddress {
- get_caller::()
+ BlockchainWrapper::::new().get_caller()
}
}
@@ -38,6 +31,8 @@ where
where
F: FnOnce(&ManagedAddress) -> R,
{
- f(&get_caller::())
+ let caller_handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER);
+ Api::blockchain_api_impl().load_caller_managed(caller_handle.clone());
+ f(&ManagedAddress::from_handle(caller_handle))
}
}
diff --git a/framework/base/src/types/interaction/tx_to/tx_to_self.rs b/framework/base/src/types/interaction/tx_to/tx_to_self.rs
new file mode 100644
index 0000000000..a4adfaa429
--- /dev/null
+++ b/framework/base/src/types/interaction/tx_to/tx_to_self.rs
@@ -0,0 +1,38 @@
+use crate::{
+ api::{const_handles, use_raw_handle, BlockchainApi, BlockchainApiImpl, CallTypeApi},
+ contract_base::BlockchainWrapper,
+ types::{AnnotatedValue, ManagedAddress, ManagedBuffer, ManagedType, TxScEnv},
+};
+
+use super::{TxTo, TxToSpecified};
+
+/// Indicates that transaction should be sent to itself.
+pub struct ToSelf;
+
+impl AnnotatedValue, ManagedAddress> for ToSelf
+where
+ Api: CallTypeApi + BlockchainApi,
+{
+ fn annotation(&self, env: &TxScEnv) -> ManagedBuffer {
+ self.with_address_ref(env, |addr_ref| addr_ref.hex_expr())
+ }
+
+ fn into_value(self, _env: &TxScEnv) -> ManagedAddress {
+ BlockchainWrapper::::new().get_sc_address()
+ }
+}
+
+impl TxTo> for ToSelf where Api: CallTypeApi + BlockchainApi {}
+impl TxToSpecified> for ToSelf
+where
+ Api: CallTypeApi + BlockchainApi,
+{
+ fn with_address_ref(&self, env: &TxScEnv, f: F) -> R
+ where
+ F: FnOnce(&ManagedAddress) -> R,
+ {
+ let sc_address_handle: Api::ManagedBufferHandle = use_raw_handle(const_handles::ADDRESS_CALLER);
+ Api::blockchain_api_impl().load_sc_address_managed(sc_address_handle.clone());
+ f(&ManagedAddress::from_handle(sc_address_handle))
+ }
+}