use super::constants::MAX_TOKEN_METHOD_LENGTH;
use super::encoding::write_varbytes;
#[derive(Debug, Clone)]
pub struct MethodToken {
pub hash: [u8; 20],
pub method: String,
pub parameters_count: u16,
pub has_return_value: bool,
pub call_flags: u8,
}
impl MethodToken {
pub fn new(hash: [u8; 20], method: &str, params: u16, has_return: bool, flags: u8) -> Self {
Self {
hash,
method: method.to_string(),
parameters_count: params,
has_return_value: has_return,
call_flags: flags,
}
}
pub fn hash_hex(&self) -> String {
hex::encode(self.hash)
}
pub fn allows_state_changes(&self) -> bool {
self.call_flags & 0x01 != 0
}
pub(super) fn serialize(&self, buffer: &mut Vec<u8>) -> Result<(), String> {
buffer.extend_from_slice(&self.hash);
let bytes = self.method.as_bytes();
if bytes.len() > MAX_TOKEN_METHOD_LENGTH {
return Err(format!(
"method token '{}' exceeds {MAX_TOKEN_METHOD_LENGTH} bytes (Neo N3 NEF3 cap)",
self.method
));
}
write_varbytes(buffer, bytes);
buffer.extend_from_slice(&self.parameters_count.to_le_bytes());
buffer.push(if self.has_return_value { 1 } else { 0 });
buffer.push(self.call_flags);
Ok(())
}
}