1 什么是 数字身份标识与数字身份体系?
首先,让我们来看下什么是分布式数字身份标识(DID):

分布式数字标识符(DID)是一种新型标识符,用以标识可验证的分布式的数字身份。 DID的控制者决定标识的主体(例如,人,组织,事物,数据模型,抽象实体等)。

— W3C DID规范

围绕分布式数字身份标识,我们可以构建如下组件:

DID 文档——用以对该 DID 相关的地址、服务以及其它特性进行进一步的阐述。
可验证声明——通过可验证声明,DID 控制者可以发放、持有、验证电子证书与电子凭证。
选择型披露——结合隐私保护技术,DID 控制者可以在保障自己隐私的情况下,向需要的第三方选择性披露自己的数据,如证明自己的年龄大于 18 岁。
数据存证——将可信数据和 DID 进行挂钩,便完整的形成了「数字身份—数字凭证—数据存证」的体系,如「学生身份—毕业证书—课堂表现」。
这便是数字身份体系。

2 什么是 WeIdentity?
WeIdentity是一套分布式多中心的技术解决方案,可承载实体对象(人或者物)的现实身份与链上身份的可信映射、以及实现实体对象之间安全的访问授权与数据交换。WeIdentity由微众银行自主研发并完全开源,秉承公众联盟链整合资源、交换价值、服务公众的理念,致力于成为链接多个垂直行业领域的分布式商业基础设施,促进泛行业、跨机构、跨地域间的身份认证和数据合作。

WeIdentity 目前主要包含两大模块:WeIdentity DID 以及 WeIdentity Credential。

WeIdentity 参考场景:

3 WeIdentity DID规范
WeIdentity 对基本的 DID 规范进行了扩展处理。

基本的 DID 规范:

DID是一个简单的文本字符串,由三部分组成:
1)DID过的URI方案标识符(Scheme,固定就是 did)
2)DID方法的标识符(DID Method)
3)DID方法生成的标识符(DID Method-Specific Identifier)

扩展后的 WeIdentity:

字段    说明
did    遵循DID规范,使用固定字符“did”
weid    WeIdentity DID规范的method name字段,固定为“weid”
chain-id    链 ID,用于路由到不同的链网络(如果需要跟其他链打通,需要找 WeIdentity 开源项目的 owner 微众银行注册路由信息),例如同时使用 WeIdentity 的可能有多条区块链,可以使用这个字段作为标识信息,路由到特定区块链
bs-specific-string    基于底层区块链平台生成,代表Entity在链上的地址,保证全网唯一
备注:bsSpecificString根据区块链底层平台和业务具体情况来确定生成规则,例如可以是随机字符串,或者区块链上的地址。

示例(这个例子中,chain-id是101: "did:weid:101:0x0086eb1f712ebc6f1c276e12ec21"。

4 数据结构设计
在今天的实践中,我们希望可以把weid保存到本地数据库中。

我们这次选择的是 Sqlite 数据库,在Rust - ORM 选择上,我们选择的是 Diesel,这个项目有 6.8k Stars。

https://github.com/diesel-rs/diesel

Tips: 接触新库时,我们可以通过学习 Repo 中的 Examples,来掌握 Repo 的用法。

因为weid中,前半部分did:weid是不变的,所以我们只需保存chain_id和``bs-specific-string`即可。

在Rust中数据结构如下:

pub struct Weid {
    id: i32,
    chain_id: i32, //当然也可以同样设置为 String
    addr: String,

created_at: NaiveDateTime, // 创建时间
    updated_at: NaiveDateTime, // 更新时间
}
数据库的创建语句如下:

CREATE TABLE weids (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  addr TEXT NOT NULL,
  chain_id INTEGER, 
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
我们用标准规范创建数据库迁移文件夹migration:

migrations
└── 2020-05-13-105400_create_weids
    ├── down.sql
    └── up.sql
其中,up.sql的内容即是上面的内容:

CREATE TABLE weids (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  addr TEXT NOT NULL,
  chain_id INTEGER,
  created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
down.sql的内容就是移除weids表:

DROP TABLE weids;
5 数据库的创建与建表(Create&Migrate)
此处我们使用diesel使用的命令行工具。

(1)复制必要文件到项目目录下

从 Diesel 的代码仓库中 Clone 代码到本地。

https://github.com/diesel-rs/diesel

将 Repo 中的 diesel、diesel_cli、diesel_derives、diesel_migrations复制到项目根目录下。

在项目根目录下新建bin文件夹。

编译 Diesel Repo,将target/debug/diesel文件复制到bin目录下。

(2)配置环境变量

我们需要设置两个环境变量:

DATABASE_URL——数据库路径
BACKEND———数据库类型
直接执行如下命令即可:

export DATABASE_URL="examples.db"
export BACKEND="sqlite"
(3)创建数据库与建表

执行如下命令:

./bin/diesel database reset
顺利的话,会出现如下返回:
image.png

同时根目录下出现examples.db文件。

6 models.rs
我们在src目录下创建models.rs文件,在其中定义结构体Weid与NewWeid,定义 schema(模式)weids。

Scheme,可以简单的理解为我们告诉程序数据库中有哪些字段,这样程序才能顺利对接数据库。

models.rs:

use chrono::NaiveDateTime;
#[cfg(test)]
use diesel::debug_query;
use diesel::insert_into;
use diesel::prelude::*;
#[cfg(test)]
use diesel::sqlite::Sqlite;
use serde_derive::Deserialize;
use std::error::Error;

pub mod schema {
    diesel::table! {
        weids {
            id -> Integer,
            chain_id -> Integer,
            addr -> Text,

created_at -> Timestamp,
            updated_at -> Timestamp,
        }
    }
}

use schema::weids;

#[derive(Insertable)]
#[table_name = "weids"]
pub struct NewWeid {
    pub chain_id: i32,
    pub addr: String,
}

#[derive(Queryable, PartialEq, Debug)]
pub struct Weid {
    pub id: i32,
    pub chain_id: i32,
    pub addr: String,

pub created_at: NaiveDateTime,
    pub updated_at: NaiveDateTime, 
}

pub fn insert_default_values(conn: &SqliteConnection) -> QueryResult<usize> {
    use schema::weids::dsl::*;

insert_into(weids).default_values().execute(conn)
}
代码解析:

注: 以下内容对《Rust 程序设计语言(第一版)》有所参考。

https://kaisery.gitbooks.io/rust-book-chinese/content/content/Traits.html

trait 是一个告诉 Rust 编译器一个类型必须提供哪些功能语言特性。

例如,我们可以为结构体Circle实现HasArea这个trait:

struct Circle {
    x: f64,
    y: f64,
    radius: f64,
}

trait HasArea {
    fn area(&self) -> f64;
}

impl HasArea for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * (self.radius * self.radius)
    }
}
如你所见,trait块与impl看起来很像,不过我们没有定义一个函数体,只是函数标记。当我们impl一个trait时,我们使用impl Trait for Item,而不是仅仅impl Item。

重复的实现像Debug和Default这样的 trait 会变得很无趣。为此,Rust 提供了一个[属性](https://kaisery.gitbooks.io/rust-book-chinese/content/content/Attributes 属性.md)来允许我们让 Rust 为我们自动实现 trait:

#[derive(Debug)]
struct Foo;

fn main() {
    println!("{:?}", Foo);
}
Rust 1.15中引入了自定义derive特性,从而让derive有了更多的想象空间。

我们通过#[derive(Insertable)]与#[derive(Queryable, PartialEq, Debug)],让该结构体具备可插入数据库,或从数据库查询的特性。

7 main.rs
main.rs 的内容如下所示:

extern crate pretty_env_logger;

pub mod models;

use diesel::prelude::*;
use std::env;
use dotenv::dotenv;

use weid_light_client::WeIdRestService;
use models::*;

use models::schema::weids;
use models::schema::weids::dsl::*;

#[macro_use] extern crate log;

fn main(){
    pretty_env_logger::init();

// create data
    let sqlite_conn = establish_connection();
    create_weid(&sqlite_conn, 1, "34be11396f3a91c5Ab5A1220e756C6300FB2b20a");
    
    // query data
    let results = weids.load::<Weid>(&sqlite_conn)
        .expect("Error loading weids");
    // log weids
    info!("Displaying {} weids", results.len());
    for weid in results{
        info!("did:weid:{}:{}", weid.chain_id, weid.addr);
    }
}

pub fn establish_connection() -> SqliteConnection {
    dotenv().ok();

let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    SqliteConnection::establish(&database_url)
        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
}

pub fn create_weid(conn: &SqliteConnection, c_id: i32, address: &str) -> usize {

let new_weid = NewWeid {chain_id: c_id, addr: address.to_string()};

diesel::insert_into(weids::table)
        .values(&new_weid)
        .execute(conn)
        .expect("Error saving new weid")
}
代码解析:

establish_connection直接拷贝自 Diesel 的Examples,作用是根据环境变量中的DATABASE_URL连接sqlite数据库。

create_weid函数中,我们先创建一个 NewWeid 结构体对象,然后通过diesel::insert_into函数将新建的结构体对象插入数据库。

通过loads函数,我们从数据库中加载Weid结构体。

8 运行
执行RUST_LOG=trace cargo run。

我们成功向数据库插入一条 weid 数据,并读取 出weid 数据。

FISCO BCOS 生态中的数字身份组件 WeIdentity 用 Sqlite 存储 WeId | Rust 学习相关推荐

  1. 手把手教你实操部署FISCO BCOS联盟链(附每一步代码)

    感谢FISCO BCOS社区贡献者--刘海锋,贡献此文. 贡献无大小,分享永留传.谢谢你们的每一次贡献.最后,如果你也想成为Mr.FISCO BCOS,一起干出点改变世界,到老了可以跟孙辈们吹吹牛的事 ...

  2. FISCO BCOS 2022年度贡献者榜单

    平台践行开源共创的精神,FISCO BCOS开源社区致力打造开放多元的开源联盟链生态. 目前,社区已汇聚了超70000名社区用户,大家聚集于此碰撞观点.交流技术,围绕FISCO BCOS开发各类实用的 ...

  3. 1.平台介绍:FISCO BCOS 区块链

    引言: 区块链技术作为一种分布式.安全可信的数据记录和交互方式,正逐渐在各行各业展现出巨大潜力.然而,公共区块链的隐私性和性能限制使得企业更倾向于采用联盟链或私有链解决方案. FISCO BCOS(B ...

  4. 「区块链+数字身份」:DID 身份认证的新战场

    美国经济学家布莱恩 • 阿瑟在其著作<技术的本质>中,写过这么一句话:「技术总是进行着这样一种循环,为解决老问题去采用新技术,新技术又引发新问题,新问题的解决又要诉诸更新的技术」. 区块链 ...

  5. 「区块链+数字身份」:身份认证的新战场,让子弹再飞会儿

    作者:李小平 美国经济学家布莱恩•阿瑟在其著作<技术的本质>中,写过这么一句话:「技术总是进行着这样一种循环,为解决老问题去采用新技术,新技术又引发新问题,新问题的解决又要诉诸更新的技术」 ...

  6. 《2022 FISCO BCOS产业应用白皮书》共编邀请,期待您的参与

    重温五载来时路,逐梦宏图新起点.FISCO BCOS开源社区在大家的陪伴下走过了五年春秋.五年间,社区汇聚3000多家机构.7万多名开发者共建共治共享,成功支持了双碳.乡村振兴.金融.政务.医疗.司法 ...

  7. 感谢有你 | FISCO BCOS 2023年第一季度贡献榜单

    平台践行开源共创的精神,FISCO BCOS开源社区致力打造开放多元的开源联盟链生态. 通过多年深耕细作,FISCO BCOS开源生态圈已汇聚超过4000家企业及机构.9万余名个人成员,大家聚集于此碰 ...

  8. 感谢有你 | FISCO BCOS 2022年第二季度贡献榜单

    践行开源共创的精神,FISCO BCOS开源社区致力打造开放多元的开源联盟链生态. 目前,社区已汇聚了超70000名社区用户,大家聚集于此碰撞观点.交流技术,围绕FISCO BCOS开发各类实用的应用 ...

  9. FISCO BCOS 与 Fabric 之较

    起"底"联盟链:FISCO BCOS 与 Fabric 之较 一.理念:设计背景与发展路径的区别 二.应用:带给开发者不同的设计思路 三.跨链:关于通道和多链的比较 四.社区:成熟 ...

最新文章

  1. Label控件属性AssociatedControlID
  2. HTML5前端常见攻击方式案例讲解!
  3. JDBC链接MySQL和Oracle
  4. 词性标注与命名实体识别
  5. 骁龙820和KryoCPU:异构计算与定制计算的作用 【转】
  6. linux php 上级目录,Linux目录架构详解_php
  7. 【C语言进阶深度学习记录】二 有符号与无符号
  8. Linux 安装 配置 Maven
  9. windows 11屏幕保护程序配置教程——设置无效解决方案
  10. 计算机机房kvm系统配件,KVM设备在机房管理改造中的解决方案
  11. HTTP:实时消息推送
  12. android化学制图软件,虚拟化学实验室(Chemist)
  13. 【Android Studio】如果你不管怎么折腾都提示Minimum supported Gradle version is 7.0.2. Current version is 6.8,请看这里
  14. audio播放器进度条
  15. THUSC2021游记
  16. 通过Gazebo仿真学TurtleBot3(四)——简单的/cmd_vel控制
  17. Pose Estimation 入门理解
  18. 毕业论文字体字号格式要求
  19. 你知道CMA与CNAS的区别和联系是什么吗?
  20. 中科院计算机研究生推免面试,【中科院信工所学生兼职面试】研究生推免面试经验分享。-看准网...

热门文章

  1. 罗斯蒙特液位变送器选用的使用设定
  2. 张俊林:对比学习在微博内容表示的应用
  3. GDKOI2018 颓废记
  4. java结合ffmpeg实现多个视频截图,按时长平均分割截取固定数量
  5. 程序员福音!Win10下使用oh-my-zsh全攻略,让Win10开发更顺滑...
  6. 基于Springcloud搭建电商平台实现高性能高并发微服务
  7. 安徽大学计算机学院博士生导师,安徽大学计算机科学与技术学院博士生导师:张兆翔教授...
  8. 【玩转IDEA】那些年装过的idea插件,用了都说好
  9. Finding Nemo(中文译名:海底总动员)与中国教育
  10. 2014年国考行测错题集(省级)