迅雷链文件系统文档

1. 文档说明

1.1 阅读对象

本文档适用于有高安全性、高隐私性、知识产权等数据存储、分发、商业化等需求的企业和个人。通过本文档,指导开发者使用迅雷链文件系统,进行数据的上传、下载、复制、删除、授权等行为,并基于此文档进行二次开发,使产品具备大数据分布式存储与信息上链等特性,让产品快速集成海量存储、不可篡改、可追溯、永不丢失、安全加密、授权转移等能力。

1.2 版本说明

v2.5(2018/6/11)

2 专业术语

2.1 迅雷链文件系统

迅雷链文件系统(简称TCFS,全称为Thunder Chain File System)是迅雷在百万级共享计算节点的基础上,使用独创的分布式技术专为区块链打造的数据云存储与授权分发的开放式文件系统。开发者可使自己的产品具备文件数据分布式存储与信息上链等特性,从而快速集成公开透明、不可篡改、可追溯、高可靠、安全加密、海量存储、授权转移等能力。

主要有四个特性:

  1. 公开透明:数据使用安全加密哈希索引,修改后的文件是新的哈希,确保数据无法被篡改;基于merkle DAG结构独创的文件管理技术,保留文件的全部变更历史,公开可查询和追溯。
  2. 高安全性:数据使用安全切片存储,使用公私钥签名技术验证用户和文件的持有关系。独创的令牌授权机制,仅有授权的用户才可以访问数据。
  3. 高可靠性:数据使用FEC(前向纠删码)编码后,冗余存储在各个共享计算节点上,在系统级别采用了文件自动修复机制,数据具有超过15个9的可靠性。使用智能合约实现存储激励机制,确保参与节点稳定,使文件存储具有更高的可靠性。
  4. 海量数据存储:文件数据分布式存储在百万级的共享计算节点上,拥有高达数百PB且不断扩展的存储空间,可存储数百亿的文件量,充分满足业务需求。

3 专业术语

3.1 APP ID

APP ID指开发者在开放平台注册时生成的用于标名所属应用的编号。

3.2 APP Key

APP Key指开发者APP ID对应的加密key,作为APP ID的令牌,不可外露。

3.3 Public Key/Private Key/Address

公钥(Public Key)与私钥(PrivateKey)是通过非对称加密算法得到的一个密钥对(即一个公钥和一个私钥)。地址(Address)是由公钥经过单向的加密哈希算法计算得到的编码值。在系统中,Address是用来标识用户, 标识文件的拥有者信息。Public Key/Private Key/Address是以keyjson的格式存储,生成方法见6.6.2节。

3.4 签名Sign

迅雷链文件系统所有的接口均需要用户对接口参数进行签名,用于验证Address身份是否合法。签名一般有以下几种获取方式:

  1. 调用链克口袋进行签名
  2. 通过服务器SDK进行签名
  3. 签名函数进行签名(具体生成算法,详见第7节签名详细说明)

4. 开始使用

4.1 迅雷链新手指南

个人或者企业开发者要使用迅雷链文件系统前,必须先注册为开放平台的用户。手机号码是用户唯一标识。注册成功后,可以绑定邮箱,个人/企业认证,应用创建等操作,参见迅雷链新手指南

4.2 如何生成APP ID和APP Key

开发者完成应用创建并通过审核便会下发APP ID和App Key给到开发者,可在管理中心-应用中心-应用详情中查阅 APP ID指开发者在云存储注册时生成的用于标名所属业务的编号,App Key指开发者APP ID对应的加密key,作为APP ID的令牌,App Key需要开发者妥善保管。

4.3 如何计费

规格 购买12个月 当前优惠活动
100GB 优惠价99链克 满12个月返还99链克

说明:每次购买只能是100GB的整数倍。

5. 流程说明

5.1 使用迅雷链文件系统流程

avatar

5.2 APP ID验证流程

5.2.1 APP ID说明

企业和个人开发者需要进行注册,经过审批后,会得到一个APP ID以及对应的密钥Key。在调用接口时,需要传入APPID以及部分参数的md5值,迅雷链文件系统内部会校验两者是否匹配和合法,以验证身份。

5.2.2 APPID验证流程序列图

avatar APPID/APPKey的验证逻辑在迅雷链文件系统的所有接口中均需要使用,key_md5的md5计算方式为: md5(APPID+APPKey+ts)。迅雷链文件系统要求ts的有效期不超过10分钟,如果迅雷链文件系统时间超过key_md5计算时间10分钟,则验证不通过。

5.2.3 举例说明

举例说明:

APPID=de61d625adef267d69d63ca711939d685ffc8007
APPKey= 4daa50d08a107185af2c015cba126575781f7b20
timestamp = 1529114930
md5_value=md5sum("de61d625adef267d69d63ca711939d685ffc80074daa50d08a107185af2c015cba126575781f7b201529114930")=2b2cface59cc85b0916a6c46b68f2f20

在 6.1参数结构定义中,传入的参数如下

TCFSAppCertification ac{
appid=”de61d625adef267d69d63ca711939d685ffc8007”
key_md5=”2b2cface59cc85b0916a6c46b68f2f20”
timestamp =1529114930
}

5.3 文件上传流程

5.3.1 上传说明

使用迅雷链文件系统中AddFile接口进行文件上传,需要进行APPID/APPKey的验证,以及Address的身份签名认证。验证通过后将读取本地文件,对文件进行编码切片,然后将切片分发到共享节点,并且将文件的文件信息写入迅雷链文件系统,上传成功后,会返回本地文件对应的filehash。以后对文件的获取/删除等操作均以filehash标识。

5.3.2 上传流程序列图

avatar

5.3.3 使用说明

第三方App在需要文件上传时,只需要完成如下步骤即可完成文件上传:

  1. 通过第三方后台获取APPID+APPKey+ timestamp的md5值
  2. 通过5.7节中描述的方式获取sign
  3. 调用AddFile接口

5.4 文件下载

5.4.1 下载说明

使用迅雷链文件系统对文件进行下载时,是只能下载上传过的文件,没有上传过的文件以及没有权限的文件是不能进行下载的。下载文件需要进行APPID/APPKey的验证,以及Address的身份签名认证。

5.4.2 下载流程序列图

avatar

5.4.3 使用说明

第三方App在需要下载文件时,只需要完成如下步骤即可完成文件下载:

  1. 通过第三方后台获取APPID+APPKey+ timestamp的md5值
  2. 通过5.7节中描述的方式获取sign
  3. 调用GetFile接口

5.5 文件复制

5.5.1 复制说明

迅雷链文件系统中的复制功能是用于将用户A(AddressA)所拥有的文件FA复制给用户B(AddressB),用户B的存储空间中也将拥有文件FA。

5.5.2 复制流程序列图

avatar

5.5.3 使用说明

第三方App在需要下复制文件时,只需要完成如下步骤即可完成文件复制:

  1. 通过第三方后台获取APPID+APPKey+ timestamp的md5值
  2. 通过5.7节中描述的方式获取sign,注意这里需要用户A(AddressA),用户B(AddressB)两者同时签名,并且签名需要增加filehash字段
  3. 调用CopyFile接口

5.5.4 复制功能使用示例

avatar 因为CopyFile是为了将文件由用户A复制给用户B,所以用户A与用户B均需要进行签名。在签名时还需要增加对filehash的签名,以表示仅授权该文件,即sign= UserSign(privatekey, appid+key+addr+ timestamp +nonce+filehash)。

5.6 文件删除

5.6.1 删除说明

迅雷链文件系统中的删除功能是将用户A(addressA)的文件FA从最新的目录树中删除,该文件不再参与计费。系统定期清理未付费文件,所以删除后一段时间可能仍被成功访问,但文件的操作历史会一直保留。

5.6.2 删除流程序列图

avatar

5.6.3 使用说明

第三方App在删除文件时,只需要需要完成如下步骤即可完成文件删除:

  1. 通过第三方后台获取APPID+APPKey+ timestamp的md5值
  2. 通过5.7节中描述的方式获取sign
  3. 调用DeleteFile接口

5.7 用户签名

5.7.1 签名说明

签名是指在接口中用于验证Address身份是否合法的认证信息。设计sign的目的是在用户的钱包用私钥进行签名时需要使用用户私钥,为了简化多次使用私钥,所以设计带有时限的签名用于一次签名后将签名保存起来,每次调用迅雷链文件系统SDK接口时将签名直接传入,以达到一次签名多次使用的目的。

5.7.2 签名生成方式

一般的,sign= UserSign(privatekey, appid+addr+ timestamp +nonce),其中privatekey为此用户钱包对应的私钥,ts表示sign的以秒为单位的到期时间戳,sign的最长时间期限控制在1个月内;nonce表示随机字符串8个字节。在某些接口比如CopyFile接口中,需要增加对filehash的签名,sign=UserSign (privatekey, appid+addr+ timestamp +nonce+filehash)。 在计算sign时,appid/key以原始字串的计算,address/filehash/nonce以字符串代入计算,ts以字符串代入计算。

签名sign获取,一般由以下三种获取方式:

  1. 调用链克口袋进行签名 avatar
  2. 通过服务器SDK进行签名 avatar
  3. 调用SDK用户签名接口UserSign avatar

6 接口列表

6.1 参数结构定义

定义两个结构体,作为通用参数,来简化后续的接口函数参数列表。

struct TCFSAppCertification { // 开发者签发的证书
char appid[64]; // 开发者标识
int64   timestamp; // sign的过期时间点(秒)
char sign[64];  // 对开发者身份的校验值 
};

struct TCFSUserCertification { // 用户签发的证书
char address[64]; // 用户身份标识
int64 timestamp; // 签名的过期时间点(秒)
char nonce[16]; // 随机数
int data_len; // 扩展数据长度
char data[128]; // 扩展数据
char sign[128]; // 对结构体中成员的签名,用于对用户身份进行自校验
};

6.2 上传接口

int AddFile(TCFSAppCertification ac, TCFSUserCertification uc, const char filename, char filehash, int length)

  • 功能说明:用于将文件加密后按切片上传存储到迅雷链文件系统
  • 参数
参数名 类型 说明
ac TCFSAppCertification* 用于传入开发者的appid以及key_md5信息
uc TCFSUserCertification* 用于传入文件拥有者钱包地址以及签名信息,其中sign= UserSign(privatekey, appid+addr+ timestamp +nonce), data=null, data_length=0
filename const char* 指需要上传的文件路径,只支持本地文件
filehash char* 至少256字节的buffer,用于返回文件的hash(以’\0’结尾)
length int filehash数组的长度
  • 返回值
参数名 类型 说明
ret int 如果上传成功返回0,失败返回-1

6.3 下载接口

int GetFile(TCFSAppCertification ac, TCFSUserCertification uc, const char filehash, int64 filesize, const char filename)

  • 功能说明:将文件从迅雷链文件系统拉取并还原到本地文件
  • 参数
参数名 类型 说明
ac TCFSAppCertification* 用于传入开发者的appid以及key_md5信息
uc TCFSUserCertification* 用于传入文件拥有者钱包地址以及签名信息,其中sign= UserSign(privatekey, appid+addr+ timestamp +nonce), data=null, data_length=0
filehash const char* 指需要取回的文件filehash
filesize int64 指需要获取的文件大小
filename const char* 用于指定取回文件的文件名
  • 返回值
参数名 类型 说明
ret int 如果上传成功返回0,失败返回-1

6.4 删除接口

int DeleteFile(TCFSAppCertification ac, TCFSUserCertification uc, const char* filehash)

  • 功能说明:将文件从迅雷链文件系统的目录树删除
  • 参数
参数名 类型 说明
ac TCFSAppCertification* 用于传入开发者的appid以及key_md5信息
uc TCFSUserCertification* 用于传入文件拥有者钱包地址以及签名信息,其中sign= UserSign(privatekey, appid+addr+ timestamp +nonce), data=null, data_length=0
filehash const char* 指需要取回的文件filehash
  • 返回值
参数名 类型 说明
ret int 如果上传成功返回0,失败返回-1

6.5 拷贝接口

int CopyFile(TCFSAppCertification ac, TCFSUserCertification srcuc, const char filehash, TCFSUserCertification destuc)

  • 功能说明:将文件从迅雷链文件系统srcuc拷贝到destuc
  • 参数
参数名 类型 说明
ac TCFSAppCertification* 用于开发者的appid以及key_md5信息
srcuc TCFSUserCertification* 用于传入原始文件拥有者钱包地址以及签名信息,其中sign= UserSign(privatekey, appid +addr+ timestamp +nonce+data), data=filehash, data_length=len(filehash)
filehash const char* 指需要拷贝的文件filehash
dstuc TCFSUserCertification * 用于传入目的地文件拥有者钱包地址以及签名信息,其中sign= UserSign(appid+key+addr+ timestamp +nonce+data, sk), data=filehash, data_length=len(filehash)
  • 返回值
参数名 类型 说明
ret int 如果上传成功返回0,失败返回-1

6.6 用户签名接口

int UserSign(const char keyjson, const char pwd, const chardata, char sign, int sign_length)

  • 功能说明:将data数据进行签名
  • 参数
参数名 类型 说明
keyjson const char* 用户的私钥文件串
pwd const char* 用户私钥文件对应的密码
data const char* 需要进行签名的数据
sign char* 用于返回得到的签名数据数组
sign_length int sign数组的长度
  • 返回值
参数名 类型 说明
ret int 如果上传成功返回0,失败返回-1

6.6.1 签名举例说明

const keyJson = `{
  "address":"7eff122b94897ea5b0e2a9abf47b86337fafebdc",
  "id":"f86a62b4-0621-4616-99af-c4b7f38fcc48","version":3,
  "crypto":{
    "cipher":"aes-128-ctr","ciphertext":"19de8a919e2f4cbdde2b7352ebd0be8ead2c87db35fc8e4c9acaf74aaaa57dad",
    "cipherparams":{"iv":"ba2bd370d6c9d5845e92fbc6f951c792"},
    "kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"c7cc2380a96adc9eb31d20bd8d8a7827199e8b16889582c0b9089da6a9f58e84"},
    "mac":"ff2c0caf051ca15d8c43b6f321ec10bd99bd654ddcf12dd1a28f730cc3c13730"
  }
}`
pwd := "1234"

appid := "de61d625adef267d69d63ca711939d685ffc8007"
address := "0x7eff122b94897ea5b0e2a9abf47b86337fafebdc"
ts := 1529216849
nonce := "abcdefgh"
filehash := ""
sign_str := appid + address + fmt.Sprintf("%d", ts)  + nonce + filehash
sign, err := UserSign (keyJson, pwd, sign_str)

其中:
sign_str= de61d625adef267d69d63ca711939d685ffc80070x7eff122b94897ea5b0e2a9abf47b86337fafebdc1529216849abcdefgh
sign= a54a4c369f608d3966dc531324795073585e288fd908e47c017302e514f8790a7bd41a2cb020230f14a48fb4d9d6f88eb33019b3b1f6ef097c486938324f593601

6.6.2 keyjson的生成示例

以下是使用链克口袋生成keyjson的步骤:

  1. 新建账户 avatar 点击右上角 新建账户,在新建页面输入 密码。

  2. 导出keystore文件 avatar 导出备份,就可以获取keystore文件, keystore文件内容即是keyjson。