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)) + } +}