WeIdentity RestService API 说明文档¶
基于私钥托管模式的RestService API¶
1. 总体介绍¶
每个API的入参都是满足以下格式的json字符串:
{
"functionArg": 随调用SDK方法而变的入参json字符串 {
...
},
"transactionArg": 交易参数json字符串 {
"invokerWeId": 用于索引私钥的WeIdentity DID,服务器端会凭此找到所托管的私钥(非必须)
}
"functionName": 调用SDK方法名
"v": API版本号
}
参数说明:
functionArg是随不同的SDK调用方法而变的,具体的参数可以查看SDK接口文档;后文会为每个所提及的接口给出对应的链接
- transactionArg仅包括一个变量invokerWeId,由传入方决定使用在服务器端托管的具体哪个WeIdentity DID所对应的私钥
非必需,只有在那些需要使用不同身份进行写交易签名的方法(如CreateAuthorityIssuer等)才会需要;后文中详细说明
functionName是调用的SDK方法名,用于决定具体调用WeIdentity Java SDK的什么功能
v是调用的API方法版本
每个API的接口返回都是满足以下格式的json字符串:
{
"respBody": 随调用SDK方法而变的输出值json字符串 {
}
"ErrorCode": 错误码
"ErrorMessage": 错误信息,成功时为"success"
}
其中具体的输出值result亦是随不同的SDK调用方法而变的。
在后文中,我们将会逐一说明目前所提供的功能及其使用方式。
2. 创建WeIdentity DID(无参创建方式)¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
createWeId |
Y |
functionArg |
Y |
|
transactionArg |
Y |
|
v |
版本号 |
Y |
注解
基于托管模式的RestService不允许通过传入公钥参数的方式创建WeID。这是因为,这样生成的WeID私钥不存在于RestService本地,因此无法在后续过程中被调用。如果您需要通过传入公钥方式创建WeID,请使用基于轻客户端方式的接口创建。
接口入参示例:
{
"functionArg": {
},
"transactionArg": {
},
"functionName": "createWeId",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
WeIdentity DID |
返回示例:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
}
3. 获取WeIdentity DID Document¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
getWeIdDocument |
Y |
functionArg |
Y |
|
functionArg.weId |
WeIdentity DID,与SDK直接调用的方式入参要求一致,下同 |
Y |
transactionArg |
N,传空 |
|
v |
版本号 |
Y |
接口入参示例:
{
"functionArg": {
"weId": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"transactionArg": {
},
"functionName": "getWeIdDocument",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
WeIdentity DID Document |
返回示例:
{
"respBody": {
"@context" : "https://w3id.org/did/v1",
"id" : "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"created" : 1553224394993,
"updated" : 1553224394993,
"publicKey" : [ ],
"authentication" : [ ],
"service" : [ ]
},
"ErrorCode": 0,
"ErrorMessage": "success"
}
4. 创建AuthorityIssuer¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
registerAuthorityIssuer |
Y |
functionArg |
Y |
|
functionArg.weId |
WeIdentity DID,与SDK直接调用的方式入参一致,下同 |
Y |
functionArg.name |
机构名 |
Y |
transactionArg |
Y |
|
transactionArg.invokerWeId |
用于索引私钥的WeIdentity DID,服务器端会凭此找到所托管的私钥。注意:如果在这里填入了预先定义在application.properties里的暗语,则可确保有足够的权限。 |
Y |
v |
版本号 |
Y |
接口调用示例:
{
"functionArg": {
"weid": "did:weid:0x1Ae5b88d37327830307ab8da0ec5D8E8692A35D3",
"name": "Sample College"
},
"transactionArg": {
"invokerWeId": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"functionName": "registerAuthorityIssuer",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
True/False |
返回示例:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": True
}
5. 查询AuthorityIssuer¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
queryAuthorityIssuer |
Y |
functionArg |
Y |
|
functionArg.weId |
WeIdentity DID,与SDK直接调用的方式入参一致,下同 |
Y |
transactionArg |
N,传空 |
|
v |
版本号 |
Y |
接口入参示例:
{
"functionArg": {
"weId": "did:weid:0x1ae5b88d37327830307ab8da0ec5d8e8692a35d3"
},
"transactionArg": {
},
"functionName": "queryAuthorityIssuer",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
完整的Authority Issuer信息 |
{
"respBody": {
"accValue": ,
"created": 16845611984115,
"name": "Sample College",
"weid": "did:weid:0x1ae5b88d37327830307ab8da0ec5d8e8692a35d3"
}
"ErrorCode": 0
"ErrorMessage": "success"
}
6. 创建CPT¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
registerCpt |
Y |
functionArg |
Y |
|
functionArg.cptJsonSchema |
CPT Json Schema,与SDK直接调用的方式入参一致,下同 |
Y |
functionArg.weId |
CPT创建者 |
Y |
transactionArg |
Y |
|
transactionArg.invokerWeId |
用于索引私钥的WeIdentity DID,服务器端会凭此找到所托管的私钥 |
Y |
v |
版本号 |
Y |
CPT Json Schema是什么?应该满足什么格式?
答:Json Schema是一种用来定义Json字符串格式的Json字符串,它定义了CPT应包括的字段、属性及规则。
WeIdentity可以接受 http://json-schema.org/draft-04/schema# 所定义第四版及之前版本作为入参。
接口入参示例:
{
"functionArg": {
"weId": "did:weid:0x1ae5b88d37327830307ab8da0ec5d8e8692a35d3",
"cptJsonSchema":{
"title": "cpt",
"description": "this is cpt",
"properties": {
"name": {
"type": "string",
"description": "the name of certificate owner"
},
"gender": {
"enum": [
"F",
"M"
],
"type": "string",
"description": "the gender of certificate owner"
},
"age": {
"type": "number",
"description": "the age of certificate owner"
}
},
"required": [
"name",
"age"
]
}
},
"transactionArg": {
"invokerWeId": "did:weid:0x1ae5b88d37327830307ab8da0ec5d8e8692a35d3"
},
"functionName": "registerCpt",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
cptBaseInfo |
返回示例:
{
"respBody": {
"cptId": 2000001,
"cptVersion": 1
},
"ErrorCode": 0,
"ErrorMessage": "success"
}
7. 查询CPT¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
queryCpt |
Y |
functionArg |
Y |
|
functionArg.cptId |
CPT ID,与SDK直接调用的方式入参一致。 |
Y |
transactionArg |
N,传空 |
|
v |
版本号 |
Y |
接口入参示例:
{
"functionArg": {
"cptId": 10,
},
"transactionArg": {
},
"functionName": "queryCpt",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
完整的CPT信息 |
接口返回示例:
{
"respBody": {
"cptBaseInfo" : {
"cptId" : 10,
"cptVersion" : 1
},
"cptId" : 10,
"cptJsonSchema" : {
"$schema" : "http://json-schema.org/draft-04/schema#",
"title" : "a CPT schema",
"type" : "object"
},
"cptPublisher" : "did:weid:0x104a58c272e8ebde0c29083552ebe78581322908",
"cptSignature" : "HJPbDmoi39xgZBGi/aj1zB6VQL5QLyt4qTV6GOvQwzfgUJEZTazKZXe1dRg5aCt8Q44GwNF2k+l1rfhpY1hc/ls=",
"cptVersion" : 1,
"created" : 1553503354555,
"metaData" : {
"cptPublisher" : "did:weid:0x104a58c272e8ebde0c29083552ebe78581322908",
"cptSignature" : "HJPbDmoi39xgZBGi/aj1zB6VQL5QLyt4qTV6GOvQwzfgUJEZTazKZXe1dRg5aCt8Q44GwNF2k+l1rfhpY1hc/ls=",
"created" : 1553503354555,
"updated" : 0
},
"updated" : 0
},
"ErrorCode": 0,
"ErrorMessage": "success"
}
8. 创建Credential¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
createCredential |
Y |
functionArg |
Y |
|
functionArg.claim |
claim Json结构体,与SDK直接调用的方式入参一致,下同 |
Y |
functionArg.cptId |
CPT ID |
Y |
functionArg.issuer |
issuer WeIdentity DID |
Y |
functionArg.expirationDate |
过期时间(使用UTC格式) |
Y |
transactionArg |
Y |
|
transactionArg.invokerWeId |
用于索引私钥的WeIdentity DID,服务器端会凭此找到所托管的私钥 |
Y |
v |
版本号 |
Y |
接口入参:Json,以signature代替私钥
{
"functionArg": {
"cptId": 10,
"issuer": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"expirationDate": "2019-04-18T21:12:33Z",
"claim": {
"name": "zhang san",
"gender": "F",
"age": 18
},
},
"transactionArg": {
"invokerWeId": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"functionName": "createCredential",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
完整的Credential信息 |
接口返回示例:
{
"respBody": {
"@context": "https://github.com/WeBankBlockchain/WeIdentity/blob/master/context/v1",
"claim": {
"content": "b1016358-cf72-42be-9f4b-a18fca610fca",
"receiver": "did:weid:101:0x7ed16eca3b0737227bc986dd0f2851f644cf4754",
"weid": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"cptId": 2000156,
"expirationDate": "2100-04-18T21:12:33Z",
"id": "da6fbdbb-b5fa-4fbe-8b0c-8659da2d181b",
"issuanceDate": "2020-02-06T22:24:00Z",
"issuer": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"proof": {
"created": "1580999040000",
"creator": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"signature": "G0XzzLY+MqUAo3xXkS3lxVsgFLnTtvdXM24p+G5hSNNMSIa5vAXYXXKl+Y79CO2ho5DIGPPvSs2hvAixmfIJGbw=",
"type": "Secp256k1"
}
},
"errorCode": 0,
"errorMessage": "success"
}
9. 验证Credential¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
verifyCredential |
Y |
functionArg |
Y |
|
functionArg.claim |
claim Json 结构体,与SDK直接调用的方式入参一致,下同 |
Y |
functionArg.cptId |
CPT ID |
Y |
functionArg.context |
context值 |
Y |
functionArg.uuid |
Credential的UUID |
Y |
functionArg.issuer |
issuer WeIdentity DID |
Y |
functionArg.issuranceDate |
颁发时间 |
Y |
functionArg.expirationDate |
过期时间 |
Y |
functionArg.proof |
Credential签名结构体 |
Y |
transactionArg |
N,传空 |
|
v |
版本号 |
Y |
接口入参:
{
"functionArg": {
"@context": "https://github.com/WeBankBlockchain/WeIdentity/blob/master/context/v1",
"claim": {
"content": "b1016358-cf72-42be-9f4b-a18fca610fca",
"receiver": "did:weid:101:0x7ed16eca3b0737227bc986dd0f2851f644cf4754",
"weid": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"cptId": 2000156,
"expirationDate": "2100-04-18T21:12:33Z",
"id": "da6fbdbb-b5fa-4fbe-8b0c-8659da2d181b",
"issuanceDate": "2020-02-06T22:24:00Z",
"issuer": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"proof": {
"created": "1580999040000",
"creator": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"signature": "G0XzzLY+MqUAo3xXkS3lxVsgFLnTtvdXM24p+G5hSNNMSIa5vAXYXXKl+Y79CO2ho5DIGPPvSs2hvAixmfIJGbw=",
"type": "Secp256k1"
}
},
"transactionArg": {
},
"functionName": "verifyCredential"
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
True/False |
接口返回:
{
"respBody": true,
"ErrorCode": 0,
"ErrorMessage": "success"
}
10. 创建CredentialPojo¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
createCredentialPojo |
Y |
functionArg |
Y |
|
functionArg.claim |
claim Json结构体,与SDK直接调用的方式入参一致,下同 |
Y |
functionArg.cptId |
CPT ID |
Y |
functionArg.issuer |
issuer WeIdentity DID |
Y |
functionArg.expirationDate |
过期时间(使用UTC格式) |
Y |
transactionArg |
Y |
|
transactionArg.invokerWeId |
用于索引私钥的WeIdentity DID,服务器端会凭此找到所托管的私钥 |
Y |
v |
版本号 |
Y |
接口入参:Json,以signature代替私钥
{
"functionArg": {
"cptId": 10,
"issuer": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"expirationDate": "2019-04-18T21:12:33Z",
"claim": {
"name": "zhang san",
"gender": "F",
"age": 18
},
},
"transactionArg": {
"invokerWeId": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"functionName": "createCredentialPojo",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
完整的CredentialPojo信息 |
接口返回示例:
{
"respBody": {
"cptId": 2000156,
"issuanceDate": 1580996777,
"context": "https://github.com/WeBankBlockchain/WeIdentity/blob/master/context/v1",
"claim": {
"content": "b1016358-cf72-42be-9f4b-a18fca610fca",
"receiver": "did:weid:101:0x7ed16eca3b0737227bc986dd0f2851f644cf4754",
"weid": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"id": "21d10ab1-75fe-4733-9f1d-f0bad71b5922",
"proof": {
"created": 1580996777,
"creator": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa#keys-0",
"salt": {
"content": "ncZ5F",
"receiver": "L0c40",
"weid": "I4aop"
},
"signatureValue": "HEugP13uDVBg2G0kmmwbTkQXobsrWNqtGQJW6BoHU2Q2VQpwVhK382dArRMFN6BDq7ogozYBRC15QR8ueX5G3t8=",
"type": "Secp256k1"
},
"type": [
"VerifiableCredential",
"hashTree"
],
"issuer": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"expirationDate": 4111737153
},
"errorCode": 0,
"errorMessage": "success"
}
11. 验证CredentialPojo¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/invoke |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
verifyCredentialPojo |
Y |
functionArg |
Y |
|
functionArg.claim |
claim Json 结构体,与SDK直接调用的方式入参要求一致,下同 |
Y |
functionArg.cptId |
CPT ID |
Y |
functionArg.context |
context值 |
Y |
functionArg.uuid |
CredentialPojo的UUID |
Y |
functionArg.issuer |
issuer WeIdentity DID |
Y |
functionArg.issuranceDate |
颁发时间 |
Y |
functionArg.expirationDate |
过期时间 |
Y |
functionArg.proof |
Credential签名值 |
Y |
transactionArg |
N,传空 |
|
v |
版本号 |
Y |
接口入参:
{
"functionArg": {
"cptId": 2000156,
"issuanceDate": 1580996777,
"context": "https://github.com/WeBankBlockchain/WeIdentity/blob/master/context/v1",
"claim": {
"content": "b1016358-cf72-42be-9f4b-a18fca610fca",
"receiver": "did:weid:101:0x7ed16eca3b0737227bc986dd0f2851f644cf4754",
"weid": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"id": "21d10ab1-75fe-4733-9f1d-f0bad71b5922",
"proof": {
"created": 1580996777,
"creator": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa#keys-0",
"salt": {
"content": "ncZ5F",
"receiver": "L0c40",
"weid": "I4aop"
},
"signatureValue": "HEugP13uDVBg2G0kmmwbTkQXobsrWNqtGQJW6BoHU2Q2VQpwVhK382dArRMFN6BDq7ogozYBRC15QR8ueX5G3t8=",
"type": "Secp256k1"
},
"type": [
"VerifiableCredential",
"hashTree"
],
"issuer": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"expirationDate": 4111737153
},
"transactionArg": {
},
"functionName": "verifyCredentialPojo"
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
True/False |
接口返回:
{
"respBody": true,
"ErrorCode": 0,
"ErrorMessage": "success"
}
基于轻客户端模式的RestService API¶
1. 总体介绍¶
基于轻客户端模式的API的入参形式与基于私钥托管模式的API相同,也是满足以下格式的json字符串。 最大的区别在于,流程包括两次交互,第一次是轻客户端提供接口参数发给RestService服务端,后者进行组装、编码区块链原始交易串并返回;第二次是轻客户端在本地使用自己的私钥,对原始交易串进行符合ECDSA的sha3签名,发给RestService服务端,后者打包并直接执行交易。
第一次交互
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/encode |
Method |
POST |
Content-Type |
application/json |
接口入参(Body):
{
"functionArg": 随调用SDK方法而变的入参json字符串 {
...
},
"transactionArg": 交易参数json字符串 {
"nonce": 用于防止重放攻击的交易随机数
}
"functionName": 调用SDK方法名
"v": API版本号
}
参数说明:
functionArg是随不同的SDK调用方法而变的,具体的参数可以查看SDK接口文档;后文会为每个所提及的接口给出对应的链接
- transactionArg仅包括一个变量nonce,用于防止重放攻击的交易随机数,您可以使用RestService jar的getNonce(),或其他类似方法生成此随机数。
必需,且必须妥善保存,这个nonce在第二次交互中还会用到
functionName是调用的SDK方法名,用于决定具体调用WeIdentity Java SDK的什么功能
v是调用的API方法版本
第一次交互的接口返回是以下格式的json字符串:
{
"respBody": {
"encodedTransaction": 基于Base64编码的原始交易串信息
"data": 交易特征值
}
"ErrorCode": 错误码
"ErrorMessage": 错误信息,成功时为"success"
}
返回结构体包含encodedTransaction和data两项。 调用者随后需要使用自己的私钥对encodeTransaction进行交易签名,然后使用Base64对其进行编码,和data、nonce一起待用, 进行第二次交互。
注解
请注意使用的ECDSA签名算法的编码格式。WeID Java SDK所使用的是椭圆曲线Secp256k1算法,这也是WeID Go轻客户端的默认算法。一般来说,ECDSA的签名算法会生成R,S,V三个值,其中R和S是32个字节的二进制字节数组,而V,以太坊原生的Secp256k1算法的结果一般是0或1。
注解
当您生成签名的R,S,V之后,您需要将R,S,V存入一个65个字节长的二进制字节数组,再进行Base64编码方可正确由RestService解析。RestService只接受两种组成方式: 1. 按照R, S, V的顺序拼接成一个65个字节长的数组并使用Base64编码(这是WeID Go轻客户端默认方式,此时V的值为0或1) 2. 按照V+27, R, S的顺序拼接成一个65个字节长的数组并使用Base64编码(这是WeID Java SDK默认序列化方式,此时V的值为27或28)
您可以参考Java侧的客户端代码,使用默认Secp256k1私钥进行签名和Base64编码的范例代码见下:
// 依赖web3sdk 2.2.2和weid-java-sdk 1.5
byte[] encodedTransaction = DataToolUtils
.base64Decode("<encodedTransaction的值>".getBytes());
SignatureData clientSignedData = Sign.getSignInterface().signMessage(encodedTransactionClient, ecKeyPair);
String base64SignedMsg = new String(
DataToolUtils.base64Encode(TransactionEncoderUtilV2.simpleSignatureSerialization(clientSignedData)));
第二次交互
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/transact |
Method |
POST |
Content-Type |
application/json |
接口入参:
{
"functionArg": 空 {
},
"transactionArg": 交易参数json字符串 {
"nonce": 用于防止重放攻击的交易随机数
"data": 交易特征值,需和第一步中返回值一致
"signedMessage": 基于Base64编码的、使用私钥签名之后的encodedTransaction签名值
}
"functionName": 调用SDK方法名
"v": API版本号
}
这一步的目的是将已签名交易的参数发给RestService,并由后者将交易打包上链。参数说明:
functionArg此时为空
transactionArg包括第一次交互起始阶段生成的nonce、第一次交互收到的data,以及最重要的,使用调用者本地私钥签名并通过Base64编码的encodedTransaction的签名值
functionName是调用的SDK方法名,用于决定具体调用WeIdentity Java SDK的什么功能
v是调用的API方法版本
第二次交互的接口返回是以下格式的json字符串:
{
"respBody": 随调用SDK方法而变的输出值json字符串 {
}
"ErrorCode": 错误码
"ErrorMessage": 错误信息,成功时为"success"
}
其中具体的输出值result亦是随不同的SDK调用方法而变的。 可以看到,基于轻客户端的交易方式,本质上,是因为签名操作必须在本地完成,因此将原始交易串分成了两次交互完成。 基于轻客户端的每个API的入参,也仅仅在第一次交互中不同。因此,在下文的介绍中,我们会忽略第二次交互的入参,只提供第一次交互的入参和第二次交互的返回值。
2. 创建WeIdentity DID(有参创建方式)¶
第一次交互,POST /weid/api/encode 的接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
createWeId |
Y |
functionArg |
Y |
|
functionArg.publicKey |
ECDSA公钥,需要为10进制的整型数字,以字符串形式传入 |
Y |
transactionArg |
Y |
|
transactionArg.nonce |
交易随机数 |
Y |
v |
版本号 |
Y |
第一次交互,POST /weid/api/encode 接口入参示例:
{
"functionArg": {
"publicKey": "712679236821355231513532168231727831978932132185632517152735621683128"
},
"transactionArg": {
"nonce": "1474800601011307365506121304576347479508653499989424346408343855615822146039"
},
"functionName": "createWeId",
"v": "1.0.0"
}
第二次交互,POST /weid/api/transact 接口入参示例:
{
"functionArg": {},
"transactionArg": {
"nonce": "1474800601011307365506121304576347479508653499989424346408343855615822146039",
"data": "809812638256c1235b1231000e000000001231287bacf213c",
"signedMessage": "HEugP13uDVBg2G0kmmwbTkQXobsrWNqtGQJW6BoHU2Q2VQpwVhK382dArRMFN6BDq7ogozYBRC15QR8ueX5G3t8="
},
"functionName": "createWeId",
"v": "1.0.0"
}
第二次交互的接口返回:
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
WeIdentity DID |
返回示例:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
}
3. 注册Authority Issuer¶
第一次交互,POST /weid/api/encode 的接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
registerAuthorityIssuer |
Y |
functionArg |
Y |
|
functionArg.name |
机构名 |
Y |
functionArg.weId |
WeIdentity DID,与SDK直接调用的方式入参要求一致 |
Y |
transactionArg |
Y |
|
transactionArg.nonce |
交易随机数 |
Y |
v |
版本号 |
Y |
第一次交互,POST /weid/api/encode 接口入参示例:
{
"functionArg": {
"name": "BV-College",
"weId": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"transactionArg": {
"nonce": "1474800601011307365506121304576347479508653499989424346408343855615822146039"
},
"functionName": "registerAuthorityIssuer",
"v": "1.0.0"
}
第二次交互,POST /weid/api/transact 接口入参示例:
{
"functionArg": {},
"transactionArg": {
"nonce": "1474800601011307365506121304576347479508653499989424346408343855615822146039",
"data": "809812638256c1235b1231000e000000001231287bacf213c",
"signedMessage": "HEugP13uDVBg2G0kmmwbTkQXobsrWNqtGQJW6BoHU2Q2VQpwVhK382dArRMFN6BDq7ogozYBRC15QR8ueX5G3t8="
},
"functionName": "registerAuthorityIssuer",
"v": "1.0.0"
}
第二次交互的接口返回:
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
Authority Isser信息 |
返回示例:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": {
"accValue": ,
"created": "1581420650",
"name": "BV-College",
"weId": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
}
}
4. 创建CPT¶
第一次交互,POST /weid/api/encode 的接口入参:
Key |
Value |
Required |
---|---|---|
functionName |
registerCpt |
Y |
functionArg |
Y |
|
functionArg.cptJsonSchema |
CPT Json Schema,与SDK直接调用的方式入参要求一致,下同 |
Y |
functionArg.weId |
CPT创建者 |
Y |
functionArg.cptSignature |
创建者使用自己的私钥对cptJsonSchema的签名(和私钥托管方式不同,本方式特有) |
Y |
transactionArg |
Y |
|
transactionArg.nonce |
交易随机数 |
Y |
v |
版本号 |
Y |
第一次交互,POST /weid/api/encode 接口入参示例:
{
"functionArg": {
"weId": "did:weid:0x1ae5b88d37327830307ab8da0ec5d8e8692a35d3",
"cptJsonSchema": {
"title": "cpt",
"description": "this is cpt",
"properties": {
"name": {
"type": "string",
"description": "the name of certificate owner"
},
"gender": {
"enum": [
"F",
"M"
],
"type": "string",
"description": "the gender of certificate owner"
},
"age": {
"type": "number",
"description": "the age of certificate owner"
}
},
"required": [
"name",
"age"
]
}
"cptSignature": "BaUeP13uDVBg2G0kmmwbTkQXobsrWNqtGQJW6BoHU2Q2VQpwVhK382dArRMFN6BDq7ogozYBRC15QR8ueX5G3t8="
},
"transactionArg": {
"nonce": "1474800601011307365506121304576347479508653499989424346408343855615822146039"
},
"functionName": "registerCpt",
"v": "1.0.0"
}
第二次交互,POST /weid/api/transact 接口入参示例:
{
"functionArg": {},
"transactionArg": {
"nonce": "1474800601011307365506121304576347479508653499989424346408343855615822146039",
"data": "809812638256c1235b1231000e000000001231287bacf213c",
"signedMessage": "HEugP13uDVBg2G0kmmwbTkQXobsrWNqtGQJW6BoHU2Q2VQpwVhK382dArRMFN6BDq7ogozYBRC15QR8ueX5G3t8="
},
"functionName": "registerAuthorityIssuer",
"v": "1.0.0"
}
第二次交互的接口返回:
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
Authority Isser信息 |
返回示例:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": {
"cptId": 2000001,
"cptVersion": 1
}
}
5. 创建CredentialPojo¶
创建CredentialPojo不需要进行区块链交互,因此,只需要进行一次交互POST /weid/api/encode,然后对返回的结果进行签名即可:
POST /weid/api/encode 接口入参
Key |
Value |
Required |
---|---|---|
functionName |
createCredentialPojo |
Y |
functionArg |
Y |
|
functionArg.claim |
claim Json结构体,与SDK直接调用的方式入参一致,下同 |
Y |
functionArg.cptId |
CPT ID |
Y |
functionArg.issuer |
issuer WeIdentity DID |
Y |
functionArg.expirationDate |
过期时间(使用UTC格式) |
Y |
transactionArg |
为空 |
Y |
v |
版本号 |
Y |
接口入参:Json,以signature代替私钥
{
"functionArg": {
"cptId": 10,
"issuer": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"expirationDate": "2019-04-18T21:12:33Z",
"claim": {
"name": "zhang san",
"gender": "F",
"age": 18
},
},
"transactionArg": {
},
"functionName": "createCredentialPojo",
"v": "1.0.0"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
完整的CredentialPojo信息 |
接口返回示例:
{
"respBody": {
"cptId": 2000156,
"issuanceDate": 1580996777,
"context": "https://github.com/WeBankBlockchain/WeIdentity/blob/master/context/v1",
"claim": {
"content": "b1016358-cf72-42be-9f4b-a18fca610fca",
"receiver": "did:weid:101:0x7ed16eca3b0737227bc986dd0f2851f644cf4754",
"weid": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa"
},
"id": "21d10ab1-75fe-4733-9f1d-f0bad71b5922",
"proof": {
"created": 1580996777,
"creator": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa#keys-0",
"salt": {
"content": "ncZ5F",
"receiver": "L0c40",
"weid": "I4aop"
},
"signatureValue": "HJPbDmoi39xgZBGi/aj1zB6VQL5QLyt4qTV6GOvQwzfgUJEZTazKZXe1dRg5aCt8Q44GwNF2k+l1rfhpY1hc/ls=",
"type": "Secp256k1"
},
"type": [
"VerifiableCredential",
"hashTree"
],
"issuer": "did:weid:101:0xfd28ad212a2de77fee518b4914b8579a40c601fa",
"expirationDate": 4111737153
},
"errorCode": 0,
"errorMessage": "success"
}
请注意,这个生成的CredentialPojo的签名值(proof中的signatureValue项)并没有经过私钥签名。因此,您还需要其经过Base64解码之后,再使用Issuer的私钥进行签名并Base64编码,就能得到一个正确的CredentialPojo了。
使用ECDSA私钥进行签名和Base64编码的范例代码见下:
String signature = DataToolUtils.sign(new String(DataToolUtils.base64Decode(signatureValue)), privateKey);
WeIdentity Endpoint Service API¶
1. 获取所有已注册的Endpoint信息¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/endpoint |
Method |
GET |
Content-Type |
application/json |
接口入参:无
接口返回:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": [
{
"requestName": "create-passphrase",
"inAddr": [
"127.0.0.1:6010",
"127.0.0.1:6011"
],
"description": "Create a valid random passphrase"
},
{
"requestName": "verify-passphrase",
"inAddr": [
"127.0.0.1:6012",
"127.0.0.1:6013"
],
"description": "Verify a passphrase"
}
]
}
2. 进行Endpoint调用¶
调用接口:
标题 |
描述 |
---|---|
接口名 |
weid/api/endpoint/{endpoint} |
Method |
POST |
Content-Type |
application/json |
接口入参:
Key |
Value |
Required |
---|---|---|
/{endpoint} |
在API路径中标明的API名,String |
Y |
body |
以```分隔的多个传入服务端用于执行API的参数 |
Y |
接口入参:
{
"body": "did:weid:0xfd28ad212a2de77fee518b4914b8579a40c601fa```25"
}
接口返回: application/json
Key |
Value |
---|---|
ErrorCode |
错误码,0表示成功 |
ErrorMessage |
错误信息 |
respBody |
SDK侧的返回值,String |
接口返回:
{
"ErrorCode": 0,
"ErrorMessage": "success",
"respBody": "did:weid:0x1Ae5b88d37327830307ab8da0ec5D8E8692A35D3",
}