Rust分布式应用开发库holochain_types的使用:构建去中心化应用的数据类型与协议支持

Rust分布式应用开发库holochain_types的使用:构建去中心化应用的数据类型与协议支持

holochain_types是Holochain项目中的一个Rust库,它包含了其他Holochain crate使用的常见类型。这个库是对holochain_zome_types的补充,后者只包含在Holochain DNA代码中使用的基本类型,而holochain_types则扩展了这些类型,包含了Holochain本身依赖的所有类型。

重要说明

不建议在你的zomes中依赖这个crate,因为它不能保证可以编译为wasm32-unknown-unknown目标,即使可以,它也会引入许多不必要的依赖,导致你的Wasm文件膨胀。如果你确实需要在DNA中使用holochain_types中的某个类型,请在holochain仓库中提交问题说明原因,可以考虑将该类型移到holochain_zome_types中。

示例代码

以下是一个使用holochain_types构建去中心化应用的简单示例:

use holochain_types::{
    app::InstalledAppId,
    prelude::{AgentPubKey, ExternIO, FunctionName, ZomeName},
};

// 定义一个简单的去中心化应用结构
struct DecentralizedApp {
    app_id: InstalledAppId,
    agent_key: AgentPubKey,
}

impl DecentralizedApp {
    // 创建新应用
    fn new(app_id: &str, agent_key: AgentPubKey) -> Self {
        Self {
            app_id: InstalledAppId::from(app_id.to_string()),
            agent_key,
        }
    }

    // 调用zome函数
    fn call_zome_function(
        &self,
        zome_name: ZomeName,
        function_name: FunctionName,
        input: ExternIO,
    ) -> Result<ExternIO, String> {
        // 在实际应用中,这里会调用Holochain API
        // 以下仅为示例代码
        Ok(input)
    }
}

fn main() {
    // 创建代理密钥
    let agent_key = AgentPubKey::from_raw_32(vec![0; 32].try_into().unwrap());
    
    // 创建去中心化应用实例
    let app = DecentralizedApp::new("my_decentralized_app", agent_key);
    
    // 准备调用zome函数的输入
    let input = ExternIO::encode("Hello, Holochain!").unwrap();
    
    // 调用zome函数
    let result = app.call_zome_function(
        ZomeName::from("my_zome"),
        FunctionName::from("greet"),
        input,
    );
    
    println!("Zome function result: {:?}", result);
}

完整示例代码

以下是一个更完整的示例,展示了如何使用holochain_types构建一个简单的去中心化应用:

use holochain_types::{
    app::InstalledAppId,
    prelude::{AgentPubKey, ExternIO, FunctionName, ZomeName},
    dna::DnaFile,
    prelude::InstallAppPayload,
};
use std::path::Path;

// 去中心化应用管理器
struct DAppManager {
    installed_apps: Vec<DecentralizedApp>,
}

impl DAppManager {
    // 创建新的应用管理器
    fn new() -> Self {
        Self {
            installed_apps: Vec::new(),
        }
    }

    // 安装新应用
    fn install_app(&mut self, dna_path: &Path, app_id: &str) -> Result<(), String> {
        // 加载DNA文件
        let dna = DnaFile::load(dna_path).map_err(|e| e.to_string())?;
        
        // 创建代理密钥
        let agent_key = AgentPubKey::from_raw_32(vec![0; 32].try_into().unwrap());
        
        // 创建安装payload
        let payload = InstallAppPayload {
            installed_app_id: InstalledAppId::from(app_id.to_string()),
            agent_key: agent_key.clone(),
            dna: dna.into(),
            membrane_proofs: Vec::new(),
        };
        
        // 在实际应用中,这里会调用Holochain的安装API
        // 以下仅为示例代码
        
        // 创建并保存应用实例
        let app = DecentralizedApp::new(app_id, agent_key);
        self.installed_apps.push(app);
        
        Ok(())
    }
}

// 定义一个简单的去中心化应用结构
struct DecentralizedApp {
    app_id: InstalledAppId,
    agent_key: AgentPubKey,
}

impl DecentralizedApp {
    // 创建新应用
    fn new(app_id: &str, agent_key: AgentPubKey) -> Self {
        Self {
            app_id: InstalledAppId::from(app_id.to_string()),
            agent_key,
        }
    }

    // 调用zome函数
    fn call_zome_function(
        &self,
        zome_name: ZomeName,
        function_name: FunctionName,
        input: ExternIO,
    ) -> Result<ExternIO, String> {
        // 在实际应用中,这里会调用Holochain API
        // 以下仅为示例代码
        println!(
            "Calling zome '{}' function '{}' with input: {:?}",
            zome_name, function_name, input
        );
        Ok(input)
    }
}

fn main() -> Result<(), String> {
    // 创建应用管理器
    let mut manager = DAppManager::new();
    
    // 安装应用
    manager.install_app(Path::new("./my_app.dna"), "my_decentralized_app")?;
    
    // 获取刚安装的应用
    let app = manager.installed_apps.first().unwrap();
    
    // 准备调用zome函数的输入
    let input = ExternIO::encode("Hello, Holochain!").unwrap();
    
    // 调用zome函数
    let result = app.call_zome_function(
        ZomeName::from("my_zome"),
        FunctionName::from("greet"),
        input,
    )?;
    
    println!("Zome function result: {:?}", result);
    
    Ok(())
}

安装

在你的项目中运行以下Cargo命令:

cargo add holochain_types

或者在Cargo.toml中添加以下行:

holochain_types = "0.5.4"

许可证

Apache-2.0许可证

版权所有 © 2019 - 2024,Holochain Foundation

贡献

Holochain是一个开源项目。我们欢迎各种形式的参与,并积极扩大接受参与的领域。请参阅我们的贡献指南,了解我们关于参与社区的一般做法和协议,以及关于代码格式化、测试实践、持续集成等方面的具体期望。

联系方式

你可以在我们的论坛上与我们联系。


1 回复

Holochain Types库:构建去中心化应用的数据类型与协议支持

介绍

Holochain_types是Rust生态中用于开发分布式应用程序的核心库,它为Holochain框架提供了基础数据类型和协议支持。Holochain是一种去中心化应用开发框架,采用代理-centric架构而非区块链,特别适合需要高扩展性和自主性的分布式应用场景。

主要功能

  • 提供Holochain核心数据类型的Rust实现
  • 支持去中心化应用(DApp)开发的基础协议
  • 实现代理-centric通信的数据结构
  • 提供加密原语和哈希类型
  • 支持网络序列化和反序列化

使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
holochain_types = "0.2"

基础数据类型示例

use holochain_types::{
    dna::DnaDef,
    entry::Entry,
    header::Header,
    element::Element,
    signature::Signature,
};

// 创建DNA定义
let dna_def = DnaDef {
    name: "my_dapp".to_string(),
    uuid: "00000000-0000-0000-0000-000000000000".to_string(),
    // ...其他字段
};

// 创建条目(Entry)
let entry = Entry::App("example data".into());

// 创建头部(Header)
let header = Header::Create(Create {
    entry_type: "post".into(),
    entry_hash: "Qm...".into(),
    // ...其他字段
});

// 组合成元素(Element)
let element = Element::new(header, Some(entry));

代理和网络通信

use holochain_types::{
    agent::AgentPubKey,
    signal::Signal,
    network::WireMessage,
};

// 创建代理公钥
let agent_key = AgentPubKey::from_raw_32(vec![0; 32]);

// 创建信号
let signal = Signal::new(
    agent_key.clone(),
    "message_type".into(),
    "payload".into(),
);

// 创建网络消息
let wire_message = WireMessage::Signal(signal);

条目定义和验证

use holochain_types::{
    entry_def::EntryDef,
    validation::ValidationStatus,
};

// 定义条目结构
let entry_def = EntryDef {
    id: "post".to_string(),
    visibility: holochain_zome_types::EntryVisibility::Public,
    required_validations: 5,
    required_validation_type: Default::default(),
};

// 验证条目
let validation_status = ValidationStatus::Valid;

高级用法

自定义条目类型

use holochain_types::prelude::*;

#[derive(Serialize, Deserialize, Debug, SerializedBytes)]
struct CustomPost {
    title: String,
    content: String,
    author: AgentPubKey,
    timestamp: u64,
}

// 转换为Entry
let post = CustomPost {
    title: "Hello Holo".to_string(),
    content: "Building decentralized apps".to_string(),
    author: AgentPubKey::from_raw_32(vec![0; 32]),
    timestamp: 1672531200,
};

let entry = Entry::App(SerializedBytes::try_from(post).unwrap());

创建自定义验证规则

use holochain_types::validation::*;

fn validate_post(entry: Entry) -> ExternResult<ValidateCallbackResult> {
    match entry {
        Entry::App(bytes) => {
            let post: CustomPost = SerializedBytes::from(bytes).try_into()?;
            if post.title.len() > 100 {
                Ok(ValidateCallbackResult::Invalid("Title too long".to_string()))
            } else {
                Ok(ValidateCallbackResult::Valid)
            }
        }
        _ => Ok(ValidateCallbackResult::Invalid("Invalid entry type".to_string())),
    }
}

完整示例DEMO

下面是一个完整的Holochain应用示例,展示了如何使用holochain_types库创建自定义数据类型、定义验证规则以及处理网络通信:

use holochain_types::prelude::*;
use serde::{Serialize, Deserialize};

// 1. 定义自定义数据类型
#[derive(Serialize, Deserialize, Debug, SerializedBytes)]
struct BlogPost {
    title: String,
    content: String,
    author: AgentPubKey,
    created_at: u64,
    tags: Vec<String>,
}

// 2. 定义条目结构
let entry_def = EntryDef {
    id: "blog_post".to_string(),
    visibility: holochain_zome_types::EntryVisibility::Public,
    required_validations: 3,
    required_validation_type: Default::default(),
};

// 3. 创建验证函数
fn validate_blog_post(entry: Entry) -> ExternResult<ValidateCallbackResult> {
    match entry {
        Entry::App(bytes) => {
            let post: BlogPost = SerializedBytes::from(bytes).try_into()?;
            
            // 验证标题长度
            if post.title.is_empty() || post.title.len() > 120 {
                return Ok(ValidateCallbackResult::Invalid("Title must be 1-120 characters".to_string()));
            }
            
            // 验证内容长度
            if post.content.len() < 10 {
                return Ok(ValidateCallbackResult::Invalid("Content too short".to_string()));
            }
            
            Ok(ValidateCallbackResult::Valid)
        }
        _ => Ok(ValidateCallbackResult::Invalid("Invalid entry type".to_string())),
    }
}

// 4. 创建并处理博客文章
fn create_and_validate_post() -> ExternResult<()> {
    // 创建代理密钥
    let agent_key = AgentPubKey::from_raw_32(vec![1; 32]);
    
    // 创建博客文章
    let post = BlogPost {
        title: "Getting Started with Holochain".to_string(),
        content: "This is a comprehensive guide to building DApps with Holochain...".to_string(),
        author: agent_key.clone(),
        created_at: 1672531200,
        tags: vec!["holochain".to_string(), "dapp".to_string()],
    };
    
    // 转换为Entry
    let entry = Entry::App(SerializedBytes::try_from(post)?);
    
    // 验证条目
    let validation_result = validate_blog_post(entry.clone())?;
    
    match validation_result {
        ValidateCallbackResult::Valid => {
            println!("Post is valid!");
            
            // 创建头部
            let header = Header::Create(Create {
                entry_type: "blog_post".into(),
                entry_hash: "Qm...".into(),
                // ...其他字段
            });
            
            // 组合成元素
            let element = Element::new(header, Some(entry));
            
            // 创建信号通知网络
            let signal = Signal::new(
                agent_key,
                "new_post".into(),
                "New blog post created".into(),
            );
            
            let wire_message = WireMessage::Signal(signal);
            
            // 这里通常会发送wire_message到网络
            // send_to_network(wire_message);
            
            Ok(())
        },
        ValidateCallbackResult::Invalid(reason) => {
            println!("Post is invalid: {}", reason);
            Err(wasm_error!(WasmErrorInner::Guest(reason)))
        }
    }
}

注意事项

  1. Holochain_types库主要面向Holochain应用开发,需要配合Holochain运行时使用
  2. 数据类型设计遵循Holochain的确定性要求
  3. 序列化使用MessagePack格式
  4. 所有操作都是不可变的,修改操作会返回新实例

通过holochain_types库,开发者可以构建完全去中心化的应用程序,数据由用户设备本地存储和验证,而不依赖中心化服务器或全局共识机制。

回到顶部