git.delta.rocks / unique-network / refs/commits / a90a9da574c3

difftreelog

source

runtime/common/ethereum/precompiles/sr25519.rs2.5 KiBsourcehistory
1use fp_evm::{Context, ExitSucceed, PrecompileHandle, PrecompileOutput};2use pallet_evm::Precompile;3use sp_core::{crypto::UncheckedFrom, sr25519, H256};4use sp_std::marker::PhantomData;5use sp_std::prelude::*;67use super::utils::{Bytes, EvmDataReader, EvmDataWriter, EvmResult, FunctionModifier, Gasometer};89#[precompile_utils_macro::generate_function_selector]10#[derive(Debug, PartialEq)]11pub enum Action {12	Verify = "verify(bytes32,bytes,bytes)",13}1415/// A precompile to wrap substrate sr25519 functions.16pub struct Sr25519Precompile<Runtime>(PhantomData<Runtime>);1718impl<Runtime: pallet_evm::Config> Precompile for Sr25519Precompile<Runtime> {19	fn execute(handle: &mut impl PrecompileHandle) -> EvmResult<PrecompileOutput> {20		log::trace!(target: "sr25519-precompile", "In sr25519 precompile");2122		let gasometer = Gasometer::new();2324		let (mut input, selector) = EvmDataReader::new_with_selector(&gasometer, handle.input())?;25		let input = &mut input;2627		gasometer.check_function_modifier(28			handle.context(),29			handle.is_static(),30			FunctionModifier::View,31		)?;3233		match selector {34			// Dispatchables35			Action::Verify => Self::verify(input, &gasometer, handle.context()),36		}37	}38}3940impl<Runtime: pallet_evm::Config> Sr25519Precompile<Runtime> {41	fn verify(42		input: &mut EvmDataReader,43		gasometer: &Gasometer,44		_: &Context,45	) -> EvmResult<PrecompileOutput> {46		// Bound check47		input.expect_arguments(gasometer, 3)?;4849		// Parse arguments50		let public: sr25519::Public =51			sr25519::Public::unchecked_from(input.read::<H256>(gasometer)?).into();52		let signature_bytes: Vec<u8> = input.read::<Bytes>(gasometer)?.into();53		let message: Vec<u8> = input.read::<Bytes>(gasometer)?.into();5455		// Parse signature56		let signature_opt = sr25519::Signature::from_slice(&signature_bytes[..]);5758		let signature = if let Some(sig) = signature_opt {59			sig60		} else {61			// Return `false` if signature length is wrong62			return Ok(PrecompileOutput {63				exit_status: ExitSucceed::Returned,64				output: EvmDataWriter::new().write(false).build(),65			});66		};6768		log::trace!(69			target: "sr25519-precompile",70			"Verify signature {:?} for public {:?} and message {:?}",71			signature, public, message,72		);7374		let is_confirmed = sp_io::crypto::sr25519_verify(&signature, &message[..], &public);7576		log::trace!(77			target: "sr25519-precompile",78			"Verified signature {:?} is {:?}",79			signature, is_confirmed,80		);8182		Ok(PrecompileOutput {83			exit_status: ExitSucceed::Returned,84			output: EvmDataWriter::new().write(is_confirmed).build(),85		})86	}87}