Trabajador fuera de la cadena (abajo)

Caso 7: Iniciar una transacción firmada a la cadena

Objetivo

  1. Modificar nodo, tiempo de ejecución, archivos de palets

  2. en su mayoría código repetitivo

  3. La transacción de firma requiere una cuenta, y la ejecución de la transacción cobrará una tarifa de tx de esta cuenta

El contenido de esta sección se centra en la configuración, ahora estableceremos algunos elementos de configuración necesarios

1.substrate-node-template/node/src/service.rs

--let client = Arc::new(client);+++// Genere una cuenta y colóquela en el almacén de claves, para que la plataforma pueda obtener la cuenta, offchain usa if config.offchain_worker.enabled { let keystore = keystore_container .sync_keystore() ; sp_keystore::SyncCryptoStore::sr25519_generate_new( &*keystore, node_template_runtime::pallet_template::KEY_TYPE, Some("//Alice"), //Se agrega la cuenta de Alice, para probar, tiene mucho saldo , y también es Sudo) .expect("La creación de la clave con la cuenta Alice debería tener éxito."); }

ubstrate-node-template/node/Cargo.toml

sp-keystore = {versión ="0.12.0",git = "https://github.com/paritytech/substrate.git", rama = "polkadot-v0.9.30" }

2.substrate-node-template/runtime/src/lib.rs

Nota: rama = versión "polkadot-v0.9.30" La llamada ha cambiado a RuntimeCall

use codec::Encode;use sp_runtime::SaturatedConversion; //Introduzca dos traitimpl pallet_sudo::Config para Runtime {type RuntimeEvent = RuntimeEvent;type RuntimeCall = RuntimeCall;}// Cuando el trabajador fuera de la cadena llama a la función en la paleta, donde el se genera una transacción real impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for RuntimewhereRuntimeCall: From<LocalCall>,{fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self ::Signature> >(call: RuntimeCall,public: <Firma como sp_runtime::traits::Verify>::Signer,account: AccountId,nonce: Index,) -> Option<(RuntimeCall,<UncheckedExtrinsic as sp_runtime::traits ::Extrinsic> ::SignaturePayload,)> {let tip = 0;let ​​period =BlockHashCount::get().checked_next_power_of_two().map(|c| c/2).unwrap_or(2) as u64;let current_block = System: :block_number().saturado_en::<u64>().saturating_sub(1);let era = generic::Era::mortal(period, current_block);let extra = (frame_system::CheckNonZeroSender::<Runtime>::new(),frame_system::CheckSpecVersion: :<Runtime>::new(),frame_system::CheckTxVersion::<Runtime>::new(),frame_system::CheckGenesis::<Runtime>::new(),frame_system::CheckEra::<Runtime>: :from(era),frame_system::CheckNonce::<Runtime>::from(nonce),frame_system::CheckWeight::<Runtime>::new(),//pallet_asset_tx_payment::ChargeAssetTxPayment::<Runtime>:: from(consejo, Ninguno),pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),);let raw_payload = SignedPayload::new(call, extra).map_err(|_| {//log::warn) !("No se pudo crear la carga útil firmada: {:?}", e);}).ok()?;let signature = raw_payload.using_encoded(|payload| C::sign(payload, public))?;let dirección = cuenta;let (llamada, extra, _) = raw_payload.deconstruct();Algunos((llamada, (sp_runtime::MultiAddress::Id(dirección), firma.into(), extra)))}}impl frame_system::offchain::SigningTypes for Runtime {type Public = <Signature as sp_runtime::traits::Verify>::Signer;type Signature = Signature;}impl<C> frame_system::offchain::SendTransactionTypes<C> for RuntimewhereRuntimeCall : From<C>,{type Extrinsic = UncheckedExtrinsic;type OverarchingCall = RuntimeCall;}/// Configure la plantilla de paleta en pallets/template./// Configure la plantilla de paleta en pallets/template.impl pallet_template::Config for Tiempo de ejecución {tipo RuntimeEvent = RuntimeEvent; tipo AuthorityId = pallet_template::crypto::OcwAuthId;}extra)))}}impl frame_system::offchain::SigningTypes for Runtime {type Public = <Signature as sp_runtime::traits::Verify>::Signer;type Signature = Signature;}impl<C> frame_system::offchain: :SendTransactionTypes<C> for RuntimewhereRuntimeCall: From<C>,{type Extrinsic = UncheckedExtrinsic;type OverarchingCall = RuntimeCall;}/// Configure la plantilla de paleta en pallets/template./// Configure la plantilla de paleta en pallets/template .impl pallet_template::Config for Runtime {type RuntimeEvent = RuntimeEvent;type AuthorityId = pallet_template::crypto::OcwAuthId;}extra)))}}impl frame_system::offchain::SigningTypes for Runtime {type Public = <Signature as sp_runtime::traits::Verify>::Signer;type Signature = Signature;}impl<C> frame_system::offchain: :SendTransactionTypes<C> for RuntimewhereRuntimeCall: From<C>,{type Extrinsic = UncheckedExtrinsic;type OverarchingCall = RuntimeCall;}/// Configure la plantilla de paleta en pallets/template./// Configure la plantilla de paleta en pallets/template .impl pallet_template::Config for Runtime {type RuntimeEvent = RuntimeEvent;type AuthorityId = pallet_template::crypto::OcwAuthId;}{type Extrinsic = UncheckedExtrinsic;type OverarchingCall = RuntimeCall;}/// Configure la plantilla de paleta en pallets/template./// Configure la plantilla de paleta en pallets/template.impl pallet_template::Config for Runtime {type RuntimeEvent = RuntimeEvent ;escriba AuthorityId = pallet_template::crypto::OcwAuthId;}{type Extrinsic = UncheckedExtrinsic;type OverarchingCall = RuntimeCall;}/// Configure la plantilla de paleta en pallets/template./// Configure la plantilla de paleta en pallets/template.impl pallet_template::Config for Runtime {type RuntimeEvent = RuntimeEvent ;escriba AuthorityId = pallet_template::crypto::OcwAuthId;}

3.substrate-node-template/pallets/template/src/lib.rs

use frame_system::{ offchain::{ AppCrypto, CreateSignedTransaction, SendSignedTransaction, Signer, },};use sp_core::crypto::KeyTypeId;pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"ocwd");pub mod crypto { use super::KEY_TYPE; use sp_core::sr25519::Signature como Sr25519Signature; use sp_runtime::{ app_crypto::{app_crypto, sr25519}, traits::Verify, MultiSignature, MultiSigner, }; app_crypto!(sr25519, KEY_TYPE); pub struct OcwAuthId; impl frame_system::offchain::AppCrypto<MultiSigner, MultiSignature> for OcwAuthId { type RuntimeAppPublic = Public; escriba GenericSignature = sp_core::sr25519::Signature; escriba GenericPublic = sp_core::sr25519::Public; } impl frame_system::offchain::AppCrypto<<Sr25519Signature as Verify>::Signer, Sr25519Signature>

3.substrate-node-template/pallets/template/Cargo.toml

[dependencias]--sp-core = { versión ="6.0.0",características predeterminadas = false,git = "https://github.com/paritytech/substrate.git", rama = "polkadot-v0.9.30 " }

Compilar y ejecutar

enfocar:

  1. Configure tres archivos de trabajador fuera de la cadena, nodo, tiempo de ejecución, plantilla

  2. Lógica fuera de cadena: función de transacción en cadena - subempaquetado y llamado en funciones auxiliares - fuera de cadena pasa parámetros y llama a funciones auxiliares

  3. Las transacciones iniciadas en el bloque actual se ejecutan en el bloque siguiente

Caso 8: Enviar una transacción sin firmar a la cadena

Objetivo

  1. No es necesario modificar el nodo (no configurar la cuenta para la tarifa de transacción de pago de la firma), solo es necesario modificar el tiempo de ejecución, los archivos de palet

  2. en su mayoría código repetitivo

  3. Aprenda macros#[pallet::validate_unsigned], TransactionValidity, ValidTransaction, asegurar_none, etc.

  4. No se recomienda enviar demasiadas transacciones sin firmar por bloque

cambiar configuración

sustrato-nodo-plantilla-case/runtime/src/lib.rs

++++use super::*;impl<C> frame_system::offchain::SendTransactionTypes<C> para RuntimewhereRuntimeCall: From<C>,{type Extrinsic = UncheckedExtrinsic;type OverarchingCall = RuntimeCall;}

sustrato-nodo-plantilla-case/pallets/template/Cargo.toml

[dependencias]--sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.30 " }log = { versión = "0.4.17", características predeterminadas = false }[características] predeterminadas = ["std"]std = [--"sp-runtime/std",]

sustrato-nodo-plantilla-case/pallets/template/src/lib.rs

use frame_system::offchain::{ SubmitTransaction,};use sp_runtime::{ transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},};
#[pallet::config]pub trait Config:frame_system::Config + frame_system::offchain::SendTransactionTypes<Call<Self>>{/// Debido a que esta paleta emite eventos, depende de la definición del tiempo de ejecución de un event.type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;}
#[pallet::call]impl<T: Config> Pallet<T> {--#[pallet::weight(0)]pub fn submit_data_unsigned(origen: OriginFor<T>, n: u64) -> DispatchResult {ensure_none (origen)?;log::info!("in submit_data_unsigned: {:?}", n);// Devolver un DispatchResultWithPostInfoOk(())}}#[palet::hooks]impl<T: Config> Exitoso <BlockNumberFor<T>> for Pallet<T> {fn offchain_worker(block_number: T::BlockNumber) {log::info!("¡Hola, mundo de los trabajadores fuera de la cadena!: {:?}", block_number);let value: u64 = 42;let call = Call::submit_data_unsigned { n: value };_ = SubmitTransaction::<T, Call<T>>::submit_unsigned_transaction(call.into()).map_err(|_| {log::error !("Error en offchain_unsigned_tx");},);log::info!("¡Salir de los trabajadores fuera de la cadena!: {:?}", block_number);}}#[pallet::validar_unsigned]impl<T: Config> ValidateUnsigned for Pallet<T> {type Call = Call<T>;fn validar_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {if let Call::submit_data_unsigned { n: _ } = llamar {//let provide = b"submit_xxx_unsigned".to_vec();ValidTransaction::with_tag_prefix("ExampleOffchainWorker").priority(10000).and_provides(1).longevity(3).propagate(true).build ()} else {InvalidTransaction::Call.into()}}}impl<T: Config> Pallet<T> {// 暂未写业务逻辑}with_tag_prefix("ExampleOffchainWorker").priority(10000).and_provides(1).longevity(3).propagate(true).build()} else {InvalidTransaction::Call.into()}}}impl<T: Config> Pallet<T> {// Lógica empresarial aún no escrita}with_tag_prefix("ExampleOffchainWorker").priority(10000).and_provides(1).longevity(3).propagate(true).build()} else {InvalidTransaction::Call.into()}}}impl<T: Config> Pallet<T> {// Lógica empresarial aún no escrita}

compilar y ejecutar

Como puede ver, hemos enviado con éxito la transacción sin firmar.

Para más casos, consulte la implementación oficial completa

https://github.com/paritytech/substrate/blob/master/frame/examples/offchain-worker/src/lib.rs

Caso 9: use la función de indexación fuera de la cadena para escribir datos de la cadena en el almacenamiento fuera de la cadena

En esta sección, usamos una implementación de casos relativamente completa, vea el código para más detalles:

https://github.com/shiyivei/substrate-advanced-course/tree/master/lesson4/backend/pallets/kitties

La versión branch = "polkadot-v0.9.30" es ligeramente diferente de la configuración branch = "polkadot-v0.9.28", pero la lógica es la misma. Esta parte del contenido se completará más adelante. He estado ocupado de nuevo recientemente. Bien, terminaremos con la introducción de trabajadores Offchain. ver siguiente tema

Supongo que te gusta

Origin blog.csdn.net/weixin_51487151/article/details/127523374
Recomendado
Clasificación