copay钱包(2.RestfulAPI初步分析)
2018-05-07 本文已影响788人
沉寂之舟
传送门
copay钱包(1.windows环境编译运行)
copay钱包(2.RestfulAPI初步分析)
copay钱包(3.转账功能报文分析)
copay钱包(4.bitcore-lib与bitcore-wallet-client类库修改)
copay钱包(5.助记词导出导入代码阅读)
官方介绍:
Copay is a secure Bitcoin and Bitcoin Cash wallet platform for both desktop and mobile devices
Copay是一个安全的Bitcoin和Bitcoin Cash钱包,而且是跨平台的,无论是PC还是移动设备都能使用。
简单分析
Copay是一个跨平台的,但是它并不是传统意义上的BitCoin钱包,为了进一步简化钱包,增加共享(多方)钱包功能,由bitpay提供了“钱包后台”服务,并且,它自己也封装了“钱包客户端”,也就是说一个完整的Bitpay钱包应用,至少包含这3个部分。
P.S. 严格来说,“钱包后台”还有请求查询全节点的block,调用Insight项目的一块。
测试数据(testnet)
个人钱包:性 制 哈 配 筑 清 篇 借 即 炉 办 喜
多方钱包:撒 的 喝 驻 顿 韦 烷 色 率 皆 掌 合
REST API 梳理(部分)
业务流程 | Http方法 | 调用API | 作用 |
---|---|---|---|
创建钱包 | Post | /api/v2/wallets/ | 通知后端记录前端生成的新钱包 |
创建钱包 | Post | /api/v2/wallets/?wallet-id/copayers | 提交钱包信息,获取多方签名钱包信息 |
创建(导入)钱包 | GET | /api/v2/wallets/?includeExtendedInfo=1&r | 获取服务器端钱包信息(通过copay-id) |
创建钱包 | PUT | /api/v1/preferences/ | 登记用户偏好(邮箱,语言,单位) |
登录 | POST | /api/v1/login | 登录(获取x-session) |
登录 | GET | /api/v1/notifications/ | 轮询通知获取(TYPE) |
导入(查询)钱包 | GET | /api/v2/wallets/?includeExtendedInfo=&r= | 获取已生成的钱包信息 |
支付 | GET | /api/v2/feelevels/?coin=btc&network=testnet&r=? | ,获取交易费用,返回各种费用等级 |
支付 | POST | /api/v2/txproposals/ | 提交交易预申请,提交交易目的地址 |
支付 | POST | /api/v1/txproposals/?tx-id/publish/ | 发布交易,提交“proposalSignature” |
支付 | POST | /api/v1/txproposals/?tx-id/signatures/ | 提交自己的交易签名 |
支付 | POST | /api/v1/txproposals/?tx-id/broadcast/ | 广播自己已经签名的交易 |
支付 | POST | /api/v1/txconfirmations/ | 查询交易状态 |
查询 | GET | /api/v1/notifications/?timeSpan=?&r=? | 轮询查询自己钱包的最新状态,新转入交易,新Block等 |
查询 | GET | /api/v1/utxos/?r= | 查询未发费交易 |
查询 | GET | /api/v1/balance/?r= | 查询余额 |
交互流程
创建钱包流程、报文
- 入口pages/add/create-wallet.ts => SetOptAndCreate()
先根据页面信息创建opts(有无种子,是否testnet...)调用ProfileProvider.createWallet()创建新钱包。 - ProfileProvider实际是引入了bitcore-wallet-client的BwcProvider作为与后端交互的封装客户端。最终调用的是client的createWallet()创建钱包。也就是在创建钱包信息后,自动doPostRequest(/v2/wallets/)与服务端交互,登记新创建的钱包,服务端返回wallet-id。
- 后续addAndBind()函数中,调用了openWallet(),会调用登录流程,轮询查询钱包通知。
- create成功后,会调用updateRemotePreferences,向服务器发送偏好设置(email,语言,币种)
导入
- 入口为pages/add/import-wallet.ts => import(),内部又分为从文件导入importFromFile()和从内存导入importFromMnemonic().
- importFromMnemonic()在解析了配置后,又再次调用importMnemonic(),这里再次使用了profileProvider.importMnemonic(words, opts)方法,又调用了client的方法进行处理。
- 与创建的不同之处就在于,import就没有了对/v2/wallets/的API调用,而是直接includeExtendedInfo()
- includeExtendedInfo()并没有传递特别的参数,而是在request-Header中传递了x-identity表明导入的钱包。该值对应于profile里面的copay-id。其具体计算方法为对公钥的xPub进行sha256的hex值。这样前后台都可以分别计算,而不需要传递其他参数表明这个钱包。
- includeExtendedInfo()的返回值就是存储在服务端的钱包信息。导入和创建一样,会把钱包信息保存到profile里面去。
登录
- 登录过程在启动钱包,或者创建新钱包过程中都会调用,调用Login接口获取当前的sessionId,在之后的轮询通知获取报文中,都会把x-session塞到request-header里面去。
支付
- 支付部分是copay改动最多的部分,系统并不区分单独转账和多方转账,都遵循同样的流程进行。(目前仅梳理的流程,代码层面还未细看)
- 在输入接收地址,转账金额后,从/api/v2/feelevels获取交易的费用,并发起/api/v2/txproposals,仅包含接收方地址,金额等必要信息,是一个不完整的交易,由服务端补充信息,并返回一个id
- 在点击发送后,首先publish交易,然后signature进行签名,最后broadcast进行广播。
- 最后,调用/api/v1/notifications确认交易情况。
接收
- 接收并没有特殊的报文,都是通过轮询查询的/api/v1/notifications/报文获得对应信息。
- 参数:
a. lastNotificationId:上次接收到通知的Id
b. timspan: 上次查询的间隔,单位为秒
c. includeOwn: 默认为false
生成opt,并添加r随机数,此时调用doGetRequestWithLogin与后台通讯 - 后台:
a. expressapp.js 为Rest入口,调用getNotifications方法,从存储中获取通知信息。