use hedera_proto::services;
use crate::{
AccountId,
ContractId,
FromProtobuf,
};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "ffi", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "ffi", serde(rename_all = "camelCase"))]
pub struct ContractFunctionResult {
pub contract_id: ContractId,
pub evm_address: Option<ContractId>,
#[cfg_attr(feature = "ffi", serde(with = "serde_with::As::<serde_with::base64::Base64>"))]
pub bytes: Vec<u8>,
pub error_message: Option<String>,
#[cfg_attr(feature = "ffi", serde(with = "serde_with::As::<serde_with::base64::Base64>"))]
pub bloom: Vec<u8>,
pub gas_used: u64,
pub gas: u64,
pub hbar_amount: u64,
#[cfg_attr(feature = "ffi", serde(with = "serde_with::As::<serde_with::base64::Base64>"))]
pub contract_function_parameters_bytes: Vec<u8>,
pub sender_account_id: Option<AccountId>,
}
impl FromProtobuf<services::ContractFunctionResult> for ContractFunctionResult {
fn from_protobuf(pb: services::ContractFunctionResult) -> crate::Result<Self>
where
Self: Sized,
{
let contract_id = pb_getf!(pb, contract_id)?;
let contract_id = ContractId::from_protobuf(contract_id)?;
let sender_account_id = Option::from_protobuf(pb.sender_id)?;
let evm_address = pb
.evm_address
.and_then(|address| <[u8; 20]>::try_from(address).ok())
.map(ContractId::from);
Ok(Self {
contract_id,
bytes: pb.contract_call_result,
error_message: if pb.error_message.is_empty() { None } else { Some(pb.error_message) },
bloom: pb.bloom,
gas_used: pb.gas_used,
gas: pb.gas as u64,
hbar_amount: pb.amount as u64,
contract_function_parameters_bytes: pb.function_parameters,
sender_account_id,
evm_address,
})
}
}
impl FromProtobuf<services::response::Response> for ContractFunctionResult {
fn from_protobuf(pb: services::response::Response) -> crate::Result<Self>
where
Self: Sized,
{
let pb = pb_getv!(pb, ContractCallLocal, services::response::Response);
let result = pb_getf!(pb, function_result)?;
let result = ContractFunctionResult::from_protobuf(result)?;
Ok(result)
}
}