zcashcoins.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. package zcash
  2. import (
  3. "encoding/json"
  4. //"errors"
  5. "fmt"
  6. "strconv"
  7. . "template"
  8. "time"
  9. simplejson "github.com/go-simplejson"
  10. tml "github.com/toml-master"
  11. )
  12. var (
  13. BucketZEC string = "ZEC"
  14. ZecConfig config
  15. zcashOp ZcashApi
  16. )
  17. type Zcash struct{}
  18. const (
  19. NameZcash = "ZEC"
  20. )
  21. func (m Zcash) InitDriver(parm interface{}) bool {
  22. if m.initconfig() == false {
  23. return false
  24. }
  25. go m.zcashgetinfo()
  26. return true
  27. }
  28. //get the server's total available balance
  29. func (m Zcash) CoinBalance(parm interface{}) ([]byte, error) {
  30. confirmedBalance, err := zcashOp.WalleGetBalance("")
  31. if err != nil {
  32. LOG("ERROR", "zcash GetBalance err:%v", err.Error())
  33. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBALANCE_ERR, getErrMsg(GETBALANCE_ERR, nil))
  34. }
  35. UnconfirmedBalance, err := zcashOp.WalleGetUnconfirmedBalance("")
  36. if err != nil {
  37. LOG("ERROR", "zcash GetUnconfirmedBalance err:%s", err.Error())
  38. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETUNCONFIRMEDBALANCE_ERR, getErrMsg(GETUNCONFIRMEDBALANCE_ERR, nil))
  39. }
  40. var jbuf []byte
  41. resp := make(map[string]interface{})
  42. resp["confirmedbalance"] = confirmedBalance
  43. resp["unconfirmed"] = UnconfirmedBalance
  44. resp["errcode"] = 0
  45. resp["exact"] = 0
  46. if jbuf, err = json.Marshal(resp); err != nil {
  47. LOG("ERROR", "zcash inner json error:%v", err.Error())
  48. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  49. }
  50. return jbuf, nil
  51. }
  52. //Returns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.
  53. func (m Zcash) TransInfo(parm interface{}) ([]byte, error) {
  54. pjs := parm.(*simplejson.Json)
  55. startH := pjs.Get("starth").MustUint64()
  56. endH := pjs.Get("endh").MustUint64()
  57. if startH < 1 {
  58. startH = 1
  59. }
  60. //get longest block count
  61. blockcount, err := zcashOp.WalleGetBlockCount()
  62. if err != nil {
  63. LOG("ERROR", "zcash WalleGetBlockCount err:%v", err.Error())
  64. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETCLOCKCOUNT_ERR, getErrMsg(GETCLOCKCOUNT_ERR, nil))
  65. }
  66. //first get block hash and time by height
  67. if startH > blockcount {
  68. LOG("DEBUG", "zcash startheight:%v > blockcount:%v", startH, blockcount)
  69. startH = blockcount
  70. }
  71. startheight := strconv.FormatUint(uint64(startH-1), 10)
  72. startblockhash, _, err := zcashOp.WalletGetBlockinfo(startheight)
  73. if err != nil {
  74. LOG("ERROR", "zcash GetBlockinfo startH:%v err:%v", startH, err.Error())
  75. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBLOCKINFO_ERR, getErrMsg(GETBLOCKINFO_ERR, nil))
  76. }
  77. if endH > blockcount {
  78. LOG("DEBUG", "zcash endheight:%v > blockcount:%v", endH, blockcount)
  79. endH = blockcount
  80. }
  81. endheight := strconv.FormatUint(endH, 10)
  82. _, endblocktime, err := zcashOp.WalletGetBlockinfo(endheight)
  83. if err != nil {
  84. LOG("ERROR", "zcash GetBlockinfo endH:%v err:%v", endH, err.Error())
  85. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBLOCKINFO_ERR, getErrMsg(GETBLOCKINFO_ERR, nil))
  86. }
  87. //Get all transactions in blocks since block [blockhash]
  88. resp, err := zcashOp.WalleListSinceBlock(startblockhash)
  89. if err != nil {
  90. LOG("ERROR", "zcash WalleListSinceBlock err:%v", err.Error())
  91. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, TRANSINFO_ERR, getErrMsg(TRANSINFO_ERR, nil))
  92. }
  93. var zcashlisttransactionsinfo []Zcashlisttransactions
  94. if err = json.Unmarshal([]byte(resp), &zcashlisttransactionsinfo); err != nil {
  95. LOG("ERROR", "zcash inner json error:%v", err.Error())
  96. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  97. }
  98. outputsArr := make([]map[string]interface{}, 0)
  99. for _, zcashtransaction := range zcashlisttransactionsinfo {
  100. // get all transactions from block startHright to endHeight
  101. if zcashtransaction.Blocktime <= endblocktime {
  102. requestData := make(map[string]interface{})
  103. height, err := zcashOp.WalletGetBlockHeight(zcashtransaction.Blockhash)
  104. if err != nil {
  105. LOG("ERROR", "zcash WalletGetBlockHeight error:%v", err.Error())
  106. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBLOCKINFO_ERR, getErrMsg(GETBLOCKINFO_ERR, nil))
  107. }
  108. requestData["confirmationheight"] = height
  109. requestData["address"] = zcashtransaction.Address
  110. requestData["confirmationtimestamp"] = zcashtransaction.Timereceived
  111. requestData["value"] = zcashtransaction.Amount
  112. requestData["transactionid"] = zcashtransaction.Txid
  113. requestData["confirmations"] = zcashtransaction.Confirmations
  114. requestData["walletaddress"] = true
  115. outputsArr = append(outputsArr, requestData)
  116. }
  117. }
  118. var jbuf []byte
  119. resptmp := make(map[string]interface{})
  120. resptmp["errcode"] = 0
  121. resptmp["cointype"] = "ZEC"
  122. resptmp["outputs"] = outputsArr
  123. if jbuf, err = json.Marshal(resptmp); err != nil {
  124. LOG("ERROR", "zcash inner json error:%v", err.Error())
  125. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  126. }
  127. return jbuf, nil
  128. }
  129. //Sent an amount from an account to a zcash address.
  130. func (m Zcash) TransferAccounts(parm interface{}) ([]byte, error) {
  131. pjs := parm.(*simplejson.Json)
  132. amountTmp := pjs.Get("amount").MustString()
  133. destination := pjs.Get("address").MustString()
  134. if len(amountTmp) == 0 {
  135. LOG("ERROR", "zcash amount illeagal")
  136. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, AMOUNT_ERR, getErrMsg(AMOUNT_ERR, nil))
  137. }
  138. f, err := strconv.ParseFloat(amountTmp, 64)
  139. if err != nil {
  140. LOG("ERROR", "zcash inner json error:%v", err.Error())
  141. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  142. }
  143. amount := float64(f)
  144. transactionid, err := zcashOp.WalleSendFrom("", destination, amount, 1, "", "")
  145. if err != nil {
  146. LOG("ERROR", "zcash Send coin error:%v", err.Error())
  147. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, SENDCOINS_ERR, getErrMsg(SENDCOINS_ERR, nil))
  148. }
  149. if len(transactionid) != 0 {
  150. var jbuf []byte
  151. resp := make(map[string]interface{})
  152. resp["transactionid"] = []string{transactionid}
  153. resp["errcode"] = 0
  154. resp["msg"] = "ok"
  155. if jbuf, err = json.Marshal(resp); err != nil {
  156. LOG("ERROR", "zcash inner json error:%v", err.Error())
  157. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  158. }
  159. return jbuf, nil
  160. }
  161. LOG("ERROR", "zcash transactionid is null error:%v", err.Error())
  162. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  163. }
  164. //create a new Zcash t-address&key for receiving payments
  165. func (m Zcash) CreateAddress(parm interface{}) ([]byte, error) {
  166. addr, err := zcashOp.WalletNewAddr()
  167. if err != nil {
  168. LOG("ERROR", "zcash get new t-address error:%v", err.Error())
  169. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETNEWADDRESS_ERR, getErrMsg(GETNEWADDRESS_ERR, nil))
  170. }
  171. if len(addr) != 0 {
  172. //get key by the address
  173. key, err := zcashOp.WalletDumpPrivKey(addr)
  174. if err != nil {
  175. LOG("ERROR", "zcash dump private key error:%v", err.Error())
  176. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, DUMPPRIVKEY_ERR, getErrMsg(DUMPPRIVKEY_ERR, nil))
  177. }
  178. if len(key) != 0 {
  179. var jbuf []byte
  180. resp := make(map[string]interface{})
  181. resp["address"] = addr
  182. resp["privkey"] = key
  183. resp["errcode"] = 0
  184. if jbuf, err = json.Marshal(resp); err != nil {
  185. LOG("ERROR", "zcash inner json error:%v", err.Error())
  186. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  187. }
  188. return jbuf, nil
  189. }
  190. LOG("ERROR", "zcash privkey is null error:%v")
  191. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  192. }
  193. LOG("ERROR", "zcash address is null error:%v")
  194. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  195. }
  196. func (m Zcash) zcashgetinfo() bool {
  197. fmt.Println("zcashgetinfo begin:")
  198. for {
  199. time.Sleep(time.Second)
  200. }
  201. }
  202. //config rpc from zcash.toml
  203. func (m Zcash) initconfig() bool {
  204. if _, err := tml.DecodeFile("./src/zcash/zcash.toml", &ZecConfig); err != nil {
  205. fmt.Println(err)
  206. return false
  207. }
  208. fmt.Printf("%+v\n", ZecConfig)
  209. zcashUser := ZecConfig.ZcashRpc.Zcashrpcuser
  210. zcashPassword := ZecConfig.ZcashRpc.Zcashrpcpassword
  211. zcashHost := ZecConfig.ZcashRpc.Zcashhost
  212. zcashPort := ZecConfig.ZcashRpc.Zcashport
  213. zcashOp.InitRpcConf(zcashUser, zcashPassword, zcashHost, zcashPort)
  214. initZcashErr()
  215. f, err := strconv.ParseFloat(ZecConfig.Limit.Fee, 64)
  216. if err != nil {
  217. LOG("ERROR", "zcash inner json error:%v", err.Error())
  218. return false
  219. }
  220. fee := float64(f)
  221. zcashOp.WalletSetTxFee(fee)
  222. return true
  223. }
  224. func (m Zcash) ChainHeight(parm interface{}) ([]byte, error) {
  225. blockcount, err := zcashOp.WalleGetBlockCount()
  226. if err != nil {
  227. LOG("ERROR", "zcash get current block count error:%v", err.Error())
  228. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETCLOCKCOUNT_ERR, getErrMsg(GETCLOCKCOUNT_ERR, nil))
  229. }
  230. sendstr := fmt.Sprintf(`{"errcode":%v,"height":%v}`, OK, blockcount)
  231. return []byte(sendstr), nil
  232. }
  233. func (m Zcash) ListUnspent(parm interface{}) ([]byte, error) {
  234. return nil, nil
  235. }
  236. func (m Zcash) SendRawTransaction(parm interface{}) ([]byte, error) {
  237. return nil, nil
  238. }
  239. func (m Zcash) SumcoinBalance(parm interface{}) ([]byte, error) {
  240. return nil, nil
  241. }
  242. func init() {
  243. Register(NameZcash, &Zcash{})
  244. }