Моя цель - записать значение в карту хранения Substrate, используя subst-api-client . Моя карта хранения, определенная в цепочке субстратов, выглядит следующим образом:
use frame_support::{decl_module, decl_storage, dispatch::result::Result, ensure, StorageMap};
use frame_system::ensure_signed;
use sp_runtime::DispatchError;
// pub trait Trait: balances::Trait {}
pub trait Trait: pallet_balances::Trait {}
decl_storage! {
trait Store for Module<T: Trait> as KittyStorage {
// Value: map T::Hash => Option<T::AccountId>;
// TODO: check whether this is the appropriate datatype(hash).
Value: map hasher(blake2_256) T::Hash => Option<T::AccountId>;
// Balances: map hasher(blake2_256) (T::AssetId, T::AccountId) => T::Balance;
}
}
decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
fn set_value(origin, value: T::Hash) -> Result<(), DispatchError> {
let sender = ensure_signed(origin)?;
ensure!(!<Value<T>>::contains_key(value), "key already exists");
<Value<T>>::insert(value, sender);
Ok(())
}
}
}
Приведенная выше карта хранения расположена по адресу:
substrate/bin/node/runtime/src/substratekitties.rs
Ожидаемый результат заключается в успешной записи значения в хранение субстрата. Как и во внешнем интерфейсе, успешно:
Однако при использовании substrate-api-client
для выполнения той же задачи я получаю следующую ошибку:
[2020-04-03T05:14:12Z ERROR substrate_api_client::rpc::client] ERROR: Object({"code": Number(1010), "data": String("BadProof"), "message": String("Invalid Transaction")})
Я попытался написать собственный пример extrinsi c в substrate-api-client
. Вот как я пишу extrinsi c:
let xt = compose_extrinsic!(
api.clone(),
"Substratekitties",
"set_value",
"0x0000000000000000000000000000000000000000000000000000000000000002"
);
Это минимальный код, необходимый для воспроизведения ошибки:
/*
Copyright 2019 Supercomputing Systems AG
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
//! This examples shows how to use the compose_extrinsic macro to create an extrinsic for any (custom)
//! module, whereas the desired module and call are supplied as a string.
use clap::{load_yaml, App};
use keyring::AccountKeyring;
use sp_core::crypto::Pair;
// use substrate_api_client::extrinsic::xt_primitives::UncheckedExtrinsicV4;
use substrate_api_client::{
compose_extrinsic, extrinsic::xt_primitives::UncheckedExtrinsicV4, Api,
};
// use crate::{compose_extrinsic, Api};
fn main() {
env_logger::init();
let url = get_node_url_from_cli();
// initialize api and set the signer (sender) that is used to sign the extrinsics
let from = AccountKeyring::Alice.pair();
let mut api = Api::new(format!("ws://{}", url)).set_signer(from);
// let signer = AccountKeyring::Alice.pair();
// api.signer = Some(signer);
// the names are given as strings
let xt = compose_extrinsic!(
api.clone(),
"Substratekitties",
"set_value",
"0x0000000000000000000000000000000000000000000000000000000000000002"
);
println!("[+] Composed Extrinsic:\n {:?}\n", xt);
// send and watch extrinsic until finalized
let signer = AccountKeyring::Alice.pair();
api.signer = Some(signer);
let tx_hash = api.send_extrinsic(xt.hex_encode()).unwrap();
println!("[+] Transaction got finalized. Hash: {:?}", tx_hash);
}
pub fn get_node_url_from_cli() -> String {
let yml = load_yaml!("../../src/examples/cli.yml");
let matches = App::from_yaml(yml).get_matches();
let node_ip = matches.value_of("node-server").unwrap_or("127.0.0.1");
let node_port = matches.value_of("node-port").unwrap_or("9944");
let url = format!("{}:{}", node_ip, node_port);
println!("Interacting with node on {}\n", url);
url
}
Приведенный выше код находится в файле: example_writing_file_hash.rs
и дерево:
substrate-api-client/src/examples/example_writing_file_hash.rs
, тогда как полная кодовая база доступна здесь .
Обновление 1
Согласно user13207835 s answer , я пытался объявить свой контент как ha sh, но не смог. PS Я новичок в Rust, Substrate.
let file_hash: Hash = "0x0000000000000000000000000000000000000000000000000000000000000002";
Получил ошибку:
error[E0308]: mismatched types; expected struct `primitive_types::H256`, found `&str`
Я понимаю эту ошибку, хотя я не знаю, как объявить вышеуказанное значение как Hash
как предложено в ответе.