signer.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. package service
  2. import (
  3. "context"
  4. "crypto/ecdsa"
  5. "crypto/sha256"
  6. "encoding/hex"
  7. "errors"
  8. "fmt"
  9. "github.com/ethereum/go-ethereum/common"
  10. "github.com/ethereum/go-ethereum/core/types"
  11. "github.com/ethereum/go-ethereum/crypto"
  12. tronaddr "github.com/fbsobreira/gotron-sdk/pkg/address"
  13. troncore "github.com/fbsobreira/gotron-sdk/pkg/proto/core"
  14. "google.golang.org/protobuf/proto"
  15. "key-manager/dao"
  16. "math/big"
  17. )
  18. func format(network, address string) (string, error) {
  19. if network == eth {
  20. address = common.HexToAddress(address).String()
  21. } else {
  22. addr, err := tronaddr.Base58ToAddress(address)
  23. if err != nil {
  24. return "", err
  25. }
  26. address = addr.String()
  27. }
  28. return address, nil
  29. }
  30. func (km *KeyManager) loadSigner(network, signer string) error {
  31. var err error
  32. signer, err = format(network, signer)
  33. if err != nil {
  34. return err
  35. }
  36. if _, ok := km.signers[signer]; !ok {
  37. var info dao.AccountInfo
  38. if network == eth {
  39. info, err = km.dao.GetEthFromAddress(signer)
  40. if err != nil {
  41. return err
  42. }
  43. } else {
  44. info, err = km.dao.GetTronFromAddress(signer)
  45. if err != nil {
  46. return err
  47. }
  48. }
  49. if _, exist := km.mnemonics[info.GetName()]; !exist {
  50. return errors.New("user mnemonic lost")
  51. }
  52. account, err := createKey(km.mnemonics[info.GetName()], network, info.GetIndex())
  53. if err != nil {
  54. return err
  55. }
  56. km.signers[signer] = account.GetPriKey()
  57. }
  58. return nil
  59. }
  60. func (km *KeyManager) Sign(ctx context.Context, req *SignRequest) (*SignResponse, error) {
  61. km.lk.Lock()
  62. defer km.lk.Unlock()
  63. if err := checkNetwork(req.Network); err != nil {
  64. return &SignResponse{
  65. Code: networkErrCode,
  66. Msg: networkErrMsg,
  67. Network: req.Network,
  68. Sender: req.Sender,
  69. SignedTx: "",
  70. }, nil
  71. }
  72. if err := km.loadSigner(req.Network, req.Sender); err != nil {
  73. return &SignResponse{
  74. Code: loadSignerErrCode,
  75. Msg: err.Error(),
  76. Network: req.Network,
  77. Sender: req.Sender,
  78. SignedTx: "",
  79. }, nil
  80. }
  81. var marshalTx string
  82. var coin string
  83. var to string
  84. var amount string
  85. if req.Network == eth {
  86. tx, err := unmarshalJEthTx(req.Tx)
  87. if err != nil {
  88. return &SignResponse{
  89. Code: unmarshalJEthTxErrCode,
  90. Msg: err.Error(),
  91. Network: req.Network,
  92. Sender: req.Sender,
  93. SignedTx: "",
  94. }, nil
  95. }
  96. coin, to, amount, err = checkErc(tx, km.whitelists)
  97. if err != nil {
  98. return &SignResponse{
  99. Code: checkErcTxErrCode,
  100. Msg: err.Error(),
  101. Network: req.Network,
  102. Sender: req.Sender,
  103. SignedTx: "",
  104. }, nil
  105. }
  106. signedTx, err := signEthTransaction(tx, km.signers[req.Sender])
  107. if err != nil {
  108. return &SignResponse{
  109. Code: signEthTxErrCode,
  110. Msg: err.Error(),
  111. Network: req.Network,
  112. Sender: req.Sender,
  113. SignedTx: "",
  114. }, nil
  115. }
  116. marshalTx, err = marshalJEthTx(signedTx)
  117. if err != nil {
  118. return &SignResponse{
  119. Code: marshalJEthTxErrCode,
  120. Msg: err.Error(),
  121. Network: req.Network,
  122. Sender: req.Sender,
  123. SignedTx: "",
  124. }, nil
  125. }
  126. } else {
  127. tx, err := unmarshalJTronTx(req.Tx)
  128. if err != nil {
  129. return &SignResponse{
  130. Code: unmarshalJTronTxErrCode,
  131. Msg: err.Error(),
  132. Network: req.Network,
  133. Sender: req.Sender,
  134. SignedTx: "",
  135. }, nil
  136. }
  137. coin, to, amount, err = checkTron(tx, km.whitelists)
  138. if err != nil {
  139. return &SignResponse{
  140. Code: checkTronTxErrCode,
  141. Msg: err.Error(),
  142. Network: req.Network,
  143. Sender: req.Sender,
  144. SignedTx: "",
  145. }, nil
  146. }
  147. signedTx, err := signTronTransaction(tx, km.signers[req.Sender])
  148. if err != nil {
  149. return &SignResponse{
  150. Code: signTronTxErrCode,
  151. Msg: err.Error(),
  152. Network: req.Network,
  153. Sender: req.Sender,
  154. SignedTx: "",
  155. }, nil
  156. }
  157. marshalTx, err = marshalJTronTx(signedTx)
  158. if err != nil {
  159. return &SignResponse{
  160. Code: marshalJTronTxErrCode,
  161. Msg: err.Error(),
  162. Network: req.Network,
  163. Sender: req.Sender,
  164. SignedTx: "",
  165. }, nil
  166. }
  167. }
  168. err := km.dao.CreateSignTx(&dao.SignTx{
  169. Network: req.Network,
  170. Coin: coin,
  171. From: req.Sender,
  172. To: to,
  173. Amount: amount,
  174. })
  175. if err != nil {
  176. log.Warnw("save Sign Tx to mysql failed", "network", req.Network, "coin", coin, "from", req.Sender, "to", to, "amount", amount, "err", err)
  177. }
  178. return &SignResponse{
  179. Code: okCode,
  180. Msg: okMsg,
  181. Network: req.Network,
  182. Sender: req.Sender,
  183. SignedTx: marshalTx,
  184. }, nil
  185. }
  186. func marshalJEthTx(transaction *types.Transaction) (string, error) {
  187. b, err := transaction.MarshalJSON()
  188. if err != nil {
  189. return "", err
  190. }
  191. return hex.EncodeToString(b), nil
  192. }
  193. func unmarshalJEthTx(tx string) (*types.Transaction, error) {
  194. b, err := hex.DecodeString(tx)
  195. if err != nil {
  196. return nil, err
  197. }
  198. var transaction = &types.Transaction{}
  199. err = transaction.UnmarshalJSON(b)
  200. if err != nil {
  201. return nil, err
  202. }
  203. return transaction, err
  204. }
  205. func marshalJTronTx(transaction *troncore.Transaction) (string, error) {
  206. b, err := proto.Marshal(transaction)
  207. if err != nil {
  208. return "", err
  209. }
  210. return hex.EncodeToString(b), nil
  211. }
  212. func unmarshalJTronTx(tx string) (*troncore.Transaction, error) {
  213. b, err := hex.DecodeString(tx)
  214. if err != nil {
  215. return nil, err
  216. }
  217. var transaction troncore.Transaction
  218. err = proto.Unmarshal(b, &transaction)
  219. if err != nil {
  220. return nil, err
  221. }
  222. return &transaction, nil
  223. }
  224. func signEthTransaction(transaction *types.Transaction, priv *ecdsa.PrivateKey) (*types.Transaction, error) {
  225. signer := types.NewLondonSigner(big.NewInt(1))
  226. var err error
  227. transaction, err = types.SignTx(transaction, signer, priv)
  228. if err != nil {
  229. return nil, err
  230. }
  231. return transaction, nil
  232. }
  233. func signTronTransaction(transaction *troncore.Transaction, priv *ecdsa.PrivateKey) (*troncore.Transaction, error) {
  234. rawData, err := proto.Marshal(transaction.GetRawData())
  235. if err != nil {
  236. return nil, fmt.Errorf("proto marshal tx raw data error: %v", err)
  237. }
  238. h256h := sha256.New()
  239. h256h.Write(rawData)
  240. hash := h256h.Sum(nil)
  241. signature, err := crypto.Sign(hash, priv)
  242. if err != nil {
  243. return nil, fmt.Errorf("sign error: %v", err)
  244. }
  245. transaction.Signature = append(transaction.Signature, signature)
  246. return transaction, nil
  247. }