迅雷链BaaS平台是以高性能区块链迅雷链为底层技术支持打造的。在迅雷链BaaS平台中,开发者可一键完成区块链部署与运维、可以进行在线编译和发布智能合约,并支持区块链规模的动态扩展,用户可以与其它企业、机构或者个人,共同构建联盟链。联盟的创建者拥有权限管理能力,在保证联盟链公正的同时,做到可控可扩展。
迅雷链为各行各业开发者提供成长的沃土,全维度解决企业和开发者应用区块链的难题,让企业专注于业务层的应用创新和功能开发。
超低成本,一键部署
迅雷BaaS平台提供超低成本、一键部署、简单易用的区块链服务,大幅度降低区块链使用门槛,让企业和开发者无需考虑底层技术,专心搭建区块链应用。
构建业务联盟生态
用户可以选择在联盟大厅展示自己的联盟链,展现联盟链下的业务场景特性,为链接不同企业赋能,助力合作伙伴构建新的商业机会。
秒级确认,快速可靠
独创的DPoA+ PBFT共识机制实现了超低延迟的实时区块写入和查询;单链的出块速度可达秒级,而且保证强一致性,不会产生分叉,从而保证快速、可靠地完成上链请求。
为数据信息安全,提供可靠保障
支持包含国密在内的多套密码算法,提供多种先进的隐私保护方案,通过强身份认证保证数据安全,支持敏感信息过滤等信息安全管理手段。独创的可追溯隐私保护技术率先同时支持链上数据追溯和隐私保护,使得区块链技术可以真正应用于政务、金融、医疗等对数据安全性要求极高的领域。
创建联盟
用户可以在我的联盟页申请创建联盟,按照指引填写和选择创建联盟的相关信息,完成相关节点配置信息操作后,联盟创建成功。用户可以在我创建的联盟页看到已创建的联盟。
加入联盟
联盟链的盟主可邀请其用户加入自己的联盟,平台的用户也可以在联盟大厅内查看公开展示的允许外部加入的联盟链,选择申请加入。照加入指引通过盟主审批并完成相关信息配置后,即可成为联盟中的一员。用户可以在我加入的联盟页看到已加入的联盟。
自动化部署
迅雷链BaaS平台的区块链节点软件采用自动化部署方式,会按照用户选择的配置信息和需求,自动快捷的完成区块链平台的建立。
区块链应用
联盟的成员可以在联盟内创建和发布区块链智能合约应用,支持联盟内所用的成员共同使用和维护。
BaaS SDK
联盟内的成员可以通过由盟主分配的SDK密钥,使用SDK连接指定的节点发起智能合约交易;SDK支持用户快速调用合约,支持合约参数与执行结果编解码功能。
BaaS区块链浏览器
联盟内用户可通过BaaS区块链浏览器查询链上的信息、包括交易数目、交易信息、账户信息等,以及合约地址、交易hash、账户地址的查询。
迅雷区块链架构图
迅雷链落地众多领域,赋能实体经济
迅雷链的合作伙伴包括中国版权保护中心、华扬联众、泰国那黎宣大学、南方新媒体、深圳市版权协会壹基金等多家政企机构,在金融、医疗、教育、版权保护、溯源、公益、保险、交通、基因、供应链、新零售等诸多领域落地应用,为这些行业带来了更高效的技术解决方案。
华扬联众:区块链赋能用户价值生态
知名数字营销服务商华扬联众宣布携手高性能区块链平台迅雷链,发布国内首个营销区块链应用“麦哲伦”,意图在去中心化时代重构品牌与用户的关系,打造全新用户价值生态。基于区块链公开、透明、可追溯的特性,麦哲伦平台得以高效构建起品牌和用户之间的信任机制和激励机制,让品牌主和用户都受益。
麦哲伦这样联合了华扬联众、安踏、多点Dmall、猫眼等重量级企业的营销平台,日均处理数据量非常庞大,少则几亿,多则几十亿,且这些数据在传输过程中往往需要瞬时确认,对于底层区块链平台的性能要求极高,一般的区块链平台很难支持如此级别的用户使用需求。
华扬联众CTO章骏博士表示,“华扬联众在寻求区块链技术伙伴时非常重视性能问题。如果传统的公链是单车道的话,那么迅雷链的技术就相当于双向八车道的高速公路,这样同时具备效率和可靠性的强大技术,是华扬联众选择迅雷链最根本的原因。”
泰国那黎宣大学医院:区块链技术赋能490+医疗机构
泰国那黎宣大学(Naresuan University )宣布与迅雷链建立战略合作关系,将迅雷链先进的区块链技术应用于泰国那黎宣大学管理的490多家医疗机构。基于迅雷链的解决方案,那黎宣大学将下属医疗机构的病例信息上链,在保护病人隐私的同时进行信息互联和追溯。这一措施可以打破不同医院之间的围墙,实现信息互通。偏远地区的医生能够通过此平台从上级医院获取病人病史信息,在信息量对等的情况下针对病患病情进行准确分析。区块链的分布式、可追溯属性还能够确保病例不被恶意篡改,每次改动信息都会自动上链,增加违规操作的成本,为事后可能出现的医疗事故提供可信证据链。
此外,基于迅雷链先进的隐私保护技术,该平台采用两层密码管理病例,医生调用病例时,病人可通过管理系统对区块链密钥进行授权,保证医生在许可的情况下,能够看到HIS上的历史病例信息,从而充分保障病例资料安全和病人隐私。
那黎宣大学项目负责人Dr. Paisarn表示,此次合作既要满足上百万病人的隐私保护与隐私授权的需要,又要兼顾用户体验,因此对技术团队的要求不仅仅是技术方案的提供,还要帮助理清用户使用逻辑和交互方案。迅雷链的技术团队不仅展现了优秀的技术实力,还在技术应用落地上有着非常丰富的经验,从而使得此次合作完美落地。
中国版权保护中心: 构建国家版权新生态
中国版权保护中心联合新浪微博、迅雷、京东商城等国内多个重量级互联网平台,重磅发布中国数字版权唯一标识(DCI)标准联盟链,用区块链技术赋能版权保护,助力全媒体时代融合纵深发展。国内区块链技术的创领者迅雷作为技术合作方,为DCI体系提供区块链技术支持。
版权业务在数字化过程中,暴露出原创作品版权保护不到位的问题,而目前对于原创内容的保护尚缺乏完善的机制和普遍性的共识。结合区块链技术可以打造提供优质、便捷、高效的版权管理服务系统,提升业务效率。
作为整个互联网的数据版权服务体系,DCI标准联盟链需要解决上亿网民存储亿级以上的数据量需求,同时需要面对随时可能出现的高并发访问要求和内容确权,以及对访问、查询结果的响应速度需要达到秒级。在区块链底层技术性能上有着极高的要求。迅雷链凭借强大的性能优势,成功为DCI标准联盟链提供了高并发、使用便捷、易扩展的技术解决方案。
壹基金:公益信息上链,探索公益新未来
壹基金-创新型公益组织,中国第一家民间公募基金会,致力搭建专业透明的公益平台。使用迅雷链解决方案将公益信息记录上链,确保信息记录的安全公正。壹基金将灾害救助项目报告同步上传至迅雷链,公益款的收入、支出、明细等财务数据记录存证,做到每一笔拨款的公开透明,实现公开且不可篡改的救助项目报告,确保信息记录的安全公正。
贝富溯源:区块链防伪溯源
贝富新技术有限公司是广州开发区政府通过认定的区块链应用科技企业。溯源码使用RFID+NFC低成本且不窜码的防伪码技术,依托于迅雷链技术记录查询从生产、仓储、物流、全环节的真是信息,实现一物一码,为打击假冒伪劣商品,印证商业诚信提供了有公信力的解决方案。
广州市地方金融区块链征信共享平台:破解中小企业融资难题
由迅雷链提供技术支持的广州市地方金融区块链征信共享平台,将充分利用各方优势资源,解决中小微企业的征信数据共享,进而解决融资难、融资贵的难题。
长久以来,作为地方经济重要命脉的中小微企业,却面临着信用状况难以评估、以致于融资难度和成本加大的困境。而传统的中心化数据采集方式存在采集成本高、隐私难保证、各征信机构间信息不流通等弊端,需要借助区块链技术高效解决。
在综合考虑性能、安全和易用性等方面后,广州市地方金融区块链征信共享平台选择迅雷链携手合作。尤其是迅雷链的多项密码学技术创新,实现多层级密钥和对称加密功能,真正实现对节点的“穿透式监管”和数据的脱敏处理,可在不泄露隐私的情况下满足信息追溯需求。此外,迅雷链提供简易的接入方式,也非常符合当前征信融资行业的实际情况。
联盟链
是指一种由有限个机构成员组成的区块链网络,联盟成员共同协作完成一个或多个特定的业务场景,通过联盟自治和节点准入准出控制策略,保障联盟的安全健康发展。联盟链有较好的性能,较高的可扩展性,更容易落地现实业务场景和服务实体经济。 联盟链节点为事先设定,并通过共识机制确认,新增的节点需要通过联盟的准入。一般不需要数字货币提供交易验证激励。联盟链容易进行节点权限设定,拥有更高应用可扩展性。联盟链可大幅降低异地结算成本和时间,比现有系统更简单,效率更高,同时继承去中心化优点减轻垄断压力。
联盟盟主
联盟链的创建者
联盟成员
已加入联盟中的各个用户。
节点
组成联盟链的基本单元,用来同步各成员的数据。提供分布式账本的所有功能或者部分功能的实体。
智能合约
智能合约是指在区块链网络中自动执行的程序,执行的规则由具体的业务应用抽象而来,必要时执行的规则可更新。智能合约是区块链上公开透明、自动执行的规则。
SDK
开发者用于接入迅雷链的开发工具包,使用SDK可以快速调用和查询指定节点的智能合约。
区块链 BaaS 服务由迅雷链平台进行托管,在使用区块链 BaaS 服务之前,您需要先加入迅雷链开放平台成为注册用户并完成实名认证。
加入迅雷链开放平台后,即可登录控制台开始使用迅雷链BaaS服务。用户可以购买节点用于创建联盟链,或者加入其他用户创建的联盟链添加属于自己的节点。
存储空间说明:购买节点时每个节点会包含100GB存储空间,用户可以根据自身业务情况选择存储空间升级服务。当联盟链开始运行后,会持续产生心跳区块,占用一部分存储空间。
用户创建完订单后,可以在迅雷链BaaS控制台 > 资产管理 > 我的订单里,查看和管理相关订单。订单的状态一般分为已支付、待支付、订单取消、订单超时、企业线下支付等。用户可以选择要查询的时间段,来查看特定时间内的订单信息。
如果您需要查看某个订单的详情,单击该条订单信息后的 详情 按钮,即可打开订单详情页面。您可以在此页面查看此订单购买的产品、数量、配置等信息。
用户可以在购买的迅雷链BaaS服务到期或到期后规定时间内进行续费(到期后相关数据为您保留10天)。为了确保您的业务续费成功,建议您在业务到期前办理续费。业务续费以最终结算成功为准。 在迅雷链BaaS控制台 > 资产管理 > 续费管理里,可以进行相关查看和续费的操作。选择续费时长并支付完成后,续费成功。
若用户在实际使用过程中,对存储空间有更高的要求,可以对已购买的服务进行升级。如果节点存储空间已满,未升级存储空间的节点将自动下线,不参与整体链的运行。下线节点过多可能导致整条链运行失败。存储空间已满的节点仍然正常计费,请用户及时升级。业务升级以最终结算成功为准。
在迅雷链BaaS控制台 > 资产管理 > 升级管理里,选择需要升级的节点,进行升级操作。选择升级并支付完成后,升级成功。
在进行升级管理时,联盟链上所有的节点都进行升级(即各个节点的存储空间都大于已使用的空间),才能保障整条链的升级成功。需要联盟内部所有成员对升级内容达成一致。
迅雷链支持申请增值税电子普通发票。增值税电子普通发票与增值税纸质普通发票代码位数不同外,效用一致。电子发票的法律效力、基本用途、基本使用规定等与税务机关监制的增值税普通发票相同。消费者可将电子发票用于维权或报销;受票企业可作为正式的会计凭证入账。
仅支持已经实际消耗的费用的开票需求,每30天后可开具前一周期费用的发票。
例:某笔订单预付费周期为6个月(180天),第1个月内不可申请开票,第2个月内可申请开具第1个月的费用发票。若第2个月未申请开票,则第3个月内可申请开具前两个月的发票。
在迅雷链BaaS控制台 > 资产管理 > 发票管理里,可以进行开票申请。申请通过审批后,电子发票将会在15个工作日内发送到用户提供的电子邮箱中。
迅雷链支持线上退款申请。仅支持该笔订单中尚未实际消耗的费用的退款需求,自申请之日起,每30天内<15天按0.5个月计算,≥15天按1个月计算。
例:如某服务每个月费用100元,预付费6个月,费用为600元。
在第10天申请退款,应退费用为5.5个月(6个月-0.5个月),即550元。
在第50天申请退款,应退费用为4个月(6个月-2个月),即400元。
通过活动参与购买产品服务时,如果通用退款规则与活动规则不一致,以活动规则为准。
若用户对某个产品服务申请退款,该服务相关的付费、续费、升级服务将一同统计后进行退费。
在迅雷链BaaS控制台 > 资产管理 > 退款申请里,可以进行退款申请。企业用户提供对公账户相关信息资料,个人用户提供开户银行账号相关信息资料。申请通过审批后,款项将会在20个工作日内退回至用户提交的账户。
创建联盟即创建一条由若干组织或部门共同参与运行维护的联盟链。个人或者企业开发者可以通过以下两种方式进入”创建联盟“页面:
登录迅雷链开放平台,点击主页面一级菜单“BaaS”进入BaaS主页,之后点击“立即使用”进入“创建联盟”页。
登录迅雷链开放平台,进入管理中心 > 迅雷链BaaS控制台 > 我的联盟 > 我创建的联盟,点击“创建联盟"即可创建联盟。 在创建联盟页面填写以下字段,完成联盟链的创建。
请注意:购买迅雷链BaaS服务的用户必须在迅雷链开放平台完成实名认证。如果在提交订单前未完成实名认证,系统会跳转实名认证,并保留订单信息。平台完成实名认证审核后,用户可从“迅雷链BaaS控制台 > 资产管理 > 我的订单”页再次进入订单确认页提交订单,完成支付。
在支付页面,用户选择支付方式。因平台限制,微信扫码支付每日限额3000元人民币,支付宝扫码和网银支付受用户个人支付宝或银行账户限额限制,应选择适合自身情况的支付方式。
联盟创建者可以邀请自己的合作伙伴加入自己创建的联盟链。在“管理中心 > 迅雷链BaaS控制台 > 我创建的联盟 >”选择查看某个联盟,在查看联盟页面点击“邀请成员”拉起邀请弹窗。
在邀请弹窗填写被邀请用户的邮箱地址和备注(可选)。点击确定后,被邀请用户将收到一封带有邀请链接的邮件。
被邀请用户点击邮件内的邀请链接,跳转迅雷链开放平台,完成开放平台注册登录和节点购买,“加入联盟”。
在”管理中心 > 迅雷链BaaS控制台 > 我的联盟 > 我创建的联盟”进入联盟后,可以查看自己创建的联盟概况,包括网络状态、在线节点/总节点数、成员数,以及通过区块链浏览器查看链的运行情况。
在”管理中心 > 迅雷链BaaS控制台 > 我的联盟 > 我创建的联盟”进入联盟后,可以管理联盟链的节点。用户可以在这里暂停/启用某个节点,但暂停节点可能影响整条链的运行,请务必谨慎操作。
当用户因为自身业务或联盟管理原因,需要添加节点数量时,可在联盟内的“节点管理”界面完成添加节点的操作。用户点击“添加节点”按钮,打开购买节点的页面,填写以下字段完成节点购买:
在当前版本中,只有联盟的创建者拥有管理联盟中智能合约的权限,包括创建、查看、发布、停止合约的权限。创建者可以在进入联盟后“合约管理”界面“创建合约”。创建时需填写以下字段:
联盟创建者可以创建和分配SDK密钥,持有密钥的用户可以通过智能合约向链上读写数据。创建密钥时需填写以下字段: 名称:密钥名称。 绑定节点:将密钥绑定在全部或特定节点,规定执行智能合约时所发送请求的节点。 用途备注:备注SDK密钥的用途。 联盟创建者还可以启用/禁用SDK密钥,以对合约的外部调用权限进行控制。
如果联盟创建者选择将联盟在大厅进行展示,则会收到其他用户的加入申请。创建者可以对收到的申请进行管理,包括通过或拒绝其他用户的申请。通过申请的用户在购买节点后正式成为联盟的一员。
用户可以通过两种方式加入其他用户创建的联盟:
用户在“管理中心 > 迅雷链BaaS控制台 > 我的联盟 > 我加入的联盟“界面进入自己加入的联盟后,可以在“节点管理”页进行“添加节点”的操作。添加节点与第一次购买节点时的的操作相同。
用户在“管理中心 > 迅雷链BaaS控制台 > 我的联盟 > 我加入的联盟 > 申请进展“界面可以查看自己的申请进展,这里显示的申请进展状态有“申请中”和“被拒绝”两种。被通过的申请将在单独的“已过审”界面呈现。
用户可通过“管理中心 > 迅雷链BaaS控制台 > 联盟大厅“进入联盟大厅。联盟大厅展示了使用迅雷链BaaS服务,并同意在此展示的联盟链网络。用户可以在此查看自身联盟的概况,以及其他联盟的简介,并申请加入其中(如果对方允许其它用户申请加入的话),寻找可能的链上合作机会。为了提高申请通过的机会,在申请时可加入一段“申请说明”。
本章节将为开发者依托迅雷链BaaS平台开发区块链合约应用提供指引。
对于开发者来说,模块视图如下:
+------------+ +------------+ +------------+ +------------+
| APP | | APP | | APP | | APP |
+------------+ +------------+ +------------+ +------------+
| | | |
v v v v
+------------------------------+ +------------------------------+
| | | |
| SDK | | SDK |
| | | |
+------------------------------+ +------------------------------+
| |
v v
+-----------------------------------------------------------------+
| |
| BaaS API |
| |
+-----------------------------------------------------------------+
其中
开发者无需关心BaaS接口,只需熟悉SDK,并遵守应用开发规范进行APP开发即可。
接下来将循序渐进,先帮助开发者熟悉SDK,随后以一个APP demo为例详解合约应用开发规范。
迅雷链提供 Go-SDK 以方便开发者与区块链系统(BaaS接入层)进行通信和交互。
当前,迅雷链SDK可由开发者在SDK的基础上自行集成,也可借助官方SDK-Server示例直接提供HTTP接口访问服务。
接入SDK所需的SDKid和SDKKey可以通过联盟链创建者在控制台添加,将生成的SDKid和SDKKey发送给指定的接入者;注意SDK密钥对的保存和管理,如有遗失或泄露,可在控制台禁用。
文档将首先介绍SDK,以帮助开发者初识原理。随后介绍官方SDK Server,方便开发者无需编码快速搭建SDK服务环境。
简言之:SDK接收账户请求并封装,随后将其转发至BaaS接入层。
SDK目录结构如下:
.
├── sdk.go // SDK接口的结构体实例
├── sdkapi.go // SDK实例的所有接口实现
├── args.go // SDK使用的消息结构
├── account.go // SDK账户管理
├── config.go // SDK包所需的所有配置信息
├── log.go // SDK包日志接口
├── dnscache.go // BaaS接入层的DNS解析缓存
├── client.go // 封装与BaaS接入层交互的客户端
├── httpcli.go // 封装简易HTTP请求方法
├── util.go // 通用函数
└── errors.go // 错误码
开发者在使用SDK时,需遵循以下步骤:
设置SDK全局配置
在SDK中,其需要的所有配置信息如下:
// AuthInfo 负责通过认证与BaaS交互 type AuthInfo struct { ChainID string `json:"chainid"` // 链ID ID string `json:"id"` // BaaS为开发者分配的SDKid Key string `json:"key"` // BaaS为开发者分配的SDKKey } // Config SDK配置信息 type Config struct { Keystore string // Keystore目录 保存用户账户秘钥 UnlockAccounts map[string]string DNSCacheUpdateInterval int // BaaS接入层 DNS刷新周期 单位:秒 RPCProtocal string // BaaS接入层 协议 XHost string // BaaS接入层 Host Namespace string // 区块链名称空间 tcapi ChainID int64 // 链ID GetFee bool // 是否从BaaS获取fee GetGasPrice bool // 是否从BaaS获取GasPrice AuthInfo AuthInfo }
开发者需构造SDK包内的Config类型,填充其信息并将包内的全局Config指向构造的Config。 需要注意的是,
UnlockAccounts
和AuthInfo
需开发者自行解析。 构造过程如本目录下的Server示例所示:// 1. 构造基础配置 sdkConf := &sdk.Config{ Keystore: conf.Keystore, UnlockAccounts: make(map[string]string), DNSCacheUpdateInterval: conf.DNSCacheUpdateInterval, RPCProtocal: conf.RPCProtocal, XHost: conf.XHost, Namespace: conf.Namespace, ChainID: conf.ChainID, GetFee: conf.GetFee, GetGasPrice: conf.GetGasPrice, } // 2. 解析得到 AuthInfo authInfoJSON, err := ioutil.ReadFile(authInfoFilePath) err = json.Unmarshal(authInfoJSON, &sdkConf.AuthInfo) // 3. 解析得到 UnlockAccounts passwdsJSON, err := ioutil.ReadFile(passwdFile) err = json.Unmarshal(passwdsJSON, &sdkConf.UnlockAccounts) // 4. SDK全局Config 指向这里构造的sdkConf sdk.Conf = sdkConf
获取SDK实例
SDK实现了所有与BaaS交互的必要接口,并以单例模式提供方法调用。
需要注意的是,获取SDK实例时需传入满足
sdk.Logger
接口的log实现,该log将在SDK内部提供日志功能。开发者可以通过调用以下接口
获取
和释放
SDK资源:func GetSDK(log Logger) *SDKImpl { setLogger(log) if GSDK == nil { newSDK() } return GSDK } func ReleaseSDK() { GSDK = nil }
随后可通过调用该实例的方法进行指向BaaS的接口调用:
import( "github.com/xunleichain/sdk" ) func foobar() { sdkInstance := sdk.GetSDK(log) // encode params resp, xerr := sdkInstance.GetBalance(params...) if xerr != nil || xerr.Code != 0 { // handle error } // parse resp }
SDK提供以下接口:
type SDK interface {
// 新建用户账户
NewAccount(params interface{}) (interface{}, *Error)
// 获取SDK管理的所有用户账户
Accounts(params interface{}) (interface{}, *Error)
// 获取某账户地址的余额
GetBalance(params interface{}) (interface{}, *Error)
// 获取某账户地址的Nonce
GetTransactionCount(params interface{}) (interface{}, *Error)
// 获取指定交易的信息
GetTransactionByHash(params interface{}) (interface{}, *Error)
// 获取指定交易收据
GetTransactionReceipt(params interface{}) (interface{}, *Error)
// 发送交易
SendTransaction(params interface{}) (interface{}, *Error)
// 发送三方交易
SendThirdTransaction(params interface{}) (interface{}, *Error)
// 发送合约交易
SendContractTransaction(params interface{}) (interface{}, *Error)
// 为数据签名
SignData(params interface{}) (interface{}, *Error)
// 为数据验签
VerifySign(params interface{}) (bool, *Error)
// 执行消息调用(无需创建交易)
Call(params interface{}) (interface{}, *Error)
}
在SDK-Server的介绍中,我们将对SDK接口进行更详细的解释。如需参考更多详细信息,请阅读SDK项目文档
官方提供SDK HTTP调用服务的代码实现,位于 SDK/server
路径。
该示例的目录结构如下:
sdk/server
├── main.go // 程序入口 提供HTTP服务
├── config.go // HTTP服务配置和SDK配置
├── server.go // HTTP服务实现
├── Makefile // 编译
├── start.sh // 运行脚本
├── README.md // 文档
└── test // 测试使用的程序配置示例
├── auth.json // SDK连接BaaS接入层的通信凭证。形如
│ // {"chainid":"10001023","id":"11",
│ // "key":"5d7d481d6a00504de0a32488bc7392c4"}
├── keystore // 用户账户的秘钥文件
│ └── UTC--2018-04-15T05-21-48.033606105Z--54fb1c7d0f011dd63b08f85ed7b518ab82028100
├── passwd.json // 启动服务时,预解锁的账户和密码对。以账户地址和密码的键值对组成,形如:
│ // {"0x7eff122b94897ea5b0e2a9abf47b86337fafebdc":"1234",
| // "0xd7e9ff289d2e1405e1bd825168d36ec917aea971":"1234"}
└── sdk-server.conf // 服务配置文件
sdk-server.conf 配置文件说明如下:
# Server配置部分:
http.addr 0.0.0.0:8080 // http服务地址
http.read.timeout 10s // http服务读超时时间
http.write.timeout 10s // http服务写超时时间
# SDK配置部分:
xhost rpc.onethingpcs.com // BaaS接入层 Host
dnscache.updateinterval 300 // BaaS接入层 DNS刷新周期 单位:秒
rpc.protocal https // BaaS接入层 http协议
chain_id 30261 // 链ID
keystore ./keystore // 私钥存储文件
getfee false // 是否从BaaS获取fee
getgasprice true // 是否从BaaS获取GasPrice
namespace tcapi // 区块链名称空间 tcapi
在启动之前,开发者需要:
随后,开发者可在当前目录下执行 make
以编译Server,随后执行 start.sh
启动Server。
Server以HTTP形式提供访问SDK所有接口的功能,故其API也与SDK API一致。
{
"errcode": -1001,
"errmsg": "params err",
"id": 6,
"jsonrpc": "2.0",
"result": ""
}
关于errcode详见:错误码定义
accounts
功能描述: 获取钱包管理的全部账户地址
参数: none
返回结果: 账户地址数组
示例:
//request
curl -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method": "accounts", "params": [], "id": 6}' localhost:8080
//result
{
"id": 6,
"jsonrpc": "2.0",
"errcode": 0,
"errmsg": "success",
"result": ["0x33d4fcb75ce608920c7e5755304c282141dfc4dc", "0x7a4877494b59c0bd929747800ab86a8b89380ac5", "0x36419474a02a507e236dc473648197f07ab4722e", "0x7fc423bd7ed1f5d17a92bdb8c39ed620f48f7559", "0x8f470d7f2b2db7b83accd008ddabc5423c06044b", "0x622bc0938fae8b028fcf124f9ba8580719009fdc"]
}
newAccount
功能描述: 创建新的账户
参数: 账户密码
返回结果: 新账户地址
示例:
//request
curl -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method": "newAccount", "params": ["123456"], "id": 6}' localhost:8080
//result
{
"id": 6,
"jsonrpc": "2.0",
"errcode": 0,
"errmsg": "success",
"result": "0x84d8698746dbe68c97965c48c7b56979c577df11"
}
getBalance
功能描述: 查询账户余额
参数: 账户地址
返回结果: 账户地址余额
示例:
//request
curl -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method": "getBalance", "params": ["0x33d4fcb75ce608920c7e5755304c282141dfc4dc"], "id": 6}' localhost:8080
//result
{
"id": 6,
"jsonrpc": "2.0",
"errcode": 0,
"errmsg": "success",
"result": 99030093892100000000170
}
getTransactionCount
功能描述: 查询账户nonce值
参数: 账户地址
返回结果: 账户地址当前nonce值
示例:
//request
curl -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method": "getTransactionCount", "params": ["0x622bc0938fae8b028fcf124f9ba8580719009fdc"], "id": 6}' localhost:8080
//result
{
"id": 6,
"jsonrpc": "2.0",
"errcode": 0,
"errmsg": "success",
"result": 26
}
sendTransaction
功能描述: 普通转账交易
参数:
- Object: 交易对象
- from: 转出账户地址
- to: 转入账户地址
- value: 转账金额 (推荐使用十进制)
- nonce: (可选) from地址nonce值
- from账户密码(可选)
示例:
params: [{ "from": "0x622bc0938fae8b028fcf124f9ba8580719009fdc", "to": "0x33d4fcb75ce608920c7e5755304c282141dfc4dc", "value": "0x10", // 16 wei }, "12345678"]
说明:如果启动服务时,已经解锁了from账户,可以不用再传密码参数
返回结果: 交易hash
示例:
//request
curl -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method": "sendTransaction", "params": [{"from": "0x622bc0938fae8b028fcf124f9ba8580719009fdc", "to": "0x33d4fcb75ce608920c7e5755304c282141dfc4dc", "value":"1200"},"12345678"], "id": 6}' localhost:8080
//result
{
"id": 6,
"jsonrpc": "2.0",
"errcode": 0,
"errmsg": "success",
"result": "0x517490b857200702453f32ed0574487b44587958ff39b26554df4f4991cae18c"
}
sendContractTransaction
功能描述: 合约执行交易,支持传1个参数,2个参数
- 1个参数则只传交易对象
- 2个参数则传交易对象和账户密码
参数:
- Object: 交易对象
- from: 转出账户地址
- to: 转入账户地址
- gas:(可选,默认90000)手续费
- gasPrice:(可选,默认1e11)
- value: 转账金额
- data:执行合约code
- nonce: (可选) from地址nonce值
- from账户密码(可选)
示例:
[{ "from": "0x622bc0938fae8b028fcf124f9ba8580719009fdc", "to": "0x7f7f7dbf351d4272eb282f16091c96b4819007f5", "data": "0x49f3870b0000000000000000000000000000000000000000000000000000000000000001" }, "12345678"]
说明:如果启动服务时,已经解锁了from账户,可以不用再传密码参数
返回结果: 交易hash
示例:
//request
curl -H "Content-Type:application/json" --data '{"jsonrpc":"2.0","method": "sendContractTransaction", "params": [{"from": "0x622bc0938fae8b028fcf124f9ba8580719009fdc", "to": "0x7f7f7dbf351d4272eb282f16091c96b4819007f5", "data":"0x49f3870b0000000000000000000000000000000000000000000000000000000000000001"},"12345678"], "id": 6}' localhost:8080
//result
{
"id": 6,
"jsonrpc": "2.0",
"errcode": 0,
"errmsg": "success",
"result": "0x517490b857200702453f32ed0574487b44587958ff39b26554df4f4991cae18c"
}
错误码 | 错误信息 | 说明 |
---|---|---|
0 | success | 请求成功 |
-1000 | invalid method | 接口请求方法错误 |
-1001 | params err | 参数错误, 一般由Params参数个数不一致导致 |
-1002 | find account err | 账号查找错误 |
-1003 | rpc getBalance err | 查看余额 rpc调用失败 |
-1004 | ks.NewAccount err | 新建账号错误 |
-1005 | rpc getNonce err | 获取Nonce值 rpc调用失败 |
-1006 | wallet SignTx err | 交易签名错误 |
-1007 | rlp EncodeToBytes err | RLP编码错误 |
-1008 | rpc sendTransaction err | 发送交易 rpc调用失败 |
-1009 | wallet SignTxWithPassphrase err | 钱包签名交易错误 |
-1012 | ContractExtension err | 合约交易参数解析错误 |
-1013 | rpc sendContractTransaction err | 发送合约交易 rpc调用失败 |
-1014 | SignDataArgs err | 签名数据解析错误 |
-1015 | wallet SignHash512 err | sha512加密错误 |
-1016 | wallet SignHash512WithPassphrase err | sha512加密错误 |
-1017 | RecoverPubkey512 err | 公钥恢复错误 |
-1018 | json unmarshal err | json解析错误 |
-1019 | rpc getTransactionByHash err | 查询交易 rpc调用失败 |
-1020 | rpc getTransactionReceipt err | 查询收据 rpc调用失败 |
-1021 | SendTxArgs err | 发送交易参数解析错误 或 获取Nonce值错误 |
基于迅雷链SDK,开发者可在部署合约之后开发合约专有的应用服务。
接下来将以一个K-V存储合约及其应用的demo为例,详细说明如何基于迅雷链BaaS平台和SDK开发合约应用以调用该存储合约。
需要注意的是,在demo中SDK以官方示例Server的形式存在,开发者可自行集成。
该 K-V 存储的链上 Solidity 合约代码为:
pragma solidity >=0.4.22 <0.6.0;
contract KVDB {
mapping(bytes32 => bytes) private _data;
function set(bytes32 key, bytes memory value) public payable returns (bool) {
_data[key]=value;
return true;
}
function get(bytes32 key) public view returns (bytes memory) {
return _data[key];
}
}
显然,该合约提供两个接口 :
demo 使用 beego 实现路由框架,并提供 RESTful 风格的、面向用户的合约调用服务。
.
├── main.go # 程序入口
├── Makefile # 编译
├── start.sh # 启动脚本
├── README.md # README
├── conf # demo系统配置目录 主要配置SDK-Server的host地址
│ └── app.conf
└── routers # beego路由框架的路由
│ └── router.go
├── controllers # controller层
│ ├── contract.go
│ └── default.go
├── models # model层
│ ├── error.go
│ ├── req_call.go
│ ├── req_execute.go
│ ├── req_gettx.go
│ └── resp.go
└── contract # 合约目录 目录下的所有合约都应注册至contract/contract.go中的合约中心
├── contract.go
├── ERC20 # ERC20测试合约
│ └── ERC20.go
└── KVDB # K-V存储测试后合约
└── KVDB.go
其中,conf/app.conf的配置内容如下:
appname = baas-demo // 应用名
httpport = 8081 // 监听端口
copyrequestbody = true // 拷贝请求体
# backend sdk-server
sdk-server = http://localhost:8080 // sdk-server的host
在文件目录下执行 go run main.go
即可运行demo示例。
demo提供的http服务所使用的数据结构定义于models包。
对于开发者来说,需要特别关注与用户调用密切相关的以下三个结构:
// 执行 对应contract/execute接口
type ReqExecute struct {
Account string `json:"account"` // 调用合约的用户账户地址
Contract string `json:"contract"` // SDK视图下的合约名
Addr string `json:"addr"` // 合约地址
Method string `json:"method"` // 合约方法
Params []interface{} `json:"params"` // 合约方法的参数 以列表形式给出
}
// 调用 对应contract/call接口
type ReqCall struct {
Account string `json:"account"` // 调用合约的用户账户地址
Contract string `json:"contract"` // SDK视图下的合约名
Addr string `json:"addr"` // 合约地址
Method string `json:"method"` // 合约方法
Params []interface{} `json:"params"` // 合约方法的参数 以列表形式给出
}
// 查询 对应contract/getTx接口
type ReqGetTx struct {
Account string `json:"account"` // 调用查询接口的用户账户地址
Hash string `json:"hash"` // 交易Hash
}
HTTP服务将从用户的JSON请求中解析得到用户账户地址(Account)、合约名(Contract)、合约方法(Method)、合约参数(Params)、交易hash(Hash)等信息,依据不同接口执行不同流程。
// 1. 首先依据合约名找到合约实例:someContract
// 2. 合约示例调用其Data接口实现对合约参数的ABI编码
cdata, err := someContract.Data(method, params)
// 3. 向SDK发送编码后的数据请求
backReqParam := []interface{}{
map[string]string{
"from": account, // 用户钱包账户地址
"to": someContract.Addr(), // 合约地址
"data": cdata, // ABI编码结果
},
}
backCall("sendContractTransaction", backReqParam)
// 1. 直接根据用户请求携带的`用户账户地址`和`交易hash`向SDK发送数据请求
backReqParam := []string{
account, // 用户账户地址
hash, // 交易hash值
}
return backCall("getTransactionReceipt", backReqParam)
容易看到,应用对外提供的接口最终都以 方法method
和 入参params
的形式进入了backCall。
接下来来看backCall做了哪些事情:
func backCall(method string, params interface{}) (interface{}, error) {
// 1. 设置请求体参数 包括id、协议、方法和参数
backReqParams := make(map[string]interface{})
backReqParams["id"] = 0
backReqParams["jsonrpc"] = "2.0"
backReqParams["method"] = method
backReqParams["params"] = params
// 2. 创建请求并填入参数 设置连接超时和读写超时时间
backReq := httplib.Post("sdk-server-address"))
backReq.SetTimeout(60*time.Second, 60*time.Second)
reqBody, err := json.Marshal(backReqParams)
if err != nil {
return nil, err
}
backReq.Body(reqBody)
// 3. 解码SDK-Server返回数据
var ret backResp
err = backReq.ToJSON(&ret)
if err != nil {
return nil, err
}
if ret.Errcode != 0 {
return nil, fmt.Errorf("errcode: %d errmsg: %s", ret.Errcode, ret.Errmsg)
}
return ret.Result, nil
}
在现有应用开发示例的基础上,开发者可以使用 curl
工具可以简单快速地对示例程序进行接口测试。
在框架析构部分对用户请求的数据结构做出了说明。开发者在模拟用户请求进行测试时,应使用数据结构规定的JSON字段。
以下示例将在 K-V合约中存储以“this is a test”并校验执行结果 :
// set
curl -H 'Content-Type: application/json' -d '{"account":"0x54fb1c7d0f011dd63b08f85ed7b518ab82028100","contract":"kvdb","addr":"0xd1abccccbd0e74e3427ab4f487e4b8ddbb8082a3","method":"set","params":["1111111111111111111111111111111111111111111111111111111111111111","this is a test"]}' http://127.0.0.1:8088/v1/contract/execute
=> 返回交易hash
// 请求参数说明:
// 1. account: 用户账户地址
// 2. contract: 调用合约名,此处为kvdb
// 3. addr: 合约地址
// 4. method: 合约方法,此处为set:设置键值对
// 5. params: 合约参数,对于kvdb的set方法,其参数列表共有两个元素:
// (1) bytes32类型的key(详情参考solidity合约部分),即此处的64个'1'
// 每两个'1'构成一个16进制数'0x11',共计32个16进制数
// (2) byte类型的value
// 开发者如需自行构造key 只需满足5(1)的8位拓展ASCII编码条件,即:使用数字'0'~'9'、字符'a'~'f'拼成总长度为64的字符串即可。
// 查询合约交易-执行结果
curl -H 'Content-Type: application/json' -d '{"account":"0x54fb1c7d0f011dd63b08f85ed7b518ab82028100","hash":"0x81f68810182a40f25416c2db3efa5a98b2c7e1dfe75078b27e9c608cbf215604"}' http://127.0.0.1:8088/v1/contract/getTx
=>
=> {
"code": 0,
"msg": "",
"data": {
"blockHash": "0x62d79b7421a28e9b47b10a2e963d0c4c2ae15fe7ff2c59dfe06e31d311533807",
"blockNumber": "0xf52c",
"contractAddress": null,
"cumulativeGasUsed": "0x8cc1",
"from": "0x54fb1c7d0f011dd63b08f85ed7b518ab82028100",
"gasUsed": "0x8cc1",
"logs": [],
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"status": "0x1",
"to": "0xd1abccccbd0e74e3427ab4f487e4b8ddbb8082a3",
"tokenAddress": "0x0000000000000000000000000000000000000000",
"transactionHash": "0x81f68810182a40f25416c2db3efa5a98b2c7e1dfe75078b27e9c608cbf215604",
"transactionIndex": "0x0"
}
}
// 请求参数说明:
// 1. account: 用户账户地址
// 2. hash: 合约交易hash
// get
curl -H 'Content-Type: application/json' -d '{"account":"0x54fb1c7d0f011dd63b08f85ed7b518ab82028100","contract":"kvdb","addr":"0xd1abccccbd0e74e3427ab4f487e4b8ddbb8082a3","method":"get","params":["1111111111111111111111111111111111111111111111111111111111111111"]}' http://127.0.0.1:8088/v1/contract/call
=>
=> {
"code": 0,
"msg": "",
"data": "this is a test"
}
// 请求参数说明:
// 1. account: 用户账户地址
// 2. contract: 调用合约名,此处为kvdb
// 3. addr: 合约地址
// 4. method: 合约方法,此处为get:设置特定键对应的值
// 5. params: 合约参数,对于kvdb的get方法,其参数列表只有一个元素:
// (1) bytes32类型的key(详情参考solidity合约部分),即此处的64个'1'
合约应用开发需遵循以下规范:
type Contract interface {
Def() string // 合约定义
Addr() string // 合约地址
Data(string, []interface{}) (string, error) // 请求数据ABI编码
Result(string, string) (interface{}, error) // 返回结果ABI解码
}
以K-V存储合约为例:
1) 新建合约结构时,依赖合约定义生成ABI:
func newKVDB() *KVDB {
kvdb := &KVDB{
def: `[{"constant":true,"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"get","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},
{"constant":false,"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"},{"internalType":"bytes","name":"value","type":"bytes"}],"name":"set","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"}]`,
addr: "0x54fb1c7d0f011dd63b08f85ed7b518ab82028101",
}
abi, err := abi.JSON(strings.NewReader(kvdb.def))
if err != nil {
panic(fmt.Errorf("newKVDB abi.JSON err: %v", err))
}
kvdb.abi = abi
return kvdb
}
2) 实现 Contract 接口:
func (self *KVDB) Def() string {
return self.def
}
func (self *KVDB) Addr() string {
return self.addr
}
// 在 K-V 存储中,链上合约提供了 set存储 和 get读取 两个接口
// 相应的,这里调用不同的方法,在方法中对参数进行ABI编码
func (self *KVDB) Data(method string, params []interface{}) (string, error) {
switch method {
case "set":
return self.Set(params) // 内部实现为ABI打包:abi.Pack
case "get":
return self.Get(params) // 内部实现为 abi.Pack
}
}
// ABI解码获取返回数据
func (self *KVDB) Result(method string, ret string) (interface{}, error) {
err := self.abi.Unpack(&val, method, common.FromHex(ret))
// ...
return string(val.([]byte)), nil
}
3) 将合约注册至合约中心:
func init() {
contract.Register(newKVDB())
}
demo中对合约逻辑和端口服务逻辑进行了解耦。开发者无需关心合约如何提供端口服务。
基于该demo和开发规范,开发者依次完成以下步骤,即可新增合约应用:
在框架的 contract/ 路径下实现新的合约代码:包括合约定义、结构及方法,init注册函数等。
在 main.go 中引入合约代码所在的Go Package以执行合约注册。(在示例中使用"_ baas-demo/contract/KVDB"的方式引入合约包是为了执行定义于其中的init函数)
参考Catalyst
相比较其他的链,迅雷链在性能上的优势?
相比其他的BaaS平台,迅雷链BaaS平台有什么优势?
迅雷链BaaS服务目前支持哪些行业应用?
理论上,任何依靠信任支撑的行业,都可以借助区块链的BaaS服务获取业务层面的提升和进化,包括但不限于版权、金融、溯源、游戏、征信、政务、工业互联网、医疗、司法、广告营销、学历认证等多个行业。
支付遇到问题怎么办?
支付如遇到问题,请通过【联系我们】进行留言。