动手编 SDK | BSN 联盟链开发(二)

人生,总避免不了开发几个 SDK ✧(•̀ω•́ )

系列索引: 上链与背后的流程 | 联盟链开发(一) 动手编 SDK | 联盟链开发(二) SDK 1.0 版本的打造 | 联盟链开发(三) 将 SDK 发布到 PIP | 联盟链开发(四) 什么样的数据应该上链?| 联盟链开发 (五) BSN 相关问与答 | 联盟链开发(六) 链上简历应用 — 设计 | 联盟链开发(七) FISCO BCOS 介绍 | 联盟链开发(八) WeIdentity 极速体验 | 联盟链开发(九) 给Remix升个级 | 联盟链开发(十) 伪代码简述 ECDSA 签名过程 | 联盟链开发(十一)


上回我们使用 BSN 官方提供的示例体验了一下上链操作及简要阐述了一下背后的原理。但是,由于仅为「示例」,所以代码耦合程度较高,要想「为我所用」还需要整理为 SDK。

自然可以将整理出来的代码直接放出来,但是记录与梳理「造轮子」的过程,对于自己的未来工作以及其它人未来的工作都会有帮助,因此我在这里会用几篇文章讲述如何一步步开发 SDK。

1 一个趁手的 SDK 需要哪些要素

SDK 相当于现实生活中的一件工具。

那么,在生活中我们要发明一件让自己和别人使用的工具,需要哪些要素?

  • 文档友善 —— 需要友善的说明书告诉我怎么使用这个工具
  • 可配置性好 —— 该能配置的地方需要配置不要写死
  • 返回结果合理 —— 用工具加工出的产品需要在我们的预料之内

2 以 get_data 为例进行函数改造

2.1 解析源码

在官方提供的示例中,找到 views.py > get_data 函数,这个函数起到的作用是从链上查询信息:

def get_data(request):

    logger.info('\n #######进入get_data方法########')

    if request.method == 'POST':
        userCode = "reddate"
        appCode = "CL1851016378620191011150518"
        chainCode = "cc_base"
        funcName = "get"
    baseKey = request.POST.get('baseKey')
    if len(baseKey.strip()) == 0:
            return render(request, 'get.html', {'hint': '唯一标识不能为空!'})

        logger.info('输入的baseKey:%s', baseKey)

        str = userCode + appCode + chainCode + funcName + baseKey
        logger.info('拼接待签名的字符串:%s', str)

        # 对字符串 A使用户证书的私钥进行 SHA256WITHECDSA签名
        mac = myecdsa256.ecdsa_sign(str, './certificate/private_key.pem').decode()
        logger.info('base64格式mac值:%s', mac)

        url = 'https://quanzhounode.bsngate.com:17602/api/node/reqChainCode'
        headers = {'content-type': 'application/json'}

        datas = {"header": {"userCode": userCode, "appCode": appCode, "tId": "dc1d6010b7ff421dae0146f193dded09"},
                 "body": {"chainCode": chainCode, "funcName": funcName, "args": [baseKey]},
                 "mac": mac}

        logger.info('get_data请求传参:%s', datas)

        try:
            r = requests.post(url, headers=headers, json=datas, verify='./certificate/bsn_https.pem')
            if r.status_code == 200:
                result = r.json()
        ……

我们可以看到,这个函数传入了一个 request 参数,然后拿了request 中的 baseKey 这个键的值,再通过一系列写死的参数加上 baseKey,去访问一个 url 最终得到结果。

2.2 函数改造

如果要设计成 SDK 中的函数,那么要做如下改造:

  • 传入的不应该是request 类型的参数,而应该是一些更基本的值,例如字符串形式的 baseKey。
  • 函数应当进一步拆分,拆分为get_data__do_get_data两个函数,使代码结构更清晰。

因此,首先设计一个函数get_data(baseKey, url)

def get_data(baseKey, url):
    userCode = "reddate"
    appCode = "CL1851016378620191011150518"
    chainCode = "cc_base"
    funcName = "get"
        if len(baseKey.strip()) == 0:
            logger.error("baseKey can not be null")
        else:
            return __do_get_data(userCode, appCode, chainCode, funcName, baseKey, url)

然后设计一个__do_get_data(...)

def __do_get_data(userCode, appCode, chainCode, funcName, baseKey, url):
    payload = userCode + appCode + chainCode + funcName + baseKey
    logger.info('拼接待签名的字符串:%s', payload)

    mac = myecdsa256.ecdsa_sign(payload, './certificate/private_key.pem').decode()
    logger.info('base64格式mac值:%s', mac)

    data = {"header": {"userCode": userCode, "appCode": appCode, "tId": "dc1d6010b7ff421dae0146f193dded09"},
                "body": {"chainCode": chainCode, "funcName": funcName, "args": [baseKey]},
                "mac": mac}
    headers = {'content-type': 'application/json'}
    res = requests.post(url, headers=headers, json=data, verify='./certificate/bsn_https.pem')
    return res.json()

那么,我们就获得了这样一个函数get_data,传入 baseKey和 节点地址 url,最终得到从链上拿下来的 json。

3 类的设计

Python 是一门基于面向对象思想的语言,所以函数最好还是放到一个类里面。因此设计一个叫做 Operator 的类。

import requests
from common.loggers import logger
from common import myecdsa256

class Operator:
    def get_data(self, baseKey, url):
    ……
    else:
        return self.__do_get_data(userCode, appCode, chainCode, funcName, baseKey, url)

    def __do_get_data(self, userCode, appCode, chainCode, funcName, baseKey, url):
    ……

4 init 文件

为了方便调取,在 sdk 文件夹下创建了__init__.py文件:

from sdk.operator import Operator

目录结构目前如下:

5 测试

现在来看一下效果如何:

Okay,如期拿到了链上结果。

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 2020-01-16 11:51
  • 阅读 ( 423 )
  • 学分 ( 102 )
  • 分类:BSN

1 条评论

请先 登录 后评论
李大狗
李大狗

上海对外经贸大学区块链研究中心副主任

19 篇文章, 3092 学分