# 接口规范

# 通信协议

采用http方式调用,接口仅支持POST方式调用。

# 字符编码

统一使用utf-8编码,避免多字符集编码造成的异常。

# 数据格式

参数的提交和结果返回统一采用json格式的数据,例如:

{
“retcode”:0,
“retmsg”:OK,
“info_no ”:19000001092016091800000001,
“sign”:8DB4A013A8B515349C307F1E448CE836
}

一般有返回码retcode参数,0表示调用成功;非0表示调用失败,失败时结果不签名,只有retcode和返回信息retmsg

# 公私钥、地址与签名

TrustSQL统一采用ECDSA进行数字签名,曲线选择与比特币相同:secp256k1

公私钥:采用secp256k1椭圆曲线生成一对,或者通过私钥可以算出公钥。在TrustSQL中公私钥的编码格式为Base64

地址:通过私钥可以算出公钥,通过公钥可以算出地址,地址使用。在TrustSQL中地址的编码格式为Base58
流程图
签名:使用secp256k1椭圆曲线签名,签名后的r/s使用der编码。在TrustSQL中签名的编码格式为Base64
相关SDK函数:

函数名 说明
GeneratePairkey 生成一对公私钥
GeneratePubkeyByPrvkey 通过私钥生产公钥
GenerateAddrByPubkey 通过公钥生成地址
GenerateAddrByPrvkey 通过私钥生产地址
CheckPairkey 验证一对公私钥是否匹配

# 参数mch_sign的签名过程

通讯方签名(mch_sign)串生成规则

通讯方签名存在于每一个接口中,签名算法建议直接调用SDK包中的SignString函数来生成通讯方签名。

  1. 拼接签名原字符串规则:

按请求接口中除mch_sign之外的所有参数字段名的ASCII码从小到大排序,排序后使用QueryString的格式(即key1=value1&key2=value2…)拼接而成。签名时字段名和字段值都采用UTF-8编码,但不进行URL 编码。

  1. 签名算法描述:

sign = base64(ECDSA (sha256(原字符串)))。签名后的r/s使用DER编码再转成base64表示。

  1. 签名源串拼接例子:
amount=12&asset_type=0&channel_id=123456&content={"test":"test","array":[1,2]}&mch_id=gbbdf99dceb1311&owner_account=15DbLM8bYDB5aAdpLuvR6GEMojgKKbTG17&sign_type=ECDSA&source_id=alvin_001&timestamp=1515110822&unit=yuan&version=1.0

调用sdk的signString(java版)生成签名,例如:

TrustSDK.signString("TpWgEhH0NFIw17TaQHNltW7oP+YQQC6+3/s2j9muMc8=", "amount=12&asset_type=0&channel_id=123456&content={"test":"test","array":[1,2]}&mch_id=gbbdf99dceb1311&owner_account=15DbLM8bYDB5aAdpLuvR6GEMojgKKbTG17&sign_type=ECDSA&source_id=alvin_001×tamp=1515110822&unit=yuan&version=1.0".getBytes("UTF-8"),false)

其中第一个参数是商户的私钥,第二个参数是把签名原串转为字节数组,第三个参数表示字符串没有进行sha256,这样sdk会进行sha256

调用该函数返回的结果是:

MEUCIQDHZEWOlKkv2ptkTjbhz+18AXsjZguLd4Np//L1hmmsKAIgRh37bgJuB7Wt+GK5P1OB+U9TRzyn8LRILaThYLF6DlU=

再将该返回结果作为mch_sign字段的值,就可以向接口post发送请求:

{"amount":"12","asset_type":"0","channel_id":"123456","content":"{"test":"test","array":[1,2]}","mch_id":"gbbdf99dceb1311","owner_account":"15DbLM8bYDB5aAdpLuvR6GEMojgKKbTG17","sign_type":"ECDSA","source_id":"alvin_001","timestamp":"1515110822","unit":"yuan","version":"1.0,"mch_sign":"MEUCIQDHZEWOlKkv2ptkTjbhz+18AXsjZguLd4Np//L1hmmsKAIgRh37bgJuB7Wt+GK5P1OB+U9TRzyn8LRILaThYLF6DlU="}

注意:此处用到的私钥是与右上角账号中心->“我的账户”->“机构公钥”中上传的公钥对应

# 参数sign的签名过程

交易签名(sign)串生成规则

交易签名只存在提交接口中,签名算法建议直接调用SDK包中的SignRenString函数来生成交易签名。

  1. 待签名串:

待签名串来自于申请接口的返回字段sign_str,具体表现格式如下:

be432e48117b912ae6d25030f2de1776f4493138dc9bc7828b48f08d3f96a569
  1. 签名算法描述:

sign = base64(ECDSA (Hex.decode(原字符串)))。签名后的r/s使用DER编码再转成base64表示。

  1. 生成过程:

调用sdk的SignRenString(java版)生成签名,例如:

TrustSDK.SignRenString("FCVDyc4UDT7lWAxk0OGssOznXZqajVLTn3lzoPtKvC4",Hex.decodeHex("be432e48117b912ae6d25030f2de1776f4493138dc9bc7828b48f08d3f96a569".toCharArray()))

其中第一个参数是账户的私钥,第二个参数是把签名原串进行十六进制解码转为字节数组。

调用该函数返回的结果是:

MEQCIG3e28gDg0S5aNjcqsYd7KqnTG73yWKEE2G8URvsg0iBAiAoNcPXgCmlmdXeEaQHzufldioDrDdrMibEdEIlTVMc1Q==

再将该返回结果作sign字段的值,在提交接口中发送。

# 数字资产两步提交说明

数字资产接口为两步接口,第一步生成提交时需要验证的签名串和签名地址,商户拿到后需要用提供的签名地址的私钥对签名串进行签名后,将结果放到对应的json object中,然后放到第二步接口中提交。

  • xxxx_apply.cgi为生成提交参数接口
  • xxxx_submit.cgi/xxxx_sign.cgi为生成提交参数接口

例子如下,调用发行接口dam_asset_issue_apply_v1.cgi后返回sign_list结果如下:

sign_list=[{"id":"1","account":"1M4ChsEeLxSU5xxxxxPjePTAjCkjZUjU","sign_str":"c68d6fbbee7aebdedc41b64a396b0b75701a7d04a16cd67aa18e7ca124d5dfa1"}]

用户拿到后,需要用account的私钥对,sign_str进行ecdsa签名,然后把签名结果(举例:MEQCIFGxxxxxsQ9az97gIazbzZS4EmQkM1W1wGZli9cpjwjDAiAXzhjsLZHfKyFzg86MRLEeBeSmxxxij63eQopIT1/Xig==)放到json object中,例子:

sign_list=[{"id":"1","account":"1M4ChsEeLxSU5xxxxxPjePTAjCkjZUjU","sign_str":"c68d6fbbee7aebdedc41b64a396b0b75701a7d04a16cd67aa18e7ca124d5dfa1",”sign”:” MEQCIFGxxxxxsQ9az97gIazbzZS4EmQkM1W1wGZli9cpjwjDAiAXzhjsLZHfKyFzg86MRLEeBeSmxxxij63eQopIT1/Xig==”}]

然后在提交接口提交该参数即可。

如果sign_list中有多个待签名串,则需要对每个串进行签名。这里多笔转让、多笔兑付的时候会返回多个待签名串。