I need to call extrinsic functions, for example utility -> batch(calls)
or utility -> batchAll(calls)
. Which library do I need to use for this?
I can't find those examples in the web.
Substrate and Polkadot Stack Exchange is a question and answer site for developers building blockchains with the Substrate SDK. It only takes a minute to sign up.
Sign up to join this communityI need to call extrinsic functions, for example utility -> batch(calls)
or utility -> batchAll(calls)
. Which library do I need to use for this?
I can't find those examples in the web.
If your making a rust program then using subtx crate might be your best bet:
https://github.com/paritytech/subxt
For example here is how to call the api:
let api = ClientBuilder::new()
.build()
.await?
.to_runtime_api::<polkadot::RuntimeApi<DefaultConfig, DefaultExtra<DefaultConfig>>>();
let mut iter = api.storage().system().account_iter(None).await?;
while let Some((key, account)) = iter.next().await? {
println!("{}: {}", hex::encode(key), account.data.free);
}
https://github.com/paritytech/subxt/blob/master/examples/examples/fetch_all_accounts.rs
The easiest way to do this is with JavaScript and using the Polkadot JS APIs.
An example for batching transactions can be found here:
// construct a list of transactions we want to batch
const txs = [
api.tx.balances.transfer(addrBob, 12345),
api.tx.balances.transfer(addrEve, 12345),
api.tx.staking.unbond(12345)
];
// construct the batch and send the transactions
api.tx.utility
.batch(txs)
.signAndSend(sender, ({ status }) => {
if (status.isInBlock) {
console.log(`included in ${status.asInBlock}`);
}
});
Besides the Polkadot JS APIs
, I would also recommend to use py-substrate-interface.
pip install substrate-interface
from substrateinterface import SubstrateInterface, Keypair
substrate = SubstrateInterface(url='ws://127.0.0.1:9944')
# or
# substrate = SubstrateInterface(url='wss://rpc.polkadot.io')
# substrate = SubstrateInterface(url='wss://kusama-rpc.polkadot.io')
alice = Keypair.create_from_uri('//Alice')
bob = Keypair.create_from_uri('//Bob')
# Transfer funds to Bob
call = substrate.compose_call(
call_module='Balances',
call_function='transfer',
call_params={
'dest': bob.ss58_address,
'value': 1 * 10**12
}
)
# Sign with Alice
extrinsic = substrate.create_signed_extrinsic(call=call, keypair=alice)
# Submit the txn
receipt = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)
print(f'Extrinsic: {extrinsic}')
print(f'Status : {receipt.is_success}')
There is a bunch of different Substrate client libraries in the Substrate documentation
Besides those referenced in the above link, there is also the Polkadot Java Client.
There are other ways to interact with a Substrate blockchain, depending on your needs, such as the Substrate Sidecar API.
This is how I do it in an external Rust project.
In this example, I have a pallet called Auditor
in my node, and a dispatchable function called claim_log
that can accept extrinsics.
I generate a signer first so that my extrinsic can be signed:
use substrate_api_client::{Api, compose_extrinsic, UncheckedExtrinsicV4, XtStatus};
use substrate_api_client::rpc::WsRpcClient;
.....
// Get the private key of the sender here
let from = AccountKeyring::Charlie.pair();
let api = Api::new(client).map(|api| api.set_signer(from)).unwrap();
Compose the extrinsic and sign it
let xt: UncheckedExtrinsicV4<_> = compose_extrinsic!(
api.clone(),
"Auditor",
"claim_log",
log_to_be_claimed.filename.to_string().into_bytes()
// TODO: maybe get the date here
);
I then submit the extrinsic to the node using this
let blockh = api.send_extrinsic(xt.hex_encode(), XtStatus::InBlock).unwrap();
I am utilizing this substrate project to perform my dispatchable functions that accept extrinsics: https://github.com/scs/substrate-api-client
There is also an option to call extrinsics natively without using libraries. Here is a working example.