前言:

最近要用区块链用于存证,然后看到京东智臻链开放联盟网络,就了解了一下,然后决定自己写代码来调用它来用于存证,免费还是挺香的。

建议在阅读本文时先了解一下京东智臻链开放联盟网络。

完成注册,登陆后就可以继续了。

一、创建自己的第一个合约:

建立子账户:

合约管理 => 我的智能合约 => 点击创建 => 添加子业务账户

选择密钥非托管,然后将密钥下载后保存后面调用需要用到。

创建第一个智能合约:

回到智能合约页面,在“我的智能合约”中点击“创建合约”。

子账户选择刚才创建的子账户,其余的根据自己心意填。

模板我选择的第一个通用存证模板,根据自己的需求进行选择。

然后便是新增字段。

索引字段即主键,我设置的为‘id’。当然此处根据自己的需求来进行填写设计,我只设置了一个字段,方便测试。

二、签名代码的实现:

合约创建成功后 => 调用 => 开发者调用 ,我们就能看到JD提供的开发文档。

JD提供的文档有些坑,有些地方有点错误。

不过建议大家还是先看一下了解一下大致的流程。

在整个过程中,一共用到了两次签名,一次是本地签名(公钥+私钥+时间戳),一次是交易签名(公钥+私钥+交易哈希)。都是调用JD提供的java编写SDK来完成,于是我将他们封装在了一起。如果不知道如何使用Python调用jar可以先看一下我的这篇文章,传送门。

公钥和私钥就是在创建子账户时,下载的key.txt中。SDK在点击调用 => 开发者调用 ,官方的第一个步骤中点击“下载SDK”。

SignName.py

from jpype import *
import jpype
import timeclass SignName:"""调用京东提供的SDK,实现本地签名,交易签名* @param01: publicKey 公钥原文* @param02: privateKey 私钥原文"""def __init__(self,publicKey:str,privateKey:str) -> None:jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=../jar/local-signature.jar")  #调用京东区块链的SDKself.__JDClass =jpype.JClass("com.jd.bt.chain.Signature") #这说明类在jar包中的目录结构是"com.jd.bt.chain.Signature"  数字签名self.__jdChain = self.__JDClass()  #实例化self.publicKey = publicKeyself.privateKey = privateKeydef localSign(self) -> str:"""返回得到本地签名。调用SDK,signOrigin方法* @param01: timestamp 时间戳* @param02: publicKey 公钥原文* @param03: privateKey 私钥原文"""self.timestampContent = str(round(time.time() * 1000))  #毫秒级时间戳self.result = str(self.__jdChain.signOrigin(self.timestampContent, self.publicKey,self.privateKey))  #子账户签名结果return self.resultdef transactionSign(self,txHash:str) -> str:"""txHash:组装交易后的返回值中。返回得到交易签名。调用SDK,sign方法* @param01: txHash 交易哈希* @param02: publicKey 公钥原文* @param03: privateKey 私钥原文"""self.result = str(self.__jdChain.sign(txHash, self.publicKey,self.privateKey))  #子账户签名结果return self.result

三、请求Token

话不多说直接上代码。使用requests的get方法即可,url为:https://openchain.jd.com/server/account/getServerToken。didKey找不到的看官方提供的开发者调用文档的第一步,上面有didKey的值,复制粘贴即可,公钥和私钥就是子账户的公钥私钥。

GetServerToken.py

import requests
import json
# from SignName import SignNameclass GetServerToken:"""token请求类"""def __init__(self,publicKey:str,privateKey:str,didKey:str,signName) -> None:"""* @param01:publicKey:子账户公钥* @param02:privateKey:子账户密钥* @param03:didKey:账户* @param04:SignName:签名类的实例化"""self.publicKey = publicKeyself.privateKey = privateKeyself.didKey = didKeyself.signName = signNamedef getURl(self,url='https://openchain.jd.com/server/account/getServerToken') -> dict:"""请求的token* @param01:url:请求的网址"""param = {'didKey':self.didKey,'subAccountPubKey':self.publicKey,'signature':self.signName.localSign(),   #子账户签名结果'timestamp':self.signName.timestampContent   #时间戳(被签名内容)}page = requests.get(url,params=param)msg = json.loads(page.text)return msg# if __name__ == '__main__':
#     didKey = '填写自己的账户'
#     publicKey = '公钥'
#     privateKey = '私钥'#     signName = SignName(publicKey,privateKey)
#     print(type(signName))
#     askToken = GetServerToken(publicKey,privateKey,didKey,signName)
#     msg = askToken.getURl()#     print(msg)

如需测试,将注释的打开给相应参数就行。返回值如下

四、组装交易

接下来就是组装交易,用到了token,需要将上一步得到的返回值中的token取出。给定参数后直接使用Post即可,url='https://openchain.jd.com/server/contract/call'

didPkPubK:DID身份信息公钥原文,contractAddress:合约地址找不到,同样也可以在官方文档的第三步中找到。

具体实现看代码,代码给出了详细注释。注意:primaryKey:存证所需的主键。它代表存的是具体参数,不是参数名,不要写错了,最初我掉了进去,然后我创建了一个托管的子账户的合约直接在页面中调用,然后F12,查看了它发送的请求才注意到。同时如果你写错了,他是能够post并返回结果的,我在最后一步中出现问题,回过头来才发现这里的坑。

ContractCall.py

import requests
import json
import sys
# from GetServerToken import GetServerToken
# from SignName import SignNameclass ContractCall():"""组装交易"""def __init__(self,result:str,didKey:str,didPkPubK:str,publicKey:str,contractAddress:str,method:str,primaryKey:str,paramJson:dict={}) -> None:"""* @param01:result:请求的token* @param02:didPkPubK:DID身份信息公钥原文* @param03:publicKey:调用合约用的子账户公钥,必须和签名用的子账户私钥是同一对秘钥* @param04:contractAddress:合约地址* @param05:method:调用方法(insert,query,update,insertOrUpdate四选一)* @param06:primaryKey:存证所需的主键。注:存的具体参数,非参数名!* @param07:paramJson:存证参数(按照数据格式的dict),调用insert和update方法时需要,query方法不需要"""if result['code'] != 20000:print(f'获取Token失败:{result["msg"]}')sys.exit(1)self.token = result['data']['token']#请求头self.postHead = {'Gateway-Appid': didKey,'Gateway-Token': self.token,}self.postData = {'didPkPubK': didPkPubK,'subAccountPubKey': publicKey,  # 调用合约用的子账户公钥,必须和签名用的子账户私钥是同一对秘钥'contractAddress': contractAddress,'method': method,'primaryKey': primaryKey,'paramJson':  json.dumps(paramJson)}def postURL(self,url:str='https://openchain.jd.com/server/contract/call') -> dict:"""组装交易后的返回值* @param01:url:请求的网址"""page = requests.post(url, headers=self.postHead, json=self.postData) msg = json.loads(page.text)return msg# if __name__ == '__main__':#     didKey = ''
#     publicKey = ''
#     privateKey = ''
#     didPkPubK = ''
#     contractAddress = ''
#     method = 'insert'
#     paramJson = {
#         'id' = 11
#     }
#     primaryKey = paramJson['id']  #存证所需的主键
#     signName = SignName(publicKey,privateKey)
#     getServerToken = GetServerToken(publicKey, privateKey, didKey,signName)
#     result = getServerToken.getURl()#     contractCall = ContractCall(result,didKey,didPkPubK,publicKey,contractAddress,method,primaryKey,paramJson)
#     ans = contractCall.postURL()
#     print(ans)

返回值示例:

{'code': 20000, 'msg': '操作成功', 'data': {'params': [{'address': 'LdeP5sRTSLNLpScahgrH51sfgVroJES2hAtjH', 'methodName': 'insert', 'key': 'wan', 'paramJson': '{"name": "wan"}', 'paramType': 'String'}], 'txContent': '112JJhCfsgmv4pK6Xhd7WCbSiCYVepFAiMdabY3RN7sRotLhTHfKQZK4WPeanxfn9VpK3Tb5h3sAQ49bpx68NRj8ZoavrTNCEt9D515BFsKwouLEenXBDJRaGa1xMmJaexZxbXqChCuAV4HjV1Wrfz8DhrsqcQ5Ek1eTvHQ7HC8xbjALNw6w6YWpvRvtTUm3xkNTz7xc8AxbpPjEHAxYVUDE4rpgrjHK4Cv5SwiB2dEp2H', 'txHash': 'j5kd9kT62AqM97QVSX8pygL8DXv8S34Z4esMpyomVqnpWB', 'signerPubKey': '7VeRLfw1QyERWTPZmPJPKwiHUHGFJIUyK9XRsU2L9cL5vf6w', 'signature': None}}

五、交易

最后一步。

官方文档在最后一步把参数名'signerPubKey' 错误的写成了 'publicKey',我使用F12调试后才发现,上一步骤我已说具体方法。同时上一步的请求头和这次是一样的,并且返回值中Data与我们Post需要给的json参数,相差不大,我们只需要再向其中加入我们的交易签名结果即可。url='https://openchain.jd.com/server/contract/sign'

Transaction.py

import requests
import json# from GetServerToken import GetServerToken
# from ContractCall import ContractCall
# from SignName import SignNameclass Transaction:"""交易"""def __init__(self,result:dict,postHead,signName) -> None:"""* @param01: result 组装交易后的返回值* @param02:SignName:签名类的实例化"""self.postHead = postHeadself.data = result['data']self.txHash = result['data']['txHash']self.signName = signNameself.signerPubKey = self.signName.transactionSign(self.txHash)self.data['signature'] = self.signerPubKeydef postURL(self,url='https://openchain.jd.com/server/contract/sign') -> dict:"""最终交易后的返回值* @param01:url:请求的网址"""page = requests.post(url, headers=self.postHead,json=self.data) msg = json.loads(page.text)return msg# if __name__ == '__main__':#     didKey = '
#     publicKey = ''
#     privateKey = ''
#     didPkPubK = ''
#     contractAddress = ''
#     method = 'insert'
#     paramJson = {
#
#     }
#     signName = SignName(publicKey,privateKey)
#     primaryKey = paramJson['id']
#     getServerToken = GetServerToken(publicKey, privateKey, didKey,signName)
#     result = getServerToken.getURl()#     contractCall = ContractCall(result,didKey,didPkPubK,publicKey,contractAddress,method,primaryKey,paramJson)
#     ans = contractCall.postURL()
#     transaction = Transaction(ans,contractCall.postHead,signName)
#     ans = transaction.postURL()
#     print(ans)

返回值示例:

{

"code": 20000,

"msg": "操作成功",

"data": {

"transactionHash": "j5pMNEQolpWgX1y1m2q37CWkBD1yQfQcpvVSVuNb5fftpd",

"blockHeight": "507",

"content": "{\"xingMing\":\"update1204\",\"zhuJian\":2}",

"time": "2020-12-04 10:58:08",

}

}

同时我们也能够在“我的智能合约” 中点击数据列表中查询到刚才上链的信息。

京东智臻链开放联盟网络的快速部署调用相关推荐

  1. 低成本快速上链 智臻链开放联盟网络正式对外开放

    近些年来,区块链一词频繁出现在人们的眼前.从央行数字货币到 Facebook的libra 项目,各大跨国银行.互联网巨头也在区块链赛道频频发力.区块链正快速走进大众视野以及政策层面,引起了全球范围内的 ...

  2. 京东智臻链首推电子营业执照区块链应用场景落地!

    9月18日,宿迁市工商局与京东集团益世商服.大数据与智能供应链事业部在京东集团总部发布国内首个电商电子营业执照区块链应用平台,宿迁市工商局.京东商城.益世商服三方成功部署区块链节点,并实际应用于京东平 ...

  3. 京东智臻链首推电子营业执照区块链应用场景落地

    9月18日,宿迁市工商局与京东集团益世商服.大数据与智能供应链事业部在京东集团总部发布国内首个电商电子营业执照区块链应用平台,宿迁市工商局.京东商城.益世商服三方成功部署区块链节点,并实际应用于京东平 ...

  4. 区块链BaaS云服务(8)京东 智臻链

    底层链:Hypreledger Fabric ,JD Chain链, Stellar 上传链码:网页 底层存储:可选择levedb或couchdb. 应用领域:商品溯源.电子合同.广告监管.版权保护. ...

  5. 京东数科与京东云联袂发布智臻链“云”

    点击「京东数科技术说」可快速关注 7月17日,"区块链+京东云 大有可为"战略合作媒体沟通会在北京国家会议中心召开. 会上,京东数科与京东云宣布在区块链技术服务领域深度合作,重磅发 ...

  6. 京东区块链(智臻链):1. 应用场景

    "京东智臻链"是京东区块链的技术品牌,致力于打造全方位.全生命周期的企业级区块链应用解决方案,让开发者和企业实现一站式规划.配置.开发.上线.运维,一键自动配置和部署区块链网络,降 ...

  7. 京东云智臻链开源两周年,JD Chain领跑国内自研区块链技术

    近年来,区块链技术发展成为全球关注的重点,国内从中央到地方均给予了高度的政策支持,国内领军企业纷纷布局.京东云智臻链自主研发JD Chain区块链底层架构,于2019年3月率先开源开放,成为了国内区块 ...

  8. 蚂蚁区块链开放联盟链发布会 | 巴比特全程支持

    [直播介绍] 蚂蚁区块链"开放联盟链"面向中小企业和开发者发布,三重福利助推全民入链: 注册即获赠1亿开发燃料GAS: 购买即享受GAS翻倍.企业版半价购和阿里流量助力: 领取现金 ...

  9. 区块链的未来:公链VS联盟链

    早科技音频:00:0009:47 区块链在历经这几年的发展后,到现在已经有了不少成果产出.不少技术积累,也在一些行业有成熟的落地项目.而在区块链的起步过程中,同样将区块链作为国家战略的中国和美国,对于 ...

最新文章

  1. C++实现树的建立,查找,遍历输出
  2. 51nod 1087 1 10 100 1000
  3. java 与 php lajp_LAJP
  4. js实现轮播图_高性能轻量级零依赖的轮播图组件——Glider.js
  5. xps13 linux 硬盘分区,在xps13上安装ubuntu16.04教程
  6. 容器编排技术 -- Kubernetes Nodes
  7. 修改蓝牙耳机按键映射_拆解报告:QCY T4 TWS蓝牙耳机
  8. Codeforces Round #518 (Div. 2): F. Knights(神题)
  9. 室内定位发展趋势分析
  10. java用switch语句抽奖_Java使用带有switch语句的枚举
  11. Joint Autoregressive and Hierarchical Priors for Learned Image Compression文献复现
  12. n918st能刷Android5吗?,中兴 N918ST中文Recovery刷机教程
  13. 3分钟了解入门「机器学习」该学习什么?(上)
  14. Matlab Deep Network Designer APP搭建神经网络及相关函数讲解
  15. ubuntu 复制文件夹到另一目录命令
  16. k3导入账套_k3新建帐套如何导入会计科目
  17. Java基础 基础数据类型
  18. 第一套微信小程序教程目录(转载侵删)
  19. 什么是APU(辅助动力装置)?
  20. SOLIDWORKS Composer关键帧-制作动画的利器

热门文章

  1. 2018UI课程总结(UI理论篇)
  2. 学奥数还是计算机,到底该不该让孩子学奥数,不妨先看看这个
  3. 在ABAQUS中开发材料模型(UMAT)的通用框架:基于Fortran的大变形本构行为的3D实现方法
  4. NOIP2016 普及组 总结+题目吐槽+代码+简单题解
  5. ANSYS APDL中的压电分析
  6. 教改论文 计算机,大学计算机教育教改论文论文
  7. 电脑手机硬件测试软件,手机硬件检测工具_手机硬件检测软件_手机硬件检测软件哪个好【最新】-太平洋电脑网...
  8. 什么是JavaScript 函数式编程?
  9. 初学Django:第七天,Redis的配置和使用
  10. CentOS 端口转发