中移链DDC-SDK技术对接全流程(三)

id:BSN_2021 公众号:BSN 研习社 作者:中移信息

2021年10月,BSN 提出搭建 BSN-DDC 基础网络,区块链团队自主研发中移链(CMBaaS)DDC 并与 BSN 开展合作,面向存在 DDC 业务需求的各行业客户提供接入服务,使其可便捷管理 DDC 操作,从而灵活升级产品模式,助力客户业务创新。

本文档是关于中移链 DDC-SDK 技术在对接全流程中,如何调用BSN-DDC门户OpenAPI接口的生成公私钥对、创建链账户、接入官方DDC合约、分配资源、业务费充值以及对应查询的操作指南,适用于 BSN 开放联盟链--中移链 DDC-SDK 开发者,帮助读者了解如何以平台方的角色集成中移链 DDC-SDK。

一、BSN-DDC门户OpenAPI简介

BSN-DDC门户 OpenAPI 是用于与中移链交互的 API 服务,主要功能可参考《BSN-DDC门户OpenAPI接口文档》。在中移链 RPC API手册的基础上,为中移链系统合约提供可访问的服务入口,方便平台方通过 OpenAPI 实现对系统合约的远程调用。

BSN-DDC门户 OpenAPI 主要包含四个部分:开放联盟链框架、项目管理、DDC链账户管理、官方DDC查询。以下是各个部分的功能介绍:

开放联盟链框架:负责开放联盟链框架的列表查询和支持的链账户类型查询,例如中移链的opbChainId为9,支持的链账户类型为上传公钥。

项目管理:负责项目的创建、列表查询和状态更新,平台方使用项目ID和项目key接入OPB网关,并发起合约交易,默认不开启项目key。

DDC链账户管理:提供完整的DDC链账户管理流程,主要包括:生成链账户公私钥对、创建链账户、接入官方DDC合约、分配资源和业务费充值等。

官方DDC查询:提供官方DDC的发行明细和交易列表查询,同时支持官方DDC的生成、授权、转移、销毁等完整流转记录的查询。

二、名词解释

开放联盟链:用于部署和运行各类区块链应用的一站式区块链服务运行环境。开放联盟链的应用共享记账节点资源和区块链数据账本;链外业务系统可以通过节点网关简单、快速接入区块链网络进行交易处理。

BSN DID:平台方的链上身份凭证标识,关联平台方的业务开通凭证、链账户以及其下终端用户的链账户,是平台方开展DDC应用和管理业务的基础标识。平台方需要妥善保存和备份好BSN DID的控制私钥。

DID-SDK:包含注册DID、更新密钥、验证DID三个方法,平台方只需注册一次DID即可,所以需妥善保存和备份好BSN DID的控制私钥,如私钥丢失或泄漏,通过更新密钥方法重新生成BSN DID的控制私钥。

门户OpenAPI:BSN联盟面向平台方开放的一套官方DDC管理服务接口。平台方按照官方门户OpenAPI开发资料进行接口对接,将官方DDC的管理侧功能和查询类功能集成到自己的业务门户内。

官方DDC合约:所有DDC开放联盟链上,部署完全一致的BSN官方DDC合约,可以生成和管理BSN官方DDC(支持ERC-721和ERC-1155)。也允许平台方部署自己的DDC合约,该类DDC由相关平台方自行负责。

BSN官方DDC:通过BSN官方DDC合约生成的官方DDC。BSN联盟为每条开放联盟链都推出一套功能一致,但实现过程不尽相同的官方DDC合约,同一条链上的每个官方DDC都由这个官方DDC合约生成,且都由BSN联盟进行背书。

apitoken:平台方调用门户OpenAPI的每个接口,都需在请求头填写apitoken,服务侧会对apitoken的值进行有效性验证,同时根据此值将请求报文关联到对应的平台方,所以平台方需妥善管理自己的apitoken。

三、开发前准备

(一)注册DDC门户账号

1、登录DDC官网门户网站,点击去注册,网站地址:https://ddc.bsnbase.com/

2、注册时需提供企业名称、法人姓名、企业营业执照、邮箱及手机号等信息

3、DDC网络运营人员在3个工作日内对注册信息进行审核,审核结果将以邮件方式进行通知

(二)申请业务开通、线下签署合同

1、注册成功后,平台方人员登录官方门户,在“业务开通”页面填写备案网站和申请说明后提交业务开通申请

2、DDC网络运营人员在3个工作日内联系平台方沟通业务开通相关事宜

3、平台方的业务开通申请经BSN联盟审核通过后,DDC网络运营人员联系平台方签署线下协议

注意: 所填写的网站备案信息必须与所提交的注册企业名称一致。此处所说的备案网站不一定是DDC业务的平台,任何注册企业名下的备案网站均可。

(三)注册DID并下载业务凭证

1、在线下签约完成后,平台方人员根据DID SDK生成DID标识(did)和DID签名值(didSign)

1)测试用例

@Test
public void generateDidtest() {
    DidClient didClient = this.getDidClient();
    DidDataWrapper didDataWrapper = didClient.createDid();
    System.out.println(JSONObject.toJSONString(didDataWrapper));
    assertNotNull(didDataWrapper);
    assertNotNull(didDataWrapper.getDid());
    assertNotNull(didDataWrapper.getDocument());
    assertNotNull(didDataWrapper.getAuthKeyInfo());
    assertNotNull(didDataWrapper.getRecyKeyInfo());
}

2)输出结果

{
    "address":"0x6b48f123fe493a144df5cfc24e74d8639622d452",
    "authKeyInfo":{
        "privateKey":"73352081742544535007412511358750380682016965583404841637572340950252082648181",
        "publicKey":"9784207274559734436040166487546186979629799048299924533536969953181115829508641603663755398772837199880448005621139241901177149041470382540707320562016661",
        "type":"Secp256k1"
    },
    "did":"did:bsn:4Qc1ZMwJ2kCDEiZaoW86gbCDopY8",
    "didSign":"P6yJGMe9O3HQZ/yXlUdsp/fAZAtqUwI1JbjJG9Xik5MVdWseWay6IaRYj2A27+wGuOeLYBbUO5aNfS+9zI1nTgA=",
    "document":{
        "authentication":{
            "publicKey":"9784207274559734436040166487546186979629799048299924533536969953181115829508641603663755398772837199880448005621139241901177149041470382540707320562016661",
            "type":"Secp256k1"
        },
        "created":"2022-09-08 10:39:52",
        "did":"did:bsn:4Qc1ZMwJ2kCDEiZaoW86gbCDopY8",
        "proof":{
            "creator":"did:bsn:4Qc1ZMwJ2kCDEiZaoW86gbCDopY8",
            "signatureValue":"qGSQGQ3LsZWzwKPjXSFpc6QNEyX3hLk4jruhKNMRB1pCh7AujHS0R8TN2HYzdan7HigqMD2RBQW8I0g50xQDZgA=",
            "type":"Secp256k1"
        },
        "recovery":{
            "publicKey":"11269225430181361242836691470083240698588912504999066036334383939658125900799001159485142543525883167181641171521691885487531759310220878775219494602416230",
            "type":"Secp256k1"
        },
        "updated":"2022-09-08 10:39:52",
        "version":"1"
    },
    "recyKeyInfo":{
        "privateKey":"108084336084494583976203572769842945795131580451324537320160683149905374350774",
        "publicKey":"11269225430181361242836691470083240698588912504999066036334383939658125900799001159485142543525883167181641171521691885487531759310220878775219494602416230",
        "type":"Secp256k1"
    }
}

注意: 平台方仅需注册一次DID,所以建议平台方单独使用DID SDK,无需将其集成到业务系统内。

2、平台方人员需在官方门户提交平台方的BSN DID和DID私钥对DID的签名值,并下载DDC业务凭证

(四)资金账户充值、创建项目

1、平台方可以在官方门户内通过微信支付、企业网银或者线下汇款的方式为自己的资金账户充值

注意: 门户资金账户充值后,平台方可通过官方门户或门户OpenAPI,将资金账户余额充值到自己的任何DDC开放联盟链上的任何链账户内,以保证这些链账户在相应的链上发起的区块链交易能正常执行。

2、在创建项目页面中输入【项目名称】,【开放链框架】下拉中选择【中移链】即可完成创建

注意: 项目创建完成后不允许修改开放链框架,参考链接:https://bsnbase.com/static/tm...

四、门户OpenAPI的接口调用

(一)在线生成链账户公私钥对

1、接口地址: /ddcoai/sys/v1/opb/account/create/publicprivatekey

2、请求方式: POST

3、接口描述

    平台方可通过OpenAPI对所属DDC链账户进行在线生成公私钥对,哪些框架支持可通过'开放联盟链框架-列表查询'接口返回值中opcOnlineCreate为0表示。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
opbChainId 开放联盟链框架 integer

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";

@Test
public void testCreateKeyPair() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/account/create/publicprivatekey";
    CreateKeyPair request = CreateKeyPair.builder()
            .opbChainId(9)
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code":0,
    "errorLogCode":null,
    "errorLogMessage":"",
    "message":"MSG_00000",
    "data":"Public key:\nEOS83Vsg9nooWLoEJNvAtAmr8en5UQMdoU7ztdrjxiL4UGytFUQnB\n\nPrivate key:\n5KbkeSYfXgBWYQsv1NoQsp1nRcYBpGe5BnvucmJcUAR1E4ALYV6\n\nChain account address:\n\n\nMnemonic:\n[calm, cram, relief, inside, pistol, blood, merit, monitor, parade, aspect, network, buffalo]\n\nAlgorithm:\nsecp256k1",
    "portalToken":null
}

(二)创建链账户

1、接口地址: /ddcoai/sys/v1/opb/account/create/save

2、请求方式: POST

3、接口描述

    生成链账户后,平台方通过官方门户OpenAPI登记注册链账户。只有接入官方DDC合约的链账户才能启用BSN-DDC业务功能。新建时可以不接入官方DDC合约,可调“接入官方DDC合约”接口接入。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
opbChainClientName 链账户名称 string
opbChainClientType 用户类型(1=平台方 2=平台方的用户) integer
opbChainId 开放联盟链框架ID(调用接口:开放联盟链-框架列表查询) integer
opbKeyType 链账户类型(调用接口:开放联盟链-框架支持的链账户类型) integer
opbPublicKey 上传公钥(根据链账户类型为2,值必填) string
openDdc 是否接入官方DDC合约 1=不接入 5=接入 integer
proof DDC业务开通凭证 内容需要通过json转义 string

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
 opbChainClientAddress 链账户地址 string
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";
private String proof = "{\"claim\":{\"entName\":\"******\",\"domain\":\"http://www.chinamobilesz.com/\",\"loginName\":\"******\",\"did\":\"******\"},\"context\":\"https://www.w3.org/2018/credentials/v1\",\"cptId\":\"882201251518080013\",\"created\":\"2022-08-19 03:14:15\",\"expirationDate\":\"2042-08-19\",\"id\":\"1560465138044243968\",\"issuerDid\":\"******\",\"proof\":{\"creator\":\"******\",\"type\":\"Secp256k1\",\"signatureValue\":\"******\"},\"shortDesc\":\"DDC业务凭证模板\",\"type\":\"Proof\",\"userDid\":\"******\"}";

@Test
public void testSaveAccount() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/account/create/save";
    SaveAccount request = SaveAccount.builder()
            .opbChainClientName("ddctest11112")
            .opbChainClientType(1)
            .opbChainId(9)
            .opbKeyType(2)
            .opbPublicKey("EOS6R3jYqb3uZsVgzJz4HVLcYV94CLkr3u9unEzm5rpuAqUos7fqK")
            .openDdc("1")
            .proof(proof)
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code":0,
    "errorLogCode":null,
    "errorLogMessage":"",
    "message":"MSG_00000",
    "data":{
        "opbChainClientAddress":"ddctest11112"
    },
    "portalToken":null
}

(三)接入官方DDC合约

1、接口地址: /ddcoai/sys/v1/opb/account/access/official/save

2、请求方式: POST

3、接口描述

基于已有的链账户地址接入官方DDC合约。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
opbChainClientAddress 链账户地址 string
opbChainClientType 用户类型(1=平台方 2=平台方的用户) integer
opbChainId 开放联盟链框架ID(调用接口:开放联盟链-框架列表查询) integer
proof DDC业务开通凭证 内容需要通过json转义 string

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
 opbChainClientAddress 链账户地址 string
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";
private String proof = "{\"claim\":{\"entName\":\"******\",\"domain\":\"http://www.chinamobilesz.com/\",\"loginName\":\"******\",\"did\":\"******\"},\"context\":\"https://www.w3.org/2018/credentials/v1\",\"cptId\":\"882201251518080013\",\"created\":\"2022-08-19 03:14:15\",\"expirationDate\":\"2042-08-19\",\"id\":\"1560465138044243968\",\"issuerDid\":\"******\",\"proof\":{\"creator\":\"******\",\"type\":\"Secp256k1\",\"signatureValue\":\"******\"},\"shortDesc\":\"DDC业务凭证模板\",\"type\":\"Proof\",\"userDid\":\"******\"}";

@Test
public void testSaveOfficial() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/account/access/official/save";
    SaveOfficial request = SaveOfficial.builder()
            .opbChainClientAddress("ddctest11112")
            .opbChainClientType(1)
            .opbChainId(9)
            .proof(proof)
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code":0,
    "errorLogCode":null,
    "errorLogMessage":"",
    "message":"MSG_00000",
    "data":{
        "opbChainClientAddress":"ddctest11112"
    },
    "portalToken":null
}

(四)查看链账户详情

1、接口地址: /ddcoai/sys/v1/opb/account/check/details/search

2、请求方式: POST

3、接口描述

查看DDC链账户的基本信息。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
opbChainClientAddress DDC链账户地址 string
opbChainId 开放联盟链框架ID integer

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
 business 官方DDC业务费余额(分) integer
 createDate 创建时间 string
 did DID string
 gasNum 能量值余额(最大50长度8个小数点) string
 opbChainClientAddress 链账户地址 string
 opbChainClientName 链账户名称 string
 opbChainClientType 用户类型(1=平台方,2=平台方的用户) integer
 opbChainName 开放联盟链框架 string
 opbChainType 链账户类型 string
 openDdcYn 是否已接入官方DDC合约:1=未接入(只开通OPB没有上DDC合约)5=已接入 integer
 opsPlatformState 运营方设置状态(0=未接入官方DDC合约 1=冻结 2=已启用(未冻结) 3=冻结中 4=解冻中) integer
 platformSetState 平台方设置状态(0=未接入官方DDC合约 1=冻结 2=已启用(未冻结) 3=冻结中 4=解冻中) integer
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";

@Test
public void testQueryAccount() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/account/check/details/search";
    SearchAccount request = SearchAccount.builder()
            .opbChainClientAddress("ddctest11112")
            .opbChainId(9)
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code":0,
    "errorLogCode":null,
    "errorLogMessage":"",
    "message":"MSG_00000",
    "data":{
        "did":"did:bsn:49oahBPHZ41zqCbzUPkqRMdqBGvb",
        "opbChainClientName":"ddctest11112",
        "opbChainClientType":1,
        "business":100,
        "createDate":"2022-09-05 17:11:22",
        "opbChainName":"中移链(基于EOS v2.1)",
        "opbChainClientAddress":"ddctest11112",
        "opbChainType":"2",
        "openDdcYn":5,
        "gasNum":"NET:1808172 bytes,CPU:688319 us,RAM:10247 bytes",
        "platformSetState":2,
        "opsPlatformState":2
    },
    "portalToken":null
}

(五)EOS分配资源

1、接口地址: /ddcoai/sys/v1/opb/eos/resource/save

2、请求方式: POST

3、接口描述

    平台方可通过OpenAPI对所属DDC链账户进行分配资源。链账户分配资源所需总金额可通过EOS分配资源价格计算接口进行预览。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
cpuValue 充值cpu数量(SYS) integer
netValue 充值net数量(SYS) integer
opbChainClientAddress 链账户地址 string
opbChainId 开放联盟链框架 integer
proof DDC业务开通凭证 内容需要通过json转义 string
ramValue 充值ram数量(KB) integer
reqTransactionSn 第三方流水号 string
validDate 资源有效期(30天起售)(格式:yyyy-MM-dd) string(date-time)

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";
private String proof = "{\"claim\":{\"entName\":\"******\",\"domain\":\"http://www.chinamobilesz.com/\",\"loginName\":\"******\",\"did\":\"******\"},\"context\":\"https://www.w3.org/2018/credentials/v1\",\"cptId\":\"882201251518080013\",\"created\":\"2022-08-19 03:14:15\",\"expirationDate\":\"2042-08-19\",\"id\":\"1560465138044243968\",\"issuerDid\":\"******\",\"proof\":{\"creator\":\"******\",\"type\":\"Secp256k1\",\"signatureValue\":\"******\"},\"shortDesc\":\"DDC业务凭证模板\",\"type\":\"Proof\",\"userDid\":\"******\"}";

@Test
public void testSaveResource() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/eos/resource/save";
    SaveResource request = SaveResource.builder()
            .cpuValue(1)
            .netValue(1)
            .opbChainClientAddress("ddctest11112")
            .opbChainId(9)
            .proof(proof)
            .ramValue(10)
            .reqTransactionSn("8950jg89j0fi94i")
            .validDate("2022-10-06")
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code": 0,
    "errorLogCode": null,
    "errorLogMessage": "",
    "message": "MSG_00000",
    "data": null,
    "portalToken": null
}

(六)EOS分配资源结果查询

1、接口地址: /ddcoai/sys/v1/opb/eos/resource/search

2、请求方式: POST

3、接口描述

    平台方可通过OpenAPI对所属DDC链账户的EOS分配资源结果进行查询。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
opbChainClientAddress 链账户地址 string
reqTransactionSn 第三方流水号 string

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
 opbChainClientAddress 链账户地址 string
 rechargeState GAS充值状态 1-充值中 5-充值失败 10=充值成功 integer
 reqTransactionSn 第三方流水号 string
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";

@Test
public void testQueryResource() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/eos/resource/search";
    SearchResource request = SearchResource.builder()
            .opbChainClientAddress("ddctest11111")
            .reqTransactionSn("8950jg89j0fi94i")
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code":0,
    "errorLogCode":null,
    "errorLogMessage":"",
    "message":"MSG_00000",
    "data":{
        "opbChainClientAddress":"ddctest11111",
        "reqTransactionSn":"8950jg89j0fi94i",
        "rechargeState":10
    },
    "portalToken":null
}

(七)官方DDC业务费充值

1、接口地址: /ddcoai/sys/v1/opb/account/business/save

2、请求方式: POST

3、接口描述

    如果使用官方合约发起DDC交易则需要官方DDC业务费,因此可通过OpenAPI给平台方所属DDC链账户进行充值。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
businessMoney 充值官方DDC业务费金额(单位:分) integer
opbChainClientAddress 链账户地址 string
opbChainId 开放联盟链框架 integer
proof DDC业务开通凭证 内容需要通过json转义 string
reqTransactionSn 第三方流水号(数字字母下划线组成) string

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";
private String proof = "{\"claim\":{\"entName\":\"******\",\"domain\":\"http://www.chinamobilesz.com/\",\"loginName\":\"******\",\"did\":\"******\"},\"context\":\"https://www.w3.org/2018/credentials/v1\",\"cptId\":\"882201251518080013\",\"created\":\"2022-08-19 03:14:15\",\"expirationDate\":\"2042-08-19\",\"id\":\"1560465138044243968\",\"issuerDid\":\"******\",\"proof\":{\"creator\":\"******\",\"type\":\"Secp256k1\",\"signatureValue\":\"******\"},\"shortDesc\":\"DDC业务凭证模板\",\"type\":\"Proof\",\"userDid\":\"******\"}";

@Test
public void testSaveBusiness() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/account/business/save";
    SaveBusiness request = SaveBusiness.builder()
            .businessMoney(100)
            .opbChainClientAddress("ddctest11112")
            .opbChainId(9)
            .proof(proof)
            .reqTransactionSn("8950jg89j0fi901")
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code": 0,
    "errorLogCode": null,
    "errorLogMessage": "",
    "message": "MSG_00000",
    "data": null,
    "portalToken": null
}

(八)官方DDC业务费充值结果查询

1、接口地址: /ddcoai/sys/v1/opb/account/business/result/search

2、请求方式: POST

3、接口描述

    平台方可通过OpenAPI对所属DDC链账户的官方DDC业务费充值结果进行查询。

4、请求头

    apitoken:eyJ0eXAiOi**********************************************UG9VHWZFBg

5、请求参数

参数名称 参数说明 是否必须 数据类型
opbChainClientAddress 链账户地址 string
reqTransactionSn 第三方流水号(数字字母下划线组成) string

6、响应参数

参数名称 参数说明 类型
code 成功:0,失败:-1 integer
errorLogCode 错误日志编码 string
errorLogMessage 错误日志说明 string
message 消息编码 string
data 结果对象 object
 opbChainClientAddress 链账户地址 string
 rechargeState 官方DDC业务费充值状态 1-充值中 5-充 值失败 10=充值成功 integer
 reqTransactionSn 第三方流水号 string
portalToken 凭此token可以访问共享接口,返回空则表示无法使用 string

7、Java请求示例

1)测试用例

private String baseUrl = "https://openapi-ddc.bsnbase.com";
private String apiToken = "eyJ0eXAiOi**********************************************UG9VHWZFBg";

@Test
public void testQueryBusiness() {
    String url = baseUrl + "/ddcoai/sys/v1/opb/account/business/result/search";
    SearchBusiness request = SearchBusiness.builder()
            .opbChainClientAddress("ddctest11112")
            .reqTransactionSn("8950jg89j0fi901")
            .build();
    String result = HttpRequest.post(url)
            .header("apitoken", apiToken)
            .body(JSONUtil.toJsonStr(request))
            .execute().body();
    System.out.println(result);
}

2) 响应结果

{
    "code":0,
    "errorLogCode":null,
    "errorLogMessage":"",
    "message":"MSG_00000",
    "data":{
        "opbChainClientAddress":"ddctest11112",
        "reqTransactionSn":"8950jg89j0fi901",
        "rechargeState":10
    },
    "portalToken":null
}

五、常见问题

(一)请求OpenAPI接口时,返回错误编码:MSG_20010005、MSG_10021005、MSG_10021029、MSG_10022013、MSG_10027007、MSG_10021059等,如何处理?

MSG_20010005:apitoken 授权认证失败,原因是请求头中的apitoken传参错误,可以从业务开通信息页面的门户OpenAPI Token获取;
MSG_10021005:链账户不存在,原因是该链账户没有创建,或者该链账户没有接入官方DDC合约;
MSG_10021029:充值流水号重复,原因是第三方流水号重复了,需要保持第三方流水号全局唯一,同时需要留存以供查询使用;
MSG_10022013:找不到平台方DID,原因是暂未注册DID标识,或者DID标识还在注册中,需要注册成功后请求;
MSG_10027007:购买的资源有效期必须大于30天,原因是资源有效期设置必须大于30天,暂不支持小于30天的资源有效期;
MSG_10021059:链账户名称格式错误,原因是中移链的链账户格式要求:12个字符,只能包括【12345和26个小写字母】。

(二)关于链账户创建,链账户的名称是否可重复、可修改,以及平台方账户和终端用户账户有什么区别?

目前是同一个账户下链账户名称不可以重复,不可以修改;平台方账户可以管理终端账户的状态,可以在DDC-SDK里对终端用户进行充值。

(三)关于DDC业务费充值,为什么用OpenAPI进行DDC业务费充值后,BSN-DDC门户网站仍显示为0?

门户的业务费、能量值、DDC的显示都不是实时的,是链上同步至链下,链下定时排队去更新的,建议用户使用OpenAPI操作创建链账户,接入官方DDC,业务费充值,账户状态变更后都直接调用DDC-SDK中的方法去链上确认结果。

(四)关于DDC生成,使用官方DDC合约生成DDC都需要支付哪些费用?

使用官方DDC合约生成DDC时,sender账户要支付本次交易所需要消耗的能量值(5分钱左右)和DDC业务费(生成1元,转移、销毁3毛)。

(五)关于DDC生成,使用官方DDC-SDK进行mint操作时ddcURI字段该如何传参?

ddcURI字段为DDC标识符,该字段为String类型,长度限制是1000,内容BSN不做限制,用户可根据自己的业务场景自行传值,例如:{"amount":5000,"id":"001","name":"name","company":"公司","seq":1710,"url":"https://xxxx/upload/file/xx.jpg"}。

(六)关于DDC授权和账户授权,两者的区别是什么?

DDC授权是用户将名下的某个DDC授权给第三方,账户授权是用户将名下的所有DDC授权给第三方,DDC授权在DDC被转移后授权失效,账户授权取消授权后才会失效。

你可能感兴趣的:(区块链开发)