dcrcashcoin.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. package dcrcash
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strconv"
  6. "sync"
  7. . "template"
  8. "time"
  9. simplejson "github.com/go-simplejson"
  10. tml "github.com/toml-master"
  11. )
  12. var (
  13. Config config
  14. CoinApi DcrCashApi
  15. WalleTxfee float64
  16. m_balanceparam map[string]float64
  17. m_mutblance sync.Mutex
  18. m_unspent []map[string]interface{}
  19. m_mutspent sync.Mutex
  20. m_AccValues map[string]float64
  21. m_mutaccoutValue sync.Mutex
  22. )
  23. type DcrCash struct {
  24. walletstatus bool
  25. }
  26. const (
  27. NameCoin = "DCR"
  28. SendToError = "-32603"
  29. DefaultMaxsumamout = 20.0
  30. DEFAULTACCOUNT = "default"
  31. )
  32. func (m DcrCash) InitDriver(param interface{}) bool {
  33. if m.initconfig() == false {
  34. return false
  35. }
  36. go m.getwalletinfo()
  37. //缓存数据
  38. go AsyncRoutine()
  39. return true
  40. }
  41. func (m DcrCash) initconfig() bool {
  42. if _, err := tml.DecodeFile("./src/dcrcash/dcrcash.toml", &Config); err != nil {
  43. fmt.Println(err)
  44. return false
  45. }
  46. fmt.Printf("%+v\n", Config)
  47. User := Config.Rpc.Rpcuser
  48. Password := Config.Rpc.Rpcpassword
  49. Host := Config.Rpc.Rpchost
  50. Port := Config.Rpc.Rpcport
  51. //Walletpass = Config.WalletInfo.Pripassphrase
  52. CoinApi.InitRpcConf(User, Password, Host, Port)
  53. initDcrError()
  54. f, err := strconv.ParseFloat(Config.Limit.Fee, 64)
  55. if err != nil {
  56. LOG("ERROR", "init json error:%v", err.Error())
  57. return false
  58. }
  59. fee := float64(f)
  60. CoinApi.WalletSetTxFee(fee) //
  61. return true
  62. }
  63. func (m DcrCash) getwalletinfo() bool {
  64. fmt.Println("Walletinfo:")
  65. m.walletstatus = false
  66. for {
  67. if m.walletstatus == false {
  68. resp, err := CoinApi.WalletInfo()
  69. if err != nil {
  70. LOG("ERROR", "WalletInfo error:%v", err.Error())
  71. time.Sleep(time.Second * 1)
  72. continue
  73. }
  74. LOG("DEBUG", "walletInfo resp:%v", string(resp))
  75. m.walletstatus = true
  76. }
  77. time.Sleep(time.Second)
  78. }
  79. }
  80. func (m DcrCash) CoinBalance(parm interface{}) ([]byte, error) {
  81. var totalbalance, maxConfirbalance, maxUnconfirbalance, querytime float64
  82. pjs := parm.(*simplejson.Json)
  83. input, err := pjs.Get("Sync").Bool()
  84. if !input {
  85. fmt.Println("the balance is not sync!!")
  86. totalbalance = m_balanceparam["totalbalance"]
  87. maxConfirbalance = m_balanceparam["confirmedbalance"]
  88. maxUnconfirbalance = m_balanceparam["unconfirmed"]
  89. querytime = m_balanceparam["ntime"]
  90. } else {
  91. acountBalace, err := CoinApi.WalleGetBalance("*")
  92. if err != nil {
  93. LOG("ERROR", " GetBalance err:%v", err.Error())
  94. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBALANCE_ERR, getErrMsg(GETBALANCE_ERR, nil))
  95. }
  96. var accounts []account
  97. if err = json.Unmarshal(acountBalace, &accounts); err != nil {
  98. LOG("ERROR", " inner json error:%v", err.Error())
  99. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  100. }
  101. for _, vbalance := range accounts {
  102. if vbalance.Total != 0 {
  103. totalbalance += vbalance.Total
  104. }
  105. if vbalance.Spendable > maxConfirbalance {
  106. maxConfirbalance = vbalance.Spendable
  107. }
  108. if vbalance.Unconfirmed > maxUnconfirbalance {
  109. maxUnconfirbalance = vbalance.Unconfirmed
  110. }
  111. }
  112. }
  113. var jbuf []byte
  114. resp := make(map[string]interface{})
  115. resp["confirmedbalance"] = maxConfirbalance
  116. resp["unconfirmed"] = maxUnconfirbalance
  117. resp["totalbalance"] = totalbalance
  118. resp["querybalancetime"] = querytime
  119. resp["errcode"] = 0
  120. resp["exact"] = 0
  121. if jbuf, err = json.Marshal(resp); err != nil {
  122. LOG("ERROR", "lite inner json error:%v", err.Error())
  123. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  124. }
  125. return jbuf, nil
  126. }
  127. func (m DcrCash) CreateAddress(parm interface{}) ([]byte, error) {
  128. addr, err := CoinApi.WalletNewAddr()
  129. if err != nil {
  130. LOG("ERROR", " get new address error:%v", err.Error())
  131. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETNEWADDRESS_ERR, getErrMsg(GETNEWADDRESS_ERR, nil))
  132. }
  133. if len(addr) != 0 {
  134. //get key by the address
  135. key, err := CoinApi.WalletDumpPrivKey(addr)
  136. if err != nil {
  137. LOG("ERROR", " dump private key error:%v", err.Error())
  138. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, DUMPPRIVKEY_ERR, getErrMsg(DUMPPRIVKEY_ERR, nil))
  139. }
  140. if len(key) != 0 {
  141. var jbuf []byte
  142. resp := make(map[string]interface{})
  143. resp["address"] = addr
  144. resp["privkey"] = key
  145. resp["errcode"] = 0
  146. if jbuf, err = json.Marshal(resp); err != nil {
  147. LOG("ERROR", " inner json error:%v", err.Error())
  148. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  149. }
  150. return jbuf, nil
  151. }
  152. LOG("ERROR", " privkey is null error:%v")
  153. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  154. }
  155. LOG("ERROR", " address is null error:%v")
  156. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  157. }
  158. func (m *DcrCash) SumcoinBalance(parm interface{}) ([]byte, error) {
  159. pjs := parm.(*simplejson.Json)
  160. //
  161. Sumamount := pjs.Get("sumamount").MustFloat64()
  162. Minsumamount := pjs.Get("minamount").MustFloat64()
  163. if Sumamount <= 0 {
  164. LOG("ERROR", " Summary amount is nil!")
  165. Sumamount = DefaultMaxsumamout
  166. }
  167. if Minsumamount < WalleTxfee {
  168. Minsumamount = WalleTxfee
  169. }
  170. //list Accounts and account of balance
  171. accountsofValues, err := CoinApi.ListAccounts()
  172. if err != nil {
  173. LOG("ERROR", "List accounts error:%v", err.Error())
  174. return nil, err
  175. }
  176. //var AccValues []AccountsOfvalue
  177. AccValues := map[string]float64{}
  178. if err = json.Unmarshal(accountsofValues, &AccValues); err != nil {
  179. LOG("ERROR", "Unmarshal error:%v", err.Error())
  180. return nil, err
  181. }
  182. var Totalbalance float64
  183. fmt.Println("SumcoinBalance >>>>:", len(AccValues), "Sumamount:", Sumamount, "Minsumamount", Minsumamount)
  184. transactionsids := make([]string, 0)
  185. for account, value := range AccValues {
  186. if (value > Minsumamount) && account != DEFAULTACCOUNT {
  187. fmt.Println("SumcoinBalance account:", account, "value:", value)
  188. amount := value - WalleTxfee
  189. transactionid, err := CoinApi.WalletSendFrom(account, DEFAULTACCOUNT, amount, 1, "", "")
  190. if err != nil {
  191. LOG("ERROR", " Send coin error:%v", err.Error())
  192. //return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, SENDCOINS_ERR, getErrMsg(SENDCOINS_ERR, nil))
  193. continue
  194. }
  195. transactionsids = append(transactionsids, transactionid)
  196. Totalbalance += amount
  197. if Totalbalance >= Sumamount {
  198. break
  199. }
  200. }
  201. }
  202. if len(transactionsids) != 0 {
  203. var jbuf []byte
  204. resp := make(map[string]interface{})
  205. resp["transcationids"] = transactionsids
  206. resp["errcode"] = 0
  207. resp["msg"] = "ok"
  208. if jbuf, err = json.Marshal(resp); err != nil {
  209. LOG("ERROR", " inner json error:%v", err.Error())
  210. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  211. }
  212. return jbuf, nil
  213. }
  214. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, SUMCOIN_ERR, getErrMsg(SUMCOIN_ERR, nil))
  215. //fromaccout = "default"
  216. }
  217. func (m DcrCash) TransferAccounts(parm interface{}) ([]byte, error) {
  218. pjs := parm.(*simplejson.Json)
  219. amountTmp := pjs.Get("amount").MustString()
  220. destination := pjs.Get("address").MustString()
  221. if len(amountTmp) == 0 {
  222. LOG("ERROR", " amount illeagal")
  223. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, AMOUNT_ERR, getErrMsg(AMOUNT_ERR, nil))
  224. }
  225. f, err := strconv.ParseFloat(amountTmp, 64)
  226. if err != nil {
  227. LOG("ERROR", " inner json error:%v", err.Error())
  228. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  229. }
  230. amount := float64(f)
  231. fromaccout := ""
  232. for account, value := range m_AccValues {
  233. if value >= (amount + WalleTxfee) {
  234. fromaccout = account
  235. break
  236. }
  237. }
  238. if fromaccout == "" {
  239. fromaccout = DEFAULTACCOUNT
  240. }
  241. transactionid, err := CoinApi.WalletSendFrom(fromaccout, destination, amount, 1, "", "")
  242. if err != nil {
  243. LOG("ERROR", " Send coin error:%v", err.Error())
  244. fmt.Println(transactionid)
  245. if transactionid == SendToError {
  246. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INSUFFICIENT_FUNDS_TRANSACTION_ERR, getErrMsg(INSUFFICIENT_FUNDS_TRANSACTION_ERR, nil))
  247. }
  248. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, SENDCOINS_ERR, getErrMsg(SENDCOINS_ERR, nil))
  249. }
  250. go func() {
  251. Cachelistaccount()
  252. }()
  253. if len(transactionid) != 0 {
  254. var jbuf []byte
  255. resp := make(map[string]interface{})
  256. resp["transcationids"] = []string{transactionid}
  257. resp["errcode"] = 0
  258. resp["msg"] = "ok"
  259. if jbuf, err = json.Marshal(resp); err != nil {
  260. LOG("ERROR", " inner json error:%v", err.Error())
  261. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  262. }
  263. return jbuf, nil
  264. }
  265. LOG("ERROR", " transactionid is null error:%v", err.Error())
  266. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  267. }
  268. func (m DcrCash) TransInfo(parm interface{}) ([]byte, error) {
  269. pjs := parm.(*simplejson.Json)
  270. startH := pjs.Get("starth").MustUint64()
  271. endH := pjs.Get("endh").MustUint64()
  272. if startH < 1 {
  273. LOG("DEBUG", " input para err:%v", startH)
  274. startH = 1
  275. }
  276. //get longest block count
  277. blockcount, err := CoinApi.WalleGetBlockCount()
  278. if err != nil {
  279. LOG("ERROR", " WalleGetBlockCount err:%v", err.Error())
  280. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETCLOCKCOUNT_ERR, getErrMsg(GETCLOCKCOUNT_ERR, nil))
  281. }
  282. //get startblock hash by height
  283. if startH > blockcount {
  284. LOG("DEBUG", " startheight:%v > blockcount:%v", startH, blockcount)
  285. startH = blockcount
  286. }
  287. startblockhash, err := CoinApi.WalletGetBlockHash(uint64(startH - 1))
  288. if err != nil {
  289. LOG("ERROR", " WalletGetBlockHash startH:%v err:%v", startH, err.Error())
  290. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBLOCKINFO_ERR, getErrMsg(GETBLOCKINFO_ERR, nil))
  291. }
  292. //get endblock time by height
  293. if endH > blockcount {
  294. LOG("DEBUG", " endheight:%v > blockcount:%v", endH, blockcount)
  295. endH = blockcount
  296. }
  297. endblockhash, err := CoinApi.WalletGetBlockHash(uint64(endH))
  298. if err != nil {
  299. LOG("ERROR", " WalletGetBlockHash startH:%v err:%v", startH, err.Error())
  300. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBLOCKINFO_ERR, getErrMsg(GETBLOCKINFO_ERR, nil))
  301. }
  302. endblocktime, err := CoinApi.WalletGetBlockTime(endblockhash)
  303. if err != nil {
  304. LOG("ERROR", " WalletGetBlockTime endH:%v err:%v", endH, err.Error())
  305. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBLOCKINFO_ERR, getErrMsg(GETBLOCKINFO_ERR, nil))
  306. }
  307. //Get all transactions in blocks since block [blockhash]
  308. resp, err := CoinApi.WalleListSinceBlock(startblockhash)
  309. if err != nil {
  310. LOG("ERROR", " WalleListSinceBlock err:%v", err.Error())
  311. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, TRANSINFO_ERR, getErrMsg(TRANSINFO_ERR, nil))
  312. }
  313. var litelisttransactionsinfo []Listtransactions
  314. if err = json.Unmarshal([]byte(resp), &litelisttransactionsinfo); err != nil {
  315. LOG("ERROR", " inner json error:%v", err.Error())
  316. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  317. }
  318. outputsArr := make([]map[string]interface{}, 0)
  319. fmt.Println("WalleListSinceBlock_num:", len(litelisttransactionsinfo))
  320. for index, listtransaction := range litelisttransactionsinfo {
  321. // get all transactions from block startHright to endHeight
  322. fmt.Println("BLockTime,Endblocktime", listtransaction.Blocktime, endblocktime, index)
  323. if listtransaction.Blocktime <= endblocktime {
  324. requestData := make(map[string]interface{})
  325. confirmationheight, err := CoinApi.WalletGetBlockHeight(listtransaction.Blockhash)
  326. if err != nil {
  327. LOG("ERROR", "WalletGetBlockHeight error:%v", err.Error())
  328. continue
  329. }
  330. requestData["confirmationheight"] = confirmationheight
  331. requestData["address"] = listtransaction.Address
  332. requestData["confirmationtimestamp"] = listtransaction.Timereceived
  333. requestData["value"] = listtransaction.Amount
  334. requestData["transactionid"] = listtransaction.Txid
  335. requestData["confirmations"] = listtransaction.Confirmations
  336. requestData["walletaddress"] = true
  337. requestData["vout"] = listtransaction.Vout
  338. outputsArr = append(outputsArr, requestData)
  339. }
  340. }
  341. var jbuf []byte
  342. resptmp := make(map[string]interface{})
  343. resptmp["errcode"] = 0
  344. resptmp["cointype"] = "DCR"
  345. resptmp["outputs"] = outputsArr
  346. if jbuf, err = json.Marshal(resptmp); err != nil {
  347. LOG("ERROR", " inner json error:%v", err.Error())
  348. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  349. }
  350. return jbuf, nil
  351. }
  352. func (m DcrCash) ListUnspent(parm interface{}) ([]byte, error) {
  353. i_listunspent := make([]map[string]interface{}, 0)
  354. pjs := parm.(*simplejson.Json)
  355. Issync, err := pjs.Get("Sync").Bool()
  356. if !Issync {
  357. fmt.Println("The listunspent data Asynchrony!!!!")
  358. i_listunspent = m_unspent
  359. } else {
  360. address, err := pjs.Get("address").StringArray()
  361. if err != nil {
  362. LOG("ERROR", " input parm error:%v", err.Error())
  363. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
  364. }
  365. unspent, err := CoinApi.Listunspent(address)
  366. if err != nil {
  367. LOG("ERROR", " get listunspent:%v", err.Error())
  368. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
  369. }
  370. i_listunspent = unspent
  371. }
  372. var jbuf []byte
  373. resptmp := make(map[string]interface{})
  374. resptmp["errcode"] = 0
  375. resptmp["cointype"] = "DCR"
  376. resptmp["unspents"] = i_listunspent
  377. if jbuf, err = json.Marshal(resptmp); err != nil {
  378. LOG("ERROR", " inner json error:%v", err.Error())
  379. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  380. }
  381. return jbuf, nil
  382. }
  383. func (m DcrCash) SendRawTransaction(parm interface{}) ([]byte, error) {
  384. pjs := parm.(*simplejson.Json)
  385. transdata := pjs.Get("data").MustString()
  386. if len(transdata) == 0 {
  387. return nil, fmt.Errorf(`{"cointype":"DCR","errcode":%v,"msg":"%v"}`, PARM_ERR, getErrMsg(PARM_ERR, []byte("hexstring is null")))
  388. }
  389. transactionhex, err := CoinApi.SendRawTransaction(transdata)
  390. if err != nil {
  391. LOG("ERROR", " SendRawTransaction err:%s", err.Error())
  392. return nil, fmt.Errorf(`{"cointype":"DCR","errcode":%v,"msg":"%s"}`, SEND_RAW_TRANSACTION_ERR, getErrMsg(SEND_RAW_TRANSACTION_ERR, nil))
  393. }
  394. var jbuf []byte
  395. resp := make(map[string]interface{})
  396. resp["cointype"] = "DCR"
  397. resp["transactionids"] = transactionhex
  398. resp["errcode"] = 0
  399. resp["msg"] = "OK"
  400. if jbuf, err = json.Marshal(resp); err != nil {
  401. LOG("ERROR", "inner json error:%v", err.Error())
  402. return nil, fmt.Errorf(`{"cointype":"DCR","errcode":%v,"msg":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  403. }
  404. return jbuf, nil
  405. }
  406. func (m DcrCash) ChainHeight(parm interface{}) ([]byte, error) {
  407. blockcount, err := CoinApi.WalleGetBlockCount()
  408. if err != nil {
  409. LOG("ERROR", " get current block count error:%v", err.Error())
  410. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETCLOCKCOUNT_ERR, getErrMsg(GETCLOCKCOUNT_ERR, nil))
  411. }
  412. sendstr := fmt.Sprintf(`{"errcode":%v,"height":%v}`, OK, blockcount)
  413. return []byte(sendstr), nil
  414. }
  415. func (m DcrCash) AccountsBalance(parm interface{}) (jbuf []byte, err error) {
  416. var balancestotal, offlinebalancetotal float64
  417. ilistunspent := m_unspent
  418. accountbalance := make([]map[string]interface{}, 0)
  419. offlinebalance := make([]map[string]interface{}, 0)
  420. for _, value := range ilistunspent {
  421. if value["spendable"] == true {
  422. balancestotal += value["Amount"].(float64)
  423. accountbalance = append(accountbalance, value)
  424. } else {
  425. offlinebalancetotal += value["Amount"].(float64)
  426. offlinebalance = append(offlinebalance, value)
  427. }
  428. }
  429. resptmp := make(map[string]interface{})
  430. resptmp["errcode"] = 0
  431. resptmp["cointype"] = "DCR"
  432. resptmp["accountbalance"] = accountbalance
  433. resptmp["balancestotal"] = balancestotal
  434. resptmp["offlinebalance"] = offlinebalance
  435. resptmp["offlinebalancetotal"] = offlinebalancetotal
  436. if jbuf, err = json.Marshal(resptmp); err != nil {
  437. LOG("ERROR", " inner json error:%v", err.Error())
  438. return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  439. }
  440. return jbuf, nil
  441. }
  442. func CacheGetbalance() {
  443. fmt.Println("Cachegetbalance time:", time.Now().Format("2006-01-02 15:04:05"))
  444. m_balanceparam = make(map[string]float64)
  445. acountBalace, err := CoinApi.WalleGetBalance("*")
  446. if err != nil {
  447. LOG("ERROR", " GetBalance err:%v", err.Error())
  448. //return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, GETBALANCE_ERR, getErrMsg(GETBALANCE_ERR, nil))
  449. }
  450. var accounts []account
  451. if err = json.Unmarshal(acountBalace, &accounts); err != nil {
  452. LOG("ERROR", " inner json error:%v", err.Error())
  453. //return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, INNER_ERR, getErrMsg(INNER_ERR, nil))
  454. }
  455. var totalbalance float64
  456. //var totalUnconfirbalance float64
  457. var maxConfirbalance float64
  458. var maxUnconfirbalance float64
  459. for _, vbalance := range accounts {
  460. if vbalance.Total != 0 {
  461. totalbalance += vbalance.Total
  462. }
  463. if vbalance.Spendable > maxConfirbalance {
  464. maxConfirbalance = vbalance.Spendable
  465. }
  466. if vbalance.Unconfirmed > maxUnconfirbalance {
  467. maxUnconfirbalance = vbalance.Unconfirmed
  468. }
  469. }
  470. m_mutblance.Lock()
  471. m_balanceparam["totalbalance"] = totalbalance
  472. m_balanceparam["confirmedbalance"] = maxConfirbalance
  473. m_balanceparam["unconfirmed"] = maxUnconfirbalance
  474. m_balanceparam["ntime"] = float64(time.Now().Unix())
  475. m_mutblance.Unlock()
  476. }
  477. func Cachelistunspent() {
  478. fmt.Println("cachelistunspent time:", time.Now().Format("2006-01-02 15:04:05"))
  479. var address []string
  480. m_unspent = make([]map[string]interface{}, 0)
  481. unspent, err := CoinApi.Listunspent(address)
  482. if err != nil {
  483. LOG("ERROR", " get listunspent:%v", err.Error())
  484. //return nil, fmt.Errorf(`{"errcode":%v,"mesage":"%s"}`, LISTUNSPENT_ERR, getErrMsg(LISTUNSPENT_ERR, nil))
  485. }
  486. m_mutspent.Lock()
  487. m_unspent = unspent
  488. m_mutspent.Unlock()
  489. }
  490. func Cachelistaccount() {
  491. fmt.Println("Cachelistaccounts time", time.Now().Format("2006-01-02 15:04:05"))
  492. //list Accounts and account of balance
  493. accountsofValues, err := CoinApi.ListAccounts()
  494. if err != nil {
  495. LOG("ERROR", "List accounts error:%v", err.Error())
  496. //return nil, err
  497. }
  498. //
  499. m_mutaccoutValue.Lock()
  500. if err = json.Unmarshal(accountsofValues, &m_AccValues); err != nil {
  501. LOG("ERROR", "Unmarshal error:%v", err.Error())
  502. //return nil, err
  503. }
  504. m_mutaccoutValue.Unlock()
  505. }
  506. func AsyncRoutine() {
  507. CacheGetbalanceTicker := time.NewTicker(120 * time.Second)
  508. CachelistaccountTicker := time.NewTicker(90 * time.Second)
  509. CachelistunspentTicker := time.NewTicker(120 * time.Second)
  510. for {
  511. select {
  512. case _ = <-CacheGetbalanceTicker.C:
  513. CacheGetbalance()
  514. case _ = <-CachelistaccountTicker.C:
  515. Cachelistaccount()
  516. case _ = <-CachelistunspentTicker.C:
  517. Cachelistunspent()
  518. }
  519. }
  520. }
  521. func init() {
  522. Register(NameCoin, &DcrCash{})
  523. }