You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Substrate中chain_specs.rs的Alice开发密钥如何添加到本地密钥库?

Substrate开发模式下密钥自动注入本地密钥库的实现逻辑

1. 创世配置阶段的密钥生成逻辑

你在chain_spec.rs中看到的authority_keys_from_seed("Alice")函数,作用是根据传入的种子派生当前Runtime中Session pallet注册的所有类型会话密钥的公钥,包括Aura、Grandpa、ImOnline等所有已声明的应用密钥类型,这些公钥最终会被写入创世存储的Session模块Keys项中,属于链上全局共识的初始权威配置,这一步并不会操作本地密钥库。

pub fn development_config() -> Result<ChainSpec, String> {
    let wasm_binary =
        WASM_BINARY.ok_or_else(|| "Development wasm binary not available".to_string())?;

    Ok(ChainSpec::from_genesis(
        // Name
        "Development",
        // ID
        "dev",
        ChainType::Development,
        move || {
            testnet_genesis(
                wasm_binary,
                // Initial PoA authorities
                vec![authority_keys_from_seed("Alice")],
                // Sudo account
                get_account_id_from_seed::<sr25519::Public>("Alice"),
                // Pre-funded accounts
                vec![
                    get_account_id_from_seed::<sr25519::Public>("Alice"),
                    get_account_id_from_seed::<sr25519::Public>("Bob"),
                    get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
                    get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
                ],
                true,
            )
        },
        // Bootnodes
        vec![],
        // Telemetry
        None,
        // Protocol ID
        None,
        // Properties
        None,
        // Extensions
        None,
    ))
}

2. 开发模式自动注入本地密钥的核心逻辑

本地密钥库的密钥注入是节点启动阶段的行为,当你使用--dev参数启动节点时,Substrate的CLI框架会识别到当前链规范的类型为ChainType::Development,会自动触发内置的测试密钥预注入逻辑:

  • 自动将Alice、Bob等通用测试账号的种子,派生所有应用类型的密钥对,插入到本地密钥库(内存密钥库或dev模式专属的文件密钥库)
  • 这个逻辑是Substrate CLI为了简化开发测试内置的,不需要额外编码配置,只要是开发链类型就会默认执行

3. Pallet中读取本地密钥的逻辑

你在im-online pallet中看到的T::AuthorityId::all()方法,是Substrate应用密钥trait AppCrypto的标准实现,它会直接从当前节点的密钥存储中,读取对应应用类型(此处为ImOnline的专属密钥类型ID)的所有公钥,因为开发模式启动时已经把Alice的ImOnline密钥对注入到本地密钥库,所以查询时可以直接获取到对应记录。

fn local_authority_keys() -> impl Iterator<Item=(u32, T::AuthorityId)> {
    // on-chain storage
    //
    // At index `idx`:
    // 1. A (ImOnline) public key to be used by a validator at index `idx` to send im-online
    //          heartbeats.
    let authorities = Keys::<T>::get();

    // local keystore
    //
    // All `ImOnline` public (+private) keys currently in the local keystore.
    let mut local_keys = T::AuthorityId::all();

    local_keys.sort();

    authorities.into_iter()
        .enumerate()
        .filter_map(move |(index, authority)| {
            local_keys.binary_search(&authority)
                .ok()
                .map(|location| (index as u32, local_keys[location].clone()))
        })
}

4. 自定义自动注入密钥的实现方法

如果你要为自定义的密钥类型实现类似的自动注入能力,可以直接修改节点启动的初始化逻辑:
在CLI的节点启动分支中,判断当前为开发/测试模式时,主动调用密钥库的插入接口写入预设测试密钥,示例代码如下:

// 示例:插入自定义应用类型的测试密钥到本地密钥库
// 自定义密钥类型的ID,需和Runtime中声明的应用ID一致
const MY_KEY_TYPE: sp_application_crypto::KeyTypeId = sp_application_crypto::KeyTypeId(*b"mykt");

// 节点初始化阶段执行
let keystore = node.keystore();
// 传入密钥类型ID、测试种子、对应公钥即可完成插入
keystore.insert(
    MY_KEY_TYPE,
    "Alice", // 测试种子
    &my_custom_key::Public::from_seed(&[0;32]).as_ref()
).expect("Insert test key failed");

内容的提问来源于stack exchange,提问作者Jdawg287

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:54:03