Using offchain::ipfs
from your Rust code
With substrate-subxt
In your Cargo.toml file
[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.5", default-features = false, features = ["derive"] }
substrate-subxt = "0.13.0"
sp-keyring = { version = "2.0.0", default-features = false }
async-std = { version = "1.6.4", features = ["attributes"] }
Then in your main.rs:
use codec::Encode;
use sp_keyring::AccountKeyring;
use substrate_subxt::{Call, ClientBuilder, EventsDecoder, NodeTemplateRuntime, PairSigner};
#[async_std::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Signer for the extrinsic
let signer = PairSigner::<NodeTemplateRuntime, _>::new(AccountKeyring::Alice.pair());
// API client, default to connect to 127.0.0.1:9944
let client = ClientBuilder::<NodeTemplateRuntime>::new().build().await?;
// Example CID for the example bytes added vec![1, 2, 3, 4]
let cid = String::from("QmRgctVSR8hvGRDLv7c5H7BCji7m1VXRfEE1vW78CFagD7").into_bytes();
// Example multiaddr to connect IPFS with
let multiaddr = String::from(
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
)
.into_bytes();
// Example Peer Id
let peer_id = String::from("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ").into_bytes();
// Begin to submit extrinsics
// ipfs_add_bytes
let add_bytes = client
.watch(
AddBytesCall {
data: vec![1, 2, 3, 4],
},
&signer,
)
.await?;
println!("\nResult for ipfs_add_bytes: {:?}", add_bytes);
// ipfs_cat_bytes
let cat_bytes = client
.watch(CatBytesCall { cid: cid.clone() }, &signer)
.await?;
data: Vec<u8>,
}
impl Call<NodeTemplateRuntime> for AddBytesCall {
const MODULE: &'static str = "TemplateModule";
const FUNCTION: &'static str = "ipfs_add_bytes";
fn events_decoder(_decoder: &mut EventsDecoder<NodeTemplateRuntime>) {}
}
#[derive(Encode)]
pub struct CatBytesCall {
cid: Vec<u8>,
}
With substrate-api-client
In your Cargo.toml file:
[dependencies]
substrate-api-client = { git = "https://github.com/scs/substrate-api-client.git" }
sp-core = { version = "2.0.0", features = ["full_crypto"] }
sp-keyring = { version = "2.0.0", default-features = false }
Then in your main.rs:
use sp_core::crypto::Pair;
use sp_keyring::AccountKeyring;
use std::{convert::TryFrom, string::String};
use substrate_api_client::{
compose_call, compose_extrinsic_offline, extrinsic::xt_primitives::UncheckedExtrinsicV4,
node_metadata::Metadata, Api, XtStatus,
};
fn main() {
// instantiate an Api that connects to the given address
let url = "127.0.0.1:9944";
// if no signer is set in the whole program, we need to give to Api a specific type instead of an associated type
// as during compilation the type needs to be defined.
let signer = AccountKeyring::Bob.pair();
// sets up api client and retrieves the node metadata
let api = Api::new(format!("ws://{}", url)).set_signer(signer.clone());
// gets the current nonce of Bob so we can increment it manually later
let mut nonce = api.get_nonce().unwrap();
// data from the node required in extrinsic
let meta = Metadata::try_from(api.get_metadata()).unwrap();
let genesis_hash = api.genesis_hash;
let spec_version = api.runtime_version.spec_version;
let transaction_version = api.runtime_version.transaction_version;
// Example bytes to add
let bytes_to_add: Vec<u8> = vec![1, 2, 3, 4];
// Example CID for the example bytes added vec![1, 2, 3, 4]
let cid = String::from("QmRgctVSR8hvGRDLv7c5H7BCji7m1VXRfEE1vW78CFagD7").into_bytes();
// Example multiaddr to connect IPFS with
let multiaddr = String::from(
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
)
.into_bytes();
// Example Peer Id
let peer_id = String::from("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ").into_bytes();
// Create input for all calls
let calls = vec![
("ipfs_add_bytes", bytes_to_add),
("ipfs_cat_bytes", cid.clone()),
("ipfs_connect", multiaddr.clone()),
("ipfs_insert_pin", cid.clone()),
for call in calls {
println!("\n Creating Extrinsic for {}", call.0);
let _call = compose_call!(meta, "TemplateModule", call.0, call.1);
let xt: UncheckedExtrinsicV4<_> = compose_extrinsic_offline!(
signer,
_call,
nonce,
Era::Immortal,
genesis_hash,
genesis_hash,
spec_version,
transaction_version
);
let blockh = api
.send_extrinsic(xt.hex_encode(), XtStatus::Finalized)
.unwrap();
println!("Transaction got finalized in block {:?}", blockh);
nonce += 1;
}
}
For full demo with all pallet functions, please visit here