mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-01 03:07:56 +00:00
Remove decoding bit from "extrinsics" and reference decoding in "blocks" (#951)
* Remove decoding bits from 'tx' and reference decoding in 'blocks' instead * newline * doc and fmt fixes
This commit is contained in:
@@ -1,99 +0,0 @@
|
||||
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! To run this example, a local polkadot node should be running. Example verified against polkadot v0.9.28-9ffe6e9e3da.
|
||||
//!
|
||||
//! E.g.
|
||||
//! ```bash
|
||||
//! curl "https://github.com/paritytech/polkadot/releases/download/v0.9.28/polkadot" --output /usr/local/bin/polkadot --location
|
||||
//! polkadot --dev --tmp
|
||||
//! ```
|
||||
|
||||
use futures::StreamExt;
|
||||
use sp_keyring::AccountKeyring;
|
||||
use std::time::Duration;
|
||||
use subxt::{tx::PairSigner, OnlineClient, PolkadotConfig};
|
||||
|
||||
#[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
pub mod polkadot {}
|
||||
|
||||
/// Subscribe to all events, and then manually look through them and
|
||||
/// pluck out the events that we care about.
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Create a client to use:
|
||||
let api = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
|
||||
// Subscribe to (in this case, finalized) blocks.
|
||||
let mut block_sub = api.blocks().subscribe_finalized().await?;
|
||||
|
||||
// While this subscription is active, balance transfers are made somewhere:
|
||||
tokio::task::spawn({
|
||||
let api = api.clone();
|
||||
async move {
|
||||
let signer = PairSigner::new(AccountKeyring::Alice.pair());
|
||||
let mut transfer_amount = 1_000_000_000;
|
||||
|
||||
// Make small balance transfers from Alice to Bob in a loop:
|
||||
loop {
|
||||
let transfer_tx = polkadot::tx()
|
||||
.balances()
|
||||
.transfer(AccountKeyring::Bob.to_account_id().into(), transfer_amount);
|
||||
api.tx()
|
||||
.sign_and_submit_default(&transfer_tx, &signer)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
transfer_amount += 100_000_000;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Get each finalized block as it arrives.
|
||||
while let Some(block) = block_sub.next().await {
|
||||
let block = block?;
|
||||
|
||||
let block_hash = block.hash();
|
||||
println!(" Block {:?}", block_hash);
|
||||
|
||||
// Ask for the extrinsics for this block.
|
||||
let extrinsics = block.body().await?.extrinsics();
|
||||
|
||||
let transfer_tx = extrinsics.find_first::<polkadot::balances::calls::types::Transfer>();
|
||||
println!(" Transfer tx: {:?}", transfer_tx);
|
||||
|
||||
// Ask for the extrinsics for this block.
|
||||
for extrinsic in extrinsics.iter() {
|
||||
let extrinsic = extrinsic?;
|
||||
|
||||
println!(
|
||||
" Extrinsic block index {:?}, pallet index {:?}, variant index {:?}",
|
||||
extrinsic.index(),
|
||||
extrinsic.pallet_index(),
|
||||
extrinsic.variant_index()
|
||||
);
|
||||
|
||||
let root_extrinsic = extrinsic.as_root_extrinsic::<polkadot::Call>();
|
||||
println!(" As root extrinsic {:?}\n", root_extrinsic);
|
||||
|
||||
let pallet_extrinsic = extrinsic
|
||||
.as_pallet_extrinsic::<polkadot::runtime_types::pallet_balances::pallet::Call>();
|
||||
println!(
|
||||
" Extrinsic as Balances Pallet call: {:?}\n",
|
||||
pallet_extrinsic
|
||||
);
|
||||
|
||||
let call = extrinsic.as_extrinsic::<polkadot::balances::calls::types::Transfer>()?;
|
||||
println!(
|
||||
" Extrinsic as polkadot::balances::calls::Transfer: {:?}\n\n",
|
||||
call
|
||||
);
|
||||
}
|
||||
|
||||
println!("\n");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -31,8 +31,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let events = ext.events().await?;
|
||||
let bytes_hex = format!("0x{}", hex::encode(ext.bytes()));
|
||||
|
||||
// See the API docs for more ways to decode extrinsics:
|
||||
let decoded_ext = ext.as_root_extrinsic::<polkadot::Call>();
|
||||
|
||||
println!(" Extrinsic #{idx}:");
|
||||
println!(" Bytes: {bytes_hex}");
|
||||
println!(" Decoded: {decoded_ext:?}");
|
||||
println!(" Events:");
|
||||
|
||||
for evt in events.iter() {
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
//! accounts, Alice to Bob:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../examples/examples/balance_transfer_basic.rs")]
|
||||
#![doc = include_str!("../../../examples/examples/tx_basic.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! This example assumes that a Polkadot node is running locally (Subxt endeavors to support all
|
||||
@@ -81,7 +81,7 @@
|
||||
//! Once Subxt is configured, the next step is interacting with a node. Follow the links
|
||||
//! below to learn more about how to use Subxt for each of the following things:
|
||||
//!
|
||||
//! - [Extrinsics](usage::extrinsics): Subxt can build and submit extrinsics, wait until they are in
|
||||
//! - [Transactions](usage::transactions): Subxt can build and submit transactions, wait until they are in
|
||||
//! blocks, and retrieve the associated events.
|
||||
//! - [Storage](usage::storage): Subxt can query the node storage.
|
||||
//! - [Events](usage::events): Subxt can read the events emitted for recent blocks.
|
||||
|
||||
@@ -35,18 +35,17 @@
|
||||
//!
|
||||
//! Defining some custom config based off the default Substrate config:
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/setup_client_custom_config.rs")]
|
||||
//! ```
|
||||
//! Writing a custom [`crate::rpc::RpcClientT`] implementation:
|
||||
//!
|
||||
//! Writing a custom [`crate::rpc::RpcClientT`] implementation:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/setup_client_custom_rpc.rs")]
|
||||
//! ```
|
||||
//! Creating an [`crate::OfflineClient`]:
|
||||
//!
|
||||
//! Creating an [`crate::OfflineClient`]:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/setup_client_offline.rs")]
|
||||
|
||||
@@ -24,14 +24,14 @@
|
||||
//! - [events](crate::blocks::Block::events())
|
||||
//! - [runtime APIs](crate::blocks::Block::runtime_api())
|
||||
//!
|
||||
//! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and
|
||||
//! decode the extrinsics in a block body.
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! Given a block, you can [download the block body](crate::blocks::Block::body()) and iterate over
|
||||
//! the extrinsics stored within it using [`crate::blocks::BlockBody::extrinsics()`].
|
||||
//!
|
||||
//! Here's an example in which we subscribe to blocks and print a bunch of information about each
|
||||
//! one:
|
||||
//!
|
||||
//! the extrinsics stored within it using [`crate::blocks::BlockBody::extrinsics()`]. From there, you
|
||||
//! can decode the extrinsics and access various details, including the associated events:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/blocks_subscribing.rs")]
|
||||
|
||||
@@ -48,12 +48,11 @@
|
||||
//!
|
||||
//! Here's an example using a static query:
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/constants_static.rs")]
|
||||
//! ```
|
||||
//! And here's one using a dynamic query:
|
||||
//!
|
||||
//! And here's one using a dynamic query:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/constants_dynamic.rs")]
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
//! keep a snapshot of the state at a small number of previous blocks, so you can sometimes access
|
||||
//! older events by using [`crate::events::EventsClient::at()`] and providing an older block hash.
|
||||
//!
|
||||
//! When we submit extrinsics using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`]
|
||||
//! When we submit transactions using Subxt, methods like [`crate::tx::TxProgress::wait_for_finalized_success()`]
|
||||
//! return [`crate::blocks::ExtrinsicEvents`], which can be used to iterate and inspect the events produced
|
||||
//! for a specific extrinsic. We can also access _all_ of the events produced in a single block using one of these
|
||||
//! two interfaces:
|
||||
//! by that transaction being executed. We can also access _all_ of the events produced in a single block using one
|
||||
//! of these two interfaces:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[tokio::main]
|
||||
@@ -43,7 +43,6 @@
|
||||
//!
|
||||
//! Here's an example which puts this all together:
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/events.rs")]
|
||||
//! ```
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
//! This modules contains examples of using Subxt; follow the links for more:
|
||||
//!
|
||||
//! - [Extrinsics](extrinsics)
|
||||
//! - [Transactions](transactions)
|
||||
//! - [Storage](storage)
|
||||
//! - [Events](events)
|
||||
//! - [Constants](constants)
|
||||
@@ -16,6 +16,6 @@
|
||||
pub mod blocks;
|
||||
pub mod constants;
|
||||
pub mod events;
|
||||
pub mod extrinsics;
|
||||
pub mod runtime_apis;
|
||||
pub mod storage;
|
||||
pub mod transactions;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//! # Runtime API interface
|
||||
//!
|
||||
//! The Runtime API interface allows Subxt to call runtime APIs exposed by certain pallets in order
|
||||
//! to obtain information. Much like [`super::storage`] and [`super::extrinsics`], Making a runtime
|
||||
//! to obtain information. Much like [`super::storage`] and [`super::transactions`], Making a runtime
|
||||
//! call to a node and getting the response back takes the following steps:
|
||||
//!
|
||||
//! 1. [Constructing a runtime call](#constructing-a-runtime-call)
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
//! # Storage
|
||||
//!
|
||||
//! A Substrate based chain has storage, whose values are determined by the extrinsics added to past
|
||||
//! blocks. Subxt allows you to query the storage of a node, which consists of the following steps:
|
||||
//! A Substrate based chain can be seen as a key/value database which starts off at some initial
|
||||
//! state, and is modified by the extrinsics in each block. This database is referred to as the
|
||||
//! node storage. With Subxt, you can query this key/value storage with the following steps:
|
||||
//!
|
||||
//! 1. [Constructing a storage query](#constructing-a-storage-query).
|
||||
//! 2. [Submitting the query to get back the associated values](#submitting-it).
|
||||
@@ -73,33 +74,33 @@
|
||||
//! [`crate::storage::Storage::fetch()`] or [`crate::storage::Storage::fetch_or_default()`] (the
|
||||
//! latter will only work for storage queries that have a default value when empty):
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/storage_fetch.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! For completeness, below is an example using a dynamic query instead. The return type from a
|
||||
//! dynamic query is a [`crate::dynamic::DecodedValueThunk`], which can be decoded into a
|
||||
//! [`crate::dynamic::Value`], or else the raw bytes can be accessed instead.
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/storage_fetch_dynamic.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ### Iterating storage entries
|
||||
//!
|
||||
//! Many storage entries are maps of values; as well as fetching individual values, it's possible to
|
||||
//! iterate over all of the values stored at that location:
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/storage_iterating.rs")]
|
||||
//! ```
|
||||
//! Here's the same logic but using dynamically constructed values instead:
|
||||
//!
|
||||
//! Here's the same logic but using dynamically constructed values instead:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/storage_iterating_dynamic.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ### Advanced
|
||||
//!
|
||||
//! For more advanced use cases, have a look at [`crate::storage::Storage::fetch_raw`] and
|
||||
|
||||
@@ -2,35 +2,35 @@
|
||||
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
|
||||
// see LICENSE for license details.
|
||||
|
||||
//! # Extrinsics
|
||||
//! # Transactions
|
||||
//!
|
||||
//! Extrinsics define function calls and their parameters, and are the only way that you can change
|
||||
//! the state of the blockchain. Submitting extrinsics to a node is one of the core features of
|
||||
//! Subxt, and generally consists of the following steps:
|
||||
//! A transaction is an extrinsic that's signed (ie it originates from a given address). The purpose
|
||||
//! of extrinsics is to modify the node storage in a deterministic way, and so being able to submit
|
||||
//! transactions to a node is one of the core features of Subxt.
|
||||
//!
|
||||
//! 1. [Constructing an extrinsic payload to submit](#constructing-an-extrinsic-payload).
|
||||
//! > Note: the documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably;
|
||||
//! > An extrinsic is some data that can be added to a block, and is either signed (a _transaction_)
|
||||
//! > or unsigned (an _inherent_). Subxt can construct either, but overwhelmingly you'll need to
|
||||
//! > sign the payload you'd like to submit.
|
||||
//!
|
||||
//! Submitting a transaction to a node consists of the following steps:
|
||||
//!
|
||||
//! 1. [Constructing a transaction payload to submit](#constructing-a-transaction-payload).
|
||||
//! 2. [Signing it](#signing-it).
|
||||
//! 3. [Submitting it (optionally with some additional parameters)](#submitting-it).
|
||||
//!
|
||||
//! We'll look at each of these steps in turn.
|
||||
//!
|
||||
//! > As a side note, an _extrinsic_ is anything that can be added to a block, and a _transaction_
|
||||
//! > is an extrinsic that is submitted from a particular user (and is therefore also signed). Subxt
|
||||
//! > can construct unsigned extrinsics, but overwhelmingly you'll need to sign them, and so the
|
||||
//! > documentation tends to use the terms _extrinsic_ and _transaction_ interchangeably.
|
||||
//! ## Constructing a transaction payload
|
||||
//!
|
||||
//! Furthermore, Subxt is capable of decoding extrinsics included in blocks.
|
||||
//!
|
||||
//! ## Constructing an extrinsic payload
|
||||
//!
|
||||
//! We can use the statically generated interface to build extrinsic payloads:
|
||||
//! We can use the statically generated interface to build transaction payloads:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! #[subxt::subxt(runtime_metadata_path = "../artifacts/polkadot_metadata.scale")]
|
||||
//! pub mod polkadot {}
|
||||
//!
|
||||
//! let remark = "Hello there".as_bytes().to_vec();
|
||||
//! let extrinsic_payload = polkadot::tx().system().remark(remark);
|
||||
//! let tx_payload = polkadot::tx().system().remark(remark);
|
||||
//! ```
|
||||
//!
|
||||
//! > If you're not sure what types to import and use to build a given payload, you can use the
|
||||
@@ -38,13 +38,13 @@
|
||||
//! > interface.rs`, to see what types and things are available (or even just to use directly
|
||||
//! > instead of the [`#[subxt]`](crate::subxt) macro).
|
||||
//!
|
||||
//! Alternately, we can dynamically construct an extrinsic payload. This will not be type checked or
|
||||
//! Alternately, we can dynamically construct a transaction payload. This will not be type checked or
|
||||
//! validated until it's submitted:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use subxt::dynamic::Value;
|
||||
//!
|
||||
//! let extrinsic_payload = subxt::dynamic::tx("System", "remark", vec![
|
||||
//! let tx_payload = subxt::dynamic::tx("System", "remark", vec![
|
||||
//! Value::from_bytes("Hello there")
|
||||
//! ]);
|
||||
//! ```
|
||||
@@ -53,7 +53,7 @@
|
||||
//! represents any type of data that can be SCALE encoded or decoded. It can be serialized,
|
||||
//! deserialized and parsed from/to strings.
|
||||
//!
|
||||
//! A valid extrinsic payload is just something that implements the [`crate::tx::TxPayload`] trait;
|
||||
//! A valid transaction payload is just something that implements the [`crate::tx::TxPayload`] trait;
|
||||
//! you can implement this trait on your own custom types if the built-in ones are not suitable for
|
||||
//! your needs.
|
||||
//!
|
||||
@@ -96,21 +96,21 @@
|
||||
//! // Create client:
|
||||
//! let client = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
//!
|
||||
//! // Create a dummy extrinsic payload to sign:
|
||||
//! // Create a dummy tx payload to sign:
|
||||
//! let payload = subxt::dynamic::tx("System", "remark", vec![
|
||||
//! Value::from_bytes("Hello there")
|
||||
//! ]);
|
||||
//!
|
||||
//! // Construct the extrinsic but don't sign it. You need to provide the nonce
|
||||
//! // Construct the tx but don't sign it. You need to provide the nonce
|
||||
//! // here, or can use `create_partial_signed` to fetch the correct nonce.
|
||||
//! let partial_extrinsic = client.tx().create_partial_signed_with_nonce(
|
||||
//! let partial_tx = client.tx().create_partial_signed_with_nonce(
|
||||
//! &payload,
|
||||
//! 0,
|
||||
//! Default::default()
|
||||
//! )?;
|
||||
//!
|
||||
//! // Fetch the payload that needs to be signed:
|
||||
//! let signer_payload = partial_extrinsic.signer_payload();
|
||||
//! let signer_payload = partial_tx.signer_payload();
|
||||
//!
|
||||
//! // ... At this point, we can hand off the `signer_payload` to be signed externally.
|
||||
//! // Ultimately we need to be given back a `signature` (or really, anything
|
||||
@@ -123,9 +123,9 @@
|
||||
//! # signature = signer.sign(&signer_payload);
|
||||
//! # address = signer.address();
|
||||
//!
|
||||
//! // Now we can build an extrinsic, which one can call `submit` or `submit_and_watch`
|
||||
//! // Now we can build an tx, which one can call `submit` or `submit_and_watch`
|
||||
//! // on to submit to a node and optionally watch the status.
|
||||
//! let extrinsic = partial_extrinsic.sign_with_address_and_signature(
|
||||
//! let tx = partial_tx.sign_with_address_and_signature(
|
||||
//! &address,
|
||||
//! &signature
|
||||
//! );
|
||||
@@ -135,7 +135,7 @@
|
||||
//!
|
||||
//! ## Submitting it
|
||||
//!
|
||||
//! Once we are able to sign the extrinsic, we need to submit it.
|
||||
//! Once we have signed the transaction, we need to submit it.
|
||||
//!
|
||||
//! ### The high level API
|
||||
//!
|
||||
@@ -146,21 +146,20 @@
|
||||
//! into a finalized block, check for an `ExtrinsicSuccess` event, and then hand back the events for
|
||||
//! inspection. This looks like:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/tx_basic.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! ### Providing transaction parameters
|
||||
//!
|
||||
//! If you'd like to provide parameters (such as mortality) to the transaction, you can use
|
||||
//! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/balance_transfer_basic.rs")]
|
||||
#![doc = include_str!("../../../../examples/examples/tx_with_params.rs")]
|
||||
//! ```
|
||||
//! ### Providing extrinsic parameters
|
||||
//!
|
||||
//! If you'd like to provide extrinsic parameters (such as mortality), you can use
|
||||
//! [`crate::tx::TxClient::sign_and_submit_then_watch`] instead, and provide parameters for your
|
||||
//! chain:
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/balance_transfer_with_params.rs")]
|
||||
//! ```
|
||||
//! This example doesn't wait for the extrinsic to be included in a block; it just submits it and
|
||||
//! This example doesn't wait for the transaction to be included in a block; it just submits it and
|
||||
//! hopes for the best!
|
||||
//!
|
||||
//! ### Custom handling of transaction status updates
|
||||
@@ -168,57 +167,10 @@
|
||||
//! If you'd like more control or visibility over exactly which status updates are being emitted for
|
||||
//! the transaction, you can monitor them as they are emitted and react however you choose:
|
||||
//!
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/balance_transfer_status_stream.rs")]
|
||||
#![doc = include_str!("../../../../examples/examples/tx_status_stream.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! Take a look at the API docs for [`crate::tx::TxProgress`], [`crate::tx::TxStatus`] and
|
||||
//! [`crate::tx::TxInBlock`] for more options.
|
||||
//!
|
||||
//! ## Decoding Extrinsics
|
||||
//!
|
||||
//! The block body is made up of extrinsics representing the generalization of the concept of transactions.
|
||||
//! Extrinsics can contain any external data the underlying chain wishes to validate and track.
|
||||
//!
|
||||
//! The process of decoding extrinsics generally involves the following steps:
|
||||
//!
|
||||
//! 1. Retrieve a block from the chain: This can be done directly by providing a specific hash using [crate::blocks::BlocksClient::at()]
|
||||
//! and [crate::blocks::BlocksClient::at_latest()], or indirectly by subscribing to the latest produced blocks of the chain using
|
||||
//! [crate::blocks::BlocksClient::subscribe_finalized()].
|
||||
//!
|
||||
//! 2. Fetch the block's body using [crate::blocks::Block::body()].
|
||||
//!
|
||||
//! 3. Obtain the extrinsics from the block's body using [crate::blocks::BlockBody::extrinsics()].
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # #[tokio::main]
|
||||
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! use subxt::client::OnlineClient;
|
||||
//! use subxt::config::PolkadotConfig;
|
||||
//!
|
||||
//! // Create client:
|
||||
//! let client = OnlineClient::<PolkadotConfig>::new().await?;
|
||||
//!
|
||||
//! // Get the lastest block (or use .at() to specify a block hash):
|
||||
//! let block = client.blocks().at_latest().await?;
|
||||
//!
|
||||
//! // Get the block's body which contains the extrinsics.
|
||||
//! let body = block.body().await?;
|
||||
//!
|
||||
//! // Fetch the extrinsics of the block's body.
|
||||
//! let extrinsics = block.body().await?.extrinsics();
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! Once the extrinsics are loaded, similar to events, you can iterate through the extrinsics or search for specific extrinsics using methods
|
||||
//! such as [crate::blocks::Extrinsics::iter()] and [crate::blocks::Extrinsics::find()]. For more information, refer to [crate::blocks::ExtrinsicDetails].
|
||||
//!
|
||||
//! ### Example
|
||||
//!
|
||||
//! Here's an example that demonstrates the usage of these concepts:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../../../examples/examples/block_extrinsics.rs")]
|
||||
//! ```
|
||||
//!
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
//! Subxt is a library for interacting with Substrate based nodes. Using it looks something like this:
|
||||
//!
|
||||
//! ```rust,ignore
|
||||
#![doc = include_str!("../../examples/examples/balance_transfer_basic.rs")]
|
||||
#![doc = include_str!("../../examples/examples/tx_basic.rs")]
|
||||
//! ```
|
||||
//!
|
||||
//! Take a look at [the Subxt guide](book) to learn more about how to use Subxt.
|
||||
|
||||
Reference in New Issue
Block a user