1 package rpcclient
2 3 import (
4 "bytes"
5 "encoding/hex"
6 js "encoding/json"
7 "github.com/p9c/p9/pkg/amt"
8 "github.com/p9c/p9/pkg/btcaddr"
9 10 "github.com/p9c/p9/pkg/btcjson"
11 "github.com/p9c/p9/pkg/chainhash"
12 "github.com/p9c/p9/pkg/util"
13 "github.com/p9c/p9/pkg/wire"
14 )
15 16 // SigHashType enumerates the available signature hashing types that the function accepts.
17 type SigHashType string
18 19 // Constants used to indicate the signature hash type for SignRawTransaction.
20 const (
21 // SigHashAll indicates ALL of the outputs should be signed.
22 SigHashAll SigHashType = "ALL"
23 // SigHashNone indicates NONE of the outputs should be signed. This can be thought of as specifying the signer does
24 // not care where the bitcoins go.
25 SigHashNone SigHashType = "NONE"
26 // SigHashSingle indicates that a SINGLE output should be signed. This can be thought of specifying the signer only
27 // cares about where ONE of the outputs goes, but not any of the others.
28 SigHashSingle SigHashType = "SINGLE"
29 // SigHashAllAnyoneCanPay indicates that signer does not care where the other inputs to the transaction come from,
30 // so it allows other people to add inputs. In addition, it uses the SigHashAll signing method for outputs.
31 SigHashAllAnyoneCanPay SigHashType = "ALL|ANYONECANPAY"
32 // SigHashNoneAnyoneCanPay indicates that signer does not care where the other inputs to the transaction come from,
33 // so it allows other people to add inputs. In addition, it uses the SigHashNone signing method for outputs.
34 SigHashNoneAnyoneCanPay SigHashType = "NONE|ANYONECANPAY"
35 // SigHashSingleAnyoneCanPay indicates that signer does not care where the other inputs to the transaction come
36 // from, so it allows other people to add inputs. In addition, it uses the SigHashSingle signing method for outputs.
37 SigHashSingleAnyoneCanPay SigHashType = "SINGLE|ANYONECANPAY"
38 )
39 40 // String returns the SighHashType in human-readable form.
41 func (s SigHashType) String() string {
42 return string(s)
43 }
44 45 // FutureGetRawTransactionResult is a future promise to deliver the result of a GetRawTransactionAsync RPC invocation
46 // (or an applicable error).
47 type FutureGetRawTransactionResult chan *response
48 49 // Receive waits for the response promised by the future and returns a transaction given its hash.
50 func (r FutureGetRawTransactionResult) Receive() (*util.Tx, error) {
51 res, e := receiveFuture(r)
52 if e != nil {
53 return nil, e
54 }
55 // Unmarshal result as a string.
56 var txHex string
57 e = js.Unmarshal(res, &txHex)
58 if e != nil {
59 return nil, e
60 }
61 // Decode the serialized transaction hex to raw bytes.
62 serializedTx, e := hex.DecodeString(txHex)
63 if e != nil {
64 return nil, e
65 }
66 // Deserialize the transaction and return it.
67 var msgTx wire.MsgTx
68 if e := msgTx.Deserialize(bytes.NewReader(serializedTx)); E.Chk(e) {
69 return nil, e
70 }
71 return util.NewTx(&msgTx), nil
72 }
73 74 // GetRawTransactionAsync returns an instance of a type that can be used to get the result of the RPC at some future
75 // time by invoking the Receive function on the returned instance. See GetRawTransaction for the blocking version and
76 // more details.
77 func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGetRawTransactionResult {
78 hash := ""
79 if txHash != nil {
80 hash = txHash.String()
81 }
82 cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(0))
83 return c.sendCmd(cmd)
84 }
85 86 // GetRawTransaction returns a transaction given its hash.
87 //
88 // See GetRawTransactionVerbose to obtain additional information about the transaction.
89 func (c *Client) GetRawTransaction(txHash *chainhash.Hash) (*util.Tx, error) {
90 return c.GetRawTransactionAsync(txHash).Receive()
91 }
92 93 // FutureGetRawTransactionVerboseResult is a future promise to deliver the result of a GetRawTransactionVerboseAsync RPC
94 // invocation (or an applicable error).
95 type FutureGetRawTransactionVerboseResult chan *response
96 97 // Receive waits for the response promised by the future and returns information about a transaction given its hash.
98 func (r FutureGetRawTransactionVerboseResult) Receive() (*btcjson.TxRawResult, error) {
99 res, e := receiveFuture(r)
100 if e != nil {
101 return nil, e
102 }
103 // Unmarshal result as a gettrawtransaction result object.
104 var rawTxResult btcjson.TxRawResult
105 e = js.Unmarshal(res, &rawTxResult)
106 if e != nil {
107 return nil, e
108 }
109 return &rawTxResult, nil
110 }
111 112 // GetRawTransactionVerboseAsync returns an instance of a type that can be used to get the result of the RPC at some
113 // future time by invoking the Receive function on the returned instance.
114 //
115 // See GetRawTransactionVerbose for the blocking version and more details.
116 func (c *Client) GetRawTransactionVerboseAsync(txHash *chainhash.Hash) FutureGetRawTransactionVerboseResult {
117 hash := ""
118 if txHash != nil {
119 hash = txHash.String()
120 }
121 cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(1))
122 return c.sendCmd(cmd)
123 }
124 125 // GetRawTransactionVerbose returns information about a transaction given its hash. See GetRawTransaction to obtain only
126 // the transaction already deserialized.
127 func (c *Client) GetRawTransactionVerbose(txHash *chainhash.Hash) (*btcjson.TxRawResult, error) {
128 return c.GetRawTransactionVerboseAsync(txHash).Receive()
129 }
130 131 // FutureDecodeRawTransactionResult is a future promise to deliver the result of a DecodeRawTransactionAsync RPC
132 // invocation (or an applicable error).
133 type FutureDecodeRawTransactionResult chan *response
134 135 // Receive waits for the response promised by the future and returns information about a transaction given its
136 // serialized bytes.
137 func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawResult, error) {
138 res, e := receiveFuture(r)
139 if e != nil {
140 return nil, e
141 }
142 // Unmarshal result as a decoderawtransaction result object.
143 var rawTxResult btcjson.TxRawResult
144 e = js.Unmarshal(res, &rawTxResult)
145 if e != nil {
146 return nil, e
147 }
148 return &rawTxResult, nil
149 }
150 151 // DecodeRawTransactionAsync returns an instance of a type that can be used to get the result of the RPC at some future
152 // time by invoking the Receive function on the returned instance. See DecodeRawTransaction for the blocking version and
153 // more details.
154 func (c *Client) DecodeRawTransactionAsync(serializedTx []byte) FutureDecodeRawTransactionResult {
155 txHex := hex.EncodeToString(serializedTx)
156 cmd := btcjson.NewDecodeRawTransactionCmd(txHex)
157 return c.sendCmd(cmd)
158 }
159 160 // DecodeRawTransaction returns information about a transaction given its serialized bytes.
161 func (c *Client) DecodeRawTransaction(serializedTx []byte) (*btcjson.TxRawResult, error) {
162 return c.DecodeRawTransactionAsync(serializedTx).Receive()
163 }
164 165 // FutureCreateRawTransactionResult is a future promise to deliver the result of a CreateRawTransactionAsync RPC
166 // invocation (or an applicable error).
167 type FutureCreateRawTransactionResult chan *response
168 169 // Receive waits for the response promised by the future and returns a new transaction spending the provided inputs and
170 // sending to the provided addresses.
171 func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) {
172 res, e := receiveFuture(r)
173 if e != nil {
174 return nil, e
175 }
176 // Unmarshal result as a string.
177 var txHex string
178 e = js.Unmarshal(res, &txHex)
179 if e != nil {
180 return nil, e
181 }
182 // Decode the serialized transaction hex to raw bytes.
183 serializedTx, e := hex.DecodeString(txHex)
184 if e != nil {
185 return nil, e
186 }
187 // Deserialize the transaction and return it.
188 var msgTx wire.MsgTx
189 if e := msgTx.Deserialize(bytes.NewReader(serializedTx)); E.Chk(e) {
190 return nil, e
191 }
192 return &msgTx, nil
193 }
194 195 // CreateRawTransactionAsync returns an instance of a type that can be used to get the result of the RPC at some future
196 // time by invoking the Receive function on the returned instance. See CreateRawTransaction for the blocking version and
197 // more details.
198 func (c *Client) CreateRawTransactionAsync(
199 inputs []btcjson.TransactionInput,
200 amounts map[btcaddr.Address]amt.Amount, lockTime *int64,
201 ) FutureCreateRawTransactionResult {
202 convertedAmts := make(map[string]float64, len(amounts))
203 for addr, amount := range amounts {
204 convertedAmts[addr.String()] = amount.ToDUO()
205 }
206 cmd := btcjson.NewCreateRawTransactionCmd(inputs, convertedAmts, lockTime)
207 return c.sendCmd(cmd)
208 }
209 210 // CreateRawTransaction returns a new transaction spending the provided inputs and sending to the provided addresses.
211 func (c *Client) CreateRawTransaction(
212 inputs []btcjson.TransactionInput,
213 amounts map[btcaddr.Address]amt.Amount, lockTime *int64,
214 ) (*wire.MsgTx, error) {
215 return c.CreateRawTransactionAsync(inputs, amounts, lockTime).Receive()
216 }
217 218 // FutureSendRawTransactionResult is a future promise to deliver the result of a SendRawTransactionAsync RPC invocation
219 // (or an applicable error).
220 type FutureSendRawTransactionResult chan *response
221 222 // Receive waits for the response promised by the future and returns the result of submitting the encoded transaction to
223 // the server which then relays it to the network.
224 func (r FutureSendRawTransactionResult) Receive() (*chainhash.Hash, error) {
225 res, e := receiveFuture(r)
226 if e != nil {
227 return nil, e
228 }
229 // Unmarshal result as a string.
230 var txHashStr string
231 e = js.Unmarshal(res, &txHashStr)
232 if e != nil {
233 return nil, e
234 }
235 return chainhash.NewHashFromStr(txHashStr)
236 }
237 238 // SendRawTransactionAsync returns an instance of a type that can be used to get the result of the RPC at some future
239 // time by invoking the Receive function on the returned instance.
240 //
241 // See SendRawTransaction for the blocking version and more details.
242 func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees bool) FutureSendRawTransactionResult {
243 txHex := ""
244 if tx != nil {
245 // Serialize the transaction and convert to hex string.
246 buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
247 if e := tx.Serialize(buf); E.Chk(e) {
248 return newFutureError(e)
249 }
250 txHex = hex.EncodeToString(buf.Bytes())
251 }
252 cmd := btcjson.NewSendRawTransactionCmd(txHex, &allowHighFees)
253 return c.sendCmd(cmd)
254 }
255 256 // SendRawTransaction submits the encoded transaction to the server which will then relay it to the network.
257 func (c *Client) SendRawTransaction(tx *wire.MsgTx, allowHighFees bool) (*chainhash.Hash, error) {
258 return c.SendRawTransactionAsync(tx, allowHighFees).Receive()
259 }
260 261 // FutureSignRawTransactionResult is a future promise to deliver the result of one of the SignRawTransactionAsync family
262 // of RPC invocations (or an applicable error).
263 type FutureSignRawTransactionResult chan *response
264 265 // Receive waits for the response promised by the future and returns the signed transaction as well as whether or not all inputs are now signed.
266 func (r FutureSignRawTransactionResult) Receive() (*wire.MsgTx, bool, error) {
267 res, e := receiveFuture(r)
268 if e != nil {
269 return nil, false, e
270 }
271 // Unmarshal as a signrawtransaction result.
272 var signRawTxResult btcjson.SignRawTransactionResult
273 e = js.Unmarshal(res, &signRawTxResult)
274 if e != nil {
275 return nil, false, e
276 }
277 // Decode the serialized transaction hex to raw bytes.
278 serializedTx, e := hex.DecodeString(signRawTxResult.Hex)
279 if e != nil {
280 return nil, false, e
281 }
282 // Deserialize the transaction and return it.
283 var msgTx wire.MsgTx
284 if e := msgTx.Deserialize(bytes.NewReader(serializedTx)); E.Chk(e) {
285 return nil, false, e
286 }
287 return &msgTx, signRawTxResult.Complete, nil
288 }
289 290 // SignRawTransactionAsync returns an instance of a type that can be used to get the result of the RPC at some future
291 // time by invoking the Receive function on returned instance. See SignRawTransaction for the blocking version and more
292 // details.
293 func (c *Client) SignRawTransactionAsync(tx *wire.MsgTx) FutureSignRawTransactionResult {
294 txHex := ""
295 if tx != nil {
296 // Serialize the transaction and convert to hex string.
297 buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
298 if e := tx.Serialize(buf); E.Chk(e) {
299 return newFutureError(e)
300 }
301 txHex = hex.EncodeToString(buf.Bytes())
302 }
303 cmd := btcjson.NewSignRawTransactionCmd(txHex, nil, nil, nil)
304 return c.sendCmd(cmd)
305 }
306 307 // SignRawTransaction signs inputs for the passed transaction and returns the signed transaction as well as whether or
308 // not all inputs are now signed.
309 //
310 // This function assumes the RPC server already knows the input transactions and private keys for the passed transaction
311 // which needs to be signed and uses the default signature hash type.
312 //
313 // Use one of the SignRawTransaction# variants to specify that information if needed.
314 func (c *Client) SignRawTransaction(tx *wire.MsgTx) (*wire.MsgTx, bool, error) {
315 return c.SignRawTransactionAsync(tx).Receive()
316 }
317 318 // SignRawTransaction2Async returns an instance of a type that can be used to get the result of the RPC at some future
319 // time by invoking the Receive on the returned instance.
320 //
321 // See SignRawTransaction2 for the blocking version and more details.
322 func (c *Client) SignRawTransaction2Async(tx *wire.MsgTx, inputs []btcjson.RawTxInput) FutureSignRawTransactionResult {
323 txHex := ""
324 if tx != nil {
325 // Serialize the transaction and convert to hex string.
326 buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
327 if e := tx.Serialize(buf); E.Chk(e) {
328 return newFutureError(e)
329 }
330 txHex = hex.EncodeToString(buf.Bytes())
331 }
332 cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, nil, nil)
333 return c.sendCmd(cmd)
334 }
335 336 // SignRawTransaction2 signs inputs for the passed transaction given the list information about the input transactions
337 // needed to perform the signing process.
338 //
339 // This only input transactions that need to be specified are ones the RPC server does not already know. Already known
340 // input transactions will be merged with the specified transactions.
341 //
342 // See SignRawTransaction if the RPC server already knows the input transactions.
343 func (c *Client) SignRawTransaction2(tx *wire.MsgTx, inputs []btcjson.RawTxInput) (*wire.MsgTx, bool, error) {
344 return c.SignRawTransaction2Async(tx, inputs).Receive()
345 }
346 347 // SignRawTransaction3Async returns an instance of a type that can be used to get the result of the RPC at some future
348 // time by invoking the Receive function on the returned instance.
349 //
350 // See SignRawTransaction3 for the blocking version and more details.
351 func (c *Client) SignRawTransaction3Async(
352 tx *wire.MsgTx,
353 inputs []btcjson.RawTxInput,
354 privKeysWIF []string,
355 ) FutureSignRawTransactionResult {
356 txHex := ""
357 if tx != nil {
358 // Serialize the transaction and convert to hex string.
359 buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
360 if e := tx.Serialize(buf); E.Chk(e) {
361 return newFutureError(e)
362 }
363 txHex = hex.EncodeToString(buf.Bytes())
364 }
365 cmd := btcjson.NewSignRawTransactionCmd(
366 txHex, &inputs, &privKeysWIF,
367 nil,
368 )
369 return c.sendCmd(cmd)
370 }
371 372 // SignRawTransaction3 signs inputs for the passed transaction given the list of information about extra input
373 // transactions and a list of private keys needed to perform the signing process. The private keys must be in wallet
374 // import format (WIF).
375 //
376 // This only input transactions that need to be specified are ones the RPC server does not already know. Already known
377 // input transactions will be merged with the specified transactions. This means the list of transaction inputs can be
378 // nil if the RPC server already knows them all.
379 //
380 // NOTE: Unlike the merging functionality of the input transactions, ONLY the specified private keys will be used, so
381 // even if the server already knows some of the private keys, they will NOT be used.
382 //
383 // See SignRawTransaction if the RPC server already knows the input transactions and private keys or SignRawTransaction2
384 // if it already knows the private keys.
385 func (c *Client) SignRawTransaction3(
386 tx *wire.MsgTx,
387 inputs []btcjson.RawTxInput,
388 privKeysWIF []string,
389 ) (*wire.MsgTx, bool, error) {
390 return c.SignRawTransaction3Async(tx, inputs, privKeysWIF).Receive()
391 }
392 393 // SignRawTransaction4Async returns an instance of a type that can be used to get the result of the RPC at some future
394 // time by invoking the Receive function on the returned instance.
395 //
396 // See SignRawTransaction4 for the blocking version and more details.
397 func (c *Client) SignRawTransaction4Async(
398 tx *wire.MsgTx,
399 inputs []btcjson.RawTxInput, privKeysWIF []string,
400 hashType SigHashType,
401 ) FutureSignRawTransactionResult {
402 txHex := ""
403 if tx != nil {
404 // Serialize the transaction and convert to hex string.
405 buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
406 if e := tx.Serialize(buf); E.Chk(e) {
407 return newFutureError(e)
408 }
409 txHex = hex.EncodeToString(buf.Bytes())
410 }
411 cmd := btcjson.NewSignRawTransactionCmd(
412 txHex, &inputs, &privKeysWIF,
413 btcjson.String(string(hashType)),
414 )
415 return c.sendCmd(cmd)
416 }
417 418 // SignRawTransaction4 signs inputs for the passed transaction using the the specified signature hash type given the
419 // list of information about extra input transactions and a potential list of private keys needed to perform the signing
420 // process.
421 //
422 // The private keys, if specified, must be in wallet import format (WIF). The only input transactions that need to be
423 // specified are ones the RPC server does not already know. This means the list of transaction inputs can be nil if the
424 // RPC server already knows them all.
425 //
426 // NOTE: Unlike the merging functionality of the input transactions, ONLY the specified private keys will be used, so
427 // even if the server already knows some of the private keys, they will NOT be used. The list of private keys can be nil
428 // in which case any private keys the RPC server knows will be used.
429 //
430 // This function should only used if a non-default signature hash type is desired.
431 //
432 // Otherwise, see SignRawTransaction if the RPC server already knows the input transactions and private keys,
433 // SignRawTransaction2 if it already knows the private keys, or SignRawTransaction3 if it does not know both.
434 func (c *Client) SignRawTransaction4(
435 tx *wire.MsgTx,
436 inputs []btcjson.RawTxInput, privKeysWIF []string,
437 hashType SigHashType,
438 ) (*wire.MsgTx, bool, error) {
439 return c.SignRawTransaction4Async(
440 tx, inputs, privKeysWIF,
441 hashType,
442 ).Receive()
443 }
444 445 // FutureSearchRawTransactionsResult is a future promise to deliver the result of the SearchRawTransactionsAsync RPC
446 // invocation (or an applicable error).
447 type FutureSearchRawTransactionsResult chan *response
448 449 // Receive waits for the response promised by the future and returns the found raw transactions.
450 func (r FutureSearchRawTransactionsResult) Receive() ([]*wire.MsgTx, error) {
451 res, e := receiveFuture(r)
452 if e != nil {
453 return nil, e
454 }
455 // Unmarshal as an array of strings.
456 var searchRawTxnsResult []string
457 e = js.Unmarshal(res, &searchRawTxnsResult)
458 if e != nil {
459 return nil, e
460 }
461 // Decode and deserialize each transaction.
462 msgTxns := make([]*wire.MsgTx, 0, len(searchRawTxnsResult))
463 for _, hexTx := range searchRawTxnsResult {
464 // Decode the serialized transaction hex to raw bytes.
465 serializedTx, e := hex.DecodeString(hexTx)
466 if e != nil {
467 return nil, e
468 }
469 // Deserialize the transaction and add it to the result slice.
470 var msgTx wire.MsgTx
471 e = msgTx.Deserialize(bytes.NewReader(serializedTx))
472 if e != nil {
473 return nil, e
474 }
475 msgTxns = append(msgTxns, &msgTx)
476 }
477 return msgTxns, nil
478 }
479 480 // SearchRawTransactionsAsync returns an instance of a type that can be used to get the result of the RPC at some future
481 // time by invoking the Receive function on the returned instance. See SearchRawTransactions for the blocking version
482 // and more details.
483 func (c *Client) SearchRawTransactionsAsync(
484 address btcaddr.Address, skip, count int, reverse bool,
485 filterAddrs []string,
486 ) FutureSearchRawTransactionsResult {
487 addr := address.EncodeAddress()
488 verbose := btcjson.Int(0)
489 cmd := btcjson.NewSearchRawTransactionsCmd(
490 addr, verbose, &skip, &count,
491 nil, &reverse, &filterAddrs,
492 )
493 return c.sendCmd(cmd)
494 }
495 496 // SearchRawTransactions returns transactions that involve the passed address.
497 //
498 // NOTE: Chain servers do not typically provide this capability unless it has specifically been enabled.
499 //
500 // See SearchRawTransactionsVerbose to retrieve a list of data structures with information about the transactions
501 // instead of the transactions themselves.
502 func (c *Client) SearchRawTransactions(
503 address btcaddr.Address,
504 skip, count int,
505 reverse bool,
506 filterAddrs []string,
507 ) ([]*wire.MsgTx, error) {
508 return c.SearchRawTransactionsAsync(address, skip, count, reverse, filterAddrs).Receive()
509 }
510 511 // FutureSearchRawTransactionsVerboseResult is a future promise to deliver the result of the
512 // SearchRawTransactionsVerboseAsync RPC invocation (or an applicable error).
513 type FutureSearchRawTransactionsVerboseResult chan *response
514 515 // Receive waits for the response promised by the future and returns the found raw transactions.
516 func (r FutureSearchRawTransactionsVerboseResult) Receive() ([]*btcjson.SearchRawTransactionsResult, error) {
517 res, e := receiveFuture(r)
518 if e != nil {
519 return nil, e
520 }
521 // Unmarshal as an array of raw transaction results.
522 var result []*btcjson.SearchRawTransactionsResult
523 e = js.Unmarshal(res, &result)
524 if e != nil {
525 return nil, e
526 }
527 return result, nil
528 }
529 530 // SearchRawTransactionsVerboseAsync returns an instance of a type that can be used to get the result of the RPC at some
531 // future time by invoking the Receive function on the returned instance.
532 //
533 // See SearchRawTransactionsVerbose for the blocking version and more details.
534 func (c *Client) SearchRawTransactionsVerboseAsync(
535 address btcaddr.Address, skip,
536 count int, includePrevOut, reverse bool, filterAddrs *[]string,
537 ) FutureSearchRawTransactionsVerboseResult {
538 addr := address.EncodeAddress()
539 verbose := btcjson.Int(1)
540 var prevOut *int
541 if includePrevOut {
542 prevOut = btcjson.Int(1)
543 }
544 cmd := btcjson.NewSearchRawTransactionsCmd(
545 addr, verbose, &skip, &count,
546 prevOut, &reverse, filterAddrs,
547 )
548 return c.sendCmd(cmd)
549 }
550 551 // SearchRawTransactionsVerbose returns a list of data structures that describe transactions which involve the passed
552 // address. NOTE: Chain servers do not typically provide this capability unless it has specifically been enabled.
553 //
554 // See SearchRawTransactions to retrieve a list of raw transactions instead.
555 func (c *Client) SearchRawTransactionsVerbose(
556 address btcaddr.Address, skip,
557 count int, includePrevOut, reverse bool, filterAddrs []string,
558 ) ([]*btcjson.SearchRawTransactionsResult, error) {
559 return c.SearchRawTransactionsVerboseAsync(
560 address, skip, count,
561 includePrevOut, reverse, &filterAddrs,
562 ).Receive()
563 }
564 565 // FutureDecodeScriptResult is a future promise to deliver the result of a DecodeScriptAsync RPC invocation (or an
566 // applicable error).
567 type FutureDecodeScriptResult chan *response
568 569 // Receive waits for the response promised by the future and returns information about a script given its serialized
570 // bytes.
571 func (r FutureDecodeScriptResult) Receive() (*btcjson.DecodeScriptResult, error) {
572 res, e := receiveFuture(r)
573 if e != nil {
574 return nil, e
575 }
576 // Unmarshal result as a decodescript result object.
577 var decodeScriptResult btcjson.DecodeScriptResult
578 e = js.Unmarshal(res, &decodeScriptResult)
579 if e != nil {
580 return nil, e
581 }
582 return &decodeScriptResult, nil
583 }
584 585 // DecodeScriptAsync returns an instance of a type that can be used to get the result of the RPC at some future time by
586 // invoking the Receive function on the returned instance.
587 //
588 // See DecodeScript for the blocking version and more details.
589 func (c *Client) DecodeScriptAsync(serializedScript []byte) FutureDecodeScriptResult {
590 scriptHex := hex.EncodeToString(serializedScript)
591 cmd := btcjson.NewDecodeScriptCmd(scriptHex)
592 return c.sendCmd(cmd)
593 }
594 595 // DecodeScript returns information about a script given its serialized bytes.
596 func (c *Client) DecodeScript(serializedScript []byte) (*btcjson.DecodeScriptResult, error) {
597 return c.DecodeScriptAsync(serializedScript).Receive()
598 }
599