## key-manager服务 key-manager是一个助记词账户管理服务,包括助记词创建,助记词加密,钱包派生,钱包查询,白名单机制,交易签名等功能。使用grpc作为服务交互协议,方便多语言之间交互。 功能: - 设置密码 - 设置的密码,将作为加密助记词的密码。务必保存好该密码,否则将丢失所有的助记词并且key-manager也将无法启动。(key-manager在启动时会校验密码) - 创建多个助记词 - 创建助记词时需指定 name,name全局唯一,是即将要创建的助记词的代号 - 助记词加密 - 创建的助记词将会被加密存储在mysql中,在运行中要注意对mysql的备份 - 创建eth和tron地址 - 通过助记词name,network,以及index,可创建对应网络的私钥和地址 - 白名单机制 - 服务为交易签名时,将识别资金接收地址,只有接收地址在白名单内,服务才会进行签名,否则将会拒绝签名。 - 白名单地址列表只有在服务启动时进行加载,不会在运行中热加载,因为防止mysql被攻击。如果想要增加白名单,需在mysql中增加地址后,重启key-manager服务。 - 为eth和tron交易签名 - key-manager接收经过编码的交易,反解码为交易详情,检查交易目的地址是否在白名单内,在白名单内时,将进行签名。并将签名过的交易进行编码返回。 ## Proto文件 根据该proto文件,自动生成客户端请求代码 java生成参考,关键字:grpc生成java代码 https://developer.aliyun.com/article/679610 https://zhuanlan.zhihu.com/p/365370775 ``` syntax = "proto3"; package service; option java_package = "proto.keyManager"; option java_outer_classname = "keyManagerProto"; option go_package = "../service"; message CreateMnemonicRequest { string name = 1; // 商户名字,名字全局唯一,每个商户只能生成一个助记词 int64 mnemonicType = 2; // 0 or 1, 0代表12个助记词,1代表24个助记词 } message CreateMnemonicResponse { string code = 1; // 响应码, 成功是200 string msg = 2; // 响应描述信息 } message CreateKeyRequest { string name = 1; // 商户名字,如果该商户未创建助记词,则返回错误 string network = 2; // 链网络名称,"eth" 或 "tron" int64 index = 3; // 派生账户使用的index,如果该index已被使用,则返回错误 } message GetIndexRequest { string network = 1; // 链网络名称,"eth" 或 "tron" string address = 2; // 查询该地址对应的商户名字和index } message GetAddressRequest { string name = 1; // 商户名字,如果该商户未创建助记词,则返回错误 string network = 2; // 链网络名称,"eth" 或 "tron" int64 index = 3; // 派生账户使用的index } message KeyResponse { string code = 1; // 响应码, 成功是200 string msg = 2; // 响应描述信息 string network = 3; // 链网络名称,"eth" 或 "tron" string name = 4; // 商户名字 int64 index = 5; // 派生账户使用的index string address = 6; // 地址 } message SignRequest { string network = 1; // 链网络名称,"eth" 或 "tron" string sender = 2; // 签名地址 string tx = 3; // 编码的交易,先将eth/tron交易Marshal为字符数组,再编码为hex字符串 } message SignResponse { string code = 1; // 响应码, 成功是200 string msg = 2; // 响应描述信息 string network = 3; // 链网络名称,"eth" 或 "tron" string sender = 4; // 签名地址 string signedTx = 5; // 编码的已签名交易,先将eth/tron已签名交易Marshal为字符数组,再编码为hex字符串 } service KeyManager { rpc CreateMnemonic(CreateMnemonicRequest) returns(CreateMnemonicResponse) {} rpc CreateKey(CreateKeyRequest) returns(KeyResponse) {} rpc GetIndex(GetIndexRequest) returns(KeyResponse) {} rpc GetAddress(GetAddressRequest) returns(KeyResponse) {} rpc Sign(SignRequest) returns(SignResponse) {} } ``` ## 交易编解码规则 对于Sign服务参数的构造,接收三个参数,分别是: - 网络,必须填写 eth或者 tron - sender,是交易发送者地址,即签名地址 - tx,是经过编码的交易 ``` message SignRequest { string network = 1; // 链网络名称,"eth" 或 "tron" string sender = 2; // 签名地址 string tx = 3; // 编码的交易,先将eth/tron交易Marshal为字符数组,再编码为hex字符串 } ``` 其中tx的编解码规则如下: **eth** 编码规则(请求参数构建): - 先json编码byte数组,再hex编码为字符串 - json编码:https://github.com/ethereum/go-ethereum/blob/master/core/types/transaction_marshalling.go#L75 - hex编码:hex.EncodeToString 解码已签名交易(返回参数解析): - 先将字符串hex解码为byte数据,再将byte数组json解码为eth交易Transaction java的以太坊库可参考 https://github.com/web3j/web3j - java Transaction:https://github.com/web3j/web3j/blob/master/core/src/main/java/org/web3j/protocol/core/methods/request/Transaction.java#L31 **tron** 编码规则(请求参数构建): - 通过proto协议将Transaction编码为byte数组,hex编码为字符串 - proto编码:https://gist.github.com/miguelmota/25568433ad8cfddb5ea556a5644c9fde - hex编码:hex.EncodeToString 解码已签名交易(返回参数解析): - 先将字符串hex解码为byte数据,再将byte数组proto解码为tron交易Transaction tron协议实现就是java,相关交易构建,编解码应该都有 https://github.com/tronprotocol/java-tron ## 请求参数示例 **CreateMnemonic** `{"name":"test", "mnemonicType": 0}` **CreateKey** `{"name":"test4", "network": "eth", "index": 0}` `{"name":"test4", "network": "tron", "index": 0}` **GetIndex** `{"network": "tron", "address": "TQxgjRTVjx6QsK4huSv2Ex3aUDJTs9g6X2"}` `{"network": "eth", "address": "0x313A1F70aCA7dE919ff2104F50f94985308E38A8"}` **GetAddress** `{"name": "test", "network": "tron", "index": 0}` `{"name": "test4","network": "eth", "index": 0}` **Sign** `{"network":"eth","sender":"0x313A1F70aCA7dE919ff2104F50f94985308E38A8","tx":"7b2274797065223a22307832222c226e6f6e6365223a22307830222c226761735072696365223a6e756c6c2c226d61785072696f72697479466565506572476173223a22307832373130222c226d6178466565506572476173223a22307832373130222c22676173223a22307832373130222c2276616c7565223a22307830222c22696e707574223a22307861393035396362623030303030303030303030303030303030303030303030303038656636313166363961623438613331666666373338303038386561613130366133626435613530303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030306634323430222c2276223a22307830222c2272223a22307830222c2273223a22307830222c22746f223a22307861306238363939316336323138623336633164313964346132653965623063653336303665623438222c22636861696e4964223a22307831222c226163636573734c697374223a5b5d2c2268617368223a22307832366136326435343633306436626265313431613038306666663463646264346533346363613932343535386531643063383063643065303830643632316566227d"}` `{"network":"tron","sender":"TLZMwPhCvqGt8w4523L7ciMcEG4EWwxWKP","tx":"0ad0010a028042220801a85c6e6c4861f740c8938b95a1315aae01081f12a9010a31747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e54726967676572536d617274436f6e747261637412740a1541dc05f6df15aa25676218932957337f6dadd5fc91121541a614f803b6fd780986a42c78ec9c7f77e6ded13c2244a9059cbb0000000000000000000000008405fb55ed44d8212061672a83ddaafecec3388f00000000000000000000000000000000000000000000000000000000000f424070dbcb8795a131900132"}`