**节点服务 Shuttle** 是访问区块链的中间服务,主要提供交易构造、签名、数据上链、交易信息订阅、发行 Token 等服务。
Shuttle 系统提供部署于业务系统内部环境的 Shuttle Proxy Docker 镜像,通过内部访问 Shuttle Proxy 实现相关功能,具体接口如下:
[TOC]
## 说明
### 演示环境
接口地址:https://shuttledemo.stringon.com/……
apiKey 和 secKey:使用 [Matrix](https://matrixdemo.stringon.com) 系统注册用户的 API_Key 和 API_Secret
### 资产标识
系统使用 coin 和 tokenKey 来标识一种资产,其中 coin 标识区块链名称或链的原生币,tokenKey 标识一条链上的 Token:
- coin:大写的币种简称,原生币等于链简称,当前支持的类型为:
| 取值 | 说明 |
|----|----|
|ASTRO_TOKEN|基于 ASTRO 发行的 Token|
- chain:链的标识简称,当前支持的类型为:
| 取值 | 说明 |
|----|----|
|chain|ASTRO|
### 参数中的签名字段
所有用户接口都使需要带有对其他请求参数内容的签名,如其他参数内容如下:
```
data: {
cb_url: 'http://localhost/api/cb'
api_key: '12345678',
}
str="api_key=12345678&cb_url=http://localhost/api/cb" + sec_key
signature=md5(str)
```
其中,sec_key 是用户密钥,对所有参数进行字母排序以&连接,后对 str 执行 md5 得到 signature
<span style="color: red">****注意!! 如果在当前页面调试接口,所有接口的api_key 和 signature 不需要填写;使用https://shuttledemo.stringon.com/,所有接口的api_key 和 signature为必填字段**** </span>
### 请求应答 Body 数据格式
~~~
{
code: 状态码 | 0: 成功 40**: 错误码
msg: 描述
data: 数据ai
}
~~~
## 通用接口
### 设置回调 URL
~~~[api:shuttleV2]
put:/api/v2/set_callback_url
*cb_url#回调url
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"data": {
"apiKey": "matrix",
"cbUrl": "http://web",
"msg": "Welcome"
}
}
<<<
error
{
"code": 40000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| apiKey | string | 用户的api_key |
| cbUrl| string | 回调的url|
| msg| string | Welcome |
### 添加订阅地址
~~~[api:shuttleV2]
post:/api/v2/subscribe
*chain# 链
*addresses#订阅地址列表,逗号分割
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"data": {
"addresses": [
"ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81C"
],
"addressesTotalCount": 1
}
}
<<<
error
{
"code": 40000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| addresses | array | 用户提交的订阅地址列表|
| addressesTotalCount | | 用户全部的订阅地址数 |
### 获取交易记录
~~~[api:shuttleV2]
get:/api/v2/history
*coin# 币种
token_key# Token标识键 (多个以“,” 分割)
token_origin# Token标识键 (跟token_key 可二选一,有该参数,token_key无效)
*address#地址
inout# 取值:【in,out】;in:address 是转入方,out 是转出方
txid# txid
tx_type#事务类型 (多个以“,” 分割)
sort# 排序方式,取值【time,height】time:时间排序,height:块高排序,默认块高
page_index# 页码 | 默认值:1
page_size# 条数 | 默认值:100
timeStart# 起始时间
timeEnd#结束时间
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"msg": "success",
"data": {
"items": [
{
"chain": "ASTRO",
"coin": "ASTRO_TOKEN",
"tokenKey": "a100",
"tokenOrigin": "a100",
"_id": "5cd3fc8507eb8c089d1dfd1b",
"from": "AfmAE1K-T8V-y4ObshuwV2faNMOdNMYW0Q",
"to": "ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81A",
"txid": "0C697F48392907A0159CF6D2C8928DC8",
"__v": 0,
"blockHeight": 8,
"blockTime": 1559731210835,
"meta": "this is a exchange 10 ",
"tokenChild": "a100_ex_cfa1caec-5810-4532-8d98-4b8ec7098924",
"txType": "astro.token.exchange",
"updatedAt": 1557396613343,
"valid": true,
"value": "10",
"createdAt": 1557461369189
},
],
"count": 1,
"total": 1
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 对象内部参数 | 参数类型 | 描述 |
| --- | --- | --- |--- |
| count | | int | 此次查询的条数 |
| total | | int | 总条数 |
| items| | int | 总条数 |
| |from| string | 转出方|
| |to| string | 转入方 |
| |tokenOrigin| string| token的源token |
| |tokenKey | string| tokenId|
| |tokenChild| string | token裂变的子token |
| |txType | string| 该事务的类型 (见 txType说明)|
### 获取 交易的 详情
~~~[api:shuttleV2]
get:/api/v2/get_create_transfer_status
request_id#创建未签名或者提交签名返回的requestId
create_id#创建未签名用户自己传入的id ;跟requestId 两者必须有一个
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"data": {
"_id": "5cd4ef123653212bcc7c896b",
"chain": "ASTRO",
"coin": "ASTRO_TOKEN",
"_account": "5cac6aa922f8273b6a76171f",
"requestBody": {
"from": "AfmAE1K-T8V-y4ObshuwV2faNMOdNMYW0Q",
"to": "ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81A",
"value": "1",
"token_key": "a100",
"metadata": "exchange",
"apiKey": "set your apiKey",
"signature": "5e39fd3f471fc98ce2595f55f10a7653",
"chain": "ASTRO",
"tokenKey": "a100",
"coin": "ASTRO_TOKEN"
},
"__v": 0,
"txData": {
"raw": "I::batch:ChMKB0FCQ0hBSU4SCEFzdHJvX3YxEgYIpPrT5gUaFBR+/f/cQGvmqgnbZ4FrYRnm1KSq:CnoKEEFTVFJPLlRPS0VOLkJVUk4SZgoEYTEwMBIIZXhjaGFuZ2UaFEFTVFJPLlRPS0VOLkVYQ0hBTkdFIglAQXN0cm9fdjEqFgoU+YATUr5PxX7Lg5uyG7BXZ9o0w51qGwoWChT5gBNSvk/FfsuDm7IbsFdn2jTDnRIBAQqaAQoQQVNUUk8uVE9LRU4uSU5JVBKFAQosYTEwMF9leF8zM2ZiZGI3Mi04ZmMxLTQ4MGMtYmYwMC0yMmMzM2MzZDNiMjkSCGV4Y2hhbmdlKhYKFPmAE1K+T8V+y4ObshuwV2faNMOdUjMKAQESFPmAE1K+T8V+y4ObshuwV2faNMOdGhQSbaukOOqE58Q8L1ajIA7WXjcbOyABKAEKgwEKEkFTVFJPLlRPS0VOLkFTU0lHThJtCixhMTAwX2V4XzMzZmJkYjcyLThmYzEtNDgwYy1iZjAwLTIyYzMzYzNkM2IyORIIZXhjaGFuZ2UqFgoU+YATUr5PxX7Lg5uyG7BXZ9o0w51CGwoBARIWChQSbaukOOqE58Q8L1ajIA7WXjcbOw==",
"hash": "23C014865044949429443E7C0A3D41E8FA066D9128393485083B95B2180343A0",
"promise": {
"txID": "pending",
"txNonce": "FH79/9xAa+aqCdtngWthGebUpKo=",
"outputs": [
{
"FundNonce": "nEhJqrtBxOgQGL6VMHjse90GbUNKwmVEZkmeel9fpos=",
"Nonce": "FH79/9xAa+aqCdtngWthGebUpKo="
},
{
"FundNonce": "zN1V_wAQ6DjHH-2en0SvQagRpsnZTmhFa1KpFDMz7fE=",
"Nonce": "FH79/9xAa+aqCdtngWthGebUpKo="
}
]
}
},
"txRaw": "EC:01,ED83704C95D829046F1AC27806211132102C34E9AC7FFA1B71110658E5B9D1BDEDC416F5CEFC1DB0625CD0C75DE8192D2B592D7E3B00BCFB4A0E860D880FD1FC,C1A93B42989F5279127E650AE1C82E2745E49A999FB83FB27448E234B52B1B15F6AD76C0E7FBFC9F9F3CE775E0DA17305D26BD976A9102BB3F7AFD2084F9AE96:",
"kafkaMsg": {
"topic": "ASTRO_TRANSACTION",
"messages": "{\"txRaw\":\"EC:01,ED83704C95D829046F1AC27806211132102C34E9AC7FFA1B71110658E5B9D1BDEDC416F5CEFC1DB0625CD0C75DE8192D2B592D7E3B00BCFB4A0E860D880FD1FC,C1A93B42989F5279127E650AE1C82E2745E49A999FB83FB27448E234B52B1B15F6AD76C0E7FBFC9F9F3CE775E0DA17305D26BD976A9102BB3F7AFD2084F9AE96:\",\"requestId\":\"5cd4ef123653212bcc7c896b\"}",
"key": "SUBMIT_TRANSFER",
"attributes": 1,
"timestamp": 1557459734029,
"partition": 0
},
"kafkaMsgResult": {
"ASTRO_TRANSACTION": {
"0": 29
}
},
"txid": "0C697F48392907A0159D35606036AF1C",
"chainBody": {
"createdAt": 1559534844165,
"value": "2",
"updatedAt": 1559534844157,
"txType": "astro.token.transfer",
"requestId": "5cf49ced08262700190dba16",
"meta": null,
"blockTime": 1559534843593,
"blockHeight": 476,
"__v": 0,
"txid": "0C697F48392907A0159D35606036AF1C",
"to": "AfmAE1K-T8V-y4ObshuwV2faNMOdNMYW0Q",
"from": "ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81A",
"_id": "5cf49ced8c0fc5ae92f76207",
"tokenOrigin": "aaaa0",
"tokenKey": "aaaa0",
"coin": "ASTRO_TOKEN",
"chain": "ASTRO"
},
"updatedAt": 1557459734245,
"createdAt": 1557458706334,
"logs": [
"update txData at: 1557458708185",
"sendTransaction at: 1557459734026",
"sendKafkaMsg at: 1557459734114",
"TX_HASH at: 1557459734245"
],
"code": 16,
"status": "TXID"
}
}
<<<
error
{
"code": 40000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| requestBody | object |用户构建该事务请求参数 |
| txData | object | 用户构造未签名事务返回的txData |
| txid| string| 该事务返回的txid |
| chainBody | object | 链上返回的事务的数据 |
| code| int| 该事务现在所处的状态 |
| status| string| 该事务现在所处的状态的文字描述 |
**code值的含义**
| 数值 | 含义 |
| --- | --- |
| -2| 用户取消了该事务 |
| -1| 该事务构建失败 |
| 0| 构建事务请求 |
| 2| 构建事务成功返回 |
| 4| 对于该事务提交签名请求 |
| 8| 签名的事务发送到shuttle消息队列中 |
| 16| 该事务返回txid |
| 32| 该事务已经上链 |
| 64| 该事务已经被确认 |
## Astro Token 专有接口
### 构造提货事务
~~~[api:shuttleV2]
post:/api/v2/astro/create_exchange_tx_data
create_id#用户自己传入的id ,不要重复
*token_key# TokenId
*from# 转账发送者
*to#收款地址
*value#转账金额
metadata#该事务的需要添加的替他属性
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"msg": "成功",
"data": {
"txData": {
"raw": "I::batch:ChMKB0FCQ0hBSU4SCEFzdHJvX3YxEgYIpPrT5gUaFBR+/f/cQGvmqgnbZ4FrYRnm1KSq:CnoKEEFTVFJPLlRPS0VOLkJVUk4SZgoEYTEwMBIIZXhjaGFuZ2UaFEFTVFJPLlRPS0VOLkVYQ0hBTkdFIglAQXN0cm9fdjEqFgoU+YATUr5PxX7Lg5uyG7BXZ9o0w51qGwoWChT5gBNSvk/FfsuDm7IbsFdn2jTDnRIBAQqaAQoQQVNUUk8uVE9LRU4uSU5JVBKFAQosYTEwMF9leF8zM2ZiZGI3Mi04ZmMxLTQ4MGMtYmYwMC0yMmMzM2MzZDNiMjkSCGV4Y2hhbmdlKhYKFPmAE1K+T8V+y4ObshuwV2faNMOdUjMKAQESFPmAE1K+T8V+y4ObshuwV2faNMOdGhQSbaukOOqE58Q8L1ajIA7WXjcbOyABKAEKgwEKEkFTVFJPLlRPS0VOLkFTU0lHThJtCixhMTAwX2V4XzMzZmJkYjcyLThmYzEtNDgwYy1iZjAwLTIyYzMzYzNkM2IyORIIZXhjaGFuZ2UqFgoU+YATUr5PxX7Lg5uyG7BXZ9o0w51CGwoBARIWChQSbaukOOqE58Q8L1ajIA7WXjcbOw==",
"hash": "23C014865044949429443E7C0A3D41E8FA066D9128393485083B95B2180343A0",
"promise": {
"txID": "pending",
"txNonce": "FH79/9xAa+aqCdtngWthGebUpKo=",
"outputs": [
{
"FundNonce": "nEhJqrtBxOgQGL6VMHjse90GbUNKwmVEZkmeel9fpos=",
"Nonce": "FH79/9xAa+aqCdtngWthGebUpKo="
},
{
"FundNonce": "zN1V_wAQ6DjHH-2en0SvQagRpsnZTmhFa1KpFDMz7fE=",
"Nonce": "FH79/9xAa+aqCdtngWthGebUpKo="
}
]
}
},
"requestId": "5cd4ef123653212bcc7c896b",
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 内部对象名 |参数类型 | 描述 |
| --- | --- | --- |--- |
| txData | | object |构造的未签名事务|
| | hash | string|用户需要对此hash值进行签名|
| | 其余 | string|展示用|
| requestId| | string |构造未签名事务返回的id,提交签名事务或查询详细信息需要此id|
### 构造发货事务
~~~[api:shuttleV2]
post:/api/v2/astro/create_deliver_tx_data
create_id#用户自己传入的id ,不要重复
*token_key# TokenId
*from# 发送者
*to#接受者地址
*value#发货数量
*split# 是否分割:true|false(true会产生新token)
metadata#该事务的需要添加的替他属性
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
code: 0,
msg: "success",
data: {
txData: {}, // 事务数据
requestId:, // 提交id
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
同构造提货事务
### 构造换货事务
~~~[api:shuttleV2]
post:/api/v2/astro/create_change_tx_data
create_id#用户自己传入的id ,不要重复
*token_key# TokenId
*from# 发送者
*to#接受者地址
*value#换货数量
metadata#该事务的需要添加的替他属性
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
code: 0,
msg: "success",
data: {
txData: {}, // 事务数据
requestId:, // 提交id
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
同构造提货事务
### 构造申请退货事务
~~~[api:shuttleV2]
post:/api/v2/astro/create_refunding_tx_data
create_id#用户自己传入的id ,不要重复
*token_key# TokenId
*from# 发送者
*to#接受者地址
*value#换货数量
metadata#该事务的需要添加的替他属性
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
code: 0,
msg: "success",
data: {
txData: {}, // 事务数据
requestId:, // 提交id
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
同构造提货事务
### 构造处理退货事务
~~~[api:shuttleV2]
post:/api/v2/astro/create_refund_tx_data
create_id#用户自己传入的id ,不要重复
*token_key# TokenId
*from# 发送者
*to#接受者地址
*value#换货数量
metadata#该事务的需要添加的替他属性
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
code: 0,
msg: "success",
data: {
txData: {}, // 事务数据
requestId:, // 提交id
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
同构造提货事务
### 构造转账事务
~~~[api:shuttleV2]
post:/api/v2/astro/create_transfer_tx_data
create_id#用户自己传入的id ,不要重复
*token_key# TokenId
*from# 发送者
*to#接受者地址
*value#发货数量
weak# true/fasle 默认fasle 转账余额检查弱还是强 【强用余额的useable、弱用useable+inlocked】
metadata#该事务的需要添加的替他属性
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
code: 0,
msg: "success",
data: {
txData: {}, // 事务数据
requestId:, // 提交id
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
同构造提货事务
### 构造多地址授权
~~~[api:shuttleV2]
post:/api/v2/astro/create_multi_auth
*addresses# 地址集,以 ‘,’分割
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
code: 0,
msg: "success",
data: {
"txid": "d60fbb07e45efd7171b127a1adaed9c7c3ccacdb0586c1502cd428d5418e3252",
"mixAddress": "Aftj1zqTIPY72_-Z2XTpxz_c3hPPTs3xpg",
"requestId": "5d3a765ab84a02001898da67"
}
}
<<<
error
{
"code": 4000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
同构造提货事务
### 提交已签名事务
~~~[api:shuttleV2]
post:/api/v2/astro/submit_tx
*signed_tx_raw#签名后事务数据
*request_id#创建未签名事务返回的requestId
*sync# true/false 是否同步请求,默认false
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
sync :false
{
"code": 0,
"data": {
"requestId": "5cd4ef123653212bcc7c896b"
"sync": fasle,
},
"msg": "create task success, the status of task will be notify"
}
sync:true
{
"code": 0,
"data": {
"requestId": "5d652f852449c29d4499d90f",
"txid": "3ea2d3f7bfa10b8fcf6cb5b3f6b32bc3db6feb2e09f75e9392e31e46c73af84d",
"sync": true,
"balance": {
"from": [
{
"address": "ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81A",
"tokeyKey": "aaaa0",
"total": "840",
"useable": "838",
"inLocked": "0",
"outLocked": "2"
}
],
"to": [
{
"address": "AfmAE1K-T8V-y4ObshuwV2faNMOdNMYW0Q",
"tokeyKey": "aaaa0",
"total": "52",
"useable": "50",
"inLocked": "2",
"outLocked": "0"
}
]
}
}
}
<<<
error
{
"code": 40000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| requestId |string | 用户传入的request_id |
| txid|string | 上链后得txid |
| balance|object| 参见 get_balance 接口描述,balance的total为 -1 表示余额请求失败,可用get_balance接口重新查询 |
### 获取余额
~~~[api:shuttleV2]
get:/api/v2/astro/get_balance
*address#地址
*token_key#tokenId
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"msg": "成功",
"data": {
"_id": "5ce7bc3c2a9efee3abd6052e",
"chain": "ASTRO",
"coin": "ASTRO_TOKEN",
"tokenKey": "a100",
"address": "ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81A",
"total": "1199",
"useable": "1196",
"inConfirming": "0",
"outConfirming": "0",
"outLocked": "3",
"inConfirmingLocks": [],
"outLocks": [
{
"value": "1",
"tfcId": "5ce7bc3cf1c29b6288415045"
},
{
"value": "2",
"tfcId": "5ce7bc41f1c29b6288415046"
}
],
"outConfirmingLocks": []
}
}
<<<
error
{
"code": 40000,
"msg": "error: ${errorId}"
}
~~~
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| chain | string|ASTRO|
| coin | string| string|ASTRO_TOKEN|
| tokenKey | string|参数 token_key|
| address | string|参数 address |
| total | string|总余额|
| useable | string|可用余额(总余额 减 outLocked)|
| inConfirming| object |转入该地址待确认的|
| outConfirming| object |该地址转出待确认的|
| outLocked| string |outLocks所有value的和|
| outLocks| object |构造此次未签名事务后未提交签名事务的锁定,包含每一个构建的id,跟数值|
| inConfirmingLocks| object |转入该地址待确认的|
| outConfirmingLocks| object |该地址转出待确认的|
### 获取地址下的token
~~~[api:shuttleV2]
get:/api/astro/get_address_token_detail
*address#地址
api_key# 用户的apiKey
signature#secKey签名后的数据
<<<
success
{
"code": 0,
"msg": "成功",
"data": {
"txCount": 16,
"token": [
{
"tokenKey": "aaaa0",
"status": "-"
},
{
"tokenKey": "aaaa0_ex_ed7fc8ff-017d-4119-94c8-b49e1e58d4cb",
"status": "astro.token.exchange"
},
{
"tokenKey": "aaaa0_ex_f4830e0e-e5db-4435-8f7f-9cde669c06e3",
"status": "-"
},
{
"tokenKey": "cccc",
"status": "-"
},
],
"_id": "5cdd366b68c0efe45d69477e",
"address": "ARJtq6Q46oTnxDwvVqMgDtZeNxs7Ybt81A",
"createdAt": 1558001259252,
"updatedAt": 1558489637928,
"__v": 0
}
}
<<<
error
{
"code": 40000,
"msg": "error: ${errorId}"
}
~~~
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| txCount| string|该地址的交易数量|
| tokenKey| string|用户请求的token_key|
| balance| string|该地址下的token的余额|
| status | string|状态:‘-’,流转中|
## 通知
### 通知消息请求结构
```
{
method: 'POST'
url: ${cbUrl}, // 用户设置的回调url
data: {
taskId:
key:
msg:
signture:
}
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| taskId | string | 消息id,用户可根据此id过滤重发消息,默认消息再没有正常发送情况下会再重发两次 |
| key | string | 消息类型 |
| msg| object | json序列化后的数据消息,用户需要使用类似 JSON.parse() 的方法反序列化成对象 |
| signture| string | 使用用户sec_key对消息签名,用户需验证消息签名正确,验签时msg为json字符串 |
### 用户收到通知后需要回复以下格式数据:
```
{
code: 0
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| * | | |
| * | | |
### 转账相关通知
#### 主动转账提交上链
```
key: "TRANSFER_ACTION",
msg {
status: "SUBMIT_TRANSACTION_TO_CHAIN",
txid: 事务ID,
tfcId:平台存入数据库的id
requestId: 转账ID, // 提交签名时需要提交此ID
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| txid | string | 事务 txid |
| tfcId| string | 平台存入该事务到数据库的id |
| requestId| string | 创建未签名事务返回的requestId |
#### 转账提交上链错误
```
key: "TRANSFER_ACTION",
msg: {
status: "SUBMIT_TRANSACTION_ERROR"
error: 错误消息,
requestId: 转账ID,
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| error| string | 错误消息 |
| requestId| string | 创建未签名事务返回的requestId |
#### 转账被打包上链
```
key: "TRANSFER_ACTION",
msg: {
status: 'TRANSFER_FROM_CHAIN',
inout: 'OUT' | 'IN', // 转出或转入
yourAddr: 用户订阅的地址,
record: { // 转账记录
id,平台存入数据库的id (tfcId)
chain,
coin,
tokenOrigin ,
tokenKey,
from,
to,
value,
txid,
blockNum,
txType
tokenChild,
meta
},
balance: { // 地址余额
coin,
tokenKey,
address,
total,
inConfirming,
outConfirming,
outLocked
},
}
```
**返回值**
| 参数名 | 对象内部参数 | 参数类型 | 描述 |
| --- | --- | --- | --- |
| status || string | 状态 |
| inout| string | 转入或者转出 |
| yourAddr| | string | 用户订阅的地址 |
| record| | object| 转账记录 |
| | id| string | 平台存入数据库的id (tfcId)|
| | chain| string | 链|
| | coin| string | 币种|
| | from| string | token发行者 |
| | to| string | token拥有者 |
| | value| string | 数量 |
| | tokenKey | string | tokenId |
| | tokenOrigin | string | token源|
| | tokenChild| string | 该事务产生的子token|
| | meta| string | 该事务附加的属性|
| | txType| string |参见txType说明 |
| | txid| string | 事务的txid |
| | blockNum| string | 块高 |
| balance | | object| 参见余额接口说明 |
#### 转账事务确认
```
key: "TRANSFER_ACTION",
msg: {
status: 'CONFIRM',
inout: 'IN' | 'OUT', // 转入或者转出
txid: 事务ID,
confirmedNum:确认数,
blockNum
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| inout| string | 转入或者转出 |
| txid | string | 事务 txid |
| confirmedNum| string | 确认数|
| blockNum| string | 块高 |
#### 转账完成
```
key: "TRANSFER_ACTION",
msg: {
status: 'TRANSFER_FINISH',
inout: 'IN' | 'OUT', // 转入或者转出
tfcId
confirmedNum: 确认数,
balance: { // 地址余额
coin,
tokenKey,
address,
total,
inConfirming,
outConfirming,
outLocked
},
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| inout| string | 转入或者转出 |
| tfcId| string | 平台存入该事务到数据库的id(与提交上链通知返回的一致) |
| confirmedNum| string | 确认数|
| balance| object| 参见余额接口余额返回|
### 发布 Token 相关通知
#### 提交上链
```
key: "TOKEN_ACTION",
msg: {
status: SUBMIT_TOKEN_TO_CHAIN
txid
requestId: 提交签名事务返回的id,
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| txid | string | 事务 txid |
| requestId| string | 创建未签名事务返回的requestId |
#### 提交签名事务错误
```
key: "TOKEN_ACTION",
msg: {
status: SUBMIT_TRANSACTION_TO_CHAIN_ERROR
error:
requestId: 转账id,
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| error| string | 错误消息 |
| requestId| string | 创建未签名事务返回的requestId |
#### 提交签名事务链上返回错误
```
key: "TOKEN_ACTION",
msg: {
status: SUBMIT_TRANSACTION_ON_CHAIN_ERROR
error:
requestId: 转账id,
}
```
**返回值**
| 参数名 | 参数类型 | 描述 |
| --- | --- | --- |
| status | string | 状态 |
| error| string | 错误消息 |
| requestId| string | 创建未签名事务返回的requestId |
#### 上链事务确认
```
key: "TOKEN_ACTION",
msg:{
status: 'TOKEN_FINISH',
requestId: 提交签名事务返回的id,
record: {
id
chain,
coin,
tokenKey,
tokenOrigin,
meta,
name,
symbol,
txType
creator,
owner,
value
txid,
blockNum,
},
balance: { // 地址余额
coin,
tokenKey,
address,
total,
inConfirming,
outConfirming,
outLocked
},
}
```
**返回值**
| 参数名 | 对象内部参数 | 参数类型 | 描述 |
| --- | --- | --- | --- |
| status || string | 状态 |
| requestId| | string | 创建未签名事务返回的requestId |
| record| | object| 创建未签名事务返回的requestId |
| | chain| string | 链|
| | coin| string | 币种|
| | tokenKey | string | tokenId |
| | tokenOrigin | string | token源|
| | meta| string | 该事务附加的属性|
| | name| string | token名称 |
| | symbol| string | token简写 |
| | creator| string | token发行者 |
| | owner| string | token拥有者 |
| | value| string | 数量 |
| | txType| string |参见txType说明 |
| | txid| string | 事务的txid |
| | blockNum| string | 块高 |
| balance | | object| 参见余额接口说明 |
## txType说明
- txType :astro 专有
- 'astro.token.offer' // 增发
- 'astro.token.create' // 发行
- 'astro.token.exchange' //提货
- 'astro.token.deliver' //发货
- 'astro.token.change' // 换货
- 'astro.token.refunding' // 申请退货
- 'astro.token.refund' // 处理退货
## 错误码
| 错误码 | 描述 |
| --- |--- |
|460003|设置回调url错误|
|460006|设置回调url异常|
| 460010 | 创建发布Token 事务异常 |
| 460011 | 创建Token 增发事务异常 |
| 460012 | 创建Token Transfer 事务异常 |
| 460013 | 创建提货事务异常 |
| 460014 | 创建发货事务异常 |
| 460015 | 创建换货事务异常 |
| 460016 | 创建处理退货事务异常 |
| 460017 | 创建申请退货事务异常 |
| 460018 | 提交签名事务类型错误 |
| 460019 | 提交签名事务RequestId错误 |
| 460020 | 提交签名事务异常 |
| 460021 | 获取余额异常 |
| 460022 | 获取交易详情异常 |
| 460023 | 获取Token状态异常 |
| 460067 | 获取转账详情失败 |
| 460068 | 获取转账详情异常 |
| 460069 | 获取历史详情异常 |
| 460070 | 订阅失败 |
| 460071 | 订阅异常 |
## token 合约简单说明
### 个别字段说明
| 字段 | 描述 |
| --- |--- |
|tokenKey|某一个具体的token|
|tokenOrigin|一个token的源token,子token包含 【 \_ex_ 】 |
| tokenChild | 一个事务中tokenKey裂变的子token,注意处理退货事务的tokenChild不是新token |
### astro token 合约接口说明
astro token 合约目前提供:转账、申请提货、发货、申请退货、处理退货等接口
下面以 用户:c,商家 b ,token:t 进行举例,以便于理解各个接口
1. 假如商家 b 发行 token t 1000个
2. 用户c 向 商家 b购买 100个 token t,调用转账接口;(from:b、to:c、 value:100 );等待链上确认结束,此时商家 b 拥有token t :900个,用户b拥有 token t 100个
3. 用户c 向商家 b 申请提货 token t 20 个,调用申请提货接口(from:c、to:b、value:20);等待链上确认结束,此次交易记录应该为:
```
"from" : "c",
"to" : "b",
"txid" : "B80704BB7B4D7C0315A17E03F23FA2FC",
"blockHeight" : 3,
"chain" : "ASTRO",
"coin" : "ASTRO_TOKEN",
"meta" : "this is a exchange 20 ",
"tokenChild" : "t_ex_t1",
"tokenKey" : "t",
"tokenOrigin" : "t",
"txType" : "astro.token.exchange",
"value" : "20"
```
此时:用户c 拥有 token t 80个,商家 b 拥有token t\_ex\_t1 20 个;
**注**
该交易记录 token t 裂变为 t_ex_t1
4. 商家 b 向 用户 c 发货 20 个,调用发货接口(from:b,to:c tokenKey:t\_ex\_t1);等待上链结束,此时交易记录应为:
```
"from" : "b",
"to" : "c",
"txid" : "365A858149C6E2D115A17E03F85F1BA4",
"blockHeight" : 4,
"chain" : "ASTRO",
"coin" : "ASTRO_TOKEN",
"meta" : null,
"tokenChild" : "t_ex_t1",
"tokenKey" : "t_ex_t2",
"tokenOrigin" : "t",
"txType" : "astro.token.deliver",
"value" : "20"
```
此时:商家拥有token t_ex_t1 0个,用户拥有token t_ex_t2 20 个
**注**
发货接口有个split 参数,true 表示token t_ex_t1 会裂变为新token t_ex_t2,false 表示不会裂变新token;
此处以 split true 为条件。 [ 如果split 为false ,则用户 b 将拥有token t_ex_t1 20个(此时不会有t_ex_t2 产生)]
5. 用户 b 向商家 c 申请换货 10 个,调用 换货接口 (from : b ,to:c,tokenKey : t\_ex\_t2);等待上链结束,此时交易记录应为:
```
"from" : "b",
"to" : "c",
"txid" : "57E9D1860D1D68D815A17E03FE2342F4",
"blockHeight" : 5,
"chain" : "ASTRO",
"coin" : "ASTRO_TOKEN",
"meta" : "change",
"tokenChild" : "t_ex_t3",
"tokenKey" : "t_ex_t2",
"tokenOrigin" : "t",
"txType" : "astro.token.change",
"value" : "10"
```
此时 用户 b 拥有 t\_ex\_t2 10个,商家 c 拥有 t\_ex\_t3 10个
**注**
用户换货后,商家应该重新发货,此时发货的tokenKey 应该为 t_ex_t3 。
6. 用户 b 向商家 c 申请退货 10 个 ,调用申请退货接口 (from : b ,to:c,tokenKey : t_ex_t2);等待上链结束,此时交易记录应为:
```
"from" : "b",
"to" : "c",
"txid" : "8866CB397916001E15A17E04020FA59C",
"blockHeight" : 6,
"chain" : "ASTRO",
"coin" : "ASTRO_TOKEN",
"meta" : "退货ing",
"tokenChild" : "t_ex_t4",
"tokenKey" : "t_ex_t2",
"tokenOrigin" : "t",
"txType" : "astro.token.refunding",
"value" : "10"
```
此时 用户 b 拥有 t_ex_t2 0个,商家 c 拥有 t_ex_t4 10个
7. 商家 c 处理退货,调用处理退货接口 (from : c ,to:b,tokenKey : t_ex_t4);等待上链结束,此时交易记录应为:
```
"from" : "c",
"to" : "b",
"txid" : "9408D2AC22C4D29415A17E0408110E90",
"blockHeight" : 7,
"chain" : "ASTRO",
"coin" : "ASTRO_TOKEN",
"meta" : "退货",
"tokenChild" : "t",
"tokenKey" : "t_ex_t4",
"tokenOrigin" : "t",
"txType" : "astro.token.refund",
"value" : "10"
```
此时 商家 c 所拥有的token t_ex_t4 为0,同时 拥有的token t 减少10个,用户拥有的token t 增加10 个
**注**
这种情况下的tokenChild t 不是新的token