bitcoin.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. package bitcoin
  2. import (
  3. "bitcoin/bitcoinRpc"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "strconv"
  8. )
  9. type BitCoinApi struct {
  10. }
  11. //get a new taddr
  12. func (m *BitCoinApi) WalletNewAddr() (string, error) {
  13. var newaddr RpcResult
  14. result, err := bitcoinRpc.RunCall("getnewaddress")
  15. if err != nil {
  16. fmt.Println("Call getnewaddress fail:", err.Error())
  17. return "", err
  18. }
  19. if err := json.Unmarshal([]byte(result), &newaddr); err != nil {
  20. fmt.Println("Unmarshal err :", err.Error())
  21. return "", err
  22. }
  23. // success
  24. if len(newaddr.Error.Message) == 0 {
  25. return newaddr.Result, nil
  26. }
  27. err = errors.New(newaddr.Error.Message)
  28. return "", err
  29. }
  30. //get PrivKey by taddr
  31. func (m *BitCoinApi) WalletDumpPrivKey(address string) (string, error) {
  32. var key RpcResult
  33. if len(address) == 0 {
  34. fmt.Println("input address err:")
  35. err := errors.New("input address error:")
  36. return "", err
  37. }
  38. //
  39. result, err := bitcoinRpc.RunCall("dumpprivkey", address)
  40. if err != nil {
  41. fmt.Println("Call dumpprivkey fail:", err.Error())
  42. return "", err
  43. }
  44. if err := json.Unmarshal([]byte(result), &key); err != nil {
  45. fmt.Println("Unmarshal err :", err.Error())
  46. return "", err
  47. }
  48. // success
  49. if len(key.Error.Message) == 0 {
  50. return key.Result, nil
  51. }
  52. err = errors.New(key.Error.Message)
  53. return "", err
  54. }
  55. //get block hash by index
  56. func (m BitCoinApi) WalletGetBlockHash(index uint64) (string, error) {
  57. var Blockhash RpcResult
  58. //get block hash by index
  59. result, err := bitcoinRpc.RunCall("getblockhash", index)
  60. if err != nil {
  61. fmt.Println("Call getblockhash fail:", err.Error())
  62. return "", err
  63. }
  64. if err := json.Unmarshal([]byte(result), &Blockhash); err != nil {
  65. fmt.Println("Unmarshal err :", err.Error())
  66. return "", err
  67. }
  68. // success
  69. if len(Blockhash.Error.Message) == 0 {
  70. return Blockhash.Result, nil
  71. }
  72. err = errors.New(Blockhash.Error.Message)
  73. return "", err
  74. }
  75. //get block time by hash;return:blocktime
  76. func (m BitCoinApi) WalletGetBlockTime(blockhash string) (uint64, error) {
  77. var blockresult BlockResult
  78. if len(blockhash) == 0 {
  79. fmt.Println("input para err:")
  80. err := errors.New("input para err")
  81. return 0, err
  82. }
  83. //get block info by blockhash
  84. result, err := bitcoinRpc.RunCall("getblock", blockhash)
  85. if err != nil {
  86. fmt.Println("Call getblock fail:", err.Error())
  87. return 0, err
  88. }
  89. if err := json.Unmarshal([]byte(result), &blockresult); err != nil {
  90. fmt.Println("Unmarshal err :", err.Error())
  91. return 0, err
  92. }
  93. // success
  94. if len(blockresult.Error.Message) == 0 {
  95. return uint64(blockresult.Result.Time), nil
  96. }
  97. err = errors.New(blockresult.Error.Message)
  98. return 0, err
  99. }
  100. //get block Height by hash;return:blocktime
  101. func (m BitCoinApi) WalletGetBlockHeight(blockhash string) (uint64, error) {
  102. var blockresult BlockResult
  103. if len(blockhash) == 0 {
  104. fmt.Println("input para err:")
  105. err := errors.New("input para err")
  106. return 0, err
  107. }
  108. //get block info by blockhash
  109. result, err := bitcoinRpc.RunCall("getblock", blockhash)
  110. if err != nil {
  111. fmt.Println("Call getblock fail:", err.Error())
  112. return 0, err
  113. }
  114. if err := json.Unmarshal([]byte(result), &blockresult); err != nil {
  115. fmt.Println("Unmarshal err :", err.Error())
  116. return 0, err
  117. }
  118. // success
  119. if len(blockresult.Error.Message) == 0 {
  120. return uint64(blockresult.Result.Height), nil
  121. }
  122. err = errors.New(blockresult.Error.Message)
  123. return 0, err
  124. }
  125. func (m *BitCoinApi) WalleListSinceBlock(blockhash string) ([]byte, error) {
  126. var listtransactionsresult Listtransactionsresult
  127. if len(blockhash) == 0 {
  128. fmt.Println("input blockhash err:")
  129. err := errors.New("input blockhash err")
  130. return nil, err
  131. }
  132. //
  133. result, err := bitcoinRpc.RunCall("listsinceblock", blockhash, 1, true)
  134. if err != nil {
  135. fmt.Println("Call listsinceblock fail:", err.Error())
  136. return nil, err
  137. }
  138. if err := json.Unmarshal([]byte(result), &listtransactionsresult); err != nil {
  139. fmt.Println("Unmarshal err :", err.Error())
  140. return nil, err
  141. }
  142. // success
  143. if len(listtransactionsresult.Error.Message) == 0 {
  144. var jbuf []byte
  145. if jbuf, err = json.Marshal(listtransactionsresult.Result.Transactions); err != nil {
  146. return nil, err
  147. }
  148. return jbuf, nil
  149. }
  150. err = errors.New(listtransactionsresult.Error.Message)
  151. return nil, err
  152. }
  153. //get the server's total available balance
  154. func (m BitCoinApi) WalleGetBalance(account string) (float64, error) {
  155. var liteBalance BalanceResult
  156. // getbalance all
  157. result, err := bitcoinRpc.RunCall("getbalance", "*")
  158. if err != nil {
  159. fmt.Println("Call getbalance fail:", err.Error())
  160. return 0, err
  161. }
  162. if err := json.Unmarshal([]byte(result), &liteBalance); err != nil {
  163. fmt.Println("Unmarshal err :", err.Error())
  164. return 0, err
  165. }
  166. // success
  167. if len(liteBalance.Error.Message) == 0 {
  168. return float64(liteBalance.Result), nil
  169. }
  170. err = errors.New(liteBalance.Error.Message)
  171. return 0, err
  172. }
  173. //get the server's total unconfirmed balance
  174. func (m BitCoinApi) WalleGetUnconfirmedBalance(account string) (float64, error) {
  175. var UnconfirmedBalance BalanceResult
  176. //
  177. result, err := bitcoinRpc.RunCall("getunconfirmedbalance")
  178. if err != nil {
  179. fmt.Println("Call getunconfirmedbalance fail:", err.Error())
  180. return 0, err
  181. }
  182. if err := json.Unmarshal([]byte(result), &UnconfirmedBalance); err != nil {
  183. fmt.Println("Unmarshal err :", err.Error())
  184. return 0, err
  185. }
  186. // success
  187. if len(UnconfirmedBalance.Error.Message) == 0 {
  188. return float64(UnconfirmedBalance.Result), nil
  189. }
  190. err = errors.New(UnconfirmedBalance.Error.Message)
  191. return 0, err
  192. }
  193. //Sent an amount from an account to a zcash address.
  194. //The amount is a real and is rounded to the nearest 0.00000001.
  195. //Result:"transactionid" (string) The transaction id.
  196. func (m *BitCoinApi) WalleSendFrom(fromaccount string, tozcashaddress string, amount float64, minconf int, comment string, commentto string) (string, error) {
  197. var SendResult RpcResult
  198. if len(tozcashaddress) == 0 {
  199. fmt.Println("input tozcashaddress err:")
  200. err := errors.New("input tozcashaddress err")
  201. return "", err
  202. }
  203. //
  204. result, err := bitcoinRpc.RunCall("sendfrom", fromaccount, tozcashaddress, amount, minconf, "", "")
  205. if err != nil {
  206. fmt.Println("Call sendfrom fail:", err.Error())
  207. return "", err
  208. }
  209. if err := json.Unmarshal([]byte(result), &SendResult); err != nil {
  210. fmt.Println("Unmarshal err :", err.Error())
  211. return "", err
  212. }
  213. // success
  214. if len(SendResult.Error.Message) == 0 {
  215. return SendResult.Result, nil
  216. }
  217. err = errors.New(SendResult.Error.Message)
  218. return "", err
  219. }
  220. //get the number of blocks in the longest block chain
  221. func (m BitCoinApi) WalleGetBlockCount() (uint64, error) {
  222. var blockcount Blockcountresult
  223. //
  224. result, err := bitcoinRpc.RunCall("getblockcount")
  225. if err != nil {
  226. fmt.Println("Call getblockcount fail:", err.Error())
  227. return 0, err
  228. }
  229. if err := json.Unmarshal([]byte(result), &blockcount); err != nil {
  230. fmt.Println("Unmarshal err :", err.Error())
  231. return 0, err
  232. }
  233. // success
  234. if len(blockcount.Error.Message) == 0 {
  235. return uint64(blockcount.Result), nil
  236. }
  237. err = errors.New(blockcount.Error.Message)
  238. return 0, err
  239. }
  240. //Set the transaction fee per kB. Overwrites the paytxfee parameter.
  241. func (m BitCoinApi) WalletSetTxFee(amount float64) (bool, error) {
  242. var settxfee Setfeeresult
  243. //
  244. result, err := bitcoinRpc.RunCall("settxfee", amount)
  245. if err != nil {
  246. fmt.Println("Call settxfee fail:", err.Error())
  247. return false, err
  248. }
  249. if err := json.Unmarshal([]byte(result), &settxfee); err != nil {
  250. fmt.Println("Unmarshal err :", err.Error())
  251. return false, err
  252. }
  253. // success
  254. if len(settxfee.Error.Message) == 0 {
  255. return settxfee.Result, nil
  256. }
  257. err = errors.New(settxfee.Error.Message)
  258. return false, err
  259. }
  260. //Result:
  261. // "walletversion": xxxxx, 钱包的额版本
  262. // "balance": xxxxxxx, 钱包中已经确认的LTC余额
  263. // "unconfirmed_balance": xxx, 钱包中未经确认的LTC余额
  264. // "immature_balance": xxxxxx, 钱包中不成熟的余额
  265. // "txcount": xxxxxxx, 钱包中交易的总数
  266. // "keypoololdest": xxxxxx, 密钥池中最早的预生成密钥的时间戳
  267. // "keypoolsize": xxxx, 预先生成了多少个新密匙
  268. // "unlocked_until": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT)
  269. // that the wallet is unlocked for transfers, or 0 if the wallet is locked
  270. // "paytxfee": x.xxxx, 交易费用的配置 set in LTC/KB
  271. // "hdmasterkeyid": "<hash160>", (string) the Hash160 of the HD master pubkey
  272. func (m BitCoinApi) WalletInfo() ([]byte, error) {
  273. var walletinfoResult WalletinfoResult
  274. //
  275. result, err := bitcoinRpc.RunCall("getwalletinfo")
  276. if err != nil {
  277. fmt.Println("Call getwalletinfo fail:", err.Error())
  278. return nil, err
  279. }
  280. if err := json.Unmarshal([]byte(result), &walletinfoResult); err != nil {
  281. fmt.Println("Unmarshal err :", err.Error())
  282. return nil, err
  283. }
  284. // success
  285. if len(walletinfoResult.Error.Message) == 0 {
  286. var jbuf []byte
  287. if jbuf, err = json.Marshal(walletinfoResult.Result); err != nil {
  288. return nil, err
  289. }
  290. return jbuf, nil
  291. }
  292. err = errors.New(walletinfoResult.Error.Message)
  293. return nil, err
  294. }
  295. func (m BitCoinApi) InitRpcConf(rpcuser string, rpcpassword string, rpchost string, rpcport int) bool {
  296. bitcoinRpc.InitRpcConfig(rpcuser, rpcpassword, rpchost, rpcport)
  297. return true
  298. }
  299. //Adds a script (in hex) or address that can be watched as if it were in your wallet but cannot be used to spend.
  300. func (m BitCoinApi) WalletImportAddress(address string, rescan bool) (bool, error) {
  301. var rpcResult RpcResult
  302. var err error
  303. var result []byte
  304. if len(address) == 0 {
  305. fmt.Println("Call WalletImportAddress address is null:")
  306. err = errors.New("address is null")
  307. return false, err
  308. }
  309. // import address in Wallet
  310. result, err = bitcoinRpc.RunCall("importaddress", address, "", rescan)
  311. if err != nil {
  312. fmt.Println("WalletImportAddress call bitcoinRpc.RunCall fail:", err.Error(), address)
  313. return false, err
  314. }
  315. if err = json.Unmarshal([]byte(result), &rpcResult); err != nil {
  316. fmt.Println("Unmarshal err :", err.Error())
  317. return false, err
  318. }
  319. // success
  320. if len(rpcResult.Error.Message) == 0 {
  321. return true, nil
  322. }
  323. err = errors.New(rpcResult.Error.Message)
  324. return false, err
  325. }
  326. /*
  327. //list unspent transaction outputs
  328. func (m BitCoinApi) Listunspent(address []string) ([]UnspentInfo, error) {
  329. var unspentResult RpcUnspentResult
  330. result, err := bitcoinRpc.RunCall("listunspent",1,9999999,address)
  331. if err != nil {
  332. fmt.Println("Call listunspent fail:", err.Error())
  333. return nil, err
  334. }
  335. if err := json.Unmarshal([]byte(result), &unspentResult); err != nil {
  336. fmt.Println("Unmarshal err :", err.Error())
  337. return nil, err
  338. }
  339. // success
  340. if len(unspentResult.Error.Message) == 0 {
  341. return unspentResult.Result, nil
  342. }
  343. err = errors.New(unspentResult.Error.Message)
  344. return nil, err
  345. }
  346. */
  347. //list unspent transaction outputs
  348. func (m BitCoinApi) Listunspent(address []string) ([]map[string]interface{}, error) {
  349. var unspentResult RpcUnspentResult
  350. result, err := bitcoinRpc.RunCall("listunspent", 1, 9999999, address)
  351. if err != nil {
  352. fmt.Println("Call listunspent fail:", err.Error())
  353. return nil, err
  354. }
  355. if err := json.Unmarshal([]byte(result), &unspentResult); err != nil {
  356. fmt.Println("Unmarshal err :", err.Error())
  357. return nil, err
  358. }
  359. // success
  360. if len(unspentResult.Error.Message) != 0 {
  361. err = errors.New(unspentResult.Error.Message)
  362. return nil, err
  363. }
  364. //地址里面有相同的过滤
  365. //var ilistunspent listunspent
  366. unspentValue := map[string]*listunspent{}
  367. for _, unspentInfo := range unspentResult.Result {
  368. addr := unspentInfo.Address
  369. if addr == "" {
  370. break
  371. }
  372. if unspentValue[addr] == nil {
  373. unspentValue[addr] = &listunspent{unspentInfo.Amount, unspentInfo.Spendable}
  374. } else {
  375. unspentValue[addr].amout += unspentInfo.Amount
  376. }
  377. }
  378. outputsArr := make([]map[string]interface{}, 0)
  379. for k, v := range unspentValue {
  380. requestData := make(map[string]interface{})
  381. requestData["address"] = k
  382. valuestr := fmt.Sprintf("%.8f", v.amout)
  383. value, _ := strconv.ParseFloat(valuestr, 64)
  384. requestData["Amount"] = value
  385. requestData["spendable"] = v.spendable
  386. outputsArr = append(outputsArr, requestData)
  387. }
  388. return outputsArr, nil
  389. }
  390. //Send Raw Transaction
  391. func (m BitCoinApi) SendRawTransaction(hexstring string) (string, error) {
  392. var rawtransactioninfo RpcResult
  393. if len(hexstring) == 0 {
  394. fmt.Println("input para err:")
  395. err := errors.New("input para err")
  396. return "", err
  397. }
  398. result, err := bitcoinRpc.RunCall("sendrawtransaction", hexstring)
  399. if err != nil {
  400. fmt.Println("Call sendrawtransaction fail:", err.Error())
  401. return "", err
  402. }
  403. if err := json.Unmarshal([]byte(result), &rawtransactioninfo); err != nil {
  404. fmt.Println("Unmarshal err :", err.Error())
  405. return "", err
  406. }
  407. if len(rawtransactioninfo.Error.Message) == 0 {
  408. return rawtransactioninfo.Result, nil
  409. }
  410. err = errors.New(rawtransactioninfo.Error.Message)
  411. return "", err
  412. }