企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
**钥匙库 Keeper** 是 Token 应用系统的私钥管理服务,类似于手机加密货币钱包,提供生成、保存私钥和签名的服务,Keeper 以 Docker 镜像部署于业务系统的内部环境,并通过接口进行内网访问,通过加密等防护措施确保私钥安全。具体接口如下: [TOC] ## 演示环境 接口地址:https://47.104.196.35/bwallet/…… 目前测试环境中使用的种子为: ~~~ "mnemonic": "donate hedgehog exit connect fly cargo velvet basic portion injury vehicle juice", "seed": "f0a09a464d5c6d7af067841efc5d475f53f58fcb39b87716506a713b9fdb865e4391fd9457de77be98e45f487c3a02f23408859c63124e40a8078ae758e6e6e5" ~~~ 虽然可以使用 generateseed 接口无限制的生成种子,但是一旦某种子被启用,在后继的生成私钥的操作中,该种子不可变更。除非清空数据库才可以重新启用新的种子,派生新的私钥。 ## 接口 ### 1. 生成种子 <span id="api00"></span> 接口名称:/api/v2/generate_seed 请求方法:GET 响应类型:JSON 状态:有效 接口描述:向私钥管理服务请求生成密钥种子,一旦使用了某密钥种子,请妥善保存该种子,可以将其记录与纸质文件或U盘中,由重要的人保管! ~~~[api:keeper] get:/api/v2/generate_seed <<< success { "code": 0, "data": { "mnemonic": "supply disagree case say pipe unit use raw test faith mistake hole", "seed": "05e8585bb7d5f6a3a7059c17c6213a980a34619edfe46b858553556e2c79041e8a30f8e1abd23ed27b7b60f0c34b1575cab254c67b8e9d9fcbf9439c1516e59a" } } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | mnemonic | string | 种子助记词 | | seed | string | 种子 | ### 2. 批量生成地址 <span id="api01"></span> 接口名称:/api/v2/generate_keys 请求方法:POST 响应类型:JSON 状态:有效 接口描述:向私钥管理服务请求生成新的私钥,私钥加密保存在内网,返回对应的公钥和地址,这里生成的地址都是未分配使用的。私钥的加密是定期更新的,确保即使加密被破解,也仅仅会影响一段时间的安全性。 ~~~[api:keeper] post:/api/v2/generate_keys *string:seed#生成私钥所需要的种子 *number:amount#新生成地址数量 string:network_id#1:测试网络(缺省),4:正式网络 <<< success { "code": 0, "data": [ { "pubKey": "f25fad5ae82804d3e990af6a1b5379dabae5fafd5f26a5295f6cbfc2b33e8989b896192bf14be8c0b2bab184242bc569bccfae224b511a65fd1c51c4f85a96d8", "address": "AUUk3GpbpZum_B5YKLGgQT3FhaXNbN0QGA", "index": 0 }, { "pubKey": "483c5cb5d57bbe2b8223548269dd65d7f9c8d2ceb7b8afa8fa7da7a27960475db45be102e5aa396600d12f1864b2bc6e1c7d5601a37acf28f4c0444de02fe61b", "address": "AfdIP-Gy32OQztxT1iimiWBBHGcbxecG0A", "index": 1 }, { "pubKey": "29b20d5a0e9523a78525698b3d2506e3091630f0a32f0ee86cc95cff7d4aec4258f207e25d3e0286a5c38234a73154f26be8056e5e757e8582dc47da8199e857", "address": "AYRhYtOjRmQ_VXFDZPihkQcZB4Za2fjByg", "index": 2 }, { "pubKey": "2fa3b60b50a587af844c6daefb084c37796b41c85600bdf2f07d7511a00227aeffd0f756e4a734dfbbbd58f31451c1e5d2f20b135341b66662ccf47bacb880ce", "address": "Admlc1WtfTi2ygjoS-_zNHiWSrTUcE3EoA", "index": 3 }, { "pubKey": "3a0d1e5f9aec94c91acb9432f2fa993bea017b38ca95da6d3a975b99f1aead4e300adc8622d9ea3fe262653915b944d3190e8790d722568286e08908351f4733", "address": "AVXND9zP2cX2RABbMiTj0ON5jmKBTHYvCw", "index": 4 } ], "msg": "success" } <<< error { "code": 5000, "msg": "系统异常" } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | pubKey | string | 地址公钥 | | address | string | 地址 | | index | integer | 地址索引 | ### 3. 获取 1 个未使用的地址 接口名称:/api/v2/get_unused_key 请求方法:POST 响应类型:JSON 状态:有效 接口描述:申请一个未使用的地址公钥对 ~~~[api:keeper] post:/api/v2/get_unused_key <<< success { "code": 0, "data": { "pubKey": "f7fd57df8a840a26af0cd5671af737d78bfd183a286ea926015a06933a31646b1b6e81976882a245d34a907d0e898580fda242c27cdc16123d8adedb83b400d8", "address": "AdkELJpYcCk4U5QCAit1t54OtasEBH8wtw", "index": 14 } } <<< error { "code": 5000, "msg": "系统异常" } ~~~ ** 返回第一个未使用的地址公钥对, "pubKey"为公钥, "address"为对应地址, "index"为索引, 该地址返回后, keeper内部将标示其为已使用. 如果没有可用的地址, "data"为 {} ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | pubKey | string | 地址公钥 | | address | string | 地址 | | index | integer | 地址索引 | ### 4. 获取未使用的地址数量 接口名称: /api/v2/get_unused_key_count 请求方法:GET 响应类型:JSON 状态:有效 接口描述:返回keeper内部未使用的地址公钥对数量 ~~~[api:keeper] get:/api/v2/get_unused_key_count <<< success { "code": 0, "data": { "count": 11 } } <<< error { "code": 5000, "msg": "系统异常" } ~~~ ** 返回未使用的地址公钥对数量** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | count | int | 未使用地址数量 | ### 5. 事务签名(指定公钥) 接口名称:/api/v2/sign_by_key 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:指定由公钥对应的私钥对未签名事务 hash 进行签名,返回签名 ~~~[api:keeper] post:/api/v2/sign_by_key string:hash#待签名事务hash(32字节,编码后为64字符) string:pub_key#服务端使用参数所指定公钥对应的私钥进行签名 <<< success { code: 0, data: { "signed_hash" : "f62a74dd5c55e2dc4af650654348b6884bf6b08a2fbb59f424c1ddcfa3974fb49c281fb2aafa7394f0bc20e84866a1094bd9d9ea7ab11a7d91b610855e312764,de67efffc14cc1b2f0bc3bec5f993471f1fa9c411b90249b60511ed960041abb445d49711168315d01ef20a842675f9c89f9a14839d1f093fa934ac9f008f85a" } } <<< error { code: 4100, msg: '签名服务已关闭' } ~~~ ** 返回数据里"signed_hash"即为签名成功后的数据, 如果公钥不合法,或者签名服务已关闭,则将返回错误信息 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | signed_hash | string | 签名数据 | ### 6. 事务签名(指定地址) 接口名称:/api/v2/sign_by_addr 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:指定由参数所指定地址对应的私钥对未签名事务 hash 进行签名,返回签名 ~~~[api:keeper] post:/api/v2/sign_by_addr string:hash#待签名事务 hash(32 字节,编码后为 64 字符) string:address#服务端使用该地址对应的私钥进行签名 <<< success { code: 0, data: { "signed_hash" : "f62a74dd5c55e2dc4af650654348b6884bf6b08a2fbb59f424c1ddcfa3974fb49c281fb2aafa7394f0bc20e84866a1094bd9d9ea7ab11a7d91b610855e312764,de67efffc14cc1b2f0bc3bec5f993471f1fa9c411b90249b60511ed960041abb445d49711168315d01ef20a842675f9c89f9a14839d1f093fa934ac9f008f85a" } } <<< error { code: 4200, msg: '系统异常' } ~~~ ** 接口返回数据里"signed_hash"即为签名成功后的数据, 如果地址不合法,或者签名服务已关闭,则将返回错误信息 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | signed_hash | string | 签名数据 | ### 7. 设置系统参数 接口名称:/api/v2/set_params 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:设置系统的运行时参数,用于限制是否可以签名,黑白地址名单等,这里设置的黑白名单将清除服务端原有的黑白名单设置。 ~~~[api:keeper] post:/api/v2/set_params number:sign_count#签名数,目前 <= 0 关闭签名服务 > 0 开启签名服务 string:blacklist#白名单数组(数组字符串需要经过编码处理:[],等数组里的特俗字符) string:whitelist#黑名单数组(数组字符串需要经过编码处理:[],等数组里的特俗字符) <<< success { code: 0, msg: 'success' } <<< error { code: 4500, msg: '系统异常' } ~~~ 参数示例: ``` { sign_count: 1, blacklist: [{"pub_key": "89c114d91fad38a04a4b0ecc682e7b87bf5e386869c183cac5052c0d8852b1aae139595e811ce95ab93b6a05d3687206f839f13dce0bc27d6334ac918bcfb5f7", "address": "AZvnLUhQSmyE0t-sWTacMdu4ldnsE66mrA"}], whitelist: [{"pub_key": "23e484676e5c783afa8fd4a8fa8783f965d7954649419ed6659e6f6a1796646e97235464d96a137c016f9f2442f8443057fad5208765a0faff8140b1e4f385ac", "address": "ASYJcGipUeKzHxxnILy7T9v8nFZlRAK_gw"}] } ``` ### 8. 黑名单操作 接口名称:/api/v2/operate_black_list 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:对黑名单进行操作 ~~~[api:keeper] post:/api/v2/operate_black_list string:action#动作(add、remove、get) string:keypairs#公钥地址对数组(数组字符串,特殊字符需要经过编码处理 ) <<< success { code: 0, msg: 'success' } <<< error { code: 4600, msg: '系统异常' } ~~~ 参数示例: - 新增黑名单 ``` { action: 'add', keypairs: [{"pub_key": "89c114d91fad38a04a4b0ecc682e7b87bf5e386869c183cac5052c0d8852b1aae139595e811ce95ab93b6a05d3687206f839f13dce0bc27d6334ac918bcfb5f7", "address": "AZvnLUhQSmyE0t-sWTacMdu4ldnsE66mrA"}] } ``` - 移除黑名单 ``` { action: 'remove', keypairs: [{"pub_key": "89c114d91fad38a04a4b0ecc682e7b87bf5e386869c183cac5052c0d8852b1aae139595e811ce95ab93b6a05d3687206f839f13dce0bc27d6334ac918bcfb5f7", "address": "AZvnLUhQSmyE0t-sWTacMdu4ldnsE66mrA"}] } ``` - 获取黑名单 ``` { action: 'get' } ``` ### 9. 白名单操作 接口名称:/api/v2/operate_white_list 请求方法:POST 响应类型:JSON 请求数据类型:application/json 状态:有效 接口描述:对白名单进行操作 ~~~[api:keeper] post:/api/v2/operate_white_list string:action#动作(add、remove、get) string:keypairs#公钥地址对数组(数组字符串,特殊字符需要经过编码处理 ) <<< success { code: 0, msg: 'success' } <<< error { code: 4700, msg: '系统异常' } ~~~ 参数示例: - 新增白名单 ``` { action: 'add', keypairs: [{"pub_key": "89c114d91fad38a04a4b0ecc682e7b87bf5e386869c183cac5052c0d8852b1aae139595e811ce95ab93b6a05d3687206f839f13dce0bc27d6334ac918bcfb5f7", "address": "AZvnLUhQSmyE0t-sWTacMdu4ldnsE66mrA"}] } ``` - 移除白名单 ``` { action: 'remove', keypairs: [{"pub_key":"89c114d91fad38a04a4b0ecc682e7b87bf5e386869c183cac5052c0d8852b1aae139595e811ce95ab93b6a05d3687206f839f13dce0bc27d6334ac918bcfb5f7", "address": "AZvnLUhQSmyE0t-sWTacMdu4ldnsE66mrA"}] } ``` - 获取白名单 ``` { action: 'get' } ``` ### 10. 获取地址使用状态 接口名称:/api/v2/export_keys 请求方法:GET 响应类型:JSON 状态:有效 接口描述:导出私钥管理服务系统中的的私钥被使用的数量以及总数等信息。由外部调用,用于定期备份密钥状态 ~~~[api:keeper] get:/api/v2/export_keys <<< success { "code": 0, "data": [ { "used": 10, "total": 32, "pubkey": "89c114d91fad38a04a4b0ecc682e7b87bf5e386869c183cac5052c0d8852b1aae139595e811ce95ab93b6a05d3687206f839f13dce0bc27d6334ac918bcfb5f7" } ] } <<< error { "code": 5000, "msg": "系统异常" } ~~~ ** 接口返回数据里"used"为已使用的私钥的数量,"total"为总的私钥数量,"pubkey"为total对应的公钥的值,如果签名服务已关闭,则将返回错误信息 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | used | integer | 已使用的私钥的数量 | | total | integer | 总的私钥数量 | | pubkey | string | total对应公钥 | ### 11. 恢复密钥 接口名称:/api/v2/import_keys 请求方法:POST 响应类型:JSON 请求数据类型:application/json 状态:有效 接口描述:通过输入种子和外部备份的密钥状态信息,可以恢复导出密钥状态时的密钥状态情况。当服务异常、升级等情况下可以用来恢复数据 **请求参数** ~~~ { "seed":"38627b052f6ac556cc09e0812f272b37f2f4036b1af919b79f9c93ed6ba17d0938280b72aa3749da30e9cae7a7b79c72f57204a7730283dfc3ba000e33bc3510", "used":1, "total":1, "pubkey":"d82677732d9fdb46265e0f80c2086770e792e5e2a497271e47b623a24bb6bc907ce2dcddc0d0510dd452ef384a30ef733e805a04273be34d449bd55d1874a101" } ~~~ ~~~[api:keeper] post:/api/v2/import_keys string:seed#种子字符串 int:used#使用过的密钥数 int:total#总共的密钥数 string:pubkey#total对应的公钥 <<< success { "code": 0, "data": [ { "pubKey": "f25fad5ae82804d3e990af6a1b5379dabae5fafd5f26a5295f6cbfc2b33e8989b896192bf14be8c0b2bab184242bc569bccfae224b511a65fd1c51c4f85a96d8", "address": "AUUk3GpbpZum_B5YKLGgQT3FhaXNbN0QGA", "index": 0 }, { "pubKey": "483c5cb5d57bbe2b8223548269dd65d7f9c8d2ceb7b8afa8fa7da7a27960475db45be102e5aa396600d12f1864b2bc6e1c7d5601a37acf28f4c0444de02fe61b", "address": "AfdIP-Gy32OQztxT1iimiWBBHGcbxecG0A", "index": 1 }, { "pubKey": "29b20d5a0e9523a78525698b3d2506e3091630f0a32f0ee86cc95cff7d4aec4258f207e25d3e0286a5c38234a73154f26be8056e5e757e8582dc47da8199e857", "address": "AYRhYtOjRmQ_VXFDZPihkQcZB4Za2fjByg", "index": 2 }, { "pubKey": "2fa3b60b50a587af844c6daefb084c37796b41c85600bdf2f07d7511a00227aeffd0f756e4a734dfbbbd58f31451c1e5d2f20b135341b66662ccf47bacb880ce", "address": "Admlc1WtfTi2ygjoS-_zNHiWSrTUcE3EoA", "index": 3 }, { "pubKey": "3a0d1e5f9aec94c91acb9432f2fa993bea017b38ca95da6d3a975b99f1aead4e300adc8622d9ea3fe262653915b944d3190e8790d722568286e08908351f4733", "address": "AVXND9zP2cX2RABbMiTj0ON5jmKBTHYvCw", "index": 4 } ], msg: 'success' } <<< error { code: 5000, msg: '系统异常' } ~~~ ** 接口返回数据里"code"为0表示正常,data为公钥地址对数组,"pubkey"为公钥,"address"为公钥对应的地址,"index"为账户索引 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | data | array | 公钥地址对数组 | | pubkey | string | 公钥 | | address | string | 地址 | | index | integer | 地址索引 | ### 12. 根据对方公钥加密 接口名称:/api/v2/ecies_encrypt_by_address 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:指定由参数所指定地址对应的私钥对明文加密加密数据,返回加密数据(base64编码), 此接口可用于提货信息的加密, 自己和拥有公钥双方都可以对加密串解密. **请求参数** ~~~ { "address":"AZSqDujzrpq--uXcD5dJgpDFWzYqmbV4rQ", "to_pubkey": "cabb8a3a73ea4a03d025a6ac2ebbbb19a545e4fb10e791ec9b5c942d77aa20760f64e4604cdfbec665435a382a8c9bfd560c6f0fca8a2708cda302f658368b36", "plain_text":"'{reply:"ok", orderNo: "238812132423"}'", } ~~~ ~~~[api:keeper] post:/api/v2/ecies_encrypt_by_address string:plain_text#待加密数据(utf8编码) string:to_pubkey#对方的公钥(hex编码) string:address#服务端使用该地址对应的私钥进行加密 <<< success { "code": 0, "data": { "encrypted_base64_str": "UJNCe6+ewXCTNuQC9KOAnQR5GtrgTppdZYkpd8nTcgdZDdsqwnnmcPkl17aap+G/nmFRRK+5xQ8kNh5v2OAnvpymwaRP/TrzvN/8xo+a0HmKBLr9Z2aNfUd989RSidMJ2hQT6nivV8iMXzCyGDbnLcy0iVwAJ0aEPMQvCKynadZWC6YCq8MsncJeM0GSN+o3zkM5BvYQtbA33ZuHMFlCXvzCyRPZCrMin/qCOhz2HdxFYwWslh+eafIQMhyu6YAr4gzC+O+SgE7aDQAZUpI4107b7Tt3gclFw12ztDDeiD1bgA==" } } <<< error { code: 5000, msg: '系统异常' } ~~~ ** 接口返回数据里"encrypted_base64_str"即为加密成功后的数据 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | encrypted_base64_str | string | 加密数据 | ### 13. 根据已加密信息加密 接口名称:/api/v2/ecies_encrypt_by_address_reply 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:根据已经加密信息包含的上下文信息进行加,返回加密数据(base64编码), 此接口可用于商品发货后, 提货token的打回. **请求参数** ~~~ { "address":"AZSqDujzrpq--uXcD5dJgpDFWzYqmbV4rQ", "old_data":"UJNCe6+ewXCTNuQC9KOAnQR5GtrgTppdZYkpd8nTcgdZDdsqwnnmcPkl17aap+G/nmFRRK+5xQ8kNh5v2OAnvpymwaRP/TrzvN/8xo+a0HmKBLr9Z2aNfUd989RSidMJ2hQT6nivV8iMXzCyGDbnLcy0iVwAJ0aEPMQvCKynadZWC6YCq8MsncJeM0GSN+o3zkM2dZw1NWruOFrCSqcVE5gpsRgp6axPLVt1jaeYRQqLKcXIQK/8VWleldytDV2MkknKxwtUqqD1PW4a6aYW0+yq/F2RXHIcgsjtqO58Wa3ptjJ5sQu90cK+tfNhL8DeVc77lSeD7DXYvnkNg0OrdbdtNb0vmdqTskMWaGWR3k0h2Q==", "plain_text":"'{reply:"ok", orderNo: "238812132423"}'", } ~~~ ~~~[api:keeper] post:/api/v2/ecies_encrypt_by_address_reply string:plain_text#待加密数据(utf8编码) string:old_data#原加密数据(base64编码) string:address#服务端使用该地址对应的私钥进行加密 <<< success { "code": 0, "data": { "encrypted_base64_str": "UJNCe6+ewXCTNuQC9KOAnQR5GtrgTppdZYkpd8nTcgdZDdsqwnnmcPkl17aap+G/nmFRRK+5xQ8kNh5v2OAnvpymwaRP/TrzvN/8xo+a0HmKBLr9Z2aNfUd989RSidMJ2hQT6nivV8iMXzCyGDbnLcy0iVwAJ0aEPMQvCKynadZWC6YCq8MsncJeM0GSN+o3zkM5BvYQtbA33ZuHMFlCXvzCyRPZCrMin/qCOhz2HdxFYwWslh+eafIQMhyu6YAr4gzC+O+SgE7aDQAZUpI4107b7Tt3gclFw12ztDDeiD1bgA==" } } <<< error { code: 5000, msg: '系统异常' } ~~~ ** 接口返回数据里"encrypted_base64_str"即为加密成功后的数据 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | encrypted_base64_str | string | 加密数据 | ### 14. 解密 接口名称:/api/v2/ecies_decrypt_by_address 请求方法:POST 响应类型:JSON 请求数据类型: application/json 状态:有效 接口描述:指定由参数所指定地址对应的私钥对加密数据进行解密,返回解密密数据(utf8编码) **请求参数** ~~~ { "address":"AZSqDujzrpq--uXcD5dJgpDFWzYqmbV4rQ", "encrypted_str":"UJNCe6+ewXCTNuQC9KOAnQR5GtrgTppdZYkpd8nTcgdZDdsqwnnmcPkl17aap+G/nmFRRK+5xQ8kNh5v2OAnvpymwaRP/TrzvN/8xo+a0HmKBLr9Z2aNfUd989RSidMJ2hQT6nivV8iMXzCyGDbnLcy0iVwAJ0aEPMQvCKynadZWC6YCq8MsncJeM0GSN+o3zkM2dZw1NWruOFrCSqcVE5gpsRgp6axPLVt1jaeYRQqLKcXIQK/8VWleldytDV2MkknKxwtUqqD1PW4a6aYW0+yq/F2RXHIcgsjtqO58Wa3ptjJ5sQu90cK+tfNhL8DeVc77lSeD7DXYvnkNg0OrdbdtNb0vmdqTskMWaGWR3k0h2Q==", } ~~~ ~~~[api:keeper] post:/api/v2/ecies_decrypt_by_address string:encrypted_str#原加密数据(base64编码) string:address#服务端使用该地址对应的私钥进行解密 <<< success { "code": 0, "data": { "decrypted_utf8_str": "{foo:\"aaaaaaaaaaaaaaa\",baz:10000, address: \"北京朝阳区望京西路15号楼7单元203\"}" } } <<< error { code: 5000, msg: '系统异常' } ~~~ ** 接口返回数据里"decrypted_utf8_str"即为解密成功后的数据 ** **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | decrypted_utf8_str | string | 解密数据 | ## shuttle接口封装 **封装提货、转账、发货、退货创建交易事务, keeper签名, 上链的接口调用** ### 1. 转账 <span id="api00"></span> 接口名称:/api/v2/tx/transfer_by_address 请求方法:POST 响应类型:JSON 状态:有效 接口描述: 构建转账事务并上链 **请求参数** ~~~ { token_key:VCT1000 from:AcLO3hwkncntl9tTsO1-xUzEeP8SP-hYQw to: AXhfvSAiXjSZaOqBC221BmeLGHbLLtwL5g value:"1" metadata:keeper transfer a token to_pub_key:14c5fe881149bb3c79fe7012670a1106ed7e5d3745dcbea7e6687e25e38408ea0f451096bf99fe13006e7c56ad218e6e7fc20c20d2cc93ed6efeaf2d6090ff4c } ~~~ ~~~[api:keeper] post:/api/v2/tx/transfer_by_address *string:token_key#商品token *string:from#token转账发起人 *string:to#token转账接收人 *string:value#token转账数量 string:metadata#交易meta信息 string:to_pub_key#加密meta所有的公钥, 该公钥需要和目标地址对应,否则转账接收者不能解密meta数据. 该参数为空,则meta信息不加密 <<< success { "code": 0, "data": { "requestId": "5ce535a78329f30018da6bc6" }, "msg": "create task success, the status of task will be notify" } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | requestId | string | 上链事务管理id | ### 2. 提货 <span id="api00"></span> 接口名称:/api/v2/tx/exchange_by_address 请求方法:POST 响应类型:JSON 状态:有效 接口描述: 构建提货事务并上链 **请求参数** ~~~ { token_key:VCT1000 from:AcLO3hwkncntl9tTsO1-xUzEeP8SP-hYQw value:"1" metadata:{"out\_pickup\_no":"","consignee":"张三","cellphone":"13912345678","address":\["北京市","四环到五环之间","朝阳区","望京地区","望京SOHO T1 C座1915室"\],"zipcode":"100001"} } ~~~ ~~~[api:keeper] post:/api/v2/tx/exchange_by_address *string:token_key#商品token *string:from#token提货发起人 *string:value#token提货数量 *string:metadata#提货地址信息 <<< success { "code": 0, "data": { "requestId": "5ce535a78329f30018da6bc6" }, "msg": "create task success, the status of task will be notify" } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | requestId | string | 上链事务管理id | ### 3. 发货 <span id="api00"></span> 接口名称:/api/v2/tx/deliver_by_address 请求方法:POST 响应类型:JSON 状态:有效 接口描述: 构建发货事务并上链 **请求参数** ~~~ { token_key:VCT1000 from:AcLO3hwkncntl9tTsO1-xUzEeP8SP-hYQw to: AXhfvSAiXjSZaOqBC221BmeLGHbLLtwL5g value:"1" metadata:keeper deliver a token to_pub_key:14c5fe881149bb3c79fe7012670a1106ed7e5d3745dcbea7e6687e25e38408ea0f451096bf99fe13006e7c56ad218e6e7fc20c20d2cc93ed6efeaf2d6090ff4c, split: 'false' } ~~~ ~~~[api:keeper] post:/api/v2/tx/deliver_by_address *string:token_key#商品token *string:from#token发货发起人 *string:to#token发货接收人 *string:value#token发货数量 *string:split#是否生成新的token, 取值'true' 或者 'false' string:metadata#交易meta信息 string:to_pub_key#加密meta所有的公钥, 该公钥需要和目标地址对应,否则发货接收者不能解密meta数据. 该参数为空,则meta信息不加密 <<< success { "code": 0, "data": { "requestId": "5ce535a78329f30018da6bc6" }, "msg": "create task success, the status of task will be notify" } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | requestId | string | 上链事务管理id | ### 4. 申请退货 <span id="api00"></span> 接口名称:/api/v2/tx/refunding_by_address 请求方法:POST 响应类型:JSON 状态:有效 接口描述: 构建客户申请退货事务并上链 **请求参数** ~~~ { token_key:VCT1000 from:AcLO3hwkncntl9tTsO1-xUzEeP8SP-hYQw to: AXhfvSAiXjSZaOqBC221BmeLGHbLLtwL5g value:"1" metadata:keeper deliver a token to_pub_key:14c5fe881149bb3c79fe7012670a1106ed7e5d3745dcbea7e6687e25e38408ea0f451096bf99fe13006e7c56ad218e6e7fc20c20d2cc93ed6efeaf2d6090ff4c } ~~~ ~~~[api:keeper] post:/api/v2/tx/refunding_by_address *string:token_key#商品token *string:from#token申请退货发起人 *string:value#token申请退货数量 string:metadata#交易meta信息 <<< success { "code": 0, "data": { "requestId": "5ce535a78329f30018da6bc6" }, "msg": "create task success, the status of task will be notify" } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | requestId | string | 上链事务管理id | ### 5. 退货 <span id="api00"></span> 接口名称:/api/v2/tx/refund_by_address 请求方法:POST 响应类型:JSON 状态:有效 接口描述: 构建退货事务并上链 **请求参数** ~~~ { token_key:VCT1000 from:AcLO3hwkncntl9tTsO1-xUzEeP8SP-hYQw to: AXhfvSAiXjSZaOqBC221BmeLGHbLLtwL5g value:1 metadata:keeper deliver a token to_pub_key:14c5fe881149bb3c79fe7012670a1106ed7e5d3745dcbea7e6687e25e38408ea0f451096bf99fe13006e7c56ad218e6e7fc20c20d2cc93ed6efeaf2d6090ff4c } ~~~ ~~~[api:keeper] post:/api/v2/tx/refund_by_address *string:token_key#商品token *string:from#token退货发起人 *string:to#token退货接收人 *string:value#token退货数量 string:metadata#交易meta信息 string:to_pub_key#加密meta所有的公钥, 该公钥需要和目标地址对应,否则退货接收者不能解密meta数据. 该参数为空,则meta信息不加密 <<< success { "code": 0, "data": { "requestId": "5ce535a78329f30018da6bc6" }, "msg": "create task success, the status of task will be notify" } ~~~ **返回值** | 参数名 | 参数类型 | 描述 | | --- | --- | --- | | requestId | string | 上链事务管理id | ## 接口错误码汇总 ``` 4000: 接口请求参数错误 4100: keeper签名服务已关闭 4200: keeper签名地址不合法 4300: keeper签名公钥不合法 4400: keeper更新黑名单失败 4500: keeper更新白名单失败 4600: keeper使用错误种子生成批量生成地址 5000: 接口调用异常 ``` ## 接口使用示例 **获取密钥种子 seed** 该部署完成后,该接口只需要调用一次,一旦用该 seed 生成了地址后,除非恢复,后续将不能再修改,请妥善保存seed。 *使用我们提供的测试环境则不需要再调用了* ``` # curl http://127.0.0.1:8003/api/v2/generate_seed # { "code": 0, "data": { "mnemonic": "supply disagree case say pipe unit use raw test faith mistake hole", "seed": "05e8585bb7d5f6a3a7059c17c6213a980a34619edfe46b858553556e2c79041e8a30f8e1abd23ed27b7b60f0c34b1575cab254c67b8e9d9fcbf9439c1516e59a" } } ``` **批量生成密钥对** ``` # curl -H "Content-Type: application/json" -X POST --data '{"seed":"6f21c9239acc5d127d9159d06bbfc656f6eba20bd3fb658105fba456f9eef4d4907e452bdc79b9f3fd0781a8375707f76270380788151866691604015e891151", "amount" : 1}' http://127.0.0.1:8003/api/v2/generate_keys ``` **返回公钥地址对, 这里生成的公钥对都是未分配的** ``` # {"code":0,"data":\[{"pubKey":"06032117d1367819cf010cdba9efd2f57c7f223c6e1fc5489e0e8cc8d547b25756ae03ca816fa9b8269f61f07915fa49b45c3f4577d8f71323f078212d4d4e61","address":"AYZe38fxK7bUivWOrBbGKb0EAraGP1I17A","index":38}\],"msg":"success"} ``` **申请一个未使用的地址** ``` # curl http://127.0.0.1:8003//api/v2/get_unused_key ``` **返回一个地址,系统内部标示其为已使用** ``` # {"code":0,"data":{"pubKey":"799f5e6ed68f90d7131ae7e82fde680cde039e705be88e34ee91b6c22974e1cb6d30ffc4d0c91657e0f530e86582935678c0f8111970a9818019b88c8343833e","address":"AWKgbWiyhRIh09PZ6-OBv46nJDEE6tTyOA","index":0}} ``` **使用公钥签名** ``` #curl -H "Content-Type: application/json" -X POST --data '{"hash":"D36BF29D562CF53F92727A8608C054D26F122611D9DF06EC923C6F7868813CC3", "pub_key" : "06032117d1367819cf010cdba9efd2f57c7f223c6e1fc5489e0e8cc8d547b25756ae03ca816fa9b8269f61f07915fa49b45c3f4577d8f71323f078212d4d4e61"}' http://127.0.0.1:8003//api/v2/sign_by_key ``` **签名后返回数据** ``` # {"code":0,"data":{"signed\_hash":"EC:01,06032117d1367819cf010cdba9efd2f57c7f223c6e1fc5489e0e8cc8d547b25756ae03ca816fa9b8269f61f07915fa49b45c3f4577d8f71323f078212d4d4e61,6dae86c6fe20af788167a53da6a0475542e65ed7362269e8d7ba7a96d235a13b2eeee041ca7d6d641714b99d67af036090b6871a4a165bcad1ca165ee461d0df:"}} ``` ## Docker 容器 Keeper 服务需要部署在应用系统的服务器环境,我们提供 Keeper Docker 容器镜像。用户可在自己的服务器环境中启动一个 Keeper 容器,用户直接请求容器,Keeper 容器将提供如上的接口功能。 **如何启动一个 Keeper docker 容器(地址/私钥保存在docker容器对应外部存储中)** ``` docker run --name keeper -p 8003:8003 -d -v /opt/data:/var/lib/mysql -e PORT=8003 -e EGG_SERVER_ENV=test -e SHUTTLE_APIKEY=5a72327aafbb45fe9917938e1a9f1c4b -e SHUTTLE_SECKEY=3e2d7169f946458b92febf3140327014 -e SHUTTLE_BASE=https://shuttle.stringon.com -e MATRIX_BASE=https://matrix.stringon.com -e MYSQL_ROOT_PASSWORD=mypassword stringon/keeper:1.0.26 /apps/apj/setup.sh ``` **如何启动一个 Keeper docker 容器(地址/私钥不保存在docker容器)** ``` docker run --name keeper -p 8003:8003 -d -e PORT=8003 -e EGG_SERVER_ENV=test -e SHUTTLE_APIKEY=5a72327aafbb45fe9917938e1a9f1c4b -e SHUTTLE_SECKEY=3e2d7169f946458b92febf3140327014 -e SHUTTLE_BASE=https://shuttle.stringon.com -e MATRIX_BASE=https://matrix.stringon.com -e MYSQL_ROOT_PASSWORD=mypassword stringon/keeper:2.0.7 /apps/apj/setup.sh ``` - env:环境,test-测试环境,prod-生产环境 - /opt/data:数据保存目录(该目录自行指定) - SHUTTLE_BASE: shuttle访问url - SHUTTLE_APIKEY, SHUTTLE_SECKEY对应在matrix上申请 - MATRIX_BASE: matrix访问url