├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── Make.bat ├── Makefile ├── README.md ├── base ├── Error.go ├── ErrorCode.go ├── RPC.go ├── Request.go └── Response.go ├── client ├── Client.go ├── ClientBlockChain.go ├── ClientControl.go ├── ClientGenerating.go ├── ClientMining.go ├── ClientNetwork.go ├── ClientRawTransactions.go ├── ClientUtil.go ├── ClientWallet.go ├── Command.go ├── Command_test.go ├── Config.go └── Errors.go ├── conf ├── log.json └── zap.json ├── documents └── conventions.md ├── examples ├── demos │ ├── BlockChainTest.go │ ├── ControlTest.go │ ├── Demos.go │ ├── GeneratingTest.go │ ├── MiningTest.go │ ├── NetworkTest.go │ ├── RawTransactionsTest.go │ ├── UtilTest.go │ └── WalletTest.go └── main.go ├── futures ├── Future.go ├── FutureBool.go ├── FutureByteArray.go ├── FutureFloat64.go ├── FutureFloat64Array.go ├── FutureGetBestBlockHashResult.go ├── FutureGetBlockChainInfoResult.go ├── FutureGetBlockCountResult.go ├── FutureGetBlockHashResult.go ├── FutureGetBlockHeaderResult.go ├── FutureGetBlockResult.go ├── FutureGetBlockVerboseTXResult.go ├── FutureGetChainTXStatsResult.go ├── FutureGetChainTipsResult.go ├── FutureGetDifficultyResult.go ├── FutureGetMempoolEntryResult.go ├── FutureGetMempoolInfoResult.go ├── FutureGetRawMempoolResult.go ├── FutureGetRawMempoolVerboseResult.go ├── FutureGetTXOutSetInfoResult.go ├── FutureGetTxOutResult.go ├── FutureInt32.go ├── FutureInt32Array.go ├── FutureString.go ├── FutureStringArray.go └── FutureVerifyChainResult.go ├── main.go ├── results ├── BlockHeader.go ├── GetBlockChainInfoResult.go ├── GetBlockHeaderResult.go ├── GetBlockResult.go ├── GetBlockStatsResult.go ├── GetBlockVerboseTXResult.go ├── GetChainTXStatsResult.go ├── GetChainTipsResult.go ├── GetMempoolEntryResult.go ├── GetMempoolInfoResult.go ├── GetRawMempoolVerboseResult.go ├── GetTXOutSetInfoResult.go ├── GetTxOutResult.go ├── Hash.go └── TxRawResult.go └── utils ├── Basis.go ├── Basis_test.go ├── Http.go └── Http_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | /.idea 14 | /*.log 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - "1.10" -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to ChainLibs 2 | ============================ 3 | 4 | The ChainLibs project operates an open contributor model where anyone is 5 | welcome to contribute towards development in the form of peer review, testing 6 | and patches. This document explains the practical process and guidelines for 7 | contributing. 8 | 9 | If you're looking for somewhere to start contributing, check out the issues list. 10 | 11 | Communication Channels 12 | ---------------------- 13 | 14 | The way to discuss with Chainlibs developer is Gitter. 15 | 16 | Contributor Workflow 17 | -------------------- 18 | 19 | The codebase is maintained using the "contributor workflow" where everyone 20 | without exception contributes patch proposals using "pull requests". This 21 | facilitates social contribution, easy testing and peer review. 22 | 23 | To contribute a patch, the workflow is as follows: 24 | 25 | 1. Fork repository 26 | 1. Create topic branch 27 | 1. Commit patches 28 | 29 | The project coding conventions in the [developer notes](documents/conventions.md) 30 | must be adhered to. 31 | 32 | In general [commits should be atomic](https://en.wikipedia.org/wiki/Atomic_commit#Atomic_commit_convention) 33 | and diffs should be easy to read. For this reason do not mix any formatting 34 | fixes or code moves with actual code changes. 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 chainlibs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Make.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | cd %~dp0 3 | if %0 == "install" goto install 4 | 5 | 6 | 7 | :install 8 | echo -------------------------------------- begin to make install... 9 | ::go get github.com/chainlibs/gobtclib 10 | go get -u go.uber.org/zap 11 | go get -u github.com/gobasis/log 12 | mkdir %GOPATH%\src\github.com\chainlibs 13 | rmdir /s/q %GOPATH%\src\github.com\chainlibs\gobtclib 14 | mklink /D %GOPATH%\src\github.com\chainlibs\gobtclib %cd% 15 | echo -------------------------------------- finished successfully! 16 | pause -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | .PHONY : all 4 | all : clean deps build deploy 5 | 6 | .PHONY: deps 7 | deps : 8 | go get -u go.uber.org/zap;go get -u github.com/gobasis/log; 9 | 10 | .PHONY: build 11 | build : 12 | go build -o demo examples/main.go 13 | 14 | .PHONY: clean 15 | clean : 16 | rm -rf /tmp/mktarget && rm -rf ./target 17 | 18 | .PHONY: deploy 19 | deploy : clean 20 | mkdir ./target 21 | 22 | .PHONY: tar 23 | tar : 24 | cd ./target; tar -zvcf bbb.tar.gz * 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gobtclib 2 | 3 | A client library with golang for Bitcoin 4 | 5 | ![GitHub release](https://img.shields.io/github/release/chainlibs/gobtclib.svg) 6 | ![Github commits (since latest release)](https://img.shields.io/github/commits-since/chainlibs/gobtclib/latest.svg) 7 | [![Build Status](https://travis-ci.org/chainlibs/gobtclib.svg?branch=master)](https://travis-ci.org/chainlibs/gobtclib) 8 | [![GitHub issues](https://img.shields.io/github/issues/chainlibs/gobtclib.svg)](https://github.com/chainlibs/gobtclib/issues) 9 | [![GitHub stars](https://img.shields.io/github/stars/chainlibs/gobtclib.svg)](https://github.com/chainlibs/gobtclib/stargazers) 10 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/chainlibs/gobtclib/master/LICENSE) 11 | [![Gitter chat](https://badges.gitter.im/owner/repo.png)](https://gitter.im/gobtclib/Lobby) 12 | 13 | What is Bitcoin? 14 | ---------------- 15 | 16 | Bitcoin is an experimental digital currency that enables instant payments to 17 | anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate 18 | with no central authority: managing transactions and issuing money are carried 19 | out collectively by the network. Bitcoin Core is the name of open source 20 | software which enables the use of this currency. 21 | 22 | The current project is the client library for bitcoin, you can read the document from 23 | https://bitcoincore.org/en/doc for more information. 24 | 25 | What is gobtclib? 26 | ---------------- 27 | 28 | gobtclib is a golang-based library for working with the Bitcoin protocol. It can maintain a wallet, send/receive transactions without 29 | needing a local copy of Bitcoin Core and has many other advanced features. 30 | 31 | Support RPC list 32 | ---------------- 33 | 34 | - BLOCKCHAIN 35 | - getbestblockhash 36 | - getblock 37 | - getblockchaininfo 38 | - getblockcount 39 | - getblockhash 40 | - getblockheader 41 | - getblockstats 42 | - getchaintips 43 | - getchaintxstats 44 | - getdifficulty 45 | - getmempoolancestors 46 | - getmempooldescendants 47 | - getmempoolentry 48 | - getmempoolinfo 49 | - getrawmempool 50 | - gettxout 51 | - gettxoutproof 52 | - gettxoutsetinfo 53 | - preciousblock 54 | - pruneblockchain 55 | - savemempool 56 | - verifychain 57 | - verifytxoutproof 58 | - CONTROL 59 | - getmemoryinfo 60 | - help 61 | - logging 62 | - stop 63 | - uptime 64 | - GENERATING 65 | - MINING 66 | - NETWORK 67 | - RAWTRANSACTIONS 68 | - CombineRawTransaction 69 | - CreateRawTransaction 70 | - DecodeRawTransaction 71 | - DecodeScript 72 | - FundRawTransaction 73 | - GetRawTransaction 74 | - GetRawTransactionVerbose 75 | - SendRawTransaction 76 | - SignRawTransactionWithKey 77 | - TestMempoolAccept 78 | - UTIL 79 | - WALLET 80 | - abandontransaction 81 | - abortrescan 82 | - addmultisigaddress 83 | - backupwallet 84 | - bumpfee 85 | - createwallet 86 | - dumpprivkey 87 | - dumpwallet 88 | - encryptwallet 89 | - getaccount 90 | - getaccountaddress 91 | - getaddressesbylabel 92 | - getaddressinfo 93 | - getbalance 94 | - getnewaddress 95 | - getrawchangeaddress 96 | - getreceivedbyaccount 97 | - getreceivedbyaddress 98 | - gettransaction 99 | - getunconfirmedbalance 100 | - getwalletinfo 101 | - importaddress 102 | - importmulti 103 | - importprivkey 104 | - -importprunedfunds- 105 | - importpubkey 106 | - importwallet 107 | - keypoolrefill 108 | - listaddressgroupings 109 | - listlabels 110 | - listlockunspent 111 | - listreceivedbyaddress 112 | - listsinceblock 113 | - listtransactions 114 | - listunspent 115 | - listwallets 116 | - loadwallet 117 | - lockunspent 118 | - move 119 | - removeprunedfunds 120 | - rescanblockchain 121 | - sendfrom 122 | - sendmany 123 | - sendtoaddress 124 | - sethdseed 125 | - settxfee 126 | - signmessage 127 | - -signrawtransactionwithwallet- 128 | - unloadwallet 129 | - -walletcreatefundedpsbt- 130 | - walletlock 131 | - walletpassphrase 132 | - walletpassphrasechange 133 | - -walletprocesspsbt- 134 | 135 | Usage 136 | ----- 137 | 138 | 1. download dependency library: go get -u go.uber.org/zap;go get -u github.com/gobasis/log; 139 | 1. Take example from [examples/main.go](/examples/main.go) 140 | 141 | Development Process 142 | ------------------- 143 | 144 | The `master` branch is regularly built and tested, but is not guaranteed to be 145 | completely stable. [Tags](https://github.com/chainlibs/gobtclib/tags) are created 146 | regularly to indicate new official, stable release versions of Bitcoin Core. 147 | 148 | The contribution workflow is described in [CONTRIBUTING.md](CONTRIBUTING.md). 149 | 150 | Testing 151 | ------- 152 | 153 | Testing and code review is the bottleneck for development; we get more pull requests than 154 | we can review and test on short notice. Please be patient and help out by testing 155 | other people's pull requests, and remember this is a security-critical project where 156 | any mistake might cost people lots of money. 157 | 158 | ### Automated Testing 159 | 160 | Developers are strongly encouraged to write unit tests for new code, and to 161 | submit new unit tests for old code. Unit tests can be compiled and run. 162 | 163 | The Travis CI system makes sure that every pull request is built for Windows, Linux, and macOS, 164 | and that unit/sanity tests are run automatically. 165 | 166 | ### Manual Quality Assurance (QA) Testing 167 | 168 | Changes should be tested by somebody other than the developer who wrote the 169 | code. This is especially important for large or high-risk changes. It is useful 170 | to add a test plan to the pull request description if testing the changes is 171 | not straightforward. 172 | 173 | License 174 | ------- 175 | 176 | Chainlibs/gobtclib is released under the terms of the MIT license. See [COPYING](LICENSE) for more 177 | information or see https://opensource.org/licenses/MIT. 178 | -------------------------------------------------------------------------------- /base/Error.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | /* 8 | Description: 9 | NewError creates an Error given a set of arguments. 10 | Constructs and returns a new JSON-RPC error that is suitable 11 | for use in a JSON-RPC JRPCResponse object. 12 | * Author: architect.bian 13 | * Date: 2018/10/08 12:09 14 | */ 15 | func NewError(c ErrorCode, msg string) Error { 16 | return Error{Code: c, Message: msg} 17 | } 18 | 19 | /* 20 | Description: 21 | NewErrorF create an Error given an ErrorCode and a format specifier then returns the error. 22 | * Author: architect.bian 23 | * Date: 2018/10/08 12:17 24 | */ 25 | func NewErrorF(c ErrorCode, format string, a ...interface{}) Error { 26 | return NewError(c, fmt.Sprintf(format, a...)) 27 | } 28 | 29 | /* 30 | Description: 31 | Guarantee RPCError satisifies the builtin error interface. 32 | * Author: architect.bian 33 | * Date: 2018/10/08 12:22 34 | */ 35 | var _, _ error = Error{}, (*Error)(nil) 36 | 37 | /* 38 | Description: 39 | RPCError represents an error that is used as a part of a JSON-RPC JRPCResponse object. 40 | * Author: architect.bian 41 | * Date: 2018/10/08 12:21 42 | */ 43 | type Error struct { 44 | Code ErrorCode `json:"code,omitempty"` 45 | Message string `json:"message,omitempty"` 46 | } 47 | 48 | /* 49 | Description: 50 | Error returns a string describing the RPC error. 51 | This satisifies the builtin error interface. 52 | * Author: architect.bian 53 | * Date: 2018/10/08 12:23 54 | */ 55 | func (e Error) Error() string { 56 | return fmt.Sprintf("%d: %s", e.Code, e.Message) 57 | } 58 | -------------------------------------------------------------------------------- /base/ErrorCode.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | /* 4 | Description: 5 | RPCErrorCode represents an error code to be used as a part of an RPCError 6 | which is in turn used in a JSON-RPC JRPCResponse object. 7 | 8 | A specific type is used to help ensure the wrong errors aren't used. 9 | * Author: architect.bian 10 | * Date: 2018/10/08 12:21 11 | */ 12 | type ErrorCode int 13 | 14 | const ( 15 | 16 | // ErrInvalidType indicates a type was passed that is not the required type. 17 | ErrInvalidTypeCode ErrorCode = iota 18 | 19 | //// ErrDuplicateMethodCode indicates a command with the specified method 20 | //// already exists. 21 | //ErrDuplicateMethodCode 22 | 23 | ) 24 | 25 | -------------------------------------------------------------------------------- /base/RPC.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | /* 9 | Description: 10 | NewJRPC returns a new JSON-RPC 1.0 request object given the provided id, 11 | method, and parameters. The parameters are marshalled into a json.RawMessage 12 | for the Params field of the returned request object. This function is only 13 | provided in case the caller wants to construct raw requests for some reason. 14 | 15 | Typically callers will instead want to create a registered concrete command 16 | type with the NewCmd or NewCmd functions and call the MarshalCmd 17 | function with that command to generate the marshalled JSON-RPC request. 18 | * Author: architect.bian 19 | * Date: 2018/08/26 17:29 20 | */ 21 | func NewJRPC(id interface{}, method string, params []interface{}) (*JRPC, error) { 22 | if !isValidIDType(id) { 23 | return nil, NewError(ErrInvalidTypeCode, fmt.Sprintf("the id of type '%T' is invalid", id)) 24 | } 25 | 26 | rawParams := make([]json.RawMessage, 0, len(params)) 27 | for _, param := range params { 28 | marshalledParam, err := json.Marshal(param) 29 | if err != nil { 30 | return nil, err 31 | } 32 | rawMessage := json.RawMessage(marshalledParam) 33 | rawParams = append(rawParams, rawMessage) 34 | } 35 | 36 | return &JRPC{ 37 | Jsonrpc: "1.0", 38 | ID: id, 39 | Method: method, 40 | Params: rawParams, 41 | }, nil 42 | } 43 | 44 | /* 45 | Description: 46 | JRPC is a type for raw JSON-RPC 1.0 requests. The Method field identifies 47 | the specific command type which in turns leads to different parameters. 48 | Callers typically will not use this directly since this package provides a 49 | statically typed command infrastructure which handles creation of these 50 | requests, however this struct it being exported in case the caller wants to 51 | construct raw requests for some reason. 52 | * Author: architect.bian 53 | * Date: 2018/08/26 17:27 54 | */ 55 | type JRPC struct { 56 | Jsonrpc string `json:"jsonrpc"` 57 | Method string `json:"method"` 58 | Params []json.RawMessage `json:"params"` 59 | ID interface{} `json:"id"` 60 | } 61 | 62 | /* 63 | Description: 64 | isValidIDType checks that the ID field (which can go in any of the JSON-RPC 65 | requests, responses, or notifications) is valid. JSON-RPC 1.0 allows any 66 | valid JSON type. JSON-RPC 2.0 (which bitcoind follows for some parts) only 67 | allows string, number, or null, so this function restricts the allowed types 68 | to that list. This function is only provided in case the caller is manually 69 | marshalling for some reason. The functions which accept an ID in this 70 | package already call this function to ensure the provided id is valid. 71 | * Author: architect.bian 72 | * Date: 2018/08/26 17:23 73 | */ 74 | func isValidIDType(id interface{}) bool { 75 | switch id.(type) { 76 | case int, int8, int16, int32, int64, 77 | uint, uint8, uint16, uint32, uint64, 78 | float32, float64, string, nil: 79 | return true 80 | default: 81 | return false 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /base/Request.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | /* 8 | Description: 9 | RequestDetail houses an HTTP POST request to send to an RPC server as well 10 | as the original JSON-RPC command and a channel to reply on when the server 11 | responds with the result. 12 | * Author: architect.bian 13 | * Date: 2018/08/26 15:42 14 | */ 15 | type RequestDetail struct { 16 | HttpRequest *http.Request 17 | Detail *JsonDetail 18 | } 19 | 20 | /* 21 | Description: 22 | JsonDetail holds information about a json request that is used to properly 23 | detect, interpret, and deliver a reply to it. 24 | * Author: architect.bian 25 | * Date: 2018/08/26 15:43 26 | */ 27 | type JsonDetail struct { 28 | Id uint64 29 | Method string 30 | Cmd interface{} 31 | MarshalledJSON []byte 32 | ResponseChan chan *Response // Generate the request and send it along with a channel to respond on. 33 | } 34 | -------------------------------------------------------------------------------- /base/Response.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | /* 8 | Description: 9 | response is the raw bytes of a JSON-RPC result, or the error if the response 10 | error object was non-null. 11 | * Author: architect.bian 12 | * Date: 2018/08/26 15:44 13 | */ 14 | type Response struct { 15 | Result []byte 16 | Err error 17 | } 18 | 19 | /* 20 | Description: 21 | RespRaw is a partially-unmarshaled JSON-RPC response. For this 22 | to be valid (according to JSON-RPC 1.0 spec), ID may not be nil. 23 | * Author: architect.bian 24 | * Date: 2018/08/26 17:06 25 | */ 26 | type RespRaw struct { 27 | Result json.RawMessage `json:"result"` 28 | Error *Error `json:"error"` 29 | } 30 | 31 | /* 32 | Description: 33 | GetRaw checks whether the unmarshaled response contains a non-nil error, 34 | returning an unmarshaled btcjson.RPCError (or an unmarshaling error) if so. 35 | If the response is not an error, the raw bytes of the request are 36 | returned for further unmashaling into specific result types. 37 | * Author: architect.bian 38 | * Date: 2018/08/26 17:54 39 | */ 40 | func (r RespRaw) GetRaw() (result []byte, err error) { 41 | if r.Error != nil { 42 | return nil, r.Error 43 | } 44 | return r.Result, nil 45 | } 46 | -------------------------------------------------------------------------------- /client/Client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "net/http" 5 | "sync" 6 | "sync/atomic" 7 | glog "log" 8 | "io/ioutil" 9 | "fmt" 10 | "bytes" 11 | "github.com/chainlibs/gobtclib/utils" 12 | "encoding/json" 13 | "github.com/gobasis/log" 14 | "github.com/chainlibs/gobtclib/base" 15 | "github.com/chainlibs/gobtclib/futures" 16 | ) 17 | 18 | /* 19 | Description: 20 | New creates a new RPC client based on the provided connection configuration details. 21 | * Author: architect.bian 22 | * Date: 2018/08/23 14:53 23 | */ 24 | func NewClient(config *Config) (*Client) { 25 | var httpClient *http.Client 26 | var err error 27 | httpClient, err = utils.Http.NewClient(config.Proxy, config.EnableTLS, config.Certificates) 28 | if err != nil { 29 | glog.Fatal(err) 30 | return nil 31 | } 32 | 33 | client := &Client{ 34 | config: config, 35 | httpClient: httpClient, 36 | requestsChan: make(chan *base.RequestDetail, requestsChanBufferSize), 37 | disconnect: make(chan struct{}), 38 | shutdown: make(chan struct{}), 39 | } 40 | 41 | return client 42 | } 43 | 44 | /* 45 | Description: 46 | Client represents a Bitcoin RPC client which allows easy access to the various RPC methods available 47 | on a Bitcoin RPC server. Each of the wrapper functions handle the details of converting the passed and 48 | return types th and from the underlying JSON types which are required for the JSON-RPC invocations. 49 | 50 | The client provides each RPC in both synchronous (blocking) and asynchronous (non-blocking) forms. 51 | The asynchronous forms are based on the concept of futures where they return an instance of a type that 52 | promises to deliver the result of the invocation at some future time. Invoking the Receive method on 53 | the returned future will block util the result is available if it's not already. 54 | * Author: architect.bian 55 | * Date: 2018/08/26 14:03 56 | */ 57 | type Client struct { 58 | id uint64 // atomic, so must stay 64-bit aligned 59 | // config holds the connection configuration assoiated with this client. 60 | config *Config 61 | // httpClient is the underlying HTTP client to use when running in HTTP POST mode. 62 | httpClient *http.Client 63 | // mtx is a mutex to protect access to connection related fields. 64 | mtx sync.Mutex 65 | // disconnected indicated whether or not the server is disconnected. 66 | disconnected bool 67 | // Networking infrastructure. 68 | requestsChan chan *base.RequestDetail 69 | disconnect chan struct{} 70 | shutdown chan struct{} 71 | wg sync.WaitGroup 72 | } 73 | 74 | /* 75 | Description: 76 | start begins processing input and output messages. 77 | * Author: architect.bian 78 | * Date: 2018/08/23 16:02 79 | */ 80 | func (c *Client) Startup() *Client { 81 | log.Info("Starting RPC client", "Host", c.config.Host) 82 | c.wg.Add(1) 83 | go c.handleRequests() 84 | //go c.handleRequests() // more routine? 85 | //go c.handleRequests() 86 | return c 87 | } 88 | 89 | /* 90 | Description: 91 | SendAsync send command and args, return an instance of a future type 92 | * Author: architect.bian 93 | * Date: 2018/08/23 16:02 94 | */ 95 | func (c *Client) SendAsync(command string, args ...interface{}) futures.FutureResult { 96 | cmd := NewCommand(command, args...) 97 | return futures.FutureResult(c.sendCmd(cmd)) 98 | } 99 | 100 | /* 101 | Description: 102 | Send send any command and arguments, then return a result of interface type 103 | * Author: architect.bian 104 | * Date: 2018/08/23 16:02 105 | */ 106 | func (c *Client) Send(command string, args ...interface{}) (*interface{}, error) { 107 | cmd := NewCommand(command, args...) 108 | return futures.FutureResult(c.sendCmd(cmd)).Receive() 109 | } 110 | 111 | /* 112 | Description: 113 | handleRequests handles all outgoing messages when the client is running 114 | in HTTP POST mode. It uses a buffered channel to serialize output messages 115 | while allowing the sender to continue running asynchronously. It must be run 116 | as a goroutine. 117 | * Author: architect.bian 118 | * Date: 2018/08/26 16:05 119 | */ 120 | func (c *Client) handleRequests() { 121 | out: 122 | for { 123 | // Send any messages ready for send until the shutdown channel is closed. 124 | select { 125 | case req := <-c.requestsChan: 126 | c.doRequest(req) 127 | 128 | case <-c.shutdown: 129 | break out 130 | } 131 | } 132 | 133 | // Drain any wait channels before exiting so nothing is left waiting 134 | // around to send. 135 | cleanup: 136 | for { 137 | select { 138 | case req := <-c.requestsChan: 139 | req.Detail.ResponseChan <- &base.Response{ 140 | Result: nil, 141 | Err: ErrClientShutdown, 142 | } 143 | default: 144 | break cleanup 145 | } 146 | } 147 | c.wg.Done() 148 | log.Info("RPC client send task clean up", "host", c.config.Host) 149 | } 150 | 151 | /* 152 | Description: 153 | handlebase.RequestDetail handles performing the passed HTTP request, reading the 154 | result, unmarshalling it, and delivering the unmarshalled result to the 155 | provided response channel. 156 | * Author: architect.bian 157 | * Date: 2018/10/07 18:26 158 | */ 159 | func (c *Client) doRequest(requestDetail *base.RequestDetail) { 160 | detail := requestDetail.Detail 161 | log.Debug("Sending command", "command", detail.Method, "id", detail.Id) 162 | response, err := c.httpClient.Do(requestDetail.HttpRequest) 163 | if err != nil { 164 | detail.ResponseChan <- &base.Response{Err: err} 165 | return 166 | } 167 | // Read the raw bytes and close the response. 168 | bodyBytes, err := ioutil.ReadAll(response.Body) 169 | response.Body.Close() 170 | if err != nil { 171 | err = fmt.Errorf("error reading json reply: %v", err) 172 | detail.ResponseChan <- &base.Response{Err: err} 173 | return 174 | } 175 | log.Debug("receive result data after posted", "result", string(bodyBytes)) 176 | // Try to unmarshal the response as a regular JSON-RPC response. 177 | var respRaw base.RespRaw 178 | err = json.Unmarshal(bodyBytes, &respRaw) 179 | if err != nil { 180 | // When the response itself isn't a valid JSON-RPC response 181 | // return an error which includes the HTTP status code and raw 182 | // response bytes. 183 | err = fmt.Errorf("status code: %d, response: %q", response.StatusCode, string(bodyBytes)) 184 | detail.ResponseChan <- &base.Response{Err: err} 185 | return 186 | } 187 | respBytes, err := respRaw.GetRaw() 188 | detail.ResponseChan <- &base.Response{Result: respBytes, Err: err} 189 | } 190 | 191 | /* 192 | Description: 193 | sendRequest sends the passed HTTP request to the RPC server using the 194 | HTTP client associated with the client. It is backed by a buffered channel, 195 | so it will not block until the send channel is full. 196 | * Author: architect.bian 197 | * Date: 2018/08/26 19:29 198 | */ 199 | func (c *Client) sendRequest(req *http.Request, detail *base.JsonDetail) { 200 | // Don't send the request if shutting down. 201 | select { 202 | case <-c.shutdown: 203 | detail.ResponseChan <- &base.Response{Result: nil, Err: ErrClientShutdown} 204 | default: 205 | } 206 | 207 | c.requestsChan <- &base.RequestDetail{ 208 | HttpRequest: req, 209 | Detail: detail, 210 | } 211 | } 212 | 213 | /* 214 | Description: 215 | sendDetail sends the passed request to the server by issuing an HTTP POST 216 | request using the provided response channel for the reply. Typically a new 217 | connection is opened and closed for each command when using this method, 218 | however, the underlying HTTP client might coalesce multiple commands 219 | depending on several factors including the remote server configuration. 220 | * Author: architect.bian 221 | * Date: 2018/08/26 19:29 222 | */ 223 | func (c *Client) sendDetail(detail *base.JsonDetail) { 224 | // Generate a request to the configured RPC server. 225 | protocol := "http" 226 | if c.config.EnableTLS { 227 | protocol = "https" 228 | } 229 | url := protocol + "://" + c.config.Host 230 | bodyReader := bytes.NewReader(detail.MarshalledJSON) 231 | request, err := http.NewRequest("POST", url, bodyReader) 232 | if err != nil { 233 | detail.ResponseChan <- &base.Response{Result: nil, Err: err} 234 | return 235 | } 236 | request.Close = true 237 | request.Header.Set("Content-Type", "application/json") 238 | // Configure basic access authorization. 239 | request.SetBasicAuth(c.config.User, c.config.Pass) 240 | c.sendRequest(request, detail) 241 | } 242 | 243 | /* 244 | Description: 245 | NextID returns the next id to be used when sending a JSON-RPC message. This 246 | ID allows responses to be associated with particular requestsChan per the 247 | JSON-RPC specification. Typically the consumer of the client does not need 248 | to call this function, however, if a custom request is being created and used 249 | this function should be used to ensure the ID is unique amongst all requestsChan 250 | being made. 251 | * Author: architect.bian 252 | * Date: 2018/08/26 14:30 253 | */ 254 | func (c *Client) NextID() uint64 { 255 | return atomic.AddUint64(&c.id, 1) 256 | } 257 | 258 | /* 259 | Description: 260 | sendCmd sends the passed command to the associated server and returns a 261 | response channel on which the reply will be delivered at some point in the 262 | future. It handles both websocket and HTTP POST mode depending on the 263 | configuration of the client. 264 | * Author: architect.bian 265 | * Date: 2018/08/26 18:46 266 | */ 267 | func (c *Client) sendCmd(cmd *Command) chan *base.Response { 268 | // Marshal the command. 269 | id := c.NextID() 270 | marshalledJSON, err := MarshalCmdToJRPC(id, cmd) 271 | if err != nil { 272 | return futures.NewFutureError(err) 273 | } 274 | log.Debug("posting json content", "json", string(marshalledJSON)) 275 | // Generate the request and send it along with a channel to respond on. 276 | responseChan := make(chan *base.Response, 1) 277 | detail := &base.JsonDetail{ 278 | Id: id, 279 | Method: cmd.name, 280 | Cmd: cmd, 281 | MarshalledJSON: marshalledJSON, 282 | ResponseChan: responseChan, 283 | } 284 | c.sendDetail(detail) 285 | 286 | return responseChan 287 | } 288 | 289 | /* 290 | Description: 291 | sendCmdAndWait sends the passed command to the associated server, waits 292 | for the reply, and returns the result from it. It will return the error 293 | field in the reply if there is one. 294 | * Author: architect.bian 295 | * Date: 2018/10/06 19:50 296 | */ 297 | func (c *Client) sendCmdAndWait(cmd *Command) (interface{}, error) { 298 | // Marshal the command to JSON-RPC, send it to the connected server, and 299 | // wait for a response on the returned channel. 300 | return futures.ReceiveFuture(c.sendCmd(cmd)) 301 | } 302 | 303 | /* 304 | Description: 305 | Shutdown closes the shutdown channel and logs the shutdown unless shutdown 306 | is already in progress. It will return false if the shutdown is not needed. 307 | This function is safe for concurrent access. 308 | * Author: architect.bian 309 | * Date: 2018/08/26 19:38 310 | */ 311 | func (c *Client) Shutdown() { 312 | // Ignore the shutdown request if the client is already in the process 313 | // of shutting down or already shutdown. 314 | select { 315 | case <-c.shutdown: 316 | return 317 | default: 318 | } 319 | 320 | close(c.shutdown) 321 | c.wg.Wait() //blocks until the client goroutines are stopped and the connection is closed. 322 | log.Info("Shut down RPC client", "host", c.config.Host) 323 | } 324 | -------------------------------------------------------------------------------- /client/ClientBlockChain.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/results" 5 | "github.com/chainlibs/gobtclib/futures" 6 | "github.com/chainlibs/gobtclib/utils" 7 | "encoding/hex" 8 | ) 9 | 10 | /* 11 | Description: 12 | GetBestBlockHashAsync returns an instance of a type that can be used to get 13 | the result of the RPC at some future time by invoking the Receive function on 14 | the returned instance. 15 | 16 | See GetBestBlockHash for the blocking version and more details. 17 | * Author: architect.bian 18 | * Date: 2018/09/14 13:18 19 | */ 20 | func (c *Client) GetBestBlockHashAsync() futures.FutureGetBestBlockHashResult { 21 | cmd := NewCommand("getbestblockhash") 22 | return c.sendCmd(cmd) 23 | } 24 | 25 | /* 26 | Description: 27 | GetBestBlockHash returns the hash of the best block in the longest block chain. 28 | * Author: architect.bian 29 | * Date: 2018/09/14 13:15 30 | */ 31 | func (c *Client) GetBestBlockHash() (*results.Hash, error) { 32 | return c.GetBestBlockHashAsync().Receive() 33 | } 34 | 35 | /* 36 | Description: 37 | GetBlockCountAsync returns an instance of a type that can be used to get the 38 | result of the RPC at some future time by invoking the Receive function on the 39 | returned instance. 40 | 41 | See GetBlockCount for the blocking version and more details. 42 | * Author: architect.bian 43 | * Date: 2018/09/14 12:49 44 | */ 45 | func (c *Client) GetBlockCountAsync() futures.FutureGetBlockCountResult { 46 | cmd := NewCommand("getblockcount") 47 | return c.sendCmd(cmd) 48 | } 49 | 50 | /* 51 | Description: 52 | GetBlockCount returns the number of blocks in the longest block chain. 53 | * Author: architect.bian 54 | * Date: 2018/09/14 12:46 55 | */ 56 | func (c *Client) GetBlockCount() (int64, error) { 57 | return c.GetBlockCountAsync().Receive() 58 | } 59 | 60 | /* 61 | Description: 62 | GetBlockHashAsync returns an instance of a type that can be used to get the 63 | result of the RPC at some future time by invoking the Receive function on the 64 | returned instance. 65 | 66 | See GetBlockHash for the blocking version and more details. 67 | * Author: architect.bian 68 | * Date: 2018/09/15 15:35 69 | */ 70 | func (c *Client) GetBlockHashAsync(blockHeight int64) futures.FutureGetBlockHashResult { 71 | cmd := NewCommand("getblockhash", blockHeight) 72 | return c.sendCmd(cmd) 73 | } 74 | 75 | /* 76 | Description: 77 | GetBlockHash returns the hash of the block in the best block chain at the given height. 78 | * Author: architect.bian 79 | * Date: 2018/09/15 15:34 80 | */ 81 | func (c *Client) GetBlockHash(blockHeight int64) (*results.Hash, error) { 82 | return c.GetBlockHashAsync(blockHeight).Receive() 83 | } 84 | 85 | /* 86 | Description: 87 | GetBlockHeaderAsync returns an instance of a type that can be used to get the 88 | result of the RPC at some future time by invoking the Receive function on the 89 | returned instance. 90 | 91 | See GetBlockHeader for the blocking version and more details. 92 | * Author: architect.bian 93 | * Date: 2018/09/17 15:23 94 | */ 95 | func (c *Client) GetBlockHeaderAsync(blockHash *results.Hash, verbose *bool) futures.FutureResult { 96 | hash := "" 97 | if blockHash != nil { 98 | hash = blockHash.String() 99 | } 100 | cmd := NewCommand("getblockheader", hash, verbose) 101 | return c.sendCmd(cmd) 102 | } 103 | 104 | /* 105 | Description: 106 | GetBlockHeaderBytes returns the bytes of blockheader from the server given its hash. 107 | See GetBlockHeader to retrieve a data structure with information about the block instead. 108 | * Author: architect.bian 109 | * Date: 2018/09/17 15:22 110 | */ 111 | func (c *Client) GetBlockHeaderBytes(blockHash *results.Hash) (*[]byte, error) { 112 | future := c.GetBlockHeaderAsync(blockHash, utils.Basis.Bool(false)) 113 | result, err := futures.ReceiveFuture(future) 114 | if err != nil { 115 | return nil, err 116 | } 117 | return &result, nil 118 | } 119 | 120 | /* 121 | Description: 122 | GetBlockHeader returns the blockheader from the server given its hash. 123 | See GetBlockHeader to retrieve a data structure with information about the 124 | block instead. 125 | * Author: architect.bian 126 | * Date: 2018/09/17 15:22 127 | */ 128 | func (c *Client) GetBlockHeader(blockHash *results.Hash) (*results.GetBlockHeaderResult, error) { 129 | return futures.FutureGetBlockHeaderResult(c.GetBlockHeaderAsync(blockHash, utils.Basis.Bool(true))).Receive() 130 | } 131 | 132 | /* 133 | Description: 134 | GetBlockChainInfoAsync returns an instance of a type that can be used to get 135 | the result of the RPC at some future time by invoking the Receive function 136 | on the returned instance. 137 | 138 | See GetBlockChainInfo for the blocking version and more details. 139 | * Author: architect.bian 140 | * Date: 2018/09/17 14:49 141 | */ 142 | func (c *Client) GetBlockChainInfoAsync() futures.FutureGetBlockChainInfoResult { 143 | cmd := NewCommand("getblockchaininfo") 144 | return c.sendCmd(cmd) 145 | } 146 | 147 | /* 148 | Description: 149 | GetBlockChainInfo returns information related to the processing state of 150 | various chain-specific details such as the current difficulty from the tip 151 | of the main chain. 152 | * Author: architect.bian 153 | * Date: 2018/09/17 14:47 154 | */ 155 | func (c *Client) GetBlockChainInfo() (*results.GetBlockChainInfoResult, error) { 156 | return c.GetBlockChainInfoAsync().Receive() 157 | } 158 | 159 | /* 160 | Description: 161 | GetBlockAsync returns an instance of a type that can be used to get the 162 | result of the RPC at some future time by invoking the Receive function on the 163 | returned instance. 164 | 165 | See GetBlock for the blocking version and more details. 166 | * Author: architect.bian 167 | * Date: 2018/09/17 16:09 168 | */ 169 | func (c *Client) GetBlockAsync(blockHash *results.Hash, verbosity *int) futures.FutureResult { 170 | hash := "" 171 | if blockHash != nil { 172 | hash = blockHash.String() 173 | } 174 | cmd := NewCommand("getblock", hash, verbosity) 175 | return c.sendCmd(cmd) 176 | } 177 | 178 | /* 179 | Description: 180 | GetBlock returns a raw block from the server given its hash. 181 | 182 | See GetBlockVerbose to retrieve a data structure with information about the 183 | block instead. 184 | * Author: architect.bian 185 | * Date: 2018/09/17 16:09 186 | */ 187 | func (c *Client) GetBlockBytes(blockHash *results.Hash) (*[]byte, error) { 188 | future := c.GetBlockAsync(blockHash, utils.Basis.Int(0)) 189 | result, err := futures.ReceiveFuture(future) 190 | if err != nil { 191 | return nil, err 192 | } 193 | return &result, nil 194 | } 195 | 196 | /* 197 | Description: 198 | GetBlock returns a raw block from the server given its hash. 199 | See GetBlockVerbose to retrieve a data structure with information about the block instead. 200 | * Author: architect.bian 201 | * Date: 2018/09/17 16:09 202 | */ 203 | func (c *Client) GetBlock(blockHash *results.Hash) (*results.GetBlockResult, error) { 204 | future := futures.FutureGetBlockResult(c.GetBlockAsync(blockHash, utils.Basis.Int(1))) 205 | return future.Receive() 206 | } 207 | 208 | /* 209 | Description: 210 | GetBlockVerbose returns a data structure from the server with information 211 | about a block given its hash. 212 | 213 | See GetBlockVerboseTx to retrieve transaction data structures as well. 214 | See GetBlock to retrieve a raw block instead. 215 | * Author: architect.bian 216 | * Date: 2018/09/17 16:21 217 | */ 218 | func (c *Client) GetBlockVerboseTX(blockHash *results.Hash) (*results.GetBlockVerboseTXResult, error) { 219 | future := futures.FutureGetBlockVerboseTXResult(c.GetBlockAsync(blockHash, utils.Basis.Int(2))) 220 | return future.Receive() 221 | } 222 | 223 | /* 224 | Description: 225 | GetBlockStatsAsync returns an instance of a type that can be used to get the 226 | result of the RPC at some future time by invoking the Receive function on the 227 | returned instance. 228 | 229 | See GetBlockStats for more details. 230 | * Author: architect.bian 231 | * Date: 2018/09/17 16:09 232 | */ 233 | func (c *Client) GetBlockStatsAsync(heightOrHash interface{}, stats *[]string) futures.FutureResult { 234 | cmd := NewCommand("getblockstats", heightOrHash, stats) 235 | return c.sendCmd(cmd) 236 | } 237 | 238 | /* 239 | Description: 240 | GetBlockStats Compute per block statistics for a given window. All amounts are in satoshis. 241 | * Author: architect.bian 242 | * Date: 2018/10/10 15:17 243 | */ 244 | func (c *Client) GetBlockStats(heightOrHash interface{}) (*results.GetBlockStatsResult, error) { 245 | var result results.GetBlockStatsResult 246 | _, err := c.GetBlockStatsAsync(heightOrHash, nil).Receive() //TODO result is nil? need *? 247 | if err != nil { 248 | return nil, err 249 | } 250 | return &result, err 251 | } 252 | 253 | /* 254 | Description: 255 | GetBlockStats Compute per block statistics for a given window. All amounts are in satoshis. 256 | * Author: architect.bian 257 | * Date: 2018/10/10 15:17 258 | */ 259 | func (c *Client) GetBlockStatsEntire(heightOrHash interface{}, stats *[]string) (*map[interface{}]interface{}, error) { 260 | var result map[interface{}]interface{} 261 | _, err := c.GetBlockStatsAsync(heightOrHash, nil).Receive() 262 | if err != nil { 263 | return nil, err 264 | } 265 | return &result, err 266 | } 267 | 268 | /* 269 | Description: 270 | GetChainTipsAsync returns an instance of a type that can be used to get 271 | the result of the RPC at some future time by invoking the Receive function 272 | on the returned instance. 273 | 274 | See GetChainTips for more details. 275 | * Author: architect.bian 276 | * Date: 2018/09/17 14:49 277 | */ 278 | func (c *Client) GetChainTipsAsync() futures.FutureResult { 279 | cmd := NewCommand("getchaintips") 280 | return c.sendCmd(cmd) 281 | } 282 | 283 | /* 284 | Description: 285 | GetChainTips return information about all known tips in the block tree, including the main chain 286 | as well as orphaned branches. 287 | of the main chain. 288 | * Author: architect.bian 289 | * Date: 2018/09/17 14:47 290 | */ 291 | func (c *Client) GetChainTips() (*[]results.GetChainTipsResult, error) { 292 | future := futures.FutureGetChainTipsResult(c.GetChainTipsAsync()) 293 | return future.Receive() 294 | } 295 | 296 | /* 297 | Description: 298 | GetChainTXStatsAsync returns an instance of a type that can be used to get the 299 | result of the RPC at some future time by invoking the Receive function on the 300 | returned instance. 301 | 302 | See GetChainTXStats for more details. 303 | * Author: architect.bian 304 | * Date: 2018/09/17 16:09 305 | */ 306 | func (c *Client) GetChainTXStatsAsync(nblocks int32, blockhash *results.Hash) futures.FutureResult { 307 | cmd := NewCommand("getchaintxstats", nblocks, blockhash.String()) 308 | return c.sendCmd(cmd) 309 | } 310 | 311 | /* 312 | Description: 313 | GetChainTXStats Compute statistics about the total number and rate of transactions in the chain. 314 | * Author: architect.bian 315 | * Date: 2018/10/11 10:23 316 | */ 317 | func (c *Client) GetChainTXStats() (*results.GetChainTXStatsResult, error) { 318 | cmd := NewCommand("getchaintxstats") 319 | var err error 320 | result, err := futures.FutureGetChainTXStatsResult(c.sendCmd(cmd)).Receive() 321 | if err != nil { 322 | return nil, err 323 | } 324 | return result, err 325 | } 326 | 327 | /* 328 | Description: 329 | GetChainTXStatsEntire Compute statistics about the total number and rate of transactions in the chain. 330 | Can specify nblocks blockhash 331 | * Author: architect.bian 332 | * Date: 2018/10/11 10:24 333 | */ 334 | func (c *Client) GetChainTXStatsEntire(nblocks int32, blockhash *results.Hash) (*results.GetChainTXStatsResult, error) { 335 | result, err := futures.FutureGetChainTXStatsResult(c.GetChainTXStatsAsync(nblocks, blockhash)).Receive() 336 | if err != nil { 337 | return nil, err 338 | } 339 | return result, err 340 | } 341 | 342 | /* 343 | Description: 344 | GetDifficultyAsync returns an instance of a type that can be used to get the 345 | result of the RPC at some future time by invoking the Receive function on the 346 | returned instance. 347 | 348 | See GetDifficulty for the blocking version and more details. 349 | * Author: architect.bian 350 | * Date: 2018/09/14 17:35 351 | */ 352 | func (c *Client) GetDifficultyAsync() futures.FutureGetDifficultyResult { 353 | cmd := NewCommand("getdifficulty") 354 | return c.sendCmd(cmd) 355 | } 356 | 357 | /* 358 | Description: 359 | GetDifficulty returns the proof-of-work difficulty as a multiple of the 360 | minimum difficulty. The result is bits/params.PowLimitBits 361 | * Author: architect.bian 362 | * Date: 2018/09/14 17:34 363 | */ 364 | func (c *Client) GetDifficulty() (float64, error) { 365 | return c.GetDifficultyAsync().Receive() 366 | } 367 | 368 | /* 369 | Description: 370 | GetMempoolAncestorsAsync returns an instance of a type that can be used to get the 371 | result of the RPC at some future time by invoking the Receive function on the 372 | returned instance. 373 | 374 | See GetMempoolAncestors for the blocking version and more details. 375 | * Author: architect.bian 376 | * Date: 2018/10/11 10:19 377 | */ 378 | func (c *Client) GetMempoolAncestorsAsync(txid results.Hash, verbose bool) futures.FutureResult { 379 | cmd := NewCommand("getmempoolancestors", txid.String(), verbose) 380 | return c.sendCmd(cmd) 381 | } 382 | 383 | /* 384 | Description: 385 | GetMempoolAncestors If txid is in the mempool, returns all in-mempool ancestors. 386 | * Author: architect.bian 387 | * Date: 2018/10/11 11:41 388 | */ 389 | func (c *Client) GetMempoolAncestors(txid results.Hash) (*[]string, error) { 390 | var result []string 391 | _, err := c.GetMempoolAncestorsAsync(txid, false).Receive() 392 | if err != nil { 393 | return nil, err 394 | } 395 | return &result, err 396 | } 397 | 398 | /* 399 | Description: 400 | GetMempoolAncestorsVerbose If txid is in the mempool, returns all in-mempool ancestors. 401 | verbose is true for a json object. 402 | * Author: architect.bian 403 | * Date: 2018/10/11 11:42 404 | */ 405 | func (c *Client) GetMempoolAncestorsVerbose(txid results.Hash) (*map[string]interface{}, error) { 406 | var result map[string]interface{} 407 | _, err := c.GetMempoolAncestorsAsync(txid, true).Receive() 408 | if err != nil { 409 | return nil, err 410 | } 411 | return &result, err 412 | } 413 | 414 | /* 415 | Description: 416 | GetMempoolDescendantsAsync returns an instance of a type that can be used to get the 417 | result of the RPC at some future time by invoking the Receive function on the 418 | returned instance. 419 | 420 | See GetMempoolDescendants for the blocking version and more details. 421 | * Author: architect.bian 422 | * Date: 2018/10/11 10:19 423 | */ 424 | func (c *Client) GetMempoolDescendantsAsync(txid results.Hash, verbose bool) futures.FutureResult { 425 | cmd := NewCommand("getmempooldescendants", txid.String(), verbose) 426 | return c.sendCmd(cmd) 427 | } 428 | 429 | /* 430 | Description: 431 | GetMempoolDescendants If txid is in the mempool, returns all in-mempool descendants. 432 | * Author: architect.bian 433 | * Date: 2018/10/11 11:49 434 | */ 435 | func (c *Client) GetMempoolDescendants(txid results.Hash) (*[]string, error) { 436 | var result []string 437 | _, err := c.GetMempoolDescendantsAsync(txid, false).Receive() 438 | if err != nil { 439 | return nil, err 440 | } 441 | return &result, err 442 | } 443 | 444 | /* 445 | Description: 446 | GetMempoolDescendantsVerbose If txid is in the mempool, returns all in-mempool descendants. 447 | * Author: architect.bian 448 | * Date: 2018/10/11 11:49 449 | */ 450 | func (c *Client) GetMempoolDescendantsVerbose(txid results.Hash) (*map[string]interface{}, error) { 451 | var result map[string]interface{} 452 | _, err := c.GetMempoolDescendantsAsync(txid, true).Receive() 453 | if err != nil { 454 | return nil, err 455 | } 456 | return &result, err 457 | } 458 | 459 | /* 460 | Description: 461 | GetMempoolEntryAsync returns an instance of a type that can be used to get the 462 | result of the RPC at some future time by invoking the Receive function on the 463 | returned instance. 464 | 465 | See GetMempoolEntry for the blocking version and more details. 466 | * Author: architect.bian 467 | * Date: 2018/09/17 20:23 468 | */ 469 | func (c *Client) GetMempoolEntryAsync(txHash string) futures.FutureGetMempoolEntryResult { 470 | cmd := NewCommand("getmempoolentry", txHash) 471 | return c.sendCmd(cmd) 472 | } 473 | 474 | /* 475 | Description: 476 | GetMempoolEntry returns a data structure with information about the 477 | transaction in the memory pool given its hash. 478 | * Author: architect.bian 479 | * Date: 2018/09/17 20:23 480 | */ 481 | func (c *Client) GetMempoolEntry(txHash string) (*results.GetMempoolEntryResult, error) { //TODO txhash changed to hash? 482 | return c.GetMempoolEntryAsync(txHash).Receive() 483 | } 484 | 485 | /* 486 | Description: 487 | GetMempoolInfoAsync returns an instance of a type that can be used to get the 488 | result of the RPC at some future time by invoking the Receive function on the 489 | returned instance. 490 | 491 | See GetMempoolInfo for the blocking version and more details. 492 | * Author: architect.bian 493 | * Date: 2018/10/11 10:19 494 | */ 495 | func (c *Client) GetMempoolInfoAsync() futures.FutureResult { 496 | cmd := NewCommand("getmempoolinfo") 497 | return c.sendCmd(cmd) 498 | } 499 | 500 | /* 501 | Description: 502 | GetMempoolInfo Returns details on the active state of the TX memory pool. 503 | * Author: architect.bian 504 | * Date: 2018/10/11 11:52 505 | */ 506 | func (c *Client) GetMempoolInfo() (*results.GetMempoolInfoResult, error) { 507 | result, err := futures.FutureGetMempoolInfoResult(c.GetMempoolInfoAsync()).Receive() 508 | if err != nil { 509 | return nil, err 510 | } 511 | return result, err 512 | } 513 | 514 | /* 515 | Description: 516 | GetRawMempoolAsync returns an instance of a type that can be used to get the 517 | result of the RPC at some future time by invoking the Receive function on the 518 | returned instance. 519 | 520 | See GetRawMempool for the blocking version and more details. 521 | * Author: architect.bian 522 | * Date: 2018/09/17 19:51 523 | */ 524 | func (c *Client) GetRawMempoolAsync() futures.FutureGetRawMempoolResult { 525 | cmd := NewCommand("getrawmempool", utils.Basis.Bool(false)) 526 | return c.sendCmd(cmd) 527 | } 528 | 529 | /* 530 | Description: 531 | GetRawMempool returns the hashes of all transactions in the memory pool. 532 | 533 | See GetRawMempoolVerbose to retrieve data structures with information about 534 | the transactions instead. 535 | * Author: architect.bian 536 | * Date: 2018/09/17 19:50 537 | */ 538 | func (c *Client) GetRawMempool() ([]*results.Hash, error) { 539 | return c.GetRawMempoolAsync().Receive() 540 | } 541 | 542 | /* 543 | Description: 544 | GetRawMempoolVerboseAsync returns an instance of a type that can be used to 545 | get the result of the RPC at some future time by invoking the Receive 546 | function on the returned instance. 547 | 548 | See GetRawMempoolVerbose for the blocking version and more details. 549 | * Author: architect.bian 550 | * Date: 2018/09/17 20:10 551 | */ 552 | func (c *Client) GetRawMempoolVerboseAsync() futures.FutureGetRawMempoolVerboseResult { 553 | cmd := NewCommand("getrawmempool", utils.Basis.Bool(true)) 554 | return c.sendCmd(cmd) 555 | } 556 | 557 | /* 558 | Description: 559 | GetRawMempoolVerbose returns a map of transaction hashes to an associated 560 | data structure with information about the transaction for all transactions in 561 | the memory pool. 562 | 563 | See GetRawMempool to retrieve only the transaction hashes instead. 564 | * Author: architect.bian 565 | * Date: 2018/09/17 20:09 566 | */ 567 | func (c *Client) GetRawMempoolVerbose() (map[string]results.GetRawMempoolVerboseResult, error) { 568 | return c.GetRawMempoolVerboseAsync().Receive() 569 | } 570 | 571 | /* 572 | Description: 573 | GetTxOutAsync returns an instance of a type that can be used to get 574 | the result of the RPC at some future time by invoking the Receive function on 575 | the returned instance. 576 | 577 | See GetTxOut for the blocking version and more details. 578 | * Author: architect.bian 579 | * Date: 2018/09/17 21:07 580 | */ 581 | func (c *Client) GetTxOutAsync(txHash *results.Hash, index uint32, mempool bool) futures.FutureGetTxOutResult { 582 | hash := "" 583 | if txHash != nil { 584 | hash = txHash.String() 585 | } 586 | cmd := NewCommand("gettxout", hash, index, &mempool) 587 | return c.sendCmd(cmd) 588 | } 589 | 590 | /* 591 | Description: 592 | GetTxOut returns the transaction output info if it's unspent and 593 | nil, otherwise. 594 | * Author: architect.bian 595 | * Date: 2018/09/17 21:07 596 | */ 597 | func (c *Client) GetTxOut(txHash *results.Hash, index uint32, mempool bool) (*results.GetTxOutResult, error) { 598 | return c.GetTxOutAsync(txHash, index, mempool).Receive() 599 | } 600 | 601 | /* 602 | Description: 603 | GetTXOutProofAsync returns an instance of a type that can be used to get the 604 | result of the RPC at some future time by invoking the Receive function on the 605 | returned instance. 606 | 607 | See GetTXOutProof for the blocking version and more details. 608 | * Author: architect.bian 609 | * Date: 2018/10/11 10:20 610 | */ 611 | func (c *Client) GetTXOutProofAsync(txids []string, blockhash results.Hash) futures.FutureResult { 612 | cmd := NewCommand("gettxoutproof", txids, blockhash) 613 | return c.sendCmd(cmd) 614 | } 615 | 616 | func (c *Client) GetTXOutProof(txids ...string) (*[]byte, error) { 617 | cmd := NewCommand("gettxoutproof", txids) 618 | result, err := futures.ReceiveFuture(c.sendCmd(cmd)) 619 | if err != nil { 620 | return nil, err 621 | } 622 | return &result, nil 623 | } 624 | 625 | func (c *Client) GetTXOutProofEntire(txids []string, blockhash results.Hash) (*[]byte, error) { 626 | future := c.GetTXOutProofAsync(txids, blockhash) 627 | result, err := futures.ReceiveFuture(future) 628 | if err != nil { 629 | return nil, err 630 | } 631 | return &result, nil 632 | } 633 | 634 | /* 635 | Description: 636 | GetTXOutSetInfoAsync returns an instance of a type that can be used to get the 637 | result of the RPC at some future time by invoking the Receive function on the 638 | returned instance. 639 | 640 | See GetTXOutSetInfo for the blocking version and more details. 641 | * Author: architect.bian 642 | * Date: 2018/10/11 10:20 643 | */ 644 | func (c *Client) GetTXOutSetInfoAsync() futures.FutureResult { 645 | cmd := NewCommand("gettxoutsetinfo") 646 | return c.sendCmd(cmd) 647 | } 648 | 649 | func (c *Client) GetTXOutSetInfo() (*results.GetTXOutSetInfoResult, error) { 650 | result, err := futures.FutureGetTXOutSetInfoResult(c.GetTXOutSetInfoAsync()).Receive() 651 | if err != nil { 652 | return nil, err 653 | } 654 | return result, err 655 | } 656 | 657 | /* 658 | Description: 659 | PreciousBlockAsync returns an instance of a type that can be used to get the 660 | result of the RPC at some future time by invoking the Receive function on the 661 | returned instance. 662 | 663 | See PreciousBlock for the blocking version and more details. 664 | * Author: architect.bian 665 | * Date: 2018/10/11 10:20 666 | */ 667 | func (c *Client) PreciousBlockAsync(blockhash results.Hash) futures.FutureResult { 668 | cmd := NewCommand("preciousblock", blockhash.String()) 669 | return c.sendCmd(cmd) 670 | } 671 | 672 | /* 673 | Description: 674 | PreciousBlock Treats a block as if it were received before others with the same work. 675 | * Author: architect.bian 676 | * Date: 2018/10/11 12:33 677 | */ 678 | func (c *Client) PreciousBlock(blockhash results.Hash) (error) { 679 | future := c.PreciousBlockAsync(blockhash) 680 | _, err := futures.ReceiveFuture(future) 681 | if err != nil { 682 | return err 683 | } 684 | return nil 685 | } 686 | 687 | /* 688 | Description: 689 | PruneBlockchainAsync returns an instance of a type that can be used to get the 690 | result of the RPC at some future time by invoking the Receive function on the 691 | returned instance. 692 | 693 | See PruneBlockchain for the blocking version and more details. 694 | * Author: architect.bian 695 | * Date: 2018/10/11 10:20 696 | */ 697 | func (c *Client) PruneBlockchainAsync(height int32) futures.FutureResult { 698 | cmd := NewCommand("pruneblockchain", height) 699 | return c.sendCmd(cmd) 700 | } 701 | 702 | /* 703 | Description: 704 | PruneBlockchain prune blocks 705 | * Author: architect.bian 706 | * Date: 2018/10/11 12:33 707 | */ 708 | func (c *Client) PruneBlockchain(height int32) (int32, error) { 709 | var result int32 710 | _, err := c.PruneBlockchainAsync(height).Receive() 711 | if err != nil { 712 | return -1, err 713 | } 714 | return result, nil 715 | } 716 | 717 | /* 718 | Description: 719 | SaveMempoolAsync returns an instance of a type that can be used to get the 720 | result of the RPC at some future time by invoking the Receive function on the 721 | returned instance. 722 | 723 | See SaveMempool for the blocking version and more details. 724 | * Author: architect.bian 725 | * Date: 2018/10/11 10:20 726 | */ 727 | func (c *Client) SaveMempoolAsync() futures.FutureResult { 728 | cmd := NewCommand("savemempool") 729 | return c.sendCmd(cmd) 730 | } 731 | 732 | /* 733 | Description: 734 | SaveMempool Dumps the mempool to disk. It will fail until the previous dump is fully loaded. 735 | * Author: architect.bian 736 | * Date: 2018/10/11 12:32 737 | */ 738 | func (c *Client) SaveMempool() (error) { 739 | _, err := futures.ReceiveFuture(c.SaveMempoolAsync()) 740 | if err != nil { 741 | return err 742 | } 743 | return nil 744 | } 745 | 746 | /* 747 | Description: 748 | VerifyChainAsync returns an instance of a type that can be used to get the 749 | result of the RPC at some future time by invoking the Receive function on the 750 | returned instance. 751 | 752 | See VerifyChain for the blocking version and more details. 753 | * Author: architect.bian 754 | * Date: 2018/09/17 20:54 755 | */ 756 | func (c *Client) VerifyChainAsync() futures.FutureVerifyChainResult { 757 | cmd := NewCommand("verifychain") 758 | return c.sendCmd(cmd) 759 | } 760 | 761 | /* 762 | Description: 763 | VerifyChain requests the server to verify the block chain database using 764 | the default check level and number of blocks to verify. 765 | 766 | See VerifyChainLevel and VerifyChainBlocks to override the defaults. 767 | * Author: architect.bian 768 | * Date: 2018/09/17 20:54 769 | */ 770 | func (c *Client) VerifyChain() (bool, error) { 771 | return c.VerifyChainAsync().Receive() 772 | } 773 | 774 | /* 775 | Description: 776 | VerifyTXOutProofAsync returns an instance of a type that can be used to get the 777 | result of the RPC at some future time by invoking the Receive function on the 778 | returned instance. 779 | 780 | See VerifyTXOutProof for the blocking version and more details. 781 | * Author: architect.bian 782 | * Date: 2018/10/11 10:20 783 | */ 784 | func (c *Client) VerifyTXOutProofAsync(proof []byte) futures.FutureResult { 785 | dst := make([]byte, hex.EncodedLen(len(proof))) 786 | hex.Encode(dst, proof) 787 | cmd := NewCommand("verifytxoutproof", string(dst)) 788 | return c.sendCmd(cmd) 789 | } 790 | 791 | func (c *Client) VerifyTXOutProof(proof []byte) (*[]string, error) { 792 | var result []string 793 | _, err := c.VerifyTXOutProofAsync(proof).Receive() 794 | if err != nil { 795 | return nil, err 796 | } 797 | return &result, nil 798 | } 799 | 800 | /* 801 | Description: 802 | VerifyChainLevelAsync returns an instance of a type that can be used to get 803 | the result of the RPC at some future time by invoking the Receive function on 804 | the returned instance. 805 | 806 | See VerifyChainLevel for the blocking version and more details. 807 | * Author: architect.bian 808 | * Date: 2018/09/17 21:00 809 | */ 810 | func (c *Client) VerifyChainLevelAsync(checkLevel int32) futures.FutureVerifyChainResult { 811 | cmd := NewCommand("verifychain", &checkLevel) 812 | return c.sendCmd(cmd) 813 | } 814 | 815 | /* 816 | Description: 817 | VerifyChainLevel requests the server to verify the block chain database using 818 | the passed check level and default number of blocks to verify. 819 | 820 | The check level controls how thorough the verification is with higher numbers 821 | increasing the amount of checks done as consequently how long the 822 | verification takes. 823 | 824 | See VerifyChain to use the default check level and VerifyChainBlocks to 825 | override the number of blocks to verify. 826 | * Author: architect.bian 827 | * Date: 2018/09/17 21:00 828 | */ 829 | func (c *Client) VerifyChainLevel(checkLevel int32) (bool, error) { 830 | return c.VerifyChainLevelAsync(checkLevel).Receive() 831 | } 832 | 833 | /* 834 | Description: 835 | VerifyChainBlocksAsync returns an instance of a type that can be used to get 836 | the result of the RPC at some future time by invoking the Receive function on 837 | the returned instance. 838 | 839 | See VerifyChainBlocks for the blocking version and more details. 840 | * Author: architect.bian 841 | * Date: 2018/09/17 21:00 842 | */ 843 | func (c *Client) VerifyChainBlocksAsync(checkLevel, numBlocks int32) futures.FutureVerifyChainResult { 844 | cmd := NewCommand("verifychain", &checkLevel, &numBlocks) 845 | return c.sendCmd(cmd) 846 | } 847 | 848 | /* 849 | Description: 850 | VerifyChainBlocks requests the server to verify the block chain database 851 | using the passed check level and number of blocks to verify. 852 | 853 | The check level controls how thorough the verification is with higher numbers 854 | increasing the amount of checks done as consequently how long the 855 | verification takes. 856 | 857 | The number of blocks refers to the number of blocks from the end of the 858 | current longest chain. 859 | 860 | See VerifyChain and VerifyChainLevel to use defaults. 861 | * Author: architect.bian 862 | * Date: 2018/09/17 20:59 863 | */ 864 | func (c *Client) VerifyChainBlocks(checkLevel, numBlocks int32) (bool, error) { 865 | return c.VerifyChainBlocksAsync(checkLevel, numBlocks).Receive() 866 | } 867 | -------------------------------------------------------------------------------- /client/ClientControl.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/futures" 5 | ) 6 | 7 | /* 8 | Description: 9 | GetMemoryInfoAsync returns an instance of a type that can be used to get 10 | the result of the RPC at some future time by invoking the Receive function on 11 | the returned instance. 12 | 13 | See GetMemoryInfo for more details. 14 | * Author: architect.bian 15 | * Date: 2018/09/14 13:18 16 | */ 17 | func (c *Client) GetMemoryInfoAsync(model string) futures.FutureResult { 18 | cmd := NewCommand("getmemoryinfo", model) 19 | return c.sendCmd(cmd) 20 | } 21 | 22 | /* 23 | Description: 24 | GetMemoryInfo returns general statistics about memory usage in the daemon. 25 | * Author: architect.bian 26 | * Date: 2018/09/14 13:15 27 | */ 28 | func (c *Client) GetMemoryInfo() (*interface{}, error) { 29 | return c.GetMemoryInfoAsync("stats").Receive() 30 | } 31 | 32 | /* 33 | Description: 34 | GetMemoryInfo4MallocInfo returns an XML string describing 35 | low-level heap state (only available if compiled with glibc 2.10+) 36 | * Author: architect.bian 37 | * Date: 2018/09/14 13:15 38 | */ 39 | func (c *Client) GetMemoryInfo4MallocInfo() (*string, error) { 40 | return futures.FutureString(c.GetMemoryInfoAsync("mallocinfo")).Receive() 41 | } 42 | 43 | /* 44 | Description: 45 | HelpAsync returns an instance of a type that can be used to get 46 | the result of the RPC at some future time by invoking the Receive function on 47 | the returned instance. 48 | 49 | See Help for more details. 50 | * Author: architect.bian 51 | * Date: 2018/10/15 10:40 52 | */ 53 | func (c *Client) HelpAsync() futures.FutureString { 54 | cmd := NewCommand("help") 55 | return c.sendCmd(cmd) 56 | } 57 | 58 | /* 59 | Description: 60 | Help List all commands, or get help for a specified command. 61 | * Author: architect.bian 62 | * Date: 2018/10/15 10:40 63 | */ 64 | func (c *Client) Help() (*string, error) { 65 | return c.HelpAsync().Receive() 66 | } 67 | 68 | /* 69 | Description: 70 | StopAsync returns an instance of a type that can be used to get 71 | the result of the RPC at some future time by invoking the Receive function on 72 | the returned instance. 73 | 74 | See Stop for more details. 75 | * Author: architect.bian 76 | * Date: 2018/10/15 10:38 77 | */ 78 | func (c *Client) StopAsync() futures.FutureResult { 79 | cmd := NewCommand("stop") 80 | return c.sendCmd(cmd) 81 | } 82 | 83 | /* 84 | Description: 85 | Stop Bitcoin server. 86 | * Author: architect.bian 87 | * Date: 2018/10/15 10:38 88 | */ 89 | func (c *Client) Stop() (error) { 90 | _, err := c.StopAsync().Receive() 91 | if err != nil { 92 | return err 93 | } 94 | return nil 95 | } 96 | 97 | /* 98 | Description: 99 | GetUptimeAsync returns an instance of a type that can be used to get 100 | the result of the RPC at some future time by invoking the Receive function on 101 | the returned instance. 102 | 103 | See GetUptime for more details. 104 | * Author: architect.bian 105 | * Date: 2018/10/15 10:36 106 | */ 107 | func (c *Client) UptimeAsync() futures.FutureInt32 { 108 | cmd := NewCommand("uptime") 109 | return c.sendCmd(cmd) 110 | } 111 | 112 | /* 113 | Description: 114 | Uptime Returns the total uptime of the server. 115 | * Author: architect.bian 116 | * Date: 2018/10/15 10:36 117 | */ 118 | func (c *Client) Uptime() (int32, error) { 119 | return c.UptimeAsync().Receive() 120 | } 121 | -------------------------------------------------------------------------------- /client/ClientGenerating.go: -------------------------------------------------------------------------------- 1 | package client 2 | -------------------------------------------------------------------------------- /client/ClientMining.go: -------------------------------------------------------------------------------- 1 | package client 2 | -------------------------------------------------------------------------------- /client/ClientNetwork.go: -------------------------------------------------------------------------------- 1 | package client 2 | -------------------------------------------------------------------------------- /client/ClientRawTransactions.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/futures" 5 | ) 6 | 7 | /* 8 | Description: 9 | CombinePSBT returns an instance of a type that can be used to get 10 | the result of the RPC at some future time by invoking the Receive function on 11 | the returned instance. 12 | 13 | See CombinePSBT for more details. 14 | * Author: architect.bian 15 | * Date: 2018/10/15 20:09 16 | */ 17 | func (c *Client) CombinePSBTAsync(txHexs []string) futures.FutureResult { 18 | cmd := NewCommand("combinepsbt", txHexs) 19 | return c.sendCmd(cmd) 20 | } 21 | 22 | /* 23 | Description: 24 | Combine multiple partially signed Bitcoin transactions into one transaction. 25 | Implements the Combiner role. 26 | * Author: architect.bian 27 | * Date: 2018/10/15 20:18 28 | */ 29 | func (c *Client) CombinePSBT(txHexs []string) (*interface{}, error) { 30 | return c.CombinePSBTAsync(txHexs).Receive() 31 | } 32 | 33 | /* 34 | Description: 35 | CombineRawTransactionAsync returns an instance of a type that can be used to get 36 | the result of the RPC at some future time by invoking the Receive function on 37 | the returned instance. 38 | 39 | See CombineRawTransaction for more details. 40 | * Author: architect.bian 41 | * Date: 2018/10/15 20:09 42 | */ 43 | func (c *Client) CombineRawTransactionAsync(txs []string) futures.FutureResult { 44 | cmd := NewCommand("combinerawtransaction", txs) 45 | return c.sendCmd(cmd) 46 | } 47 | 48 | /* 49 | Description: 50 | Combine multiple partially signed transactions into one transaction. 51 | The combined transaction may be another partially signed transaction or a 52 | fully signed transaction. 53 | * Author: architect.bian 54 | * Date: 2018/10/15 20:18 55 | */ 56 | func (c *Client) CombineRawTransaction(txs []string) (*interface{}, error) { 57 | return c.CombineRawTransactionAsync(txs).Receive() 58 | } 59 | 60 | /* 61 | Description: 62 | ConvertToPSBTAsync returns an instance of a type that can be used to get 63 | the result of the RPC at some future time by invoking the Receive function on 64 | the returned instance. 65 | 66 | See ConvertToPSBT for more details. 67 | * Author: architect.bian 68 | * Date: 2018/10/15 20:09 69 | */ 70 | func (c *Client) ConvertToPSBTAsync(txHex string, permitsigdata bool, iswitness bool) futures.FutureString { 71 | cmd := NewCommand("converttopsbt", txHex, permitsigdata, iswitness) 72 | return c.sendCmd(cmd) 73 | } 74 | 75 | /* 76 | Description: 77 | Converts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction 78 | createpsbt and walletcreatefundedpsbt should be used for new applications. 79 | * Author: architect.bian 80 | * Date: 2018/10/15 20:22 81 | */ 82 | func (c *Client) ConvertToPSBT(txHex string) (*string, error) { 83 | cmd := NewCommand("converttopsbt", txHex) 84 | return futures.FutureString(c.sendCmd(cmd)).Receive() 85 | } 86 | 87 | /* 88 | Description: 89 | Converts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction 90 | createpsbt and walletcreatefundedpsbt should be used for new applications. 91 | * Author: architect.bian 92 | * Date: 2018/10/15 20:23 93 | */ 94 | func (c *Client) ConvertToPSBTEntire(txHex string, permitsigdata bool, iswitness bool) (*string, error) { 95 | return c.ConvertToPSBTAsync(txHex, permitsigdata, iswitness).Receive() 96 | } 97 | 98 | /* 99 | Description: 100 | CreatepSBTAsync returns an instance of a type that can be used to get 101 | the result of the RPC at some future time by invoking the Receive function on 102 | the returned instance. 103 | 104 | See CreatepSBT for more details. 105 | * Author: architect.bian 106 | * Date: 2018/10/15 20:09 107 | */ 108 | func (c *Client) CreatepSBTAsync(inputs []map[string]interface{}, outputs []map[string]interface{}, locktime int32, replaceable bool) futures.FutureString { 109 | cmd := NewCommand("createpsbt", inputs, outputs, locktime, replaceable) 110 | return c.sendCmd(cmd) 111 | } 112 | 113 | /* 114 | Description: 115 | Creates a transaction in the Partially Signed Transaction format. 116 | Implements the Creator role. 117 | * Author: architect.bian 118 | * Date: 2018/10/15 20:27 119 | */ 120 | func (c *Client) CreatepSBT(inputs []map[string]interface{}, outputs []map[string]interface{}, locktime int32, replaceable bool) (*string, error) { 121 | return c.CreatepSBTAsync(inputs, outputs, locktime, replaceable).Receive() 122 | } 123 | 124 | /* 125 | Description: 126 | CreateRawTransactionAsync returns an instance of a type that can be used to get 127 | the result of the RPC at some future time by invoking the Receive function on 128 | the returned instance. 129 | 130 | See CreateRawTransaction for more details. 131 | * Author: architect.bian 132 | * Date: 2018/10/15 20:09 133 | */ 134 | func (c *Client) CreateRawTransactionAsync(inputs []map[string]interface{}, outputs []map[string]interface{}, locktime int32, replaceable bool) futures.FutureString { 135 | cmd := NewCommand("createrawtransaction", inputs, outputs, locktime, replaceable) 136 | return c.sendCmd(cmd) 137 | } 138 | 139 | /* 140 | Description: 141 | Create a transaction spending the given inputs and creating new outputs. 142 | Outputs can be addresses or data. 143 | Returns hex-encoded raw transaction. 144 | Note that the transaction's inputs are not signed, and 145 | it is not stored in the wallet or transmitted to the network. 146 | * Author: architect.bian 147 | * Date: 2018/10/15 20:31 148 | */ 149 | func (c *Client) CreateRawTransaction(inputs []map[string]interface{}, outputs []map[string]interface{}, 150 | locktime int32, replaceable bool) (*string, error) { 151 | return c.CreateRawTransactionAsync(inputs, outputs, locktime, replaceable).Receive() 152 | } 153 | 154 | /* 155 | Description: 156 | DecodePSBTAsync returns an instance of a type that can be used to get 157 | the result of the RPC at some future time by invoking the Receive function on 158 | the returned instance. 159 | 160 | See DecodePSBT for more details. 161 | * Author: architect.bian 162 | * Date: 2018/10/15 20:09 163 | */ 164 | func (c *Client) DecodePSBTAsync(psbtBase64 string) futures.FutureResult { 165 | cmd := NewCommand("decodepsbt", psbtBase64) 166 | return c.sendCmd(cmd) 167 | } 168 | 169 | /* 170 | Description: 171 | Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction. 172 | * Author: architect.bian 173 | * Date: 2018/10/15 20:32 174 | */ 175 | func (c *Client) DecodePSBT(psbtBase64 string) (*interface{}, error) { 176 | return c.DecodePSBTAsync(psbtBase64).Receive() 177 | } 178 | 179 | /* 180 | Description: 181 | DecodeRawTransactionAsync returns an instance of a type that can be used to get 182 | the result of the RPC at some future time by invoking the Receive function on 183 | the returned instance. 184 | 185 | See DecodeRawTransaction for more details. 186 | * Author: architect.bian 187 | * Date: 2018/10/15 20:09 188 | */ 189 | func (c *Client) DecodeRawTransactionAsync(txHex string, isWitness bool) futures.FutureResult { 190 | cmd := NewCommand("decoderawtransaction", txHex, isWitness) 191 | return c.sendCmd(cmd) 192 | } 193 | 194 | /* 195 | Description: 196 | Return a JSON object representing the serialized, hex-encoded transaction. 197 | * Author: architect.bian 198 | * Date: 2018/10/15 20:34 199 | */ 200 | func (c *Client) DecodeRawTransaction(txHex string, isWitness bool) (*interface{}, error) { 201 | return c.DecodeRawTransactionAsync(txHex, isWitness).Receive() 202 | } 203 | 204 | /* 205 | Description: 206 | DecodeScriptAsync returns an instance of a type that can be used to get 207 | the result of the RPC at some future time by invoking the Receive function on 208 | the returned instance. 209 | 210 | See DecodeScript for more details. 211 | * Author: architect.bian 212 | * Date: 2018/10/15 20:09 213 | */ 214 | func (c *Client) DecodeScriptAsync(scriptHex string) futures.FutureResult { 215 | cmd := NewCommand("decodescript", scriptHex) 216 | return c.sendCmd(cmd) 217 | } 218 | 219 | /* 220 | Description: 221 | Decode a hex-encoded script. 222 | * Author: architect.bian 223 | * Date: 2018/10/15 20:36 224 | */ 225 | func (c *Client) DecodeScript(scriptHex string) (*interface{}, error) { 226 | return c.DecodeScriptAsync(scriptHex).Receive() 227 | } 228 | 229 | /* 230 | Description: 231 | FinalizePSBTAsync returns an instance of a type that can be used to get 232 | the result of the RPC at some future time by invoking the Receive function on 233 | the returned instance. 234 | 235 | See FinalizePSBT for more details. 236 | * Author: architect.bian 237 | * Date: 2018/10/15 20:09 238 | */ 239 | func (c *Client) FinalizePSBTAsync(psbt string, extract bool) futures.FutureResult { 240 | cmd := NewCommand("finalizepsbt", psbt, extract) 241 | return c.sendCmd(cmd) 242 | } 243 | 244 | /* 245 | Description: 246 | Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a 247 | network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be 248 | created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete. 249 | Implements the Finalizer and Extractor roles. 250 | * Author: architect.bian 251 | * Date: 2018/10/15 20:38 252 | */ 253 | func (c *Client) FinalizePSBT(psbt string, extract bool) (*interface{}, error) { 254 | return c.FinalizePSBTAsync(psbt, extract).Receive() 255 | } 256 | 257 | /* 258 | Description: 259 | FundRawTransactionAsync returns an instance of a type that can be used to get 260 | the result of the RPC at some future time by invoking the Receive function on 261 | the returned instance. 262 | 263 | See FundRawTransaction for more details. 264 | * Author: architect.bian 265 | * Date: 2018/10/15 20:09 266 | */ 267 | func (c *Client) FundRawTransactionAsync(txHex string, options map[string]interface{}, iswitness bool) futures.FutureResult { 268 | cmd := NewCommand("fundrawtransaction", txHex, options, iswitness) 269 | return c.sendCmd(cmd) 270 | } 271 | 272 | /* 273 | Description: 274 | Add inputs to a transaction until it has enough in value to meet its out value. 275 | This will not modify existing inputs, and will add at most one change output to the outputs. 276 | No existing outputs will be modified unless "subtractFeeFromOutputs" is specified. 277 | Note that inputs which were signed may need to be resigned after completion since in/outputs have been added. 278 | The inputs added will not be signed, use signrawtransaction for that. 279 | Note that all existing inputs must have their previous output transaction be in the wallet. 280 | Note that all inputs selected must be of standard form and P2SH scripts must be 281 | in the wallet using importaddress or addmultisigaddress (to calculate fees). 282 | You can see whether this is the case by checking the "solvable" field in the listunspent output. 283 | Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only 284 | * Author: architect.bian 285 | * Date: 2018/10/15 20:36 286 | */ 287 | func (c *Client) FundRawTransaction(txHex string, options map[string]interface{}, iswitness bool) (*interface{}, error) { 288 | return c.FundRawTransactionAsync(txHex, options, iswitness).Receive() 289 | } 290 | 291 | /* 292 | Description: 293 | GetRawTransactionAsync returns an instance of a type that can be used to get 294 | the result of the RPC at some future time by invoking the Receive function on 295 | the returned instance. 296 | 297 | See GetRawTransaction for more details. 298 | * Author: architect.bian 299 | * Date: 2018/10/15 20:09 300 | */ 301 | func (c *Client) GetRawTransactionAsync(txid string, verbose bool, blockhash string) futures.FutureResult { 302 | cmd := NewCommand("getrawtransaction", txid, verbose) 303 | if blockhash != "" { 304 | cmd.AddArgs(blockhash) 305 | } 306 | return c.sendCmd(cmd) 307 | } 308 | 309 | /* 310 | Description: 311 | NOTE: By default this function only works for mempool transactions. If the -txindex option is 312 | enabled, it also works for blockchain transactions. If the block which contains the transaction 313 | is known, its hash can be provided even for nodes without -txindex. Note that if a blockhash is 314 | provided, only that block will be searched and if the transaction is in the mempool or other 315 | blocks, or if this node does not have the given block available, the transaction will not be found. 316 | DEPRECATED: for now, it also works for transactions with unspent outputs. 317 | 318 | Return the raw transaction data. 319 | * Author: architect.bian 320 | * Date: 2018/10/15 20:41 321 | */ 322 | func (c *Client) GetRawTransaction(txid string, blockhash string) (*string, error) { 323 | result, err := futures.FutureString(c.GetRawTransactionAsync(txid, false, blockhash)).Receive() 324 | if err != nil { 325 | return nil, err 326 | } 327 | return result, nil 328 | } 329 | 330 | /* 331 | Description: 332 | Return the verbose raw transaction data. 333 | * Author: architect.bian 334 | * Date: 2018/10/15 20:42 335 | */ 336 | func (c *Client) GetRawTransactionVerbose(txid string, blockhash string) (*interface{}, error) { 337 | return c.GetRawTransactionAsync(txid, true, blockhash).Receive() 338 | } 339 | 340 | /* 341 | Description: 342 | SendRawTransactionAsync returns an instance of a type that can be used to get 343 | the result of the RPC at some future time by invoking the Receive function on 344 | the returned instance. 345 | 346 | See SendRawTransaction for more details. 347 | * Author: architect.bian 348 | * Date: 2018/10/15 20:09 349 | */ 350 | func (c *Client) SendRawTransactionAsync(txHex string, allowhighfees bool) futures.FutureResult { 351 | cmd := NewCommand("sendrawtransaction", txHex, allowhighfees) 352 | return c.sendCmd(cmd) 353 | } 354 | 355 | /* 356 | Description: 357 | Submits raw transaction (serialized, hex-encoded) to local node and network. 358 | 359 | Also see createrawtransaction and signrawtransaction calls. 360 | * Author: architect.bian 361 | * Date: 2018/10/15 20:54 362 | */ 363 | func (c *Client) SendRawTransaction(txHex string, allowhighfees bool) (*interface{}, error) { 364 | return c.SendRawTransactionAsync(txHex, allowhighfees).Receive() 365 | } 366 | 367 | /* 368 | Description: 369 | SignRawTransactionWithKeyAsync returns an instance of a type that can be used to get 370 | the result of the RPC at some future time by invoking the Receive function on 371 | the returned instance. 372 | 373 | See SignRawTransactionWithKey for more details. 374 | * Author: architect.bian 375 | * Date: 2018/10/15 20:09 376 | */ 377 | func (c *Client) SignRawTransactionWithKeyAsync(txHex string, privkeys []string, prevtxs interface{}, sighashtype string) futures.FutureResult { 378 | cmd := NewCommand("signrawtransactionwithkey", txHex, privkeys, prevtxs, sighashtype) 379 | return c.sendCmd(cmd) 380 | } 381 | 382 | /* 383 | Description: 384 | Sign inputs for raw transaction (serialized, hex-encoded). 385 | The second argument is an array of base58-encoded private 386 | keys that will be the only keys used to sign the transaction. 387 | The third optional argument (may be null) is an array of previous transaction outputs that 388 | this transaction depends on but may not yet be in the block chain. 389 | * Author: architect.bian 390 | * Date: 2018/10/15 21:11 391 | */ 392 | func (c *Client) SignRawTransactionWithKey(txHex string, privkeys []string) (*interface{}, error) { 393 | return c.SignRawTransactionWithKeyEntire(txHex, privkeys, nil, "ALL") 394 | } 395 | 396 | /* 397 | Description: 398 | Sign inputs for raw transaction (serialized, hex-encoded). 399 | The second argument is an array of base58-encoded private 400 | keys that will be the only keys used to sign the transaction. 401 | The third optional argument (may be null) is an array of previous transaction outputs that 402 | this transaction depends on but may not yet be in the block chain. 403 | * Author: architect.bian 404 | * Date: 2018/10/15 21:11 405 | */ 406 | func (c *Client) SignRawTransactionWithKeyEntire(txHex string, privkeys []string, prevtxs interface{}, sighashtype string) (*interface{}, error) { 407 | return c.SignRawTransactionWithKeyAsync(txHex, privkeys, prevtxs, sighashtype).Receive() 408 | } 409 | 410 | /* 411 | Description: 412 | TestMempoolAcceptAsync returns an instance of a type that can be used to get 413 | the result of the RPC at some future time by invoking the Receive function on 414 | the returned instance. 415 | 416 | See TestMempoolAccept for more details. 417 | * Author: architect.bian 418 | * Date: 2018/10/15 20:09 419 | */ 420 | func (c *Client) TestMempoolAcceptAsync(rawTXs []string, allowHighFees bool) futures.FutureResult { 421 | cmd := NewCommand("testmempoolaccept", rawTXs, allowHighFees) 422 | return c.sendCmd(cmd) 423 | } 424 | 425 | /* 426 | Description: 427 | Returns if raw transaction (serialized, hex-encoded) would be accepted by mempool. 428 | * Author: architect.bian 429 | * Date: 2018/10/15 23:13 430 | */ 431 | func (c *Client) TestMempoolAccept(rawTXs []string, allowHighFees bool) (*interface{}, error) { 432 | return c.TestMempoolAcceptAsync(rawTXs, allowHighFees).Receive() 433 | } 434 | -------------------------------------------------------------------------------- /client/ClientUtil.go: -------------------------------------------------------------------------------- 1 | package client 2 | -------------------------------------------------------------------------------- /client/Command.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | NewCommand create a new command with cmd and args. 11 | arguments: 12 | name, the command name. 13 | args, the arguments for current command 14 | * Author: architect.bian 15 | * Date: 2018/10/06 18:26 16 | */ 17 | func NewCommand(name string, args ...interface{}) *Command { 18 | return &Command{ 19 | name: name, 20 | args: args, 21 | } 22 | } 23 | 24 | /* 25 | Description: 26 | MarshalCmdToJRPC marshals the passed command to a JSON-RPC request byte slice that 27 | is suitable for transmission to an RPC server. The provided command type 28 | must be a registered type. All commands provided by this package are 29 | registered by default. 30 | * Author: architect.bian 31 | * Date: 2018/08/26 19:14 32 | */ 33 | func MarshalCmdToJRPC(id uint64, cmd *Command) ([]byte, error) { 34 | // Generate and marshal the final JSON-RPC request. 35 | jsonRPC, err := base.NewJRPC(id, cmd.name, cmd.args) 36 | if err != nil { 37 | return nil, err 38 | } 39 | return json.Marshal(jsonRPC) 40 | } 41 | 42 | /* 43 | Description: 44 | Command represents a rpc command 45 | * Author: architect.bian 46 | * Date: 2018/10/06 18:28 47 | */ 48 | type Command struct { 49 | name string 50 | args []interface{} 51 | } 52 | 53 | func (c *Command) AddArgs(args ...interface{}) { 54 | c.args = append(c.args[:], args...) 55 | } 56 | 57 | func (c *Command) AddJsonArgs(args ...interface{}) error { 58 | slice := make([]interface{}, 0) 59 | for _, item := range args { 60 | bytes, err := json.Marshal(item) 61 | if err != nil { 62 | return nil 63 | } 64 | slice = append(slice, string(bytes)) 65 | } 66 | 67 | c.args = append(c.args[:], slice...) 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /client/Command_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Description: 3 | Tester for Command.go 4 | Usage: go test -v Command_test.go Command.go 5 | * Author: architect.bian 6 | * Date: 2018/10/06 19:09 7 | */ 8 | package client 9 | 10 | import ( 11 | "testing" 12 | "fmt" 13 | ) 14 | 15 | func TestNewCommand(t *testing.T) { 16 | cmd := NewCommand("getblockchaininfo") 17 | fmt.Println(cmd) 18 | cmd = NewCommand("gettxout", "68e84c5caf7adc40d71e12bfefb8715934c2a7693ba8d4abf1664d8af327bf69", 0, true) 19 | fmt.Println(cmd) 20 | } 21 | 22 | func TestAddArgs(t *testing.T) { 23 | cmd := NewCommand("getblockchaininfo") 24 | fmt.Println(cmd) 25 | cmd.AddArgs("68e84c5caf7adc40d71e12bfefb8715934c2a7693ba8d4abf1664d8af327bf69", 0, true) 26 | fmt.Println(cmd) 27 | } 28 | 29 | func TestAddJsonArgs(t *testing.T) { 30 | cmd := NewCommand("AddJsonArgs") 31 | fmt.Println(cmd) 32 | a1 := []string {"68e84c5caf7adc40d71e12bfefb8715934c2a7693ba8d4abf1664d8af327bf69"} 33 | a2 := []string {"0", "true"} 34 | cmd.AddJsonArgs(a1, a2) 35 | fmt.Println(cmd) 36 | } -------------------------------------------------------------------------------- /client/Config.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | const ( 4 | // requestsChanBufferSize is the number of elements the HTTP POST send 5 | // channel can queue before blocking. 6 | requestsChanBufferSize = 100 7 | ) 8 | 9 | /* 10 | Description: 11 | ConnConfig describes the connection configuration parameters for the client. 12 | * Author: architect.bian 13 | * Date: 2018/08/23 15:32 14 | */ 15 | type Config struct { 16 | // Host is the IP address and port of the RPC server you want to connect to. 17 | Host string 18 | 19 | // User is the username to use to authenticate to the RPC server. 20 | User string 21 | 22 | // Pass is the passphrase to use to authenticate to the RPC server. 23 | Pass string 24 | 25 | // EnableTLS specifies whether transport layer security should be disabled. 26 | // It is recommended to always use TLS if the RPC server 27 | // supports it as otherwise your username and password is sent across the wire in cleartext. 28 | EnableTLS bool 29 | 30 | // Certificates are the bytes for a PEM-encoded certificate chain used 31 | // for the TLS connection. It only has effect if the EnableTLS parameter is true. 32 | Certificates []byte 33 | 34 | // Proxy specifies to connect through a SOCKS 5 proxy server. It may 35 | // be an empty string if a proxy is not required. 36 | Proxy string 37 | 38 | // ProxyUser is an optional username to use for the proxy server if it 39 | // requires authentication. It has no effect if the Proxy parameter is not set. 40 | ProxyUser string 41 | 42 | // ProxyPass is an optional password to use for the proxy server if it 43 | // requires authentication. It has no effect if the Proxy parameter is not set. 44 | ProxyPass string 45 | 46 | // DisableAutoReconnect specifies the client should not automatically 47 | // try to reconnect to the server when it has been disconnected. 48 | DisableAutoReconnect bool 49 | 50 | // HTTPPostMode instructs the client to run using multiple independent 51 | // connections issuing HTTP POST requests instead of using the default 52 | // of websockets. Websockets are generally preferred as some of the 53 | // features of the client such notifications only work with websockets, 54 | // however, not all servers support the websocket extensions, so this 55 | // flag can be set to true to use basic HTTP POST requests instead. 56 | //HTTPPostMode bool 57 | } -------------------------------------------------------------------------------- /client/Errors.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import "errors" 4 | 5 | var ( 6 | // ErrClientShutdown is an error to describe the condition where the 7 | // client is either already shutdown, or in the process of shutting 8 | // down. Any outstanding futures when a client shutdown occurs will 9 | // return this error as will any new requests. 10 | ErrClientShutdown = errors.New("the client has been shutdown") 11 | 12 | ) 13 | -------------------------------------------------------------------------------- /conf/log.json: -------------------------------------------------------------------------------- 1 | { 2 | "level": "debug", 3 | "outputPaths": ["stdout", "debug.log"], 4 | "errorOutputPaths": ["stderr"] 5 | } -------------------------------------------------------------------------------- /conf/zap.json: -------------------------------------------------------------------------------- 1 | { 2 | "encoding": "json", 3 | "initialFields": {}, 4 | "encoderConfig": { 5 | "messageKey": "message", 6 | "levelKey": "level", 7 | "levelEncoder": "lowercase" 8 | } 9 | } -------------------------------------------------------------------------------- /documents/conventions.md: -------------------------------------------------------------------------------- 1 | Conventions 2 | =============== 3 | 4 | 5 | **Table of Contents** 6 | -------------------------------------------------------------------------------- /examples/demos/BlockChainTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/gobasis/log" 5 | "github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | a demo test of GetBlockCount, Get the current block count. 11 | * Author: architect.bian 12 | * Date: 2018/09/02 18:24 13 | */ 14 | func GetBlockCountTest() { 15 | blockCount, err := cli.GetBlockCount() 16 | if err != nil { 17 | log.Fatal("", "error", err) 18 | } 19 | log.Info("GetBlockCount", "count", blockCount) 20 | } 21 | 22 | /* 23 | Description: 24 | a demo test of GetBestBlockHash, Get the current best block hash. 25 | * Author: architect.bian 26 | * Date: 2018/09/14 13:13 27 | */ 28 | func GetBestBlockHashTest() { 29 | hash, err := cli.GetBestBlockHash() 30 | if err != nil { 31 | log.Fatal("", "error", err) 32 | } 33 | log.Info("GetBestBlockHash", "hash", hash) 34 | } 35 | 36 | /* 37 | Description: 38 | a demo test of GetBlockHash, Get the height block hash of current best chain. 39 | * Author: architect.bian 40 | * Date: 2018/09/14 13:13 41 | */ 42 | func GetBlockHashTest() { 43 | hash, err := cli.GetBlockHash(1) 44 | if err != nil { 45 | log.Fatal("", "error", err) 46 | } 47 | log.Info("GetBlockHash", "hash", hash) 48 | } 49 | 50 | /* 51 | Description: 52 | a demo test of GetBlockHeader, Get the special blockheader data structure. 53 | * Author: architect.bian 54 | * Date: 2018/09/14 13:13 55 | */ 56 | func GetBlockHeaderBytesTest() { 57 | hash, err := cli.GetBlockHash(1) 58 | if err != nil { 59 | log.Fatal("", "error", err) 60 | } 61 | log.Info("GetBlockHash", "hash", hash) 62 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 63 | header, err := cli.GetBlockHeaderBytes(hash) 64 | if err != nil { 65 | log.Error("", "error", err) 66 | panic(err) 67 | } 68 | log.Info("GetBlockHeader", "header", string(*header)) 69 | } 70 | 71 | /* 72 | Description: 73 | a demo test of GetBlockHeader, Get the special blockheader data structure. 74 | * Author: architect.bian 75 | * Date: 2018/09/14 13:13 76 | */ 77 | func GetBlockHeaderTest() { 78 | hash, err := cli.GetBlockHash(1) 79 | if err != nil { 80 | log.Fatal("", "error", err) 81 | } 82 | log.Info("GetBlockHash", "hash", hash) 83 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 84 | header, err := cli.GetBlockHeader(hash) 85 | if err != nil { 86 | log.Error("", "error", err) 87 | panic(err) 88 | } 89 | log.Info("GetBlockHeader", "header", header) 90 | } 91 | 92 | /* 93 | Description: 94 | a demo test of GetBlockChainInfo, Get the blockchain state info. 95 | * Author: architect.bian 96 | * Date: 2018/09/14 13:13 97 | */ 98 | func GetBlockChainInfoTest() { 99 | info, err := cli.GetBlockChainInfo() 100 | if err != nil { 101 | log.Error("", "error", err) 102 | panic(err) 103 | } 104 | log.Info("GetBlockChainInfo", "info", info) 105 | } 106 | 107 | /* 108 | Description: 109 | a demo test of GetBlock, Get the special block data structure. 110 | * Author: architect.bian 111 | * Date: 2018/09/14 13:13 112 | */ 113 | func GetBlockBytesTest() { 114 | hash, err := cli.GetBlockHash(1) 115 | if err != nil { 116 | log.Fatal("", "error", err) 117 | } 118 | log.Info("GetBlockHash", "hash", hash) 119 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 120 | block, err := cli.GetBlockBytes(hash) 121 | if err != nil { 122 | log.Error("", "error", err) 123 | panic(err) 124 | } 125 | log.Info("GetBlockBytes", "block", string(*block)) 126 | } 127 | 128 | /* 129 | Description: 130 | a demo test of GetBlock, Get the special block data structure. 131 | * Author: architect.bian 132 | * Date: 2018/09/14 13:13 133 | */ 134 | func GetBlockTest() { 135 | hash, err := cli.GetBlockHash(1) 136 | if err != nil { 137 | log.Fatal("", "error", err) 138 | } 139 | log.Info("GetBlockHash", "hash", hash) 140 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 141 | block, err := cli.GetBlock(hash) 142 | if err != nil { 143 | log.Error("", "error", err) 144 | panic(err) 145 | } 146 | log.Info("GetBlock", "block", block) 147 | } 148 | 149 | /* 150 | Description: 151 | a demo test of GetBlockVerbose, Get the special block data structure. 152 | * Author: architect.bian 153 | * Date: 2018/09/14 13:13 154 | */ 155 | func GetBlockVerboseTXTest() { 156 | hash, err := cli.GetBlockHash(1) 157 | if err != nil { 158 | log.Fatal("", "error", err) 159 | } 160 | log.Info("GetBlockHash", "hash", hash) 161 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 162 | block, err := cli.GetBlockVerboseTX(hash) 163 | if err != nil { 164 | log.Error("", "error", err) 165 | panic(err) 166 | } 167 | log.Info("GetBlockVerboseTX", "block", block) 168 | } 169 | 170 | /* 171 | Description: 172 | a demo test of GetBlockStats. 173 | * Author: architect.bian 174 | * Date: 2018/10/10 10:45 175 | */ 176 | func GetBlockStatsTest() { 177 | hash, err := cli.GetBlockHash(1) 178 | if err != nil { 179 | log.Fatal("", "error", err) 180 | } 181 | log.Info("GetBlockHash", "hash", hash) 182 | result, err := cli.GetBlockStats(hash) 183 | if err != nil { 184 | log.Error("", "error", err) 185 | panic(err) 186 | } 187 | log.Info("GetBlockStats", "result", result) 188 | result4Height, err := cli.GetBlockStats(1) 189 | if err != nil { 190 | log.Error("", "error", err) 191 | panic(err) 192 | } 193 | log.Info("GetBlockStats", "result", result4Height) 194 | } 195 | 196 | /* 197 | Description: 198 | a demo test of GetChainTips, Return information about all known tips in the block tree, 199 | including the main chain as well as orphaned branches. 200 | * Author: architect.bian 201 | * Date: 2018/10/10 10:45 202 | */ 203 | func GetChainTipsTest() { 204 | result, err := cli.GetChainTips() 205 | if err != nil { 206 | log.Error("", "error", err) 207 | panic(err) 208 | } 209 | log.Info("GetChainTips", "result", result) 210 | } 211 | 212 | /* 213 | Description: 214 | GetChainTXStatsTest a demo test of GetChainTXStats 215 | * Author: architect.bian 216 | * Date: 2018/10/11 10:17 217 | */ 218 | func GetChainTXStatsTest() { 219 | result, err := cli.GetChainTXStats() 220 | if err != nil { 221 | log.Error("", "error", err) 222 | panic(err) 223 | } 224 | log.Info("GetChainTXStats", "result", result) 225 | } 226 | 227 | /* 228 | Description: 229 | GetChainTXStatsEntireTest a demo test of GetChainTXStatsEntire 230 | * Author: architect.bian 231 | * Date: 2018/10/11 10:18 232 | */ 233 | func GetChainTXStatsEntireTest() { 234 | hash, err := cli.GetBlockHash(105) 235 | if err != nil { 236 | log.Fatal("", "error", err) 237 | } 238 | log.Info("GetBlockHash", "hash", hash) 239 | result, err := cli.GetChainTXStatsEntire(100, hash) 240 | if err != nil { 241 | log.Error("", "error", err) 242 | panic(err) 243 | } 244 | log.Info("GetChainTXStats", "result", result) 245 | } 246 | 247 | /* 248 | Description: 249 | a demo test of GetDifficulty, Get the current difficulty for mining difficulty target. 250 | * Author: architect.bian 251 | * Date: 2018/09/14 13:13 252 | */ 253 | func GetDifficultyTest() { 254 | hash, err := cli.GetDifficulty() 255 | if err != nil { 256 | log.Fatal("", "error", err) 257 | } 258 | log.Info("GetDifficulty", "difficulty", hash) 259 | } 260 | 261 | /* 262 | Description: 263 | GetMempoolAncestorsTest a demo test of GetMempoolAncestors 264 | * Author: architect.bian 265 | * Date: 2018/10/11 11:40 266 | */ 267 | func GetMempoolAncestorsTest() { 268 | hashs, err := cli.GetRawMempool() 269 | if err != nil { 270 | log.Fatal("", "error", err) 271 | } 272 | for _, h := range hashs { 273 | result, err := cli.GetMempoolAncestors(*h) 274 | if err != nil { 275 | log.Error("", "error", err) 276 | panic(err) 277 | } 278 | log.Info("GetMempoolAncestors", "result", result) 279 | break 280 | } 281 | } 282 | 283 | /* 284 | Description: 285 | GetMempoolAncestorsVerboseTest a demo test of GetMempoolAncestorsVerbose 286 | * Author: architect.bian 287 | * Date: 2018/10/11 11:41 288 | */ 289 | func GetMempoolAncestorsVerboseTest() { 290 | hashs, err := cli.GetRawMempool() 291 | if err != nil { 292 | log.Fatal("", "error", err) 293 | } 294 | for _, h := range hashs { 295 | result, err := cli.GetMempoolAncestorsVerbose(*h) 296 | if err != nil { 297 | log.Error("", "error", err) 298 | panic(err) 299 | } 300 | log.Info("GetMempoolAncestorsVerbose", "result", result) 301 | break 302 | } 303 | } 304 | 305 | /* 306 | Description: 307 | GetMempoolDescendantsTest a demo test of GetMempoolDescendants 308 | * Author: architect.bian 309 | * Date: 2018/10/11 11:44 310 | */ 311 | func GetMempoolDescendantsTest() { 312 | hashs, err := cli.GetRawMempool() 313 | if err != nil { 314 | log.Fatal("", "error", err) 315 | } 316 | for _, h := range hashs { 317 | result, err := cli.GetMempoolDescendants(*h) 318 | if err != nil { 319 | log.Error("", "error", err) 320 | panic(err) 321 | } 322 | log.Info("GetMempoolDescendants", "result", result) 323 | break 324 | } 325 | } 326 | 327 | /* 328 | Description: 329 | GetMempoolDescendantsVerboseTest a demo test of GetMempoolDescendantsVerbose 330 | * Author: architect.bian 331 | * Date: 2018/10/11 11:45 332 | */ 333 | func GetMempoolDescendantsVerboseTest() { 334 | hashs, err := cli.GetRawMempool() 335 | if err != nil { 336 | log.Fatal("", "error", err) 337 | } 338 | for _, h := range hashs { 339 | result, err := cli.GetMempoolDescendantsVerbose(*h) 340 | if err != nil { 341 | log.Error("", "error", err) 342 | panic(err) 343 | } 344 | log.Info("GetMempoolDescendants", "result", result) 345 | break 346 | } 347 | } 348 | 349 | /* 350 | Description: 351 | a demo test of GetRawMempool, Get all tx ids in memory pool as a string array 352 | * Author: architect.bian 353 | * Date: 2018/09/14 13:13 354 | */ 355 | func GetMempoolEntryTest() { 356 | hashs, err := cli.GetRawMempool() 357 | if err != nil { 358 | log.Fatal("", "error", err) 359 | } 360 | for _, h := range hashs { 361 | log.Info("GetRawMempool", "hashs", h) 362 | result, _ := cli.GetMempoolEntry(h.String()) 363 | log.Info("GetMempoolEntry", "entry", result) 364 | break 365 | } 366 | } 367 | 368 | /* 369 | Description: 370 | GetMempoolInfoTest a demo test of GetMempoolInfo 371 | * Author: architect.bian 372 | * Date: 2018/10/11 11:51 373 | */ 374 | func GetMempoolInfoTest() { 375 | result, err := cli.GetMempoolInfo() 376 | if err != nil { 377 | log.Error("", "error", err) 378 | panic(err) 379 | } 380 | log.Info("GetMempoolInfo", "result", result) 381 | } 382 | 383 | /* 384 | Description: 385 | a demo test of GetRawMempool, Get all tx ids in memory pool as a string array 386 | * Author: architect.bian 387 | * Date: 2018/09/14 13:13 388 | */ 389 | func GetRawMempoolTest() { 390 | hashs, err := cli.GetRawMempool() 391 | if err != nil { 392 | log.Fatal("", "error", err) 393 | } 394 | for _, h := range hashs { 395 | log.Info("GetRawMempool", "hashs", h) 396 | } 397 | } 398 | 399 | /* 400 | Description: 401 | a demo test of GetRawMempoolVerbose, Get all tx ids in memory pool as a tx array 402 | * Author: architect.bian 403 | * Date: 2018/09/14 13:13 404 | */ 405 | func GetRawMempoolVerboseTest() { 406 | result, err := cli.GetRawMempoolVerbose() 407 | if err != nil { 408 | log.Fatal("", "error", err) 409 | } 410 | for _, r := range result { 411 | log.Info("GetRawMempoolVerbose", "hashs", r) 412 | } 413 | } 414 | 415 | /* 416 | Description: 417 | a demo test of GetTxOut, Get all tx ids in memory pool as a string array 418 | * Author: architect.bian 419 | * Date: 2018/09/14 13:13 420 | */ 421 | func GetTXOutTest() { 422 | hash, err := cli.GetBlockHash(1) 423 | if err != nil { 424 | log.Fatal("", "error", err) 425 | } 426 | log.Info("GetBlockHash", "hash", hash) 427 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 428 | block, err := cli.GetBlock(hash) 429 | if err != nil { 430 | log.Error("", "error", err) 431 | panic(err) 432 | } 433 | log.Info("GetBlock", "block", block) 434 | for _, h := range block.Tx { 435 | log.Info("block.Tx", "hashs", h) 436 | hs, e := results.NewHashFromStr(h) 437 | if e != nil { 438 | log.Error("", "error", e) 439 | panic(e) 440 | } 441 | result, _ := cli.GetTxOut(hs, 0, true) 442 | log.Info("GetTxOut", "result", result) //TODO bestblock value ? 443 | break 444 | } 445 | } 446 | 447 | /* 448 | Description: 449 | GetTXOutProofTest a demo test of GetTXOutProof 450 | * Author: architect.bian 451 | * Date: 2018/10/11 12:25 452 | */ 453 | func GetTXOutProofTest() { 454 | hash, err := cli.GetBlockHash(1) 455 | if err != nil { 456 | log.Fatal("", "error", err) 457 | } 458 | log.Info("GetBlockHash", "hash", hash) 459 | //hash, _ := client.NewHashFromStr("353eb168c70770b281f634fd0d22fbaee94b3fed1d76276e91165444e876f658") 460 | block, err := cli.GetBlock(hash) 461 | if err != nil { 462 | log.Error("", "error", err) 463 | panic(err) 464 | } 465 | log.Info("GetBlock", "block", block) 466 | for _, h := range block.Tx { 467 | log.Info("block.Tx", "hashs", h) 468 | result, err := cli.GetTXOutProof(h) 469 | if err != nil { 470 | log.Error("", "error", err) 471 | panic(err) 472 | } 473 | log.Info("GetTXOutProof", "result", string(*result)) 474 | break 475 | } 476 | } 477 | 478 | /* 479 | Description: 480 | GetTXOutSetInfoTest a demo test of GetTXOutSetInfo 481 | * Author: architect.bian 482 | * Date: 2018/10/11 12:25 483 | */ 484 | func GetTXOutSetInfoTest() { 485 | result, err := cli.GetTXOutSetInfo() 486 | if err != nil { 487 | log.Error("", "error", err) 488 | panic(err) 489 | } 490 | log.Info("GetTXOutSet", "result", result) 491 | } 492 | 493 | /* 494 | Description: 495 | PreciousBlockTest a demo test of PreciousBlock 496 | * Author: architect.bian 497 | * Date: 2018/10/11 12:31 498 | */ 499 | func PreciousBlockTest() { 500 | hash, err := cli.GetBlockHash(100) 501 | if err != nil { 502 | log.Fatal("", "error", err) 503 | } 504 | log.Info("GetBlockHash", "hash", hash) 505 | err2 := cli.PreciousBlock(*hash) 506 | if err2 != nil { 507 | log.Error("", "error", err2) 508 | panic(err2) 509 | } 510 | log.Info("PreciousBlock", "result", "success") 511 | } 512 | 513 | /* 514 | Description: 515 | PruneBlockchainTest a demo test of PruneBlockchain 516 | * Author: architect.bian 517 | * Date: 2018/10/11 12:31 518 | */ 519 | func PruneBlockchainTest() { 520 | result, err := cli.PruneBlockchain(101) 521 | if err != nil { 522 | log.Error("", "error", err) 523 | panic(err) 524 | } 525 | log.Info("PruneBlockchain", "result", result) 526 | } 527 | 528 | /* 529 | Description: 530 | SaveMempoolTest a demo test of SaveMempool 531 | * Author: architect.bian 532 | * Date: 2018/10/11 12:32 533 | */ 534 | func SaveMempoolTest() { 535 | err := cli.SaveMempool() 536 | if err != nil { 537 | log.Error("", "error", err) 538 | panic(err) 539 | } 540 | log.Info("SaveMempool", "result", "success") 541 | } 542 | 543 | /* 544 | Description: 545 | ScanTXOutSetTest a demo test of ScanTXOutSet, not supported until now. 546 | * Author: architect.bian 547 | * Date: 2018/10/11 12:35 548 | */ 549 | func ScanTXOutSetTest() { 550 | //EXPERIMENTAL warning: this call may be removed or changed in future releases. 551 | } 552 | 553 | /* 554 | Description: 555 | a demo test of VerifyChain, Verifies blockchain database. 556 | * Author: architect.bian 557 | * Date: 2018/09/14 13:13 558 | */ 559 | func VerifyChainTest() { 560 | verify, err := cli.VerifyChain() 561 | if err != nil { 562 | log.Fatal("", "error", err) 563 | } 564 | log.Info("VerifyChain", "verify", verify) 565 | } 566 | 567 | /* 568 | Description: 569 | VerifyTXOutProofTest a demo test of VerifyTXOutProof 570 | * Author: architect.bian 571 | * Date: 2018/10/11 12:38 572 | */ 573 | func VerifyTXOutProofTest() { 574 | hash, err := cli.GetBlockHash(1) 575 | if err != nil { 576 | log.Fatal("", "error", err) 577 | } 578 | log.Info("GetBlockHash", "hash", hash) 579 | block, err := cli.GetBlock(hash) 580 | if err != nil { 581 | log.Error("", "error", err) 582 | panic(err) 583 | } 584 | log.Info("GetBlock", "block", block) 585 | for _, h := range block.Tx { 586 | log.Info("block.Tx", "hashs", h) 587 | result, err := cli.GetTXOutProof(h) 588 | if err != nil { 589 | log.Error("", "error", err) 590 | panic(err) 591 | } 592 | log.Info("GetTXOutProof", "result", string(*result)) 593 | verify, err := cli.VerifyTXOutProof(*result) 594 | if err != nil { 595 | log.Fatal("", "error", err) 596 | } 597 | log.Info("VerifyTXOutProof", "verify", verify) 598 | break 599 | } 600 | } 601 | 602 | /* 603 | Description: 604 | a demo test of VerifyChainLevel, Verifies blockchain database. 605 | * Author: architect.bian 606 | * Date: 2018/09/14 13:13 607 | */ 608 | func VerifyChainLevelTest() { 609 | verify, err := cli.VerifyChainLevel(3) 610 | if err != nil { 611 | log.Fatal("", "error", err) 612 | } 613 | log.Info("VerifyChain", "verify", verify) 614 | } 615 | 616 | /* 617 | Description: 618 | a demo test of VerifyChainBlocks, Verifies blockchain database. 619 | * Author: architect.bian 620 | * Date: 2018/09/14 13:13 621 | */ 622 | func VerifyChainBlocksTest() { 623 | verify, err := cli.VerifyChainBlocks(3, 10) 624 | if err != nil { 625 | log.Fatal("", "error", err) 626 | } 627 | log.Info("VerifyChain", "verify", verify) 628 | } 629 | -------------------------------------------------------------------------------- /examples/demos/ControlTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/gobasis/log" 5 | //"github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | a demo test of GetMemoryInfo, Get the memory info from server peer. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 11:19 13 | */ 14 | func GetMemoryInfoTest() { 15 | result, err := cli.GetMemoryInfo() 16 | if err != nil { 17 | log.Fatal("", "error", err) 18 | } 19 | log.Info("GetMemoryInfo", "result", result) 20 | } 21 | 22 | /* 23 | Description: 24 | GetMemoryInfo4MallocInfoTest a demo test of GetMemoryInfo with argument: 25 | model as mallocinfo 26 | * Author: architect.bian 27 | * Date: 2018/10/15 11:08 28 | */ 29 | func GetMemoryInfo4MallocInfoTest() { 30 | result, err := cli.GetMemoryInfo4MallocInfo() 31 | if err != nil { 32 | log.Fatal("", "error", err) 33 | } 34 | log.Info("GetMemoryInfo", "result", result) 35 | } 36 | 37 | /* 38 | Description: 39 | a demo test of Help. 40 | * Author: architect.bian 41 | * Date: 2018/10/15 11:18 42 | */ 43 | func HelpTest() { 44 | result, err := cli.Help() 45 | if err != nil { 46 | log.Fatal("", "error", err) 47 | } 48 | log.Info("Help", "result", result) 49 | } 50 | 51 | ///* 52 | //Description: 53 | //a demo test of Logging. 54 | // * Author: architect.bian 55 | // * Date: 2018/09/02 18:24 56 | // */ 57 | //func LoggingTest() { 58 | // result, err := cli.Logging() 59 | // if err != nil { 60 | // log.Fatal("", "error", err) 61 | // } 62 | // log.Info("Logging", "result", result) 63 | //} 64 | 65 | /* 66 | Description: 67 | a demo test of Stop. 68 | * Author: architect.bian 69 | * Date: 2018/10/15 11:18 70 | */ 71 | func StopTest() { 72 | err := cli.Stop() 73 | if err != nil { 74 | log.Fatal("", "error", err) 75 | } 76 | log.Info("Stop", "result", "success") 77 | } 78 | 79 | /* 80 | Description: 81 | a demo test of Uptime. 82 | * Author: architect.bian 83 | * Date: 2018/10/15 11:17 84 | */ 85 | func UptimeTest() { 86 | result, err := cli.Uptime() 87 | if err != nil { 88 | log.Fatal("", "error", err) 89 | } 90 | log.Info("Uptime", "result", result) 91 | } 92 | -------------------------------------------------------------------------------- /examples/demos/Demos.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/client" 5 | ) 6 | 7 | var cli *client.Client 8 | 9 | /* 10 | Description: 11 | Initialize create an instance of client.Client with client.Config 12 | * Author: architect.bian 13 | * Date: 2018/09/02 18:24 14 | */ 15 | func Initialize(cfg *client.Config) { 16 | cli = client.NewClient(cfg).Startup() 17 | } 18 | 19 | /* 20 | Description: 21 | shutdown client 22 | * Author: architect.bian 23 | * Date: 2018/09/14 12:07 24 | */ 25 | func Shutdown() { 26 | cli.Shutdown() 27 | } 28 | -------------------------------------------------------------------------------- /examples/demos/GeneratingTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/gobasis/log" 5 | ) 6 | 7 | /* 8 | Description: 9 | A demo test of rpc method generate with method Send. 10 | * Author: architect.bian 11 | * Date: 2018/10/15 12:14 12 | */ 13 | func GenerateTest() { 14 | result, err := cli.Send("generate", 1) 15 | if err != nil { 16 | log.Fatal("", "error", err) 17 | } 18 | log.Info("generate", "result", result) 19 | } 20 | 21 | /* 22 | Description: 23 | A demo test of rpc method generatetoaddress with method Send. 24 | * Author: architect.bian 25 | * Date: 2018/10/15 12:14 26 | */ 27 | func GenerateToAddressTest() { 28 | result, err := cli.Send("generatetoaddress", 1, addressTo) 29 | if err != nil { 30 | log.Fatal("", "error", err) 31 | } 32 | log.Info("generatetoaddress", "result", result) 33 | } 34 | -------------------------------------------------------------------------------- /examples/demos/MiningTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | -------------------------------------------------------------------------------- /examples/demos/NetworkTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/gobasis/log" 5 | ) 6 | 7 | /* 8 | Description: 9 | A demo test of rpc method getnetworkinfo with method Send. 10 | * Author: architect.bian 11 | * Date: 2018/10/15 12:14 12 | */ 13 | func GetNetworkInfoTest() { 14 | result, err := cli.Send("getnetworkinfo") 15 | if err != nil { 16 | log.Fatal("", "error", err) 17 | } 18 | log.Info("getnetworkinfo", "result", result) 19 | } 20 | -------------------------------------------------------------------------------- /examples/demos/RawTransactionsTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/gobasis/log" 5 | ) 6 | 7 | /* 8 | Description: 9 | A demo test of CombinePSBT. 10 | * Author: architect.bian 11 | * Date: 2018/10/15 12:14 12 | */ 13 | func CombinePSBTTest() { 14 | result, err := cli.CombinePSBT([]string{"cHNidP8BACwCAAAAAAHwufUFAAAAABl2qRR4crG2o1k4mc6eslFgrT7dktQTjIisAAAAAAAA"}) 15 | if err != nil { 16 | log.Fatal("", "error", err) 17 | } 18 | log.Info("CombinePSBT", "result", result) 19 | } 20 | 21 | /* 22 | Description: 23 | A demo test of CombineRawTransaction. 24 | * Author: architect.bian 25 | * Date: 2018/10/15 12:14 26 | */ 27 | func CombineRawTransactionTest() { 28 | result, err := cli.CombineRawTransaction([]string{"0200000001731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000000fdffffff02605af405000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e18432728700000000"}) 29 | if err != nil { 30 | log.Fatal("", "error", err) 31 | } 32 | log.Info("CombineRawTransaction", "result", result) 33 | } 34 | 35 | /* 36 | Description: 37 | A demo test of ConvertToPSBT. 38 | * Author: architect.bian 39 | * Date: 2018/10/15 12:14 40 | */ 41 | func ConvertToPSBTTest() { 42 | result, err := cli.ConvertToPSBT("020000000001f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00000000") 43 | if err != nil { 44 | log.Fatal("", "error", err) 45 | } 46 | log.Info("ConvertTopSBT", "result", result) 47 | } 48 | 49 | /* 50 | Description: 51 | A demo test of CreatepSBT. 52 | * Author: architect.bian 53 | * Date: 2018/10/15 12:14 54 | */ 55 | func CreatepSBTTest() { 56 | inputs := make([]map[string]interface{}, 0) 57 | vin := make(map[string]interface{}) 58 | vin["txid"] = "fbb4b899ae57f05154d3fdf913510ce7d91a25ca7691ddedfbbecb7bd5a1ea28" 59 | vin["vout"] = 1 60 | //vin["sequence"] = 4294967295 61 | inputs = append(inputs, vin) 62 | outputs := make([]map[string]interface{}, 0) 63 | out := make(map[string]interface{}) 64 | out[addressTo] = 1.9999 65 | outputs = append(outputs, out) 66 | out = make(map[string]interface{}) 67 | out[addressFrom1] = 1 68 | outputs = append(outputs, out) 69 | result, err := cli.CreatepSBT(inputs, outputs, 0, true) 70 | if err != nil { 71 | log.Fatal("", "error", err) 72 | } 73 | log.Info("CreatepSBT", "result", result) 74 | //result: cHNidP8BAHUCAAAAASjqodV7y7777d2RdsolGtnnDFET+f3TVFHwV66ZuLT7AQAAAAD9////AvCa6wsAAAAAGXapFHhysbajWTiZzp6yUWCtPt2S1BOMiKwA4fUFAAAAABepFKTF+v1MpAE84Keabn81F8PhhDJyhwAAAAAAAAAA 75 | } 76 | 77 | /* 78 | Description: 79 | A demo test of CreateRawTransaction. 80 | * Author: architect.bian 81 | * Date: 2018/10/15 12:14 82 | */ 83 | func CreateRawTransactionTest() { 84 | inputs := make([]map[string]interface{}, 0) 85 | vin := make(map[string]interface{}) 86 | vin["txid"] = "d326cc57ab79ee25402b08dad852f16ddf534499999bc79ae4b101e207301c73" 87 | vin["vout"] = 0 88 | //vin["sequence"] = 4294967295 89 | inputs = append(inputs, vin) 90 | outputs := make([]map[string]interface{}, 0) 91 | out := make(map[string]interface{}) 92 | out[addressTo] = 0.9999 93 | outputs = append(outputs, out) 94 | out = make(map[string]interface{}) 95 | out[addressFrom1] = 3 96 | outputs = append(outputs, out) 97 | result, err := cli.CreateRawTransaction(inputs, outputs, 0, true) 98 | if err != nil { 99 | log.Fatal("", "error", err) 100 | } 101 | log.Info("CreateRawTransaction", "result", result) 102 | //result: 020000000001f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00000000 103 | } 104 | 105 | /* 106 | Description: 107 | A demo test of DecodePSBT. 108 | * Author: architect.bian 109 | * Date: 2018/10/15 12:14 110 | */ 111 | func DecodePSBTTest() { 112 | //psbtBase64 := "cHNidP8BAHUCAAAAASjqodV7y7777d2RdsolGtnnDFET+f3TVFHwV66ZuLT7AQAAAAD9////AvCa6wsAAAAAGXapFHhysbajWTiZzp6yUWCtPt2S1BOMiKwA4fUFAAAAABepFKTF+v1MpAE84Keabn81F8PhhDJyhwAAAAAAAAAA" 113 | psbtBase64 := "cHNidP8BACwCAAAAAAHwufUFAAAAABl2qRR4crG2o1k4mc6eslFgrT7dktQTjIisAAAAAAAA" 114 | result, err := cli.DecodePSBT(psbtBase64) 115 | if err != nil { 116 | log.Fatal("", "error", err) 117 | } 118 | log.Info("DecodePSBT", "result", result) 119 | } 120 | 121 | /* 122 | Description: 123 | A demo test of DecodeRawTransaction. 124 | * Author: architect.bian 125 | * Date: 2018/10/15 12:14 126 | */ 127 | func DecodeRawTransactionTest() { 128 | //hexStr, err := cli.GetRawTransaction("d326cc57ab79ee25402b08dad852f16ddf534499999bc79ae4b101e207301c73", "") 129 | //if err != nil { 130 | // log.Fatal("", "error", err) 131 | //} 132 | //log.Info("GetRawTransaction", "result", *hexStr) 133 | //result, err := cli.DecodeRawTransaction(*hexStr, false) 134 | //if err != nil { 135 | // log.Fatal("", "error", err) 136 | //} 137 | //log.Info("DecodeRawTransaction", "result", result) 138 | //result, err := cli.DecodeRawTransaction("0200000001731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000000fdffffff02f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e18432728700000000", false) 139 | //if err != nil { 140 | // log.Fatal("", "error", err) 141 | //} 142 | //log.Info("DecodeRawTransaction", "result", result) 143 | //result, err := cli.DecodeRawTransaction("02000000000101731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000017160014fad971efdd5409cb3fba6d0af021e2513fa5b915fdffffff02f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e1843272870247304402200c61419242a85f245a81f27029d524e0c9f18a5124a51bc3f411185160da9b9202201989f8ce56e1a00586e426000412f3f630f71d7344e300284545c3189bcd1bdd012102d774b2106db7564f9c84b4ea587af57e7ee82c8b4f1353489889c901409ef6de00000000", false) 144 | //if err != nil { 145 | // log.Fatal("", "error", err) //TX decode failed 146 | //} 147 | //log.Info("DecodeRawTransaction", "result", result) 148 | result, err := cli.DecodeRawTransaction("0200000001731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000000fdffffff03605af405000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e184327287256101000000000017a914f70a0b73b39e9836aef68b586fa36f3a5c58ae178700000000", false) 149 | if err != nil { 150 | log.Fatal("", "error", err) 151 | } 152 | log.Info("DecodeRawTransaction", "result", result) 153 | } 154 | 155 | /* 156 | Description: 157 | A demo test of DecodeScript. 158 | * Author: architect.bian 159 | * Date: 2018/10/15 12:14 160 | */ 161 | func DecodeScriptTest() { 162 | result, err := cli.DecodeScript("21035be9cb700c1b2309b8c5e345efb7dacb6b183817c1b5b3f4408948a1779d6543ac") 163 | if err != nil { 164 | log.Fatal("", "error", err) 165 | } 166 | log.Info("DecodeScript", "result", result) 167 | log.Info("DecodeScript", "result.addresses", ((*result).(map[string]interface{}))["addresses"]) 168 | } 169 | 170 | /* 171 | Description: 172 | A demo test of FinalizePSBT. 173 | * Author: architect.bian 174 | * Date: 2018/10/15 12:14 175 | */ 176 | func FinalizePSBTTest() { 177 | psbtBase64 := "cHNidP8BAHUCAAAAASjqodV7y7777d2RdsolGtnnDFET+f3TVFHwV66ZuLT7AQAAAAD9////AvCa6wsAAAAAGXapFHhysbajWTiZzp6yUWCtPt2S1BOMiKwA4fUFAAAAABepFKTF+v1MpAE84Keabn81F8PhhDJyhwAAAAAAAAAA" 178 | result, err := cli.FinalizePSBT(psbtBase64, true) 179 | if err != nil { 180 | log.Fatal("", "error", err) 181 | } 182 | log.Info("FinalizePSBT", "result", result) 183 | } 184 | 185 | /* 186 | Description: 187 | A demo test of FundrawTransaction. 188 | * Author: architect.bian 189 | * Date: 2018/10/15 12:14 190 | */ 191 | func FundRawTransactionTest() { 192 | result, err := cli.FundRawTransaction("0200000001731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000000fdffffff02605af405000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e18432728700000000", 193 | nil, false) 194 | if err != nil { 195 | log.Fatal("", "error", err) 196 | } 197 | log.Info("FundrawTransaction", "result", result) 198 | } 199 | 200 | /* 201 | Description: 202 | A demo test of GetRawTransaction. 203 | * Author: architect.bian 204 | * Date: 2018/10/15 12:14 205 | */ 206 | func GetRawTransactionTest() { 207 | result, err := cli.GetRawTransaction("d326cc57ab79ee25402b08dad852f16ddf534499999bc79ae4b101e207301c73", "") 208 | if err != nil { 209 | log.Fatal("", "error", err) 210 | } 211 | log.Info("GetRawTransaction", "result", result) 212 | } 213 | 214 | /* 215 | Description: 216 | A demo test of GetRawTransactionVerbose. 217 | * Author: architect.bian 218 | * Date: 2018/10/15 12:14 219 | */ 220 | func GetRawTransactionVerboseTest() { 221 | //result, err := cli.GetRawTransactionVerbose("d326cc57ab79ee25402b08dad852f16ddf534499999bc79ae4b101e207301c73", "") 222 | //if err != nil { 223 | // log.Fatal("", "error", err) 224 | //} 225 | //log.Info("GetRawTransactionVerbose", "result", result) 226 | result, err := cli.GetRawTransactionVerbose("fbb4b899ae57f05154d3fdf913510ce7d91a25ca7691ddedfbbecb7bd5a1ea28", "") 227 | if err != nil { 228 | log.Fatal("", "error", err) 229 | } 230 | log.Info("GetRawTransactionVerbose", "result", result) 231 | } 232 | 233 | /* 234 | Description: 235 | A demo test of SendRawTransaction. 236 | * Author: architect.bian 237 | * Date: 2018/10/15 12:14 238 | */ 239 | func SendRawTransactionTest() { 240 | result, err := cli.SendRawTransaction("02000000000101731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000017160014fad971efdd5409cb3fba6d0af021e2513fa5b915fdffffff02f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e1843272870247304402200c61419242a85f245a81f27029d524e0c9f18a5124a51bc3f411185160da9b9202201989f8ce56e1a00586e426000412f3f630f71d7344e300284545c3189bcd1bdd012102d774b2106db7564f9c84b4ea587af57e7ee82c8b4f1353489889c901409ef6de00000000", 241 | false) 242 | if err != nil { 243 | log.Fatal("", "error", err) 244 | } 245 | log.Info("SendRawTransaction", "result", result) 246 | } 247 | 248 | /* 249 | Description: 250 | A demo test of SignRawTransactionWithKey. 251 | * Author: architect.bian 252 | * Date: 2018/10/15 12:14 253 | */ 254 | func SignRawTransactionWithKeyTest() { 255 | txHex := "0200000001731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000000fdffffff02f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e18432728700000000" 256 | result, err := cli.SignRawTransactionWithKey(txHex, 257 | []string{addressFrom1PrivKey}) 258 | if err != nil { 259 | log.Fatal("", "error", err) 260 | } 261 | log.Info("SignRawTransactionWithKey", "result", result) 262 | //Result: {"complete":true,"hex":"02000000000101731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000017160014fad971efdd5409cb3fba6d0af021e2513fa5b915fdffffff02f0b9f505000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e1843272870247304402200c61419242a85f245a81f27029d524e0c9f18a5124a51bc3f411185160da9b9202201989f8ce56e1a00586e426000412f3f630f71d7344e300284545c3189bcd1bdd012102d774b2106db7564f9c84b4ea587af57e7ee82c8b4f1353489889c901409ef6de00000000"} 263 | } 264 | 265 | /* 266 | Description: 267 | A demo test of TestMempoolAccept. 268 | * Author: architect.bian 269 | * Date: 2018/10/15 12:14 270 | */ 271 | func TestMempoolAcceptTest() { 272 | result, err := cli.TestMempoolAccept([]string{"02000000000101731c3007e201b1e49ac79b99994453df6df152d8da082b4025ee79ab57cc26d30000000017160014fad971efdd5409cb3fba6d0af021e2513fa5b915fdffffff02605af405000000001976a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac00a3e1110000000017a914a4c5fafd4ca4013ce0a79a6e7f3517c3e1843272870247304402207fc2b478c3445a95016fdc96b38d952f7849b2d9514e7dc7042289774277cfe302204a249216f05e6e4c9a3513a639fe862ca0c08449acdeb91345771bba14149f9d012102d774b2106db7564f9c84b4ea587af57e7ee82c8b4f1353489889c901409ef6de00000000"}, 273 | false) 274 | if err != nil { 275 | log.Fatal("", "error", err) 276 | } 277 | log.Info("TestMempoolAccept", "result", result) 278 | } -------------------------------------------------------------------------------- /examples/demos/UtilTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | -------------------------------------------------------------------------------- /examples/demos/WalletTest.go: -------------------------------------------------------------------------------- 1 | package demos 2 | 3 | import ( 4 | "github.com/gobasis/log" 5 | 6 | ) 7 | 8 | const address = "mrVpnAaPap8BXLnYBc5pNfeMwwhvKcqvMq" 9 | const privkey = "cUSG5zKm1KqRq5YzQsbe2dS86W2VRq1HwwVN5J9itRCYdaduaZED" 10 | const addressFrom1 = "2N8GTyfYg1WKg9c2WEKK6a589gwHsKb9bzo" 11 | const addressFrom1PrivKey = "cSZ8cpqinGkN9i5quXb8ZL4bdayn8jypkJzRruZdEYCVyVtVdvLE" 12 | const addressTo = "mrVpnAaPap8BXLnYBc5pNfeMwwhvKcqvMq" 13 | const address1 = "2MvobEAKN1T8VALjQZdEhr3hfDWCLxhUiLo" 14 | const address2 = "2N7rd1LkJg5UoXDBkdfi4mUuyvTEzJtoBpj" 15 | const address3 = "2N8p8fFpTPDp2rxJAMnYxvgv7W6Peiwk1rG" 16 | const address1pubkey = "03b4e61ee34b37db459316b61f0e8ce540bc3e99b427c7390cb6060fd5ca4084f1" 17 | const address1hex = "0014a906b03a31c458a92f1ce4cb512303b83483d35e" 18 | const address2pubkey = "03c7ffdaf2ef6f6887c05b20cb541ea55b3731cbeb9b3a73e8aa601a702a0fcffa" 19 | const address2hex = "0014c83fcb8543d609e52a04acc355da4839299d6a31" 20 | const address3pubkey = "03b8f68c4a59fde8e2698c63e86801fa5660467860384bf71d69a1c90d8730712d" 21 | const address3hex = "001462ae6c81f7f63b35e780bdb8f61c25b293bc5622" 22 | //2My3izAWtnSDY4Evv7AWw9ci2fM3Tf35fC5 cNj4yz9UkRrravto6GYYgoUPdVJtpshD4BKe5nyR5fof1u5gFaca 23 | func WalletTestInitialize() { 24 | addr, err := cli.GetAddressInfo(address) 25 | if err != nil { 26 | log.Fatal("", "error", err) 27 | } 28 | log.Info("GetAddressInfo", "result", addr) 29 | if addr != nil { 30 | addrResult := (*addr).(map[string]interface{}) 31 | if !addrResult["ismine"].(bool) { 32 | log.Info("current address state", "ismine", false) 33 | err := cli.ImportPrivkey(privkey) 34 | if err != nil { 35 | log.Fatal("", "error", err) 36 | } 37 | log.Info("ImportPrivkey", "result", "success") 38 | addr2, err2 := cli.GetAddressInfo(address) 39 | if err2 != nil { 40 | log.Fatal("", "error", err2) 41 | } 42 | log.Info("GetAddressInfo", "result", addr2) 43 | log.Info("address new state", "ismine", (*addr2).(map[string]interface{})["ismine"].(bool)) 44 | } else { 45 | log.Info("current address state", "ismine", true) 46 | } 47 | } else { 48 | log.Fatal("addr is null", "error", err) 49 | } 50 | } 51 | 52 | /* 53 | Description: 54 | A demo test of AbandonTransaction. 55 | * Author: architect.bian 56 | * Date: 2018/10/15 12:14 57 | */ 58 | func AbandonTransactionTest() { 59 | err := cli.AbandonTransaction("239f98f9a355fc0c3b8ac8d0556ace4c49251c5e711c22783f37e9e5f185859b") 60 | if err != nil { 61 | log.Fatal("", "error", err) 62 | } 63 | log.Info("AbandonTransaction", "result", "success") 64 | } 65 | 66 | /* 67 | Description: 68 | A demo test of AbortRescan. 69 | * Author: architect.bian 70 | * Date: 2018/10/15 12:14 71 | */ 72 | func AbortRescanTest() { 73 | err := cli.AbortRescan() 74 | if err != nil { 75 | log.Fatal("", "error", err) 76 | } 77 | log.Info("AbortRescan", "result", "success") 78 | } 79 | 80 | /* 81 | Description: 82 | A demo test of AddMultiSigAddress. 83 | * Author: architect.bian 84 | * Date: 2018/10/15 12:14 85 | */ 86 | func AddMultiSigAddressTest() { 87 | keys := make([]string, 0) 88 | keys = append(keys, address1) 89 | keys = append(keys, address2) 90 | //keys = append(keys, address3) 91 | result, err := cli.AddMultiSigAddress(2, keys) 92 | if err != nil { 93 | log.Fatal("", "error", err) 94 | } 95 | log.Info("AddMultiSigAddress", "result", result) //{"address":"2N4a69o4gPC9RjQhrcKVPjj2ib3599opZSs", 96 | // "redeemScript":"522103b4e61ee34b37db459316b61f0e8ce540bc3e99b427c7390cb6060fd5ca4084f12103c7ffdaf2ef6f6887c05b20cb541ea55b3731cbeb9b3a73e8aa601a702a0fcffa52ae"} 97 | } 98 | 99 | /* 100 | Description: 101 | A demo test of BackupWallet. 102 | * Author: architect.bian 103 | * Date: 2018/10/15 12:14 104 | */ 105 | func BackupWalletTest() { 106 | err := cli.BackupWallet("/root/wallet.bak") 107 | if err != nil { 108 | log.Fatal("", "error", err) 109 | } 110 | log.Info("BackupWallet", "result", "success") 111 | } 112 | 113 | /* 114 | Description: 115 | A demo test of BumpFee. 116 | * Author: architect.bian 117 | * Date: 2018/10/15 12:14 118 | */ 119 | func BumpFeeTest() { 120 | option := map[string]interface{}{} 121 | option["replaceable"] = true 122 | result, err := cli.BumpFee("c55623b4b9c69595859870be911c548f1e19661ac7111c15a4a11879df1725b0", option) 123 | if err != nil { 124 | log.Fatal("", "error", err) 125 | } 126 | log.Info("BumpFee", "result", result) 127 | } 128 | 129 | /* 130 | Description: 131 | A demo test of CreateWallet. 132 | * Author: architect.bian 133 | * Date: 2018/10/15 12:14 134 | */ 135 | func CreateWalletTest() { 136 | result, err := cli.CreateWallet("mywallet", false) 137 | if err != nil { 138 | log.Fatal("", "error", err) 139 | } 140 | log.Info("CreateWallet", "result", result) 141 | } 142 | 143 | /* 144 | Description: 145 | A demo test of DumpPrivkey. 146 | * Author: architect.bian 147 | * Date: 2018/10/15 12:14 148 | */ 149 | func DumpPrivkeyTest() { 150 | //addr, err := cli.GetNewAddress() 151 | //if err != nil { 152 | // log.Fatal("", "error", err) 153 | //} 154 | //log.Info("GetNewAddress", "address", addr) 155 | result, err := cli.DumpPrivkey(addressFrom1) 156 | if err != nil { 157 | log.Fatal("", "error", err) 158 | } 159 | log.Info("DumpPrivkey", "result", result) 160 | //result, err := cli.DumpPrivkey("mrVpnAaPap8BXLnYBc5pNfeMwwhvKcqvMq") 161 | //if err != nil { 162 | // log.Fatal("", "error", err) 163 | //} 164 | //log.Info("DumpPrivkey", "result", result) 165 | } 166 | 167 | /* 168 | Description: 169 | A demo test of DumpWallet. 170 | * Author: architect.bian 171 | * Date: 2018/10/15 12:14 172 | */ 173 | func DumpWalletTest() { 174 | result, err := cli.DumpWallet("/root/wallet.dump") 175 | if err != nil { 176 | log.Fatal("", "error", err) 177 | } 178 | log.Info("DumpWallet", "result", result) 179 | } 180 | 181 | /* 182 | Description: 183 | A demo test of EncryptWallet. 184 | * Author: architect.bian 185 | * Date: 2018/10/15 12:14 186 | */ 187 | func EncryptWalletTest() { 188 | err := cli.EncryptWallet("myphrase") 189 | if err != nil { 190 | log.Fatal("", "error", err) 191 | } 192 | log.Info("EncryptWallet", "result", "success") 193 | } 194 | 195 | /////* 196 | ////Description: 197 | ////Deprecated 198 | ////A demo test of GetAccount. 199 | //// * Author: architect.bian 200 | //// * Date: 2018/10/15 12:14 201 | //// */ 202 | ////func GetAccountTest() { 203 | //// result, err := cli.GetAccount() 204 | //// if err != nil { 205 | //// log.Fatal("", "error", err) 206 | //// } 207 | //// log.Info("GetAccount", "result", result) 208 | ////} 209 | // 210 | /////* 211 | ////Description: 212 | ////Deprecated 213 | ////A demo test of GetAccountAddress. 214 | //// * Author: architect.bian 215 | //// * Date: 2018/10/15 12:14 216 | //// */ 217 | ////func GetAccountAddressTest() { 218 | //// result, err := cli.GetAccountAddress() 219 | //// if err != nil { 220 | //// log.Fatal("", "error", err) 221 | //// } 222 | //// log.Info("GetAccountAddress", "result", result) 223 | ////} 224 | 225 | /* 226 | Description: 227 | A demo test of GetAddressesByLabel. 228 | * Author: architect.bian 229 | * Date: 2018/10/15 12:14 230 | */ 231 | func GetAddressesByLabelTest() { 232 | result, err := cli.GetAddressesByLabel("") 233 | if err != nil { 234 | log.Fatal("", "error", err) 235 | } 236 | log.Info("GetAddressesByLabel", "result", result) 237 | } 238 | 239 | /* 240 | Description: 241 | A demo test of GetAddressInfo. 242 | * Author: architect.bian 243 | * Date: 2018/10/15 12:14 244 | */ 245 | func GetAddressInfoTest() { 246 | result, err := cli.GetAddressInfo("2N8p8fFpTPDp2rxJAMnYxvgv7W6Peiwk1rG") 247 | if err != nil { 248 | log.Fatal("", "error", err) 249 | } 250 | log.Info("GetAddressInfo", "result", result) 251 | } 252 | 253 | /* 254 | Description: 255 | A demo test of GetBalance. 256 | * Author: architect.bian 257 | * Date: 2018/10/15 12:14 258 | */ 259 | func GetBalanceTest() { 260 | result, err := cli.GetBalance() 261 | if err != nil { 262 | log.Fatal("", "error", err) 263 | } 264 | log.Info("GetBalance", "result", result) 265 | } 266 | 267 | /* 268 | Description: 269 | A demo test of GetBalanceEntire. 270 | * Author: architect.bian 271 | * Date: 2018/10/15 12:14 272 | */ 273 | func GetBalanceEntireTest() { 274 | result, err := cli.GetBalanceEntire("*", 1, true) 275 | if err != nil { 276 | log.Fatal("", "error", err) 277 | } 278 | log.Info("GetBalance", "result", result) 279 | } 280 | 281 | /* 282 | Description: 283 | A demo test of GetNewAddress. 284 | * Author: architect.bian 285 | * Date: 2018/10/15 12:14 286 | */ 287 | func GetNewAddressTest() { 288 | result, err := cli.GetNewAddress() 289 | if err != nil { 290 | log.Fatal("", "error", err) 291 | } 292 | log.Info("GetNewAddress", "result", result) 293 | } 294 | 295 | /* 296 | Description: 297 | A demo test of GetNewAddressEntireTest. 298 | * Author: architect.bian 299 | * Date: 2018/10/15 23:44 300 | */ 301 | func GetNewAddressEntireTest() { 302 | //result, err := cli.GetNewAddressEntire("", "legacy") 303 | //if err != nil { 304 | // log.Fatal("", "error", err) 305 | //} 306 | //log.Info("GetNewAddressEntire", "result-legacy", result) //muzMwJUEkoNoepi6Krx4m4hY56YvgnE2Mf 307 | result, err := cli.GetNewAddressEntire("addr2018", "legacy") 308 | if err != nil { 309 | log.Fatal("", "error", err) 310 | } 311 | log.Info("GetNewAddressEntire", "result-legacy", result) //muzMwJUEkoNoepi6Krx4m4hY56YvgnE2Mf 312 | result2, err2 := cli.GetNewAddressEntire("addr2018", "p2sh-segwit") 313 | if err2 != nil { 314 | log.Fatal("", "error", err2) 315 | } 316 | log.Info("GetNewAddressEntire", "result-p2sh-segwit", result2) //2Mx18zD3m3MSG1wkex416pegoKKaDZJmogx 317 | result3, err3 := cli.GetNewAddressEntire("addr2018", "bech32") 318 | if err3 != nil { 319 | log.Fatal("", "error", err3) 320 | } 321 | log.Info("GetNewAddressEntire", "result-bech32", result3) //bcrt1q9grsd8w802zjnmj935r4q074rdhq786danjvg0 322 | } 323 | 324 | /* 325 | Description: 326 | A demo test of GetRawChangeAddress. 327 | * Author: architect.bian 328 | * Date: 2018/10/15 12:14 329 | */ 330 | func GetRawChangeAddressTest() { 331 | result, err := cli.GetRawChangeAddressEntire("legacy") 332 | if err != nil { 333 | log.Fatal("", "error", err) 334 | } 335 | log.Info("GetRawChangeAddress", "result", result) 336 | } 337 | 338 | /////* 339 | ////Description: 340 | ////Deprecated 341 | ////A demo test of GetReceivedByAccount. 342 | //// * Author: architect.bian 343 | //// * Date: 2018/10/15 12:14 344 | //// */ 345 | ////func GetReceivedByAccountTest() { 346 | //// result, err := cli.GetReceivedByAccount() 347 | //// if err != nil { 348 | //// log.Fatal("", "error", err) 349 | //// } 350 | //// log.Info("GetReceivedByAccount", "result", result) 351 | ////} 352 | 353 | /* 354 | Description: 355 | A demo test of GetReceivedByAddress. 356 | * Author: architect.bian 357 | * Date: 2018/10/15 12:14 358 | */ 359 | func GetReceivedByAddressTest() { 360 | result, err := cli.GetReceivedByAddress(addressTo, 0) 361 | if err != nil { 362 | log.Fatal("", "error", err) 363 | } 364 | log.Info("GetReceivedByAddress", "result", result) 365 | } 366 | 367 | /* 368 | Description: 369 | A demo test of GetTransaction. 370 | * Author: architect.bian 371 | * Date: 2018/10/15 12:14 372 | */ 373 | func GetTransactionTest() { 374 | result, err := cli.GetTransaction("fbb4b899ae57f05154d3fdf913510ce7d91a25ca7691ddedfbbecb7bd5a1ea28", true) 375 | if err != nil { 376 | log.Fatal("", "error", err) 377 | } 378 | log.Info("GetTransaction", "result", result) 379 | //result, err := cli.GetTransaction("239f98f9a355fc0c3b8ac8d0556ace4c49251c5e711c22783f37e9e5f185859b", true) 380 | //if err != nil { 381 | // log.Fatal("", "error", err) 382 | //} 383 | //log.Info("GetTransaction", "result", result) 384 | //result2, err2 := cli.GetTransaction("65bcaab247a598ae175eb5edf34531616ec7d8c4147d8ca6ad2b9b3c69543dc1", true) 385 | //if err2 != nil { 386 | // log.Fatal("", "error", err2) 387 | //} 388 | //log.Info("GetTransaction", "result", result2) 389 | } 390 | 391 | /* 392 | Description: 393 | A demo test of GetUnconfirmedBalance. 394 | * Author: architect.bian 395 | * Date: 2018/10/15 12:14 396 | */ 397 | func GetUnconfirmedBalanceTest() { 398 | result, err := cli.GetUnconfirmedBalance() 399 | if err != nil { 400 | log.Fatal("", "error", err) 401 | } 402 | log.Info("GetUnconfirmedBalance", "result", result) 403 | } 404 | 405 | /* 406 | Description: 407 | A demo test of getwalletinfo. 408 | * Author: architect.bian 409 | * Date: 2018/10/15 12:14 410 | */ 411 | func GetWalletInfoTest() { 412 | result, err := cli.GetWalletInfo() 413 | if err != nil { 414 | log.Fatal("", "error", err) 415 | } 416 | log.Info("getwalletinfo", "result", result) 417 | } 418 | 419 | /* 420 | Description: 421 | A demo test of Importaddress. 422 | * Author: architect.bian 423 | * Date: 2018/10/15 12:14 424 | */ 425 | func ImportaddressTest() { 426 | result, err := cli.Importaddress("76a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac") 427 | if err != nil { 428 | log.Fatal("", "error", err) 429 | } 430 | log.Info("Importaddress", "result", result) 431 | } 432 | 433 | /* 434 | Description: 435 | A demo test of ImportMulti. 436 | * Author: architect.bian 437 | * Date: 2018/10/15 12:14 438 | */ 439 | func ImportMultiTest() { 440 | requests := make([]interface{}, 0) 441 | scriptPubKey := make(map[string]interface{}) 442 | addr := make(map[string]interface{}) 443 | addr["address"] = "mrVpnAaPap8BXLnYBc5pNfeMwwhvKcqvMq" 444 | scriptPubKey["scriptPubKey"] = addr 445 | scriptPubKey["timestamp"] = 1455191480 446 | requests = append(requests[:], scriptPubKey) 447 | option := make(map[string]interface{}) 448 | option["rescan"] = false 449 | result, err := cli.ImportMulti(requests, option) 450 | if err != nil { 451 | log.Fatal("", "error", err) 452 | } 453 | log.Info("ImportMulti", "result", result) 454 | } 455 | 456 | /* 457 | Description: 458 | A demo test of ImportPrivkey. 459 | * Author: architect.bian 460 | * Date: 2018/10/15 12:14 461 | */ 462 | func ImportPrivkeyTest() { 463 | err := cli.ImportPrivkey(privkey) 464 | if err != nil { 465 | log.Fatal("", "error", err) 466 | } 467 | log.Info("ImportPrivkey", "result", "success") 468 | } 469 | 470 | ///* 471 | //Description: 472 | //A demo test of ImportPrunedFunds. 473 | // * Author: architect.bian 474 | // * Date: 2018/10/15 12:14 475 | // */ 476 | //func ImportPrunedFundsTest() { 477 | // result, err := cli.ImportPrunedFunds() 478 | // if err != nil { 479 | // log.Fatal("", "error", err) 480 | // } 481 | // log.Info("ImportPrunedFunds", "result", result) 482 | //} 483 | 484 | /* 485 | Description: 486 | A demo test of ImportPubkey. 487 | * Author: architect.bian 488 | * Date: 2018/10/15 12:14 489 | */ 490 | func ImportPubkeyTest() { 491 | err := cli.ImportPubkey("76a9147872b1b6a3593899ce9eb25160ad3edd92d4138c88ac") 492 | if err != nil { 493 | log.Fatal("", "error", err) 494 | } 495 | log.Info("ImportPubkey", "result", "success") 496 | } 497 | 498 | /* 499 | Description: 500 | A demo test of ImportWallet. 501 | * Author: architect.bian 502 | * Date: 2018/10/15 12:14 503 | */ 504 | func ImportWalletTest() { 505 | err := cli.ImportWallet("/root/wallet.dump") 506 | if err != nil { 507 | log.Fatal("", "error", err) 508 | } 509 | log.Info("ImportWallet", "result", "success") 510 | } 511 | 512 | /* 513 | Description: 514 | A demo test of KeypoolRefill. 515 | * Author: architect.bian 516 | * Date: 2018/10/15 12:14 517 | */ 518 | func KeypoolRefillTest() { 519 | err := cli.KeypoolRefill(100) 520 | if err != nil { 521 | log.Fatal("", "error", err) 522 | } 523 | log.Info("KeypoolRefill", "result", "success") 524 | } 525 | 526 | /////* 527 | ////Description: 528 | ////Deprecated 529 | ////A demo test of ListAccounts. 530 | //// * Author: architect.bian 531 | //// * Date: 2018/10/15 12:14 532 | //// */ 533 | ////func ListAccountsTest() { 534 | //// result, err := cli.ListAccounts() 535 | //// if err != nil { 536 | //// log.Fatal("", "error", err) 537 | //// } 538 | //// log.Info("ListAccounts", "result", result) 539 | ////} 540 | // 541 | /* 542 | Description: 543 | A demo test of ListAddressGroupings. 544 | * Author: architect.bian 545 | * Date: 2018/10/15 12:14 546 | */ 547 | func ListAddressGroupingsTest() { 548 | result, err := cli.ListAddressGroupings() 549 | if err != nil { 550 | log.Fatal("", "error", err) 551 | } 552 | log.Info("ListAddressGroupings", "result", result) 553 | } 554 | 555 | /* 556 | Description: 557 | A demo test of ListLabels. 558 | * Author: architect.bian 559 | * Date: 2018/10/15 12:14 560 | */ 561 | func ListLabelsTest() { 562 | result, err := cli.ListLabels("") 563 | if err != nil { 564 | log.Fatal("", "error", err) 565 | } 566 | log.Info("ListLabels", "result", result) 567 | result2, err2 := cli.ListLabels("receive") 568 | if err2 != nil { 569 | log.Fatal("", "error", err2) 570 | } 571 | log.Info("ListLabels", "result", result2) 572 | result3, err3 := cli.ListLabels("send") 573 | if err3 != nil { 574 | log.Fatal("", "error", err3) 575 | } 576 | log.Info("ListLabels", "result", result3) //empty? 577 | } 578 | 579 | /* 580 | Description: 581 | A demo test of ListLockUnspent. 582 | * Author: architect.bian 583 | * Date: 2018/10/15 12:14 584 | */ 585 | func ListLockUnspentTest() { 586 | result, err := cli.ListLockUnspent() 587 | if err != nil { 588 | log.Fatal("", "error", err) 589 | } 590 | log.Info("ListLockUnspent", "result", result) 591 | } 592 | 593 | /////* 594 | ////Description: 595 | ////Deprecated 596 | ////A demo test of ListReceivedByAccount. 597 | //// * Author: architect.bian 598 | //// * Date: 2018/10/15 12:14 599 | //// */ 600 | ////func ListReceivedByAccountTest() { 601 | //// result, err := cli.ListReceivedByAccount() 602 | //// if err != nil { 603 | //// log.Fatal("", "error", err) 604 | //// } 605 | //// log.Info("ListReceivedByAccount", "result", result) 606 | ////} 607 | 608 | /* 609 | Description: 610 | A demo test of ListReceivedByAddress. 611 | * Author: architect.bian 612 | * Date: 2018/10/15 12:14 613 | */ 614 | func ListReceivedByAddressTest() { 615 | result, err := cli.ListReceivedByAddress(0, true, true, "") 616 | if err != nil { 617 | log.Fatal("", "error", err) 618 | } 619 | log.Info("ListReceivedByAddress", "result", result) 620 | } 621 | 622 | /* 623 | Description: 624 | A demo test of ListsInceBlock. 625 | * Author: architect.bian 626 | * Date: 2018/10/15 12:14 627 | */ 628 | func ListSinceBlockTest() { 629 | result, err := cli.ListSinceBlock("69bf27f38a4d66f1abd4a83b69a7c2345971b8efbf121ed740dc7aaf5c4ce868", 1, false, true) 630 | if err != nil { 631 | log.Fatal("", "error", err) 632 | } 633 | log.Info("ListsInceBlock", "result", result) 634 | } 635 | 636 | /* 637 | Description: 638 | A demo test of ListTransactions. 639 | * Author: architect.bian 640 | * Date: 2018/10/15 12:14 641 | */ 642 | func ListTransactionsTest() { 643 | result, err := cli.ListTransactions() 644 | if err != nil { 645 | log.Fatal("", "error", err) 646 | } 647 | log.Info("ListTransactions", "result", result) 648 | } 649 | 650 | /* 651 | Description: 652 | A demo test of ListUnspent. 653 | * Author: architect.bian 654 | * Date: 2018/10/15 12:14 655 | */ 656 | func ListUnspentTest() { 657 | result, err := cli.ListUnspent() 658 | if err != nil { 659 | log.Fatal("", "error", err) 660 | } 661 | log.Info("ListUnspent", "result", result) 662 | } 663 | 664 | /* 665 | Description: 666 | A demo test of ListUnspentEntire. 667 | * Author: architect.bian 668 | * Date: 2018/10/15 12:14 669 | */ 670 | func ListUnspentEntireTest() { 671 | result, err := cli.ListUnspentEntire(0, 999999, nil, true, nil) 672 | if err != nil { 673 | log.Fatal("", "error", err) 674 | } 675 | log.Info("ListUnspentEntire", "result", result) 676 | } 677 | 678 | /* 679 | Description: 680 | A demo test of ListWallets. 681 | * Author: architect.bian 682 | * Date: 2018/10/15 12:14 683 | */ 684 | func ListWalletsTest() { 685 | result, err := cli.ListWallets() 686 | if err != nil { 687 | log.Fatal("", "error", err) 688 | } 689 | log.Info("ListWallets", "result", result) 690 | } 691 | 692 | /* 693 | Description: 694 | A demo test of LoadWallet. 695 | * Author: architect.bian 696 | * Date: 2018/10/15 12:14 697 | */ 698 | func LoadWalletTest() { 699 | //result, err := cli.LoadWallet("/root/.bitcoin/regtest/wallets") 700 | result, err := cli.LoadWallet("/root/.bitcoin/regtest/wallets/mywallet") 701 | if err != nil { 702 | log.Fatal("", "error", err) 703 | } 704 | log.Info("LoadWallet", "result", result) 705 | } 706 | 707 | /* 708 | Description: 709 | A demo test of LockUnspent. 710 | * Author: architect.bian 711 | * Date: 2018/10/15 12:14 712 | */ 713 | func LockUnspentTest() { 714 | result, err := cli.ListUnspent() 715 | if err != nil { 716 | log.Fatal("", "error", err) 717 | } 718 | utxos := (*result).([]interface{}) 719 | log.Info("ListUnspent", "result", utxos) 720 | if len(utxos) > 0 { 721 | utxo := utxos[0].(map[string]interface{}) 722 | txs := make([]map[string]interface{}, 1) 723 | tx := make(map[string]interface{}) 724 | tx["txid"] = utxo["txid"] 725 | tx["vout"] = utxo["vout"] 726 | txs[0] = tx 727 | result1, err1 := cli.LockUnspent(false, txs) 728 | if err1 != nil { 729 | log.Fatal("", "error", err1) 730 | } 731 | log.Info("LockUnspent", "result", result1) 732 | ListLockUnspentTest() 733 | result2, err2 := cli.LockUnspent(true, txs) 734 | if err2 != nil { 735 | log.Fatal("", "error", err2) 736 | } 737 | log.Info("LockUnspent", "result", result2) 738 | ListLockUnspentTest() 739 | } 740 | 741 | } 742 | 743 | /////* 744 | ////Description: 745 | ////Deprecated 746 | ////A demo test of Move. 747 | //// * Author: architect.bian 748 | //// * Date: 2018/10/15 12:14 749 | //// */ 750 | ////func MoveTest() { 751 | //// result, err := cli.Move() 752 | //// if err != nil { 753 | //// log.Fatal("", "error", err) 754 | //// } 755 | //// log.Info("Move", "result", result) 756 | ////} 757 | 758 | /* 759 | Description: 760 | A demo test of RemovePrunedFunds. 761 | * Author: architect.bian 762 | * Date: 2018/10/15 12:14 763 | */ 764 | func RemovePrunedFundsTest() { 765 | err := cli.RemovePrunedFunds("76a261989d3ff432f0f1846f23c6653deec70a548be76c08560bca3b1e888e77") 766 | if err != nil { 767 | log.Fatal("", "error", err) 768 | } 769 | log.Info("RemovePrunedFunds", "result", "success") 770 | } 771 | 772 | /* 773 | Description: 774 | A demo test of RescanBlockChain. 775 | * Author: architect.bian 776 | * Date: 2018/10/15 12:14 777 | */ 778 | func RescanBlockChainTest() { 779 | result, err := cli.RescanBlockChain() 780 | if err != nil { 781 | log.Fatal("", "error", err) 782 | } 783 | log.Info("RescanBlockChain", "result", result) 784 | } 785 | 786 | /////* 787 | ////Description: 788 | ////Deprecated 789 | ////A demo test of SendFrom. 790 | //// * Author: architect.bian 791 | //// * Date: 2018/10/15 12:14 792 | //// */ 793 | ////func SendFromTest() { 794 | //// result, err := cli.SendFrom() 795 | //// if err != nil { 796 | //// log.Fatal("", "error", err) 797 | //// } 798 | //// log.Info("SendFrom", "result", result) 799 | ////} 800 | 801 | /* 802 | Description: 803 | A demo test of SendMany. 804 | * Author: architect.bian 805 | * Date: 2018/10/15 12:14 806 | */ 807 | func SendManyTest() { 808 | to := make(map[string]interface{}) 809 | to[addressTo] = 10 810 | result, err := cli.SendMany(to) 811 | if err != nil { 812 | log.Fatal("", "error", err) 813 | } 814 | log.Info("SendMany", "result", result) 815 | } 816 | 817 | /* 818 | Description: 819 | A demo test of SendToAddress. 820 | * Author: architect.bian 821 | * Date: 2018/10/15 12:14 822 | */ 823 | func SendToAddressTest() { 824 | result, err := cli.SendToAddress(addressTo, 150) 825 | if err != nil { 826 | log.Fatal("", "error", err) 827 | } 828 | log.Info("SendToAddress", "result", result) 829 | } 830 | 831 | /* 832 | Description: 833 | A demo test of SendToAddressEntire. 834 | * Author: architect.bian 835 | * Date: 2018/10/15 12:14 836 | */ 837 | func SendToAddressEntireTest() { 838 | result, err := cli.SendToAddressEntire(addressTo, 6, "", "", 839 | false, true, 1, "UNSET") 840 | if err != nil { 841 | log.Fatal("", "error", err) 842 | } 843 | log.Info("SendToAddress", "result", result) 844 | } 845 | 846 | /////* 847 | ////Description: 848 | ////Deprecated 849 | ////A demo test of SetAccount. 850 | //// * Author: architect.bian 851 | //// * Date: 2018/10/15 12:14 852 | //// */ 853 | ////func SetAccountTest() { 854 | //// result, err := cli.SetAccount() 855 | //// if err != nil { 856 | //// log.Fatal("", "error", err) 857 | //// } 858 | //// log.Info("SetAccount", "result", result) 859 | ////} 860 | 861 | /* 862 | Description: 863 | A demo test of SetHDSeed. 864 | * Author: architect.bian 865 | * Date: 2018/10/15 12:14 866 | */ 867 | func SetHDSeedTest() { 868 | err := cli.SetHDSeed() 869 | if err != nil { 870 | log.Fatal("", "error", err) 871 | } 872 | log.Info("SetHDSeed", "result", "success") 873 | } 874 | 875 | /* 876 | Description: 877 | A demo test of SetTXFee. 878 | * Author: architect.bian 879 | * Date: 2018/10/15 12:14 880 | */ 881 | func SetTXFeeTest() { 882 | result, err := cli.SetTXFee(0.00001) 883 | if err != nil { 884 | log.Fatal("", "error", err) 885 | } 886 | log.Info("SetTXFee", "result", result) 887 | } 888 | 889 | /* 890 | Description: 891 | A demo test of SignMessage. 892 | * Author: architect.bian 893 | * Date: 2018/10/15 12:14 894 | */ 895 | func SignMessageTest() { 896 | result, err := cli.SignMessage(address, "hi world!") 897 | if err != nil { 898 | log.Fatal("", "error", err) 899 | } 900 | log.Info("SignMessage", "result", result) 901 | } 902 | 903 | ///* 904 | //Description: 905 | //Deprecated 906 | //A demo test of SignRawtransactionWithWallet. 907 | //* Author: architect.bian 908 | //* Date: 2018/10/15 12:14 909 | //*/ 910 | //func SignRawtransactionWithWalletTest() { 911 | // result, err := cli.SignRawtransactionWithWallet() 912 | // if err != nil { 913 | // log.Fatal("", "error", err) 914 | // } 915 | // log.Info("SignRawtransactionWithWallet", "result", result) 916 | //} 917 | 918 | /* 919 | Description: 920 | A demo test of UnloadWallet. 921 | * Author: architect.bian 922 | * Date: 2018/10/15 12:14 923 | */ 924 | func UnloadWalletTest() { 925 | err := cli.UnloadWallet("/root/.bitcoin/regtest/wallets/mywallet") 926 | if err != nil { 927 | log.Fatal("", "error", err) 928 | } 929 | log.Info("UnloadWallet", "result", "success") 930 | } 931 | 932 | ///* 933 | //Description: 934 | //A demo test of WalletCreateFundedPSBT. 935 | // * Author: architect.bian 936 | // * Date: 2018/10/15 12:14 937 | // */ 938 | //func WalletCreateFundedPSBTTest() { 939 | // result, err := cli.WalletCreateFundedPSBT() 940 | // if err != nil { 941 | // log.Fatal("", "error", err) 942 | // } 943 | // log.Info("WalletCreateFundedPSBT", "result", result) 944 | //} 945 | 946 | /* 947 | Description: 948 | A demo test of WalletLock. 949 | * Author: architect.bian 950 | * Date: 2018/10/15 12:14 951 | */ 952 | func WalletLockTest() { 953 | err := cli.WalletLock() 954 | if err != nil { 955 | log.Fatal("", "error", err) 956 | } 957 | log.Info("WalletLock", "result", "success") 958 | } 959 | 960 | /* 961 | Description: 962 | A demo test of WalletPassphrase. 963 | * Author: architect.bian 964 | * Date: 2018/10/15 12:14 965 | */ 966 | func WalletPassphraseTest() { 967 | err := cli.WalletPassphrase("myphrase", 60000) 968 | if err != nil { 969 | log.Fatal("", "error", err) 970 | } 971 | log.Info("WalletPassphrase", "result", "success") 972 | SignMessageTest() 973 | } 974 | 975 | /* 976 | Description: 977 | A demo test of WalletPassphraseChange. 978 | * Author: architect.bian 979 | * Date: 2018/10/15 12:14 980 | */ 981 | func WalletPassphraseChangeTest() { 982 | err := cli.WalletPassphraseChange("myphrase", "rpcpwd") 983 | if err != nil { 984 | log.Fatal("", "error", err) 985 | } 986 | log.Info("WalletPassphraseChange", "result", "success") 987 | err2 := cli.WalletPassphraseChange("rpcpwd", "myphrase") 988 | if err2 != nil { 989 | log.Fatal("", "error", err2) 990 | } 991 | log.Info("WalletPassphraseChange", "result", "success") 992 | } 993 | 994 | ///* 995 | //Description: 996 | //A demo test of WalletProcessPSBT. 997 | // * Author: architect.bian 998 | // * Date: 2018/10/15 12:14 999 | // */ 1000 | //func WalletProcessPSBTTest() { 1001 | // result, err := cli.WalletProcessPSBT() 1002 | // if err != nil { 1003 | // log.Fatal("", "error", err) 1004 | // } 1005 | // log.Info("WalletProcessPSBT", "result", result) 1006 | //} -------------------------------------------------------------------------------- /examples/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/client" 5 | "github.com/chainlibs/gobtclib/examples/demos" 6 | "github.com/gobasis/log" 7 | "github.com/gobasis/log/zapimpl" 8 | ) 9 | 10 | /* 11 | Description: 12 | show demos of gobtclib/client 13 | * Author: architect.bian 14 | * Date: 2018/09/02 17:40 15 | */ 16 | func main() { 17 | log.UseLog(&zapimpl.Logger{}) // use zap log 18 | log.SetLevel(log.DevDebugLevel) 19 | log.Info("start up bitcoin rpc client") 20 | //cfg := &client.Config{ 21 | // Host: "172.16.2.35:3333", 22 | // User: "et", 23 | // Pass: "www.et.com", 24 | //} 25 | cfg := &client.Config{ 26 | Host: "172.16.2.27:8332", 27 | User: "btc", 28 | Pass: "btcpwd", 29 | } 30 | demos.Initialize(cfg) 31 | defer demos.Shutdown() 32 | //common rpc method 33 | //demos.SendTest() cli.Send("command", args...) 34 | 35 | //Blockchain rpc methods 36 | //demos.GetBestBlockHashTest() 37 | //demos.GetBlockBytesTest() 38 | //demos.GetBlockTest() 39 | //demos.GetBlockVerboseTXTest() 40 | demos.GetBlockVerboseTXTest() 41 | //demos.GetBlockChainInfoTest() 42 | //demos.GetBlockCountTest() 43 | //demos.GetBlockHashTest() 44 | //demos.GetBlockHeaderTest() 45 | //demos.GetBlockStatsTest() 46 | //demos.GetChainTipsTest() 47 | //demos.GetChainTXStatsTest() 48 | //demos.GetChainTXStatsEntireTest() 49 | //demos.GetDifficultyTest() 50 | //demos.GetMempoolAncestorsTest() 51 | //demos.GetMempoolAncestorsVerboseTest() 52 | //demos.GetMempoolDescendantsTest() 53 | //demos.GetMempoolDescendantsVerboseTest() 54 | //demos.GetMempoolEntryTest() 55 | //demos.GetMempoolInfoTest() 56 | //demos.GetRawMempoolTest() 57 | //demos.GetRawMempoolVerboseTest() 58 | //demos.GetTXOutTest() 59 | //demos.GetTXOutProofTest() 60 | //demos.GetTXOutSetInfoTest() 61 | //demos.PreciousBlockTest() 62 | //demos.PruneBlockchainTest() 63 | //demos.SaveMempoolTest() 64 | //demos.VerifyChainTest() 65 | //demos.VerifyTXOutProofTest() 66 | //demos.VerifyChainLevelTest() 67 | //demos.VerifyChainBlocksTest() 68 | 69 | //Control rpc methods 70 | //demos.GetMemoryInfoTest() 71 | //demos.GetMemoryInfo4MallocInfoTest() 72 | //demos.HelpTest() 73 | //demos.StopTest() 74 | //demos.UptimeTest() 75 | 76 | //Generate rpc methods 77 | //demos.GenerateTest() 78 | //demos.GenerateToAddressTest() 79 | 80 | //Network rpc methods 81 | //demos.GetNetworkInfoTest() 82 | 83 | //RawTransactions rpc methods 84 | //demos.CombinePSBTTest() //ok 85 | //demos.CombineRawTransactionTest() //ok 86 | //demos.ConvertToPSBTTest() //ok 87 | //demos.CreatepSBTTest() //ok 88 | //demos.CreateRawTransactionTest() //ok 89 | //demos.DecodePSBTTest() //ok 90 | //demos.DecodeRawTransactionTest() //ok 91 | //demos.DecodeScriptTest() //ok 92 | //demos.FinalizePSBTTest() //ok 93 | //demos.FundRawTransactionTest() //ok 94 | //demos.GetRawTransactionTest() //ok 95 | //demos.GetRawTransactionVerboseTest() //ok 96 | //demos.SendRawTransactionTest() //ok 97 | //demos.SignRawTransactionWithKeyTest() //ok 98 | //demos.TestMempoolAcceptTest() //ok 99 | 100 | //Wallet rpc methods 101 | //demos.WalletTestInitialize() //ok 102 | //demos.AbandonTransactionTest() //ok 103 | //demos.AbortRescanTest() //ok 104 | //demos.AddMultiSigAddressTest() //ok 105 | //demos.BackupWalletTest() //ok 106 | //demos.BumpFeeTest() //ok 107 | //demos.CreateWalletTest() //ok 108 | //demos.DumpPrivkeyTest() //ok 109 | //demos.DumpWalletTest() //ok 110 | //demos.EncryptWalletTest() //ok 111 | //demos.GetAddressesByLabelTest() //ok 112 | //demos.GetAddressInfoTest() //ok 113 | //demos.GetBalanceTest() //ok 114 | //demos.GetBalanceEntireTest() //ok 115 | //demos.GetNewAddressTest() //ok 116 | //demos.GetNewAddressEntireTest() //ok 117 | //demos.GetRawChangeAddressTest() //ok 118 | //demos.GetReceivedByAddressTest() //ok 119 | //demos.GetTransactionTest() //ok 120 | //demos.GetUnconfirmedBalanceTest() //ok 121 | //demos.GetWalletInfoTest() //ok 122 | //demos.ImportaddressTest() //ok 123 | //demos.ImportMultiTest() //ok 124 | //demos.ImportPrivkeyTest() //ok 125 | //demos.ImportPrunedFundsTest() //TODO 126 | //demos.ImportPubkeyTest() //ok 127 | //demos.ImportWalletTest() //test exception 128 | //demos.KeypoolRefillTest() //ok 129 | //demos.ListAddressGroupingsTest() //ok 130 | //demos.ListLabelsTest() //ok 131 | //demos.ListLockUnspentTest() // todo https://bitcoincore.org/en/doc/0.17.0/rpc/wallet/listlockunspent/ 132 | //demos.ListReceivedByAddressTest() //ok 133 | //demos.ListSinceBlockTest() //ok 134 | //demos.ListTransactionsTest() //ok 135 | //demos.ListUnspentTest() //ok 136 | //demos.ListUnspentEntireTest() //ok 137 | //demos.ListWalletsTest() //ok 138 | //demos.LoadWalletTest() //ok 139 | //demos.LockUnspentTest() //ok 140 | //demos.RemovePrunedFundsTest() //ok 141 | //demos.RescanBlockChainTest() //ok 142 | //demos.SendManyTest() //ok 143 | //demos.SendToAddressTest() //ok 144 | //demos.SendToAddressEntireTest() //ok 145 | //demos.SetHDSeedTest() //ok 146 | //demos.SetTXFeeTest() //ok 147 | //demos.SignMessageTest() //ok 148 | //demos.SignRawtransactionWithWalletTest() //TODO 149 | //demos.UnloadWalletTest() //ok 150 | //demos.WalletCreateFundedPSBTTest() //TODO no implement 151 | //demos.WalletLockTest() //ok 152 | //demos.WalletPassphraseTest() //ok 153 | //demos.WalletPassphraseChangeTest() //ok 154 | //demos.WalletProcessPSBTTest() //TODO 155 | } -------------------------------------------------------------------------------- /futures/Future.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureResult is a future promise to deliver the result of a RPC invocation (or an applicable error). 11 | * Author: architect.bian 12 | * Date: 2018/08/26 18:56 13 | */ 14 | type FutureResult chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | data structure requested from the server given its hash. 20 | * Author: architect.bian 21 | * Date: 2018/08/26 18:56 22 | */ 23 | func (r FutureResult) Receive() (*interface{}, error) { 24 | res, err := ReceiveFuture(r) 25 | if err != nil { 26 | return nil, err 27 | } 28 | var result interface{} 29 | // Unmarshal result as a string. 30 | err = json.Unmarshal(res, &result) 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | return &result, nil 36 | } 37 | 38 | /* 39 | Description: 40 | receiveFuture receives from the passed futureResult channel to extract a 41 | reply or any errors. The examined errors include an error in the 42 | futureResult and the error in the reply from the server. This will block 43 | until the result is available on the passed channel. 44 | * Author: architect.bian 45 | * Date: 2018/09/14 12:56 46 | */ 47 | func ReceiveFuture(f chan *base.Response) ([]byte, error) { 48 | // Wait for a response on the returned channel. 49 | r := <-f 50 | return r.Result, r.Err 51 | } 52 | 53 | /* 54 | Description: 55 | newFutureError returns a new future result channel that already has the 56 | passed error waitin on the channel with the reply set to nil. This is useful 57 | to easily return errors from the various Async functions. 58 | * Author: architect.bian 59 | * Date: 2018/09/14 12:57 60 | */ 61 | func NewFutureError(err error) chan *base.Response { 62 | responseChan := make(chan *base.Response, 1) 63 | responseChan <- &base.Response{Err: err} 64 | return responseChan 65 | } -------------------------------------------------------------------------------- /futures/FutureBool.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureBool is a future promise to deliver the result of bool type. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 10:57 13 | */ 14 | type FutureBool chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of float64 type. 20 | * Author: architect.bian 21 | * Date: 2018/10/15 10:57 22 | */ 23 | func (f FutureBool) Receive() (bool, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return false, err 27 | } 28 | 29 | // Unmarshal the result as a float64. 30 | var result bool 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return false, err 34 | } 35 | return result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureByteArray.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureByteArray is a future promise to deliver the result of []Byte type. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 10:57 13 | */ 14 | type FutureByteArray chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of Byte type. 20 | * Author: architect.bian 21 | * Date: 2018/10/15 10:57 22 | */ 23 | func (f FutureByteArray) Receive() ([]byte, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | // Unmarshal the result as a Byte. 30 | var result []byte 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureFloat64.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureFloat64 is a future promise to deliver the result of float64 type. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 10:57 13 | */ 14 | type FutureFloat64 chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of float64 type. 20 | * Author: architect.bian 21 | * Date: 2018/10/15 10:57 22 | */ 23 | func (f FutureFloat64) Receive() (float64, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return 0, err 27 | } 28 | 29 | // Unmarshal the result as a float64. 30 | var result float64 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return 0, err 34 | } 35 | return result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureFloat64Array.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureFloat64Array is a future promise to deliver the result of []float64 type. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 10:57 13 | */ 14 | type FutureFloat64Array chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of float64 type. 20 | * Author: architect.bian 21 | * Date: 2018/10/15 10:57 22 | */ 23 | func (f FutureFloat64Array) Receive() ([]float64, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | // Unmarshal the result as a float64. 30 | var result []float64 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureGetBestBlockHashResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetBestBlockHashResult is a future promise to deliver the result of a 12 | GetBestBlockAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/14 13:20 15 | */ 16 | type FutureGetBestBlockHashResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns the hash of 21 | the best block in the longest block chain. 22 | * Author: architect.bian 23 | * Date: 2018/09/14 13:20 24 | */ 25 | func (r FutureGetBestBlockHashResult) Receive() (*results.Hash, error) { 26 | res, err := ReceiveFuture(r) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | // Unmarshal result as a string. 32 | var txHashStr string 33 | err = json.Unmarshal(res, &txHashStr) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return results.NewHashFromStr(txHashStr) 38 | } 39 | 40 | -------------------------------------------------------------------------------- /futures/FutureGetBlockChainInfoResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | import ( 3 | "encoding/json" 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureGetBlockChainInfoResult is a promise to deliver the result of a 11 | GetBlockChainInfoAsync RPC invocation (or an applicable error). 12 | * Author: architect.bian 13 | * Date: 2018/09/17 14:51 14 | */ 15 | type FutureGetBlockChainInfoResult chan *base.Response 16 | 17 | /* 18 | Description: 19 | Receive waits for the response promised by the future and returns chain info 20 | result provided by the server. 21 | * Author: architect.bian 22 | * Date: 2018/09/17 14:52 23 | */ 24 | func (r FutureGetBlockChainInfoResult) Receive() (*results.GetBlockChainInfoResult, error) { 25 | res, err := ReceiveFuture(r) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | var result results.GetBlockChainInfoResult 31 | if err := json.Unmarshal(res, &result); err != nil { 32 | return nil, err 33 | } 34 | return &result, nil 35 | } 36 | 37 | -------------------------------------------------------------------------------- /futures/FutureGetBlockCountResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | import ( 3 | "encoding/json" 4 | "github.com/chainlibs/gobtclib/base" 5 | ) 6 | 7 | /* 8 | Description: 9 | FutureGetBlockCountResult is a future promise to deliver the result of a 10 | GetBlockCountAsync RPC invocation (or an applicable error). 11 | * Author: architect.bian 12 | * Date: 2018/09/14 12:55 13 | */ 14 | type FutureGetBlockCountResult chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the number 19 | of blocks in the longest block chain. 20 | * Author: architect.bian 21 | * Date: 2018/09/14 12:59 22 | */ 23 | func (r FutureGetBlockCountResult) Receive() (int64, error) { 24 | res, err := ReceiveFuture(r) 25 | if err != nil { 26 | return -1, err 27 | } 28 | 29 | // Unmarshal the result as an int64. 30 | var count int64 31 | err = json.Unmarshal(res, &count) 32 | if err != nil { 33 | return -1, err 34 | } 35 | return count, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureGetBlockHashResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | import ( 3 | "encoding/json" 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureGetBlockHashResult is a future promise to deliver the result of a 11 | GetBlockHashAsync RPC invocation (or an applicable error). 12 | * Author: architect.bian 13 | * Date: 2018/09/15 15:44 14 | */ 15 | type FutureGetBlockHashResult chan *base.Response 16 | 17 | /* 18 | Description: 19 | Receive waits for the response promised by the future and returns the hash of 20 | the block in the best block chain at the given height. 21 | * Author: architect.bian 22 | * Date: 2018/09/15 15:45 23 | */ 24 | func (r FutureGetBlockHashResult) Receive() (*results.Hash, error) { 25 | res, err := ReceiveFuture(r) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | // Unmarshal the result as a string-encoded sha. 31 | var txHashStr string 32 | err = json.Unmarshal(res, &txHashStr) 33 | if err != nil { 34 | return nil, err 35 | } 36 | return results.NewHashFromStr(txHashStr) 37 | } 38 | -------------------------------------------------------------------------------- /futures/FutureGetBlockHeaderResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | import ( 3 | "encoding/json" 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureGetBlockHeaderResult is a future promise to deliver the result of a 11 | GetBlockAsync RPC invocation (or an applicable error). 12 | * Author: architect.bian 13 | * Date: 2018/09/15 17:52 14 | */ 15 | type FutureGetBlockHeaderResult chan *base.Response 16 | 17 | /* 18 | Description: 19 | Receive waits for the response promised by the future and returns the 20 | data structure of the blockheader requested from the server given its hash. 21 | * Author: architect.bian 22 | * Date: 2018/09/15 17:52 23 | */ 24 | func (r FutureGetBlockHeaderResult) Receive() (*results.GetBlockHeaderResult, error) { 25 | res, err := ReceiveFuture(r) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | // Unmarshal result as a string. 31 | var bh results.GetBlockHeaderResult 32 | err = json.Unmarshal(res, &bh) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | return &bh, nil 38 | } 39 | 40 | -------------------------------------------------------------------------------- /futures/FutureGetBlockResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetBlockResult is a future promise to deliver the result of a 12 | GetBlockVerboseAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 16:26 15 | */ 16 | type FutureGetBlockResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns the data 21 | structure from the server with information about the requested block. 22 | * Author: architect.bian 23 | * Date: 2018/09/17 16:26 24 | */ 25 | func (f FutureGetBlockResult) Receive() (*results.GetBlockResult, error) { 26 | res, err := ReceiveFuture(f) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | // Unmarshal the raw result into a BlockResult. 32 | var blockResult results.GetBlockResult 33 | err = json.Unmarshal(res, &blockResult) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return &blockResult, nil 38 | } 39 | 40 | -------------------------------------------------------------------------------- /futures/FutureGetBlockVerboseTXResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetBlockVerboseTXResult is a future promise to deliver the result of a 12 | GetBlockVerboseTXAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 16:26 15 | */ 16 | type FutureGetBlockVerboseTXResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns the data 21 | structure from the server with information about the requested block. 22 | * Author: architect.bian 23 | * Date: 2018/09/17 16:26 24 | */ 25 | func (r FutureGetBlockVerboseTXResult) Receive() (*results.GetBlockVerboseTXResult, error) { 26 | res, err := ReceiveFuture(r) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | // Unmarshal the raw result into a BlockResult. 32 | var blockResult results.GetBlockVerboseTXResult 33 | err = json.Unmarshal(res, &blockResult) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return &blockResult, nil 38 | } 39 | 40 | -------------------------------------------------------------------------------- /futures/FutureGetChainTXStatsResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | "encoding/json" 7 | "fmt" 8 | ) 9 | 10 | /* 11 | Description: 12 | FutureGetChainTXStatsResult is a future promise to deliver the result of a 13 | GetChainTXStats RPC invocation (or an applicable error). 14 | * Author: architect.bian 15 | * Date: 2018/10/10 13:56 16 | */ 17 | type FutureGetChainTXStatsResult chan *base.Response 18 | 19 | /* 20 | Description: 21 | Receive waits for the response promised by the future and returns the data 22 | structure from the server with information about the requested block. 23 | * Author: architect.bian 24 | * Date: 2018/10/10 13:57 25 | */ 26 | func (f FutureGetChainTXStatsResult) Receive() (*results.GetChainTXStatsResult, error) { 27 | res, err := ReceiveFuture(f) 28 | if err != nil { 29 | return nil, err 30 | } 31 | fmt.Println(string(res)) 32 | 33 | var result results.GetChainTXStatsResult 34 | err = json.Unmarshal(res, &result) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return &result, nil 39 | } -------------------------------------------------------------------------------- /futures/FutureGetChainTipsResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | "encoding/json" 7 | "fmt" 8 | ) 9 | 10 | /* 11 | Description: 12 | FutureGetChainTipsResult is a future promise to deliver the result of a 13 | GetChainTipsAsync RPC invocation (or an applicable error). 14 | * Author: architect.bian 15 | * Date: 2018/10/10 13:56 16 | */ 17 | type FutureGetChainTipsResult chan *base.Response 18 | 19 | /* 20 | Description: 21 | Receive waits for the response promised by the future and returns the data 22 | structure from the server with information about the requested block. 23 | * Author: architect.bian 24 | * Date: 2018/10/10 13:57 25 | */ 26 | func (f FutureGetChainTipsResult) Receive() (*[]results.GetChainTipsResult, error) { 27 | res, err := ReceiveFuture(f) 28 | if err != nil { 29 | return nil, err 30 | } 31 | fmt.Println(string(res)) 32 | var result []results.GetChainTipsResult 33 | err = json.Unmarshal(res, &result) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return &result, nil 38 | } -------------------------------------------------------------------------------- /futures/FutureGetDifficultyResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureGetDifficultyResult is a future promise to deliver the result of a 11 | GetDifficultyAsync RPC invocation (or an applicable error). 12 | * Author: architect.bian 13 | * Date: 2018/09/14 17:36 14 | */ 15 | type FutureGetDifficultyResult chan *base.Response 16 | 17 | /* 18 | Description: 19 | Receive waits for the response promised by the future and returns the 20 | proof-of-work difficulty as a multiple of the minimum difficulty. 21 | * Author: architect.bian 22 | * Date: 2018/09/14 17:36 23 | */ 24 | func (r FutureGetDifficultyResult) Receive() (float64, error) { 25 | res, err := ReceiveFuture(r) 26 | if err != nil { 27 | return 0, err 28 | } 29 | 30 | // Unmarshal the result as a float64. 31 | var difficulty float64 32 | err = json.Unmarshal(res, &difficulty) 33 | if err != nil { 34 | return 0, err 35 | } 36 | return difficulty, nil 37 | } 38 | -------------------------------------------------------------------------------- /futures/FutureGetMempoolEntryResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetMempoolEntryResult is a future promise to deliver the result of a 12 | GetMempoolEntryAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 20:24 15 | */ 16 | type FutureGetMempoolEntryResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns a data 21 | structure with information about the transaction in the memory pool given 22 | its hash. 23 | * Author: architect.bian 24 | * Date: 2018/09/17 20:24 25 | */ 26 | func (r FutureGetMempoolEntryResult) Receive() (*results.GetMempoolEntryResult, error) { 27 | res, err := ReceiveFuture(r) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | // Unmarshal the result as an array of strings. 33 | var mempoolEntryResult results.GetMempoolEntryResult 34 | err = json.Unmarshal(res, &mempoolEntryResult) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | return &mempoolEntryResult, nil 40 | } 41 | 42 | -------------------------------------------------------------------------------- /futures/FutureGetMempoolInfoResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | import ( 3 | "encoding/json" 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureGetBlockChainInfoResult is a promise to deliver the result of a 11 | GetBlockChainInfoAsync RPC invocation (or an applicable error). 12 | * Author: architect.bian 13 | * Date: 2018/09/17 14:51 14 | */ 15 | type FutureGetMempoolInfoResult chan *base.Response 16 | 17 | /* 18 | Description: 19 | Receive waits for the response promised by the future and returns chain info 20 | result provided by the server. 21 | * Author: architect.bian 22 | * Date: 2018/09/17 14:52 23 | */ 24 | func (r FutureGetMempoolInfoResult) Receive() (*results.GetMempoolInfoResult, error) { 25 | res, err := ReceiveFuture(r) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | var result results.GetMempoolInfoResult 31 | if err := json.Unmarshal(res, &result); err != nil { 32 | return nil, err 33 | } 34 | return &result, nil 35 | } 36 | 37 | -------------------------------------------------------------------------------- /futures/FutureGetRawMempoolResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetRawMempoolResult is a future promise to deliver the result of a 12 | GetRawMempoolAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 19:54 15 | */ 16 | type FutureGetRawMempoolResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns the hashes 21 | of all transactions in the memory pool. 22 | * Author: architect.bian 23 | * Date: 2018/09/17 19:54 24 | */ 25 | func (r FutureGetRawMempoolResult) Receive() ([]*results.Hash, error) { 26 | res, err := ReceiveFuture(r) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | // Unmarshal the result as an array of strings. 32 | var txHashStrs []string 33 | err = json.Unmarshal(res, &txHashStrs) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | // Create a slice of ShaHash arrays from the string slice. 39 | txHashes := make([]*results.Hash, 0, len(txHashStrs)) 40 | for _, hashStr := range txHashStrs { 41 | txHash, err := results.NewHashFromStr(hashStr) 42 | if err != nil { 43 | return nil, err 44 | } 45 | txHashes = append(txHashes, txHash) 46 | } 47 | 48 | return txHashes, nil 49 | } 50 | 51 | -------------------------------------------------------------------------------- /futures/FutureGetRawMempoolVerboseResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetRawMempoolVerboseResult is a future promise to deliver the result of 12 | a GetRawMempoolVerboseAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 20:11 15 | */ 16 | type FutureGetRawMempoolVerboseResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns a map of 21 | transaction hashes to an associated data structure with information about the 22 | transaction for all transactions in the memory pool. 23 | * Author: architect.bian 24 | * Date: 2018/09/17 20:11 25 | */ 26 | func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]results.GetRawMempoolVerboseResult, error) { 27 | res, err := ReceiveFuture(r) 28 | if err != nil { 29 | return nil, err 30 | } 31 | 32 | // Unmarshal the result as a map of strings (tx shas) to their detailed results. 33 | var mempoolItems map[string]results.GetRawMempoolVerboseResult 34 | err = json.Unmarshal(res, &mempoolItems) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return mempoolItems, nil 39 | } 40 | 41 | -------------------------------------------------------------------------------- /futures/FutureGetTXOutSetInfoResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | import ( 3 | "encoding/json" 4 | "github.com/chainlibs/gobtclib/base" 5 | "github.com/chainlibs/gobtclib/results" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureGetBlockChainInfoResult is a promise to deliver the result of a 11 | GetBlockChainInfoAsync RPC invocation (or an applicable error). 12 | * Author: architect.bian 13 | * Date: 2018/09/17 14:51 14 | */ 15 | type FutureGetTXOutSetInfoResult chan *base.Response 16 | 17 | /* 18 | Description: 19 | Receive waits for the response promised by the future and returns chain info 20 | result provided by the server. 21 | * Author: architect.bian 22 | * Date: 2018/09/17 14:52 23 | */ 24 | func (r FutureGetTXOutSetInfoResult) Receive() (*results.GetTXOutSetInfoResult, error) { 25 | res, err := ReceiveFuture(r) 26 | if err != nil { 27 | return nil, err 28 | } 29 | 30 | var result results.GetTXOutSetInfoResult 31 | if err := json.Unmarshal(res, &result); err != nil { 32 | return nil, err 33 | } 34 | return &result, nil 35 | } 36 | 37 | -------------------------------------------------------------------------------- /futures/FutureGetTxOutResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | "github.com/chainlibs/gobtclib/results" 7 | ) 8 | 9 | /* 10 | Description: 11 | FutureGetTxOutResult is a future promise to deliver the result of a 12 | GetTxOutAsync RPC invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 21:08 15 | */ 16 | type FutureGetTxOutResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns a 21 | transaction given its hash. 22 | * Author: architect.bian 23 | * Date: 2018/09/17 21:08 24 | */ 25 | func (r FutureGetTxOutResult) Receive() (*results.GetTxOutResult, error) { 26 | res, err := ReceiveFuture(r) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | // take care of the special case where the output has been spent already 32 | // it should return the string "null" 33 | if string(res) == "null" { 34 | return nil, nil 35 | } 36 | 37 | // Unmarshal result as an gettxout result object. 38 | var txOutInfo *results.GetTxOutResult 39 | err = json.Unmarshal(res, &txOutInfo) 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | return txOutInfo, nil 45 | } 46 | 47 | -------------------------------------------------------------------------------- /futures/FutureInt32.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureInt32 is a future promise to deliver the result of int32 type. 11 | * Author: architect.bian 12 | * Date: 2018/09/14 17:36 13 | */ 14 | type FutureInt32 chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of int32 type. 20 | * Author: architect.bian 21 | * Date: 2018/09/14 17:36 22 | */ 23 | func (f FutureInt32) Receive() (int32, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return 0, err 27 | } 28 | 29 | // Unmarshal the result as a int32. 30 | var result int32 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return 0, err 34 | } 35 | return result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureInt32Array.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureInt32Array is a future promise to deliver the result of []int32 type. 11 | * Author: architect.bian 12 | * Date: 2018/09/14 17:36 13 | */ 14 | type FutureInt32Array chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of int32 type. 20 | * Author: architect.bian 21 | * Date: 2018/09/14 17:36 22 | */ 23 | func (f FutureInt32Array) Receive() ([]int32, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | // Unmarshal the result as a int32. 30 | var result []int32 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureString.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureString is a future promise to deliver the result of string type. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 10:56 13 | */ 14 | type FutureString chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of string type. 20 | * Author: architect.bian 21 | * Date: 2018/10/15 10:56 22 | */ 23 | func (f FutureString) Receive() (*string, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | // Unmarshal the result as a string. 30 | var result string 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return &result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureStringArray.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureStringArray is a future promise to deliver the result of []string type. 11 | * Author: architect.bian 12 | * Date: 2018/10/15 10:56 13 | */ 14 | type FutureStringArray chan *base.Response 15 | 16 | /* 17 | Description: 18 | Receive waits for the response promised by the future and returns the 19 | result of string type. 20 | * Author: architect.bian 21 | * Date: 2018/10/15 10:56 22 | */ 23 | func (f FutureStringArray) Receive() (*[]string, error) { 24 | res, err := ReceiveFuture(f) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | // Unmarshal the result as a string. 30 | var result []string 31 | err = json.Unmarshal(res, &result) 32 | if err != nil { 33 | return nil, err 34 | } 35 | return &result, nil 36 | } 37 | -------------------------------------------------------------------------------- /futures/FutureVerifyChainResult.go: -------------------------------------------------------------------------------- 1 | package futures 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/chainlibs/gobtclib/base" 6 | ) 7 | 8 | /* 9 | Description: 10 | FutureVerifyChainResult is a future promise to deliver the result of a 11 | VerifyChainAsync, VerifyChainLevelAsyncRPC, or VerifyChainBlocksAsync 12 | invocation (or an applicable error). 13 | * Author: architect.bian 14 | * Date: 2018/09/17 20:54 15 | */ 16 | type FutureVerifyChainResult chan *base.Response 17 | 18 | /* 19 | Description: 20 | Receive waits for the response promised by the future and returns whether 21 | or not the chain verified based on the check level and number of blocks 22 | to verify specified in the original call. 23 | * Author: architect.bian 24 | * Date: 2018/09/17 20:54 25 | */ 26 | func (r FutureVerifyChainResult) Receive() (bool, error) { 27 | res, err := ReceiveFuture(r) 28 | if err != nil { 29 | return false, err 30 | } 31 | 32 | // Unmarshal the result as a boolean. 33 | var verified bool 34 | err = json.Unmarshal(res, &verified) 35 | if err != nil { 36 | return false, err 37 | } 38 | return verified, nil 39 | } 40 | 41 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package btc 2 | 3 | import "github.com/chainlibs/gobtclib/client" 4 | 5 | /* 6 | Description: 7 | global client instance 8 | * Author: architect.bian 9 | * Date: 2018/10/24 12:59 10 | */ 11 | var Client *client.Client 12 | 13 | /* 14 | Description: 15 | initialize a Client instance with host/user/passwd parameters 16 | * Author: architect.bian 17 | * Date: 2018/10/24 12:57 18 | */ 19 | func StartUp(host, user, passwd string) { 20 | cfg := &client.Config{ 21 | Host: host, 22 | User: user, 23 | Pass: passwd, 24 | } 25 | Client = client.NewClient(cfg).Startup() 26 | } -------------------------------------------------------------------------------- /results/BlockHeader.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | import ( 4 | "time" 5 | "io" 6 | ) 7 | 8 | /* 9 | Description: 10 | BlockHeader defines information about a block and is used in the bitcoin 11 | block (MsgBlock) and headers (MsgHeaders) messages. 12 | * Author: architect.bian 13 | * Date: 2018/09/17 15:27 14 | */ 15 | type BlockHeader struct { 16 | // Version of the block. This is not the same as the protocol version. 17 | Version int32 18 | 19 | // Hash of the previous block header in the block chain. 20 | PrevBlock Hash 21 | 22 | // Merkle tree reference to hash of all transactions for the block. 23 | MerkleRoot Hash 24 | 25 | // Time the block was created. This is, unfortunately, encoded as a 26 | // uint32 on the wire and therefore is limited to 2106. 27 | Timestamp time.Time 28 | 29 | // Difficulty target for the block. 30 | Bits uint32 31 | 32 | // Nonce used to generate the block. 33 | Nonce uint32 34 | } 35 | 36 | // Deserialize decodes a block header from r into the receiver using a format 37 | // that is suitable for long-term storage such as a database while respecting 38 | // the Version field. 39 | func (h *BlockHeader) Deserialize(r io.Reader) error { //TODO parse blockheader data 40 | // At the current time, there is no difference between the wire encoding 41 | // at protocol version 0 and the stable long-term storage format. As 42 | // a result, make use of readBlockHeader. 43 | return nil 44 | } 45 | 46 | // Serialize encodes a block header from r into the receiver using a format 47 | // that is suitable for long-term storage such as a database while respecting 48 | // the Version field. 49 | func (h *BlockHeader) Serialize(w io.Writer) error { 50 | // At the current time, there is no difference between the wire encoding 51 | // at protocol version 0 and the stable long-term storage format. As 52 | // a result, make use of writeBlockHeader. 53 | return nil 54 | } 55 | 56 | -------------------------------------------------------------------------------- /results/GetBlockChainInfoResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | SoftForkDescription describes the current state of a soft-fork which was 6 | deployed using a super-majority block signalling. 7 | * Author: architect.bian 8 | * Date: 2018/10/07 17:49 9 | */ 10 | type SoftForkDescription struct { 11 | ID string `json:"id"` 12 | Version uint32 `json:"version"` 13 | Reject struct { 14 | Status bool `json:"status"` 15 | } `json:"reject"` 16 | } 17 | 18 | /* 19 | Description: 20 | Bip9SoftForkDescription describes the current state of a defined BIP0009 21 | version bits soft-fork. 22 | * Author: architect.bian 23 | * Date: 2018/10/07 17:49 24 | */ 25 | type Bip9SoftForkDescription struct { 26 | Status string `json:"status"` 27 | Bit uint8 `json:"bit"` 28 | StartTime int64 `json:"startTime"` 29 | Timeout int64 `json:"timeout"` 30 | Since int32 `json:"since"` 31 | } 32 | 33 | /* 34 | Description: 35 | GetBlockChainInfoResult models the data returned from the getblockchaininfo command. 36 | * Author: architect.bian 37 | * Date: 2018/09/17 14:53 38 | */ 39 | type GetBlockChainInfoResult struct { 40 | Chain string `json:"chain"` 41 | Blocks int32 `json:"blocks"` 42 | Headers int32 `json:"headers"` 43 | BestBlockHash string `json:"bestblockhash"` 44 | Difficulty float64 `json:"difficulty"` 45 | MedianTime int64 `json:"mediantime"` 46 | VerificationProgress float64 `json:"verificationprogress,omitempty"` 47 | Pruned bool `json:"pruned"` 48 | PruneHeight int32 `json:"pruneheight,omitempty"` 49 | ChainWork string `json:"chainwork,omitempty"` 50 | SoftForks []*SoftForkDescription `json:"softforks"` 51 | Bip9SoftForks map[string]*Bip9SoftForkDescription `json:"bip9_softforks"` 52 | } 53 | 54 | -------------------------------------------------------------------------------- /results/GetBlockHeaderResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetBlockHeaderResult models the data from the getblockheader command when 6 | the verbose flag is set. When the verbose flag is not set, getblockheader 7 | returns a hex-encoded string. 8 | * Author: architect.bian 9 | * Date: 2018/10/07 17:37 10 | */ 11 | type GetBlockHeaderResult struct { 12 | Hash string `json:"hash"` 13 | Confirmations uint64 `json:"confirmations"` 14 | Height int32 `json:"height"` 15 | Version int32 `json:"version"` 16 | VersionHex string `json:"versionHex"` 17 | MerkleRoot string `json:"merkleroot"` 18 | Time int64 `json:"time"` 19 | Nonce uint64 `json:"nonce"` 20 | Bits string `json:"bits"` 21 | Difficulty float64 `json:"difficulty"` 22 | PreviousHash string `json:"previousblockhash,omitempty"` 23 | NextHash string `json:"nextblockhash,omitempty"` 24 | } 25 | 26 | -------------------------------------------------------------------------------- /results/GetBlockResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetBlockResult models the data from the getblock command when the 6 | verbose flag is 0/1. When the verbose flag is set as 0, getblock returns a 7 | hex-encoded string. 8 | * Author: architect.bian 9 | * Date: 2018/09/17 16:27 10 | */ 11 | type GetBlockResult struct { 12 | Hash string `json:"hash"` 13 | Confirmations uint64 `json:"confirmations"` 14 | StrippedSize int32 `json:"strippedsize"` 15 | Size int32 `json:"size"` 16 | Weight int32 `json:"weight"` 17 | Height int64 `json:"height"` 18 | Version int32 `json:"version"` 19 | VersionHex string `json:"versionHex"` 20 | MerkleRoot string `json:"merkleroot"` 21 | Tx []string `json:"tx,omitempty"` 22 | RawTx []TxRawResult `json:"rawtx,omitempty"` 23 | Time int64 `json:"time"` 24 | Nonce uint32 `json:"nonce"` 25 | Bits string `json:"bits"` 26 | Difficulty float64 `json:"difficulty"` 27 | PreviousHash string `json:"previousblockhash"` 28 | NextHash string `json:"nextblockhash,omitempty"` 29 | } 30 | 31 | -------------------------------------------------------------------------------- /results/GetBlockStatsResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetBlockStatsResult models the data from the GetBlockStats command 6 | * Author: architect.bian 7 | * Date: 2018/10/11 11:36 8 | */ 9 | type GetBlockStatsResult struct { 10 | Avgfee int32 `json:"avgfee,omitempty"` 11 | Avgfeerate int32 `json:"avgfeerate"` 12 | Avgtxsize int32 `json:"avgtxsize"` 13 | Blockhash string `json:"blockhash"` 14 | FeeratePercentiles []int32 `json:"feerate_percentiles"` 15 | Height int32 `json:"height"` 16 | Ins int32 `json:"ins"` 17 | Maxfee int32 `json:"maxfee"` 18 | Maxfeerate int32 `json:"maxfeerate"` 19 | Maxtxsize int32 `json:"maxtxsize"` 20 | Medianfee int32 `json:"medianfee"` 21 | Mediantime int32 `json:"mediantime"` 22 | Mediantxsize int32 `json:"mediantxsize"` 23 | Minfee int32 `json:"minfee"` 24 | Minfeerate int32 `json:"minfeerate"` 25 | Mintxsize int32 `json:"mintxsize"` 26 | Outs int32 `json:"outs"` 27 | Subsidy int32 `json:"subsidy"` 28 | SwtotalSize int32 `json:"swtotal_size"` 29 | SwtotalWeight int32 `json:"swtotal_weight"` 30 | Swtxs int32 `json:"swtxs"` 31 | Time int32 `json:"time"` 32 | TotalOut int32 `json:"total_out"` 33 | TotalSize int32 `json:"total_size"` 34 | TotalWeight int32 `json:"total_weight"` 35 | Totalfee int32 `json:"totalfee"` 36 | Txs int32 `json:"txs"` 37 | UtxoIncrease int32 `json:"utxo_increase"` 38 | UtxoSizeInc int32 `json:"utxo_size_inc"` 39 | } 40 | -------------------------------------------------------------------------------- /results/GetBlockVerboseTXResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetBlockVerboseTXResult models the data from the getblock command when the 6 | verbose flag is 2. When the verbose flag is set as 0, getblock returns a 7 | hex-encoded string. 8 | * Author: architect.bian 9 | * Date: 2018/09/17 16:27 10 | */ 11 | type GetBlockVerboseTXResult struct { 12 | GetBlockResult 13 | Tx []TxRawResult `json:"tx"` 14 | } 15 | 16 | -------------------------------------------------------------------------------- /results/GetChainTXStatsResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetChainTXStatsResult models the data from the GetChainTXStats command 6 | * Author: architect.bian 7 | * Date: 2018/10/11 11:36 8 | */ 9 | type GetChainTXStatsResult struct { 10 | Time int32 `json:"time"` 11 | Txcount int32 `json:"txcount"` 12 | WindowFinalBlockHash string `json:"window_final_block_hash"` 13 | WindowBlockCount int32 `json:"window_block_count"` 14 | WindowTXCount int32 `json:"window_tx_count"` 15 | WindowInterval int32 `json:"window_interval"` 16 | Txrate float32 `json:"txrate"` 17 | } 18 | -------------------------------------------------------------------------------- /results/GetChainTipsResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetChainTipsResult models the data from the getchaintips command 6 | * Author: architect.bian 7 | * Date: 2018/10/10 11:18 8 | */ 9 | type GetChainTipsResult struct { 10 | Height int32 `json:"height"` 11 | Hash string `json:"hash"` 12 | Branchlen int32 `json:"branchlen"` 13 | Status string `json:"status"` 14 | } 15 | -------------------------------------------------------------------------------- /results/GetMempoolEntryResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetMempoolEntryResult models the data returned from the getmempoolentry command. 6 | * Author: architect.bian 7 | * Date: 2018/09/17 20:24 8 | */ 9 | type GetMempoolEntryResult struct { 10 | Size int32 `json:"size"` 11 | Fee float64 `json:"fee"` 12 | ModifiedFee float64 `json:"modifiedfee"` 13 | Time int64 `json:"time"` 14 | Height int64 `json:"height"` 15 | StartingPriority float64 `json:"startingpriority"` 16 | CurrentPriority float64 `json:"currentpriority"` 17 | DescendantCount int64 `json:"descendantcount"` 18 | DescendantSize int64 `json:"descendantsize"` 19 | DescendantFees float64 `json:"descendantfees"` 20 | AncestorCount int64 `json:"ancestorcount"` 21 | AncestorSize int64 `json:"ancestorsize"` 22 | AncestorFees float64 `json:"ancestorfees"` 23 | Depends []string `json:"depends"` 24 | } 25 | 26 | -------------------------------------------------------------------------------- /results/GetMempoolInfoResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetMempoolInfoResult models the data from the GetMempoolInfo command 6 | * Author: architect.bian 7 | * Date: 2018/10/11 11:37 8 | */ 9 | type GetMempoolInfoResult struct { 10 | Size int32 `json:"size"` 11 | Bytes int32 `json:"bytes"` 12 | Usage int32 `json:"usage"` 13 | MaxMempool int32 `json:"maxmempool"` 14 | MempoolMinfee float32 `json:"mempoolminfee"` 15 | MinRelayTXFee float32 `json:"minrelaytxfee"` 16 | } 17 | -------------------------------------------------------------------------------- /results/GetRawMempoolVerboseResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetRawMempoolVerboseResult models the data returned from the getrawmempool 6 | command when the verbose flag is set. When the verbose flag is not set, 7 | getrawmempool returns an array of transaction hashes. 8 | * Author: architect.bian 9 | * Date: 2018/09/17 20:12 10 | */ 11 | type GetRawMempoolVerboseResult struct { 12 | Size int32 `json:"size"` 13 | Vsize int32 `json:"vsize"` 14 | Fee float64 `json:"fee"` 15 | Time int64 `json:"time"` 16 | Height int64 `json:"height"` 17 | StartingPriority float64 `json:"startingpriority"` //TODO new version compatibility 18 | CurrentPriority float64 `json:"currentpriority"` //TODO new version compatibility 19 | Depends []string `json:"depends"` 20 | } 21 | 22 | -------------------------------------------------------------------------------- /results/GetTXOutSetInfoResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | /* 4 | Description: 5 | GetTXOutSetInfoResult models the data from the GetTXOutSetInfo command 6 | * Author: architect.bian 7 | * Date: 2018/10/11 11:36 8 | */ 9 | type GetTXOutSetInfoResult struct { 10 | Height int32 `json:"height"` 11 | Bestblock string `json:"bestblock"` 12 | Transactions int32 `json:"transactions"` 13 | Txouts int32 `json:"txouts"` 14 | Bogosize int32 `json:"bogosize"` 15 | HashSerialized2 string `json:"hash_serialized_2"` 16 | DiskSize int32 `json:"disk_size"` 17 | TotalAmount float32 `json:"total_amount"` 18 | } 19 | -------------------------------------------------------------------------------- /results/GetTxOutResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | // GetTxOutResult models the data from the gettxout command. 4 | type GetTxOutResult struct { 5 | BestBlock string `json:"bestblock"` 6 | Confirmations int64 `json:"confirmations"` 7 | Value float64 `json:"value"` 8 | ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"` 9 | Coinbase bool `json:"coinbase"` 10 | } 11 | 12 | -------------------------------------------------------------------------------- /results/Hash.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | "crypto/sha256" 7 | ) 8 | 9 | /* 10 | Description: 11 | HashSize of array used to store hashes. See Hash. 12 | * Author: architect.bian 13 | * Date: 2018/09/14 15:23 14 | */ 15 | const HashSize = 32 16 | 17 | /* 18 | Description: 19 | MaxHashStringSize is the maximum length of a Hash hash string. 20 | 1byte=8*1bit 21 | 16 = 4*1bit 22 | the max of 1byte is 16*16, 1byte can present with 2 hexadecimal 23 | * Author: architect.bian 24 | * Date: 2018/09/14 15:23 25 | */ 26 | const MaxHashStringSize = HashSize * 2 27 | 28 | /* 29 | Description: 30 | HashStrSizeErr describes an error that indicates the caller specified a hash 31 | string that has too many characters. 32 | * Author: architect.bian 33 | * Date: 2018/09/14 15:29 34 | */ 35 | var HashStrSizeErr = fmt.Errorf("max hash string length is %v bytes", MaxHashStringSize) 36 | 37 | /* 38 | Description: 39 | Hash is used in several of the bitcoin messages and common structures. It 40 | typically represents the double sha256 of data. 41 | reference document https://bitcoin.org/en/developer-reference#hash-byte-order 42 | * Author: architect.bian 43 | * Date: 2018/08/27 11:10 44 | */ 45 | type Hash [HashSize]byte 46 | 47 | /* 48 | Description: 49 | String returns the Hash as the hexadecimal string of the byte-reversed hash. 50 | * Author: architect.bian 51 | * Date: 2018/08/27 11:15 52 | */ 53 | func (hash Hash) String() string { 54 | for i := 0; i < HashSize/2; i++ { 55 | hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i] 56 | } 57 | return hex.EncodeToString(hash[:]) 58 | } 59 | 60 | /* 61 | Description: 62 | CloneBytes returns a copy of the bytes which represent the hash as a byte slice. 63 | 64 | NOTE: It is generally cheaper to just slice the hash directly thereby reusing 65 | the same bytes rather than calling this method. 66 | * Author: architect.bian 67 | * Date: 2018/08/27 11:16 68 | */ 69 | func (hash *Hash) CloneBytes() []byte { 70 | newHash := make([]byte, HashSize) 71 | copy(newHash, hash[:]) 72 | return newHash 73 | } 74 | 75 | /* 76 | Description: 77 | SetBytes sets the bytes which represent the hash. An error is returned if 78 | the number of bytes passed in is not HashSize. 79 | * Author: architect.bian 80 | * Date: 2018/08/27 11:18 81 | */ 82 | func (hash *Hash) SetBytes(newHash []byte) error { 83 | nhlen := len(newHash) 84 | if nhlen != HashSize { 85 | return fmt.Errorf("invalid hash length of %v, want %v", nhlen, HashSize) 86 | } 87 | copy(hash[:], newHash) 88 | return nil 89 | } 90 | 91 | /* 92 | Description: 93 | IsEqual returns true if target is the same as hash. 94 | * Author: architect.bian 95 | * Date: 2018/08/27 11:19 96 | */ 97 | func (hash *Hash) IsEqual(target *Hash) bool { 98 | if hash == nil && target == nil { 99 | return true 100 | } 101 | if hash == nil || target == nil { 102 | return false 103 | } 104 | return *hash == *target 105 | } 106 | 107 | /* 108 | Description: 109 | NewHash returns a new Hash from a byte slice. An error is returned if 110 | the number of bytes passed in is not HashSize. 111 | * Author: architect.bian 112 | * Date: 2018/08/27 11:20 113 | */ 114 | func NewHash(newHash []byte) (*Hash, error) { 115 | var sh Hash 116 | err := sh.SetBytes(newHash) 117 | if err != nil { 118 | return nil, err 119 | } 120 | return &sh, err 121 | } 122 | 123 | /* 124 | Description: 125 | NewHashFromStr creates a Hash from a hash string. The string should be 126 | the hexadecimal string of a byte-reversed hash, but any missing characters 127 | result in zero padding at the end of the Hash. 128 | * Author: architect.bian 129 | * Date: 2018/08/27 11:30 130 | */ 131 | func NewHashFromStr(hash string) (*Hash, error) { 132 | ret := new(Hash) 133 | err := Decode(ret, hash) 134 | if err != nil { 135 | return nil, err 136 | } 137 | return ret, nil 138 | } 139 | 140 | /* 141 | Description: 142 | Decode decodes the byte-reversed hexadecimal string encoding of a Hash to a destination. 143 | * Author: architect.bian 144 | * Date: 2018/08/27 11:30 145 | */ 146 | func Decode(dst *Hash, src string) error { 147 | // Return error if hash string is too long. 148 | if len(src) > MaxHashStringSize { 149 | return HashStrSizeErr 150 | } 151 | 152 | // Hex decoder expects the hash to be a multiple of two. When not, pad with a leading zero. 153 | var srcBytes []byte 154 | if len(src)%2 == 0 { 155 | srcBytes = []byte(src) 156 | } else { 157 | srcBytes = make([]byte, 1+len(src)) 158 | srcBytes[0] = '0' 159 | copy(srcBytes[1:], src) 160 | } 161 | 162 | // Hex decode the source bytes to a temporary destination. 163 | var reversedHash Hash 164 | _, err := hex.Decode(reversedHash[HashSize-hex.DecodedLen(len(srcBytes)):], srcBytes) 165 | if err != nil { 166 | return err 167 | } 168 | 169 | // Reverse copy from the temporary hash to destination. Because the 170 | // temporary was zeroed, the written result will be correctly padded. 171 | for i, b := range reversedHash[:HashSize/2] { 172 | dst[i], dst[HashSize-1-i] = reversedHash[HashSize-1-i], b 173 | } 174 | 175 | return nil 176 | } 177 | 178 | /* 179 | Description: 180 | HashB calculates hash(b) and returns the resulting bytes. 181 | * Author: architect.bian 182 | * Date: 2018/08/27 13:05 183 | */ 184 | func HashB(b []byte) []byte { 185 | hash := sha256.Sum256(b) 186 | return hash[:] 187 | } 188 | 189 | /* 190 | Description: 191 | HashH calculates hash(b) and returns the resulting bytes as a Hash. 192 | * Author: architect.bian 193 | * Date: 2018/08/27 13:05 194 | */ 195 | func HashH(b []byte) Hash { 196 | return Hash(sha256.Sum256(b)) 197 | } 198 | 199 | /* 200 | Description: 201 | DoubleHashB calculates hash(hash(b)) and returns the resulting bytes. 202 | * Author: architect.bian 203 | * Date: 2018/08/27 13:05 204 | */ 205 | func DoubleHashB(b []byte) []byte { 206 | first := sha256.Sum256(b) 207 | second := sha256.Sum256(first[:]) 208 | return second[:] 209 | } 210 | 211 | /* 212 | Description: 213 | DoubleHashH calculates hash(hash(b)) and returns the resulting bytes as a Hash. 214 | * Author: architect.bian 215 | * Date: 2018/08/27 13:05 216 | */ 217 | func DoubleHashH(b []byte) Hash { 218 | first := sha256.Sum256(b) 219 | return Hash(sha256.Sum256(first[:])) 220 | } 221 | -------------------------------------------------------------------------------- /results/TxRawResult.go: -------------------------------------------------------------------------------- 1 | package results 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | // Vin models parts of the tx data. It is defined separately since 8 | // getrawtransaction, decoderawtransaction, and searchrawtransaction use the 9 | // same structure. 10 | type Vin struct { 11 | Coinbase string `json:"coinbase"` 12 | Txid string `json:"txid"` 13 | Vout uint32 `json:"vout"` 14 | ScriptSig *ScriptSig `json:"scriptSig"` 15 | Sequence uint32 `json:"sequence"` 16 | Witness []string `json:"txinwitness"` 17 | } 18 | 19 | // IsCoinBase returns a bool to show if a Vin is a Coinbase one or not. 20 | func (v *Vin) IsCoinBase() bool { 21 | return len(v.Coinbase) > 0 22 | } 23 | 24 | // HasWitness returns a bool to show if a Vin has any witness data associated 25 | // with it or not. 26 | func (v *Vin) HasWitness() bool { 27 | return len(v.Witness) > 0 28 | } 29 | 30 | // ScriptSig models a signature script. It is defined separately since it only 31 | // applies to non-coinbase. Therefore the field in the Vin structure needs 32 | // to be a pointer. 33 | type ScriptSig struct { 34 | Asm string `json:"asm"` 35 | Hex string `json:"hex"` 36 | } 37 | 38 | // MarshalJSON provides a custom Marshal method for Vin. 39 | func (v *Vin) MarshalJSON() ([]byte, error) { 40 | if v.IsCoinBase() { 41 | coinbaseStruct := struct { 42 | Coinbase string `json:"coinbase"` 43 | Sequence uint32 `json:"sequence"` 44 | Witness []string `json:"witness,omitempty"` 45 | }{ 46 | Coinbase: v.Coinbase, 47 | Sequence: v.Sequence, 48 | Witness: v.Witness, 49 | } 50 | return json.Marshal(coinbaseStruct) 51 | } 52 | 53 | if v.HasWitness() { 54 | txStruct := struct { 55 | Txid string `json:"txid"` 56 | Vout uint32 `json:"vout"` 57 | ScriptSig *ScriptSig `json:"scriptSig"` 58 | Witness []string `json:"txinwitness"` 59 | Sequence uint32 `json:"sequence"` 60 | }{ 61 | Txid: v.Txid, 62 | Vout: v.Vout, 63 | ScriptSig: v.ScriptSig, 64 | Witness: v.Witness, 65 | Sequence: v.Sequence, 66 | } 67 | return json.Marshal(txStruct) 68 | } 69 | 70 | txStruct := struct { 71 | Txid string `json:"txid"` 72 | Vout uint32 `json:"vout"` 73 | ScriptSig *ScriptSig `json:"scriptSig"` 74 | Sequence uint32 `json:"sequence"` 75 | }{ 76 | Txid: v.Txid, 77 | Vout: v.Vout, 78 | ScriptSig: v.ScriptSig, 79 | Sequence: v.Sequence, 80 | } 81 | return json.Marshal(txStruct) 82 | } 83 | 84 | // Vout models parts of the tx data. It is defined separately since both 85 | // getrawtransaction and decoderawtransaction use the same structure. 86 | type Vout struct { 87 | Value float64 `json:"value"` 88 | N uint32 `json:"n"` 89 | ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"` 90 | } 91 | 92 | // ScriptPubKeyResult models the scriptPubKey data of a tx script. It is 93 | // defined separately since it is used by multiple commands. 94 | type ScriptPubKeyResult struct { 95 | Asm string `json:"asm"` 96 | Hex string `json:"hex,omitempty"` 97 | ReqSigs int32 `json:"reqSigs,omitempty"` 98 | Type string `json:"type"` 99 | Addresses []string `json:"addresses,omitempty"` 100 | } 101 | 102 | // TxRawResult models the data from the getrawtransaction command. 103 | type TxRawResult struct { 104 | Hex string `json:"hex"` 105 | Txid string `json:"txid"` 106 | Hash string `json:"hash,omitempty"` 107 | Size int32 `json:"size,omitempty"` 108 | Vsize int32 `json:"vsize,omitempty"` 109 | Version int32 `json:"version"` 110 | LockTime uint32 `json:"locktime"` 111 | Vin []Vin `json:"vin"` 112 | Vout []Vout `json:"vout"` 113 | BlockHash string `json:"blockhash,omitempty"` 114 | Confirmations uint64 `json:"confirmations,omitempty"` 115 | Time int64 `json:"time,omitempty"` 116 | Blocktime int64 `json:"blocktime,omitempty"` 117 | } 118 | 119 | -------------------------------------------------------------------------------- /utils/Basis.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | /* 4 | Description: 5 | basisType is the util object with basis method, you can invoke method like utils.Basis.xxx() 6 | * Author: architect.bian 7 | * Date: 2018/08/27 14:04 8 | */ 9 | type basisType struct {} 10 | 11 | var Basis basisType 12 | /* 13 | Description: 14 | Bool is a helper routine that allocates a new bool value to store v and 15 | returns a pointer to it. This is useful when assigning optional parameters. 16 | * Author: architect.bian 17 | * Date: 2018/08/27 13:28 18 | */ 19 | func (_ basisType) Bool(v bool) *bool { 20 | p := new(bool) 21 | *p = v 22 | return p 23 | } 24 | 25 | /* 26 | Description: 27 | Int is a helper routine that allocates a new int value to store v and 28 | returns a pointer to it. This is useful when assigning optional parameters. 29 | * Author: architect.bian 30 | * Date: 2018/08/27 13:28 31 | */ 32 | func (_ basisType) Int(v int) *int { 33 | p := new(int) 34 | *p = v 35 | return p 36 | } 37 | 38 | /* 39 | Description: 40 | Uint is a helper routine that allocates a new uint value to store v and 41 | returns a pointer to it. This is useful when assigning optional parameters. 42 | * Author: architect.bian 43 | * Date: 2018/08/27 13:28 44 | */ 45 | func (_ basisType) Uint(v uint) *uint { 46 | p := new(uint) 47 | *p = v 48 | return p 49 | } 50 | 51 | /* 52 | Description: 53 | Int32 is a helper routine that allocates a new int32 value to store v and 54 | returns a pointer to it. This is useful when assigning optional parameters. 55 | * Author: architect.bian 56 | * Date: 2018/08/27 13:28 57 | */ 58 | func (_ basisType) Int32(v int32) *int32 { 59 | p := new(int32) 60 | *p = v 61 | return p 62 | } 63 | 64 | /* 65 | Description: 66 | Uint32 is a helper routine that allocates a new uint32 value to store v and 67 | returns a pointer to it. This is useful when assigning optional parameters. 68 | * Author: architect.bian 69 | * Date: 2018/08/27 13:28 70 | */ 71 | func Uint32(v uint32) *uint32 { 72 | p := new(uint32) 73 | *p = v 74 | return p 75 | } 76 | 77 | /* 78 | Description: 79 | Int64 is a helper routine that allocates a new int64 value to store v and 80 | returns a pointer to it. This is useful when assigning optional parameters 81 | * Author: architect.bian 82 | * Date: 2018/08/27 13:28 83 | */ 84 | func (_ basisType) Int64(v int64) *int64 { 85 | p := new(int64) 86 | *p = v 87 | return p 88 | } 89 | 90 | /* 91 | Description: 92 | Uint64 is a helper routine that allocates a new uint64 value to store v and 93 | returns a pointer to it. This is useful when assigning optional parameters. 94 | * Author: architect.bian 95 | * Date: 2018/08/27 13:29 96 | */ 97 | func (_ basisType) Uint64(v uint64) *uint64 { 98 | p := new(uint64) 99 | *p = v 100 | return p 101 | } 102 | 103 | /* 104 | Description: 105 | Float64 is a helper routine that allocates a new float64 value to store v and 106 | returns a pointer to it. This is useful when assigning optional parameters. 107 | * Author: architect.bian 108 | * Date: 2018/08/27 13:29 109 | */ 110 | func (_ basisType) Float64(v float64) *float64 { 111 | p := new(float64) 112 | *p = v 113 | return p 114 | } 115 | 116 | /* 117 | Description: 118 | String is a helper routine that allocates a new string value to store v and 119 | returns a pointer to it. This is useful when assigning optional parameters. 120 | * Author: architect.bian 121 | * Date: 2018/08/27 13:29 122 | */ 123 | func (_ basisType) String(v string) *string { 124 | p := new(string) 125 | *p = v 126 | return p 127 | } -------------------------------------------------------------------------------- /utils/Basis_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Description: 3 | test Basis.go method 4 | Cmd: go test -v Basis.go Basis_test.go 5 | * Author: architect.bian 6 | * Date: 2018/08/27 13:59 7 | */ 8 | package utils 9 | 10 | import ( 11 | "testing" 12 | ) 13 | 14 | func TestBool(t *testing.T) { 15 | var b bool 16 | var bp *bool 17 | if b != false { 18 | t.Error("b bool default value should be false") 19 | } 20 | if bp != nil { 21 | t.Error("bp *bool default value should be nil") 22 | } 23 | bp = nil 24 | bp = Basis.Bool(true) 25 | if bp == nil { 26 | t.Error("bp *bool current value should not be nil") 27 | } 28 | if *bp != true { 29 | t.Error("bp *bool current value should be true") 30 | } 31 | } 32 | 33 | func TestInt(t *testing.T) { 34 | var v int 35 | var vp *int 36 | if v != 0 { 37 | t.Error("v default value should be 0") 38 | } 39 | if vp != nil { 40 | t.Error("v default value should be nil") 41 | } 42 | vp = nil 43 | vp = Basis.Int(-1) 44 | if vp == nil { 45 | t.Error("vp current value should not be nil") 46 | } 47 | if *vp != -1 { 48 | t.Error("vp current value should be -1") 49 | } 50 | } 51 | 52 | func TestString(t *testing.T) { 53 | var v string 54 | var vp *string 55 | if v != "" { 56 | t.Error("v default value should be empty") 57 | } 58 | if vp != nil { 59 | t.Error("v default value should be nil") 60 | } 61 | vp = nil 62 | vp = Basis.String("s") 63 | if vp == nil { 64 | t.Error("vp current value should not be nil") 65 | } 66 | if *vp != "s" { 67 | t.Error("vp current value should be s") 68 | } 69 | } -------------------------------------------------------------------------------- /utils/Http.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "net/url" 5 | "net/http" 6 | "crypto/tls" 7 | "crypto/x509" 8 | ) 9 | 10 | type httpUtil struct {} 11 | 12 | var Http httpUtil 13 | 14 | /* 15 | Description: 16 | NewClientSimple returns a new instance of http.client with no arguments 17 | * Author: architect.bian 18 | * Date: 2018/10/05 18:08 19 | */ 20 | func (h httpUtil) NewClientSimple() (*http.Client, error) { 21 | return h.NewClient("", false, nil) 22 | } 23 | 24 | /* 25 | Description: 26 | NewClient returns a new instance of http.client with proxy, enableTLS, certificates 27 | * Author: architect.bian 28 | * Date: 2018/10/05 18:11 29 | */ 30 | func (h httpUtil) NewClient(proxy string, enableTLS bool, certificates []byte) (*http.Client, error) { 31 | // Set proxy function if there is a proxy configured. 32 | var proxyFunc func(*http.Request) (*url.URL, error) 33 | if proxy != "" { 34 | proxyURL, err := url.Parse(proxy) 35 | if err != nil { 36 | return nil, err 37 | } 38 | proxyFunc = http.ProxyURL(proxyURL) 39 | } 40 | 41 | // Configure TLS if needed. 42 | var tlsConfig *tls.Config 43 | if enableTLS { 44 | if len(certificates) > 0 { 45 | pool := x509.NewCertPool() 46 | pool.AppendCertsFromPEM(certificates) 47 | tlsConfig = &tls.Config{ 48 | RootCAs: pool, 49 | } 50 | } 51 | } 52 | 53 | client := http.Client{ 54 | Transport: &http.Transport{ 55 | Proxy: proxyFunc, 56 | TLSClientConfig: tlsConfig, 57 | }, 58 | } 59 | 60 | return &client, nil 61 | } -------------------------------------------------------------------------------- /utils/Http_test.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "testing" 4 | 5 | func TestNewClient(t *testing.T) { 6 | _, err := Http.NewClientSimple() 7 | if err != nil { 8 | t.Error(err) 9 | } 10 | } 11 | --------------------------------------------------------------------------------