目录
目录README.md

Xuperchain

xuperchain的安装和配置

环境配置

  • 操作系统: ubuntu18.04
  • 编译需求: gcc4.8.x及以上,Go1.12.x及以上

确保安装且配置了gcc和go的环境变量后再进行下面的操作.

构建

git clone https://github.com/xuperchain/xuperchain

编译

cd xuperchain  
make

单机版xchain创建

cd ./output
bash ./control.sh start 
./bin/xchain-cli status

xuperchain单机模拟存证过程

在确保进行了上面的单机版xchain创建后执行以下步骤。

创建一个能够接受交易的中心化账户

1. 创建账户 ./bin/xchain-cli account newkeys --output ./data/superkeys
2. 得到该账户的地址 cat data/superkeys/address
3. 向该账户转账1000 ./bin/xchain-cli transfer --to iffqrfJmidknCSTBt91rAjJQRVPfzVj8k(上一步输出的地址) --amount 1000 
4. 查询确认该账户余额 ./bin/xchain-cli account balance iffqrfJmidknCSTBt91rAjJQRVPfzVj8k

创建一个普通用户

1. 创建账户 ./bin/xchain-cli account newkeys --output ./data/superkeys
2. 得到该账户的地址 cat data/superkeys/address

用户购买存证次数
购买的本质是将货币(如RMB)转化为区块链余额。

  • 在用户付出一定货币后,用super账户向user账户中转账1(个)存证次数,记下交易ID,作为发货证明。
1. 在线付款
2. 增加次数 ./bin/xchain-cli transfer --to g3DAtJtLgpMQrsTHKnKwRRVBfpT3iaFFT --amount 1 --keys data/superkeys 
3. 验证super账户是否少了1 ./bin/xchain-cli account balance iffqrfJmidknCSTBt91rAjJQRVPfzVj8k
4. 验证user账户是否多了1 ./bin/xchain-cli account balance g3DAtJtLgpMQrsTHKnKwRRVBfpT3iaFFT

准备一个需要上传的文件并且根据加密算法得到文件哈希值

  • hello.txt内容
luochensama
  • 计算哈希值
md5sum hello.txt
  • 准备上链文档
{    "file_hash" : "4d1ce57c78cd11bf44eaafb5bf37c9ab",    "file_name" : "hello",    "file_author" : "luochensama"}

上传存证

  • 使用user账户向super账户转账1,并在desc里表明存证内容,记下交易ID,作为存证证明和查看记录
1.转账并上传存证 ./bin/xchain-cli transfer --to iffqrfJmidknCSTBt91rAjJQRVPfzVj8k --amount 1 --keys data/luochen --desc /home/luochensama/hello_evidence.txt2. 查询信息 ./bin/xchain-cli tx query 2d9751e7823be469afc7a4fee40afb2f0c04788cff7bd1eb4d05395fae6a3ac0(上一步获得的交易id)得到的结果(一部分):  "desc": "{\n\t\"file_hash\" : \"4d1ce57c78cd11bf44eaafb5bf37c9ab\",\n\t\"file_name\" : \"hello\",\n\t\"file_author\" : \"luochensama\"\n}\n",

Rust代替命令行进行操作

以下操作需要的Xuperchain环境为github最新版本的Xuperchain

环境配置

  • Rust

    按照官方文档中的教程安装好Rust环境并且安装Clion IDE后进行下列步骤。

    首先把xuperchain的工具加入到Linux环境中,以Ubuntu为例:

    # 编辑 .bashrcsudo gedit ~/.bashrc# .bashrc 末尾加入export PATH=$PATH:/home/luochensama/xuperchain/output/bin# 使环境变量生效source ~/.bashrc

    将xuperchain的工具添加到Clion运行环境中:点击run->edit configurations,添加xupchain的工具到Environment variables中

    xchain=/home/luochensama/xuperchain/output/bin/xchain;xchain-cli=/home/luochensama/xuperchain/output/bin/xchain-cli;

    此外还需要将output目录下的 conf 文件夹放到Rust Project下。

在某些业务逻辑中,可能需要服务器自动定时地进行存证的过程,Rust能够便捷的实现这个过程。

Sample

现在有这样一个业务环境:硬件设备会采集实时的温湿度数据,并且将这些数据定时的上传到我们的区块链上。

采集数据的源码:

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>

#define MAX_SEN     200
#define MAX_REC        200
#define SERPORT     5675

void write_data_to_file(const char *path, char *str)
{
    FILE *fd = fopen(path, "a+");
    if (fd == NULL) 
    {
        printf("fd is NULL and open file fail\n");
        return;
    }
    printf("fd != NULL\n");
    if (str && str[0] != 0) 
    {
        fwrite(str, strlen(str), 1, fd);
        char *next = "\n";
        fwrite(next, strlen(next), 1, fd);
    }
    fclose(fd);
}

int main(void)
{
        char *path = "/home/luochensama/udplog.txt";
        int s_fd = -1, ret = -1;
        //char ser_senbuf[MAX_SEN] = "hello"; 
        char cli_recbuf[MAX_REC]; 
        
        struct sockaddr_in ser_sin = {0};
        struct sockaddr_in ser_cin = {0};
        socklen_t addr_len;
            char ipbuf[INET_ADDRSTRLEN];
        
        s_fd = socket(AF_INET,SOCK_DGRAM,0);
        if (s_fd == -1 )
        {
            perror("socket");
            return -1;
        }
        printf("s_fd = %d.\n", s_fd);
            
        bzero(&ser_sin,sizeof(ser_sin)); 
        ser_sin.sin_family = AF_INET;        
        ser_sin.sin_addr.s_addr = INADDR_ANY;
        ser_sin.sin_port = htons(SERPORT);    
        ret = bind(s_fd, (const struct sockaddr *)&ser_sin, sizeof(ser_sin));  
        if (ret < 0)
        {
            perror("bind");
            return -1;
        }
        printf("bind success.\n");
    while(1)
    {
        addr_len = sizeof(ser_cin);
        ret = recvfrom(s_fd, cli_recbuf, MAX_REC, 0, (struct sockaddr *)&ser_cin, &addr_len);
        printf("服务器成功接收了%d个字节\n", ret);
        printf("服务器接收的内容是:%s\n", cli_recbuf);
        
        inet_ntop(AF_INET, &ser_cin.sin_addr, ipbuf,sizeof(ipbuf));
        printf("ip地址是:%s\n", ipbuf);
        write_data_to_file(path, cli_recbuf);
    
    }
    return 0;
}

上述程序将采集到的数据存储到 udplog.txt 中,接下来将这个文件定时存证。

上传数据的源码:

use std::process::Command;
use std::thread;
use std::time;
use blake2::{Blake2b, Digest};
use std::{fs, io};
use std::path::Path;
use std::fmt::Write;
use std::fs::File;
use std::io::Write as wri;

fn main(){
    let str1 = r#"{
    "file_hash" : ""#;
    let str2 = r#"",
    "file_name" : "udplog.txt",
    "file_author" : "luochensama"
}"#;
    for _i in 0..10 {
        // 自定义业务逻辑
        let path = Path::new("/home/luochensama/udplog.txt");
        let mut file = fs::File::open(&path).unwrap();
        let mut hasher = Blake2b::new();
        let n = io::copy(&mut file, &mut hasher).unwrap();
        let hash = hasher.finalize();
        let u8vec : [u8; 64]= hash.as_slice().try_into().expect("What?");
        let mut str = String::new();
        for i in u8vec.iter(){
            write!(str, "{:02x}", i);
        }
        let fstr = str1.to_owned() + &str + str2;
        let writepath = Path::new("/home/luochensama/evidence.txt");
        let mut mfile = File::create(&writepath).unwrap();
        mfile.write_all(fstr.as_bytes());

        // 自定义命令行
        let output = Command::new("xchain-cli")
            .arg(r"transfer")
            .arg(r"--to")
            .arg(r"iDoLaraQyoLoubRwACtKYahBUs37SjEUw")
            .arg(r"--amount")
            .arg(r"1")
            .arg(r"--keys")
            .arg(r"/home/luochensama/xuperchain/output/data/luochen")
            .arg(r"--desc")
            .arg(r"/home/luochensama/evidence.txt")
            .output().unwrap_or_else(|e| {
            panic!("failed to execute process: {}", e)
        });
        if output.status.success() {
            let s = String::from_utf8_lossy(&output.stdout);

            print!("upload succeeded and message was:\n{}", s);
        } else {
            let s = String::from_utf8_lossy(&output.stderr);

            print!("rustc failed and stderr was:\n{}", s);
        }
        thread::sleep(time::Duration::new(5,0));
    }
}

如此一来我们就成功的实现了自动存证的功能。

关于

开放原子超级链(OpenAtom XuperChain)由百度率先研发,并于2020年捐赠给开放原子开源基金会(https://www.openatom.org)进一步开源孵化,OpenAtom XuperChain在加密技术、共识算法、智能合约、权限账户等核心技术上具有技术独创性。

88.3 MB
邀请码