1234567891011121314151617use fp_evm::{Context, ExitSucceed, PrecompileHandle, PrecompileOutput};18use pallet_evm::Precompile;19use sp_core::{crypto::UncheckedFrom, sr25519, H256};20use sp_std::{marker::PhantomData, prelude::*};2122use super::utils::{Bytes, EvmDataReader, EvmDataWriter, EvmResult, FunctionModifier, Gasometer};2324#[precompile_utils_macro::generate_function_selector]25#[derive(Debug, PartialEq)]26pub enum Action {27 Verify = "verify(bytes32,bytes,bytes)",28}293031pub struct Sr25519Precompile<Runtime>(PhantomData<Runtime>);3233impl<Runtime: pallet_evm::Config> Precompile for Sr25519Precompile<Runtime> {34 fn execute(handle: &mut impl PrecompileHandle) -> EvmResult<PrecompileOutput> {35 log::trace!(target: "sr25519-precompile", "In sr25519 precompile");3637 let gasometer = Gasometer::new();3839 let (mut input, selector) = EvmDataReader::new_with_selector(&gasometer, handle.input())?;40 let input = &mut input;4142 gasometer.check_function_modifier(43 handle.context(),44 handle.is_static(),45 FunctionModifier::View,46 )?;4748 match selector {49 50 Action::Verify => Self::verify(input, &gasometer, handle.context()),51 }52 }53}5455impl<Runtime: pallet_evm::Config> Sr25519Precompile<Runtime> {56 fn verify(57 input: &mut EvmDataReader,58 gasometer: &Gasometer,59 _: &Context,60 ) -> EvmResult<PrecompileOutput> {61 62 input.expect_arguments(gasometer, 3)?;6364 65 let public: sr25519::Public =66 sr25519::Public::unchecked_from(input.read::<H256>(gasometer)?);67 let signature_bytes: Vec<u8> = input.read::<Bytes>(gasometer)?.into();68 let message: Vec<u8> = input.read::<Bytes>(gasometer)?.into();6970 71 let signature_opt = sr25519::Signature::from_slice(&signature_bytes[..]);7273 let signature = if let Some(sig) = signature_opt {74 sig75 } else {76 77 return Ok(PrecompileOutput {78 exit_status: ExitSucceed::Returned,79 output: EvmDataWriter::new().write(false).build(),80 });81 };8283 log::trace!(84 target: "sr25519-precompile",85 "Verify signature {:?} for public {:?} and message {:?}",86 signature, public, message,87 );8889 let is_confirmed = sp_io::crypto::sr25519_verify(&signature, &message[..], &public);9091 log::trace!(92 target: "sr25519-precompile",93 "Verified signature {:?} is {:?}",94 signature, is_confirmed,95 );9697 Ok(PrecompileOutput {98 exit_status: ExitSucceed::Returned,99 output: EvmDataWriter::new().write(is_confirmed).build(),100 })101 }102}