前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 实现比特币多重签名服务

Go 实现比特币多重签名服务

作者头像
李海彬
发布2018-12-14 14:36:39
2.3K0
发布2018-12-14 14:36:39
举报
文章被收录于专栏:Golang语言社区Golang语言社区

作者:老码农不上班 链接:https://www.jianshu.com/p/21107f737b98 來源:简书

使用 Go 写了个比特币多重签名的服务,这篇文章总结服务的结构及实现思路。

源码中主要涉及到的 Go package :

  • dep Go package 管理工具
  • cobra 实现 cli
  • LevelDB 保存加密处理后的私钥
  • gin 实现接口接受外部服务请求
  • gRPC & protocol buffer 内部服务调用
  • btcd 连接比特币节点的 JSON-RPC 比特币区块、交易数据结构工具

采用 3-3 多重签名(在这里硬编码了,最好的做法是让用户动态选择 x-y 签名),也就是三个普通地址生成多签地址,消费多签地址中的比特币需要三个地址对应的私钥成功签名才可构建交易的数据结构,签名服务通过 gRPC 获取普通地址私钥进行签名,最后把签名的数据通过节点广播到比特币网络。

代码语言:javascript
复制
 1// serveCmd represents the api command
 2var serveCmd = &cobra.Command{
 3    Use:   "api",
 4    Short: "External API",
 5    Long:  `Provide WEB API for external`,
 6    Run: func(cmd *cobra.Command, args []string) {
 7        ormDB = ormBbAlias{dbConn()}
 8        ormDB.DBMigrate()
 9        defer ormDB.Close()
10        switch api {
11        case "normal_address":
12            normalAddress()
13        case "multisig_address":
14            multisigAddress()
15        case "sign_tx":
16            signTx()
17        case "grpc":
18            addressServer()
19        default:
20            log.Fatalf("You must specify -a flag")
21        }
22    },
23}

启动服务命令:

代码语言:javascript
复制
 1➜  bitcoin_multisig_with_node git:(master) ✗ bitcoin_multisig_with_node api -h
 2Using Configure file: /Users/hww/bitcoin.yml
 3Provide WEB API for external
 4
 5Usage:
 6  bitcoin_multisig_with_node api [flags]
 7
 8Flags:
 9  -a, --api string   External API(value: normal_address, multisig_address sign_tx grpc)
10  -h, --help         help for api

生成普通地址

在三台独立的内网服务器部署生成普通地址的服务,确保私钥不集中存储在一台服务器。当然在本地开发时,我们可以开启不同的端口启动服务给外部请求生成普通地址:

代码语言:javascript
复制
 1var (
 2    client bitcoinClientAlias
 3    g      errgroup.Group
 4)
 5
 6func mormalRoute() http.Handler {
 7    r := ginEngine()
 8    r.Use(location.Default())
 9    r.GET("/address", normolAddressHandler)
10    return r
11}
12
13func normalAddress() {
14    server00 := &http.Server{
15        Addr:         ":3000",
16        Handler:      mormalRoute(),
17        ReadTimeout:  5 * time.Second,
18        WriteTimeout: 10 * time.Second,
19    }
20
21    server01 := &http.Server{
22        Addr:         ":3001",
23        Handler:      mormalRoute(),
24        ReadTimeout:  5 * time.Second,
25        WriteTimeout: 10 * time.Second,
26    }
27
28    server02 := &http.Server{
29        Addr:         ":3002",
30        Handler:      mormalRoute(),
31        ReadTimeout:  5 * time.Second,
32        WriteTimeout: 10 * time.Second,
33    }
34
35    g.Go(func() error {
36        return server00.ListenAndServe()
37    })
38
39    g.Go(func() error {
40        return server01.ListenAndServe()
41    })
42
43    g.Go(func() error {
44        return server02.ListenAndServe()
45    })
46
47    if err := g.Wait(); err != nil {
48        log.Fatal(err)
49    }
50}
51
52func normolAddressHandler(c *gin.Context) {
53    address, pubkey, err := generateNormalAddress("regtest")
54    if err != nil {
55        ginResponseException(c, 400, err)
56        return
57    }
58
59    ormDB.Create(&AddressPub{Address: *address, PublicKeyBytes: *pubkey, URL: location.Get(c).Hostname()})
60
61    c.JSON(200, gin.H{
62        "status":  200,
63        "address": address,
64    })
65}

生成多签地址

生成多签地址服务当初部署,你也可以通过实现比特币多签地址生成协议脱离节点生成多钱地址,在这里我们提供一个对外的接口,用户把三个普通地址传给 web 服务,服务端处理请求并返回多签地址。

代码语言:javascript
复制
 1func multisigAddress() {
 2    c := config.bitcoinClient()
 3    client = bitcoinClientAlias{c}
 4
 5    r := ginEngine()
 6    r.GET("/address", multisigAddressHandle)
 7    if err := r.Run(":3003"); err != nil {
 8        log.Fatalf(err.Error())
 9    }
10}

构建交易并首次签名

签名服务单独部署,通过 gRPC 去部署生成普通地址的服务获取私钥进行签名。

代码语言:javascript
复制
 1func signTx() {
 2    c := config.bitcoinClient()
 3    client = bitcoinClientAlias{c}
 4    r := ginEngine()
 5    r.GET("/issue", issueTx)
 6    r.GET("/confirm", confirmHandle)
 7    if err := r.Run(":3004"); err != nil {
 8        log.Fatalf(err.Error())
 9    }
10
11}

开启 gRPC 服务端服务,接收签名服务发来的获取私钥请求

代码语言:javascript
复制
 1func addressServer() {
 2    lis, err := net.Listen("tcp", port)
 3    if err != nil {
 4        log.Fatalf("failed to listen: %v", err)
 5    }
 6
 7    s := grpc.NewServer()
 8    RegisterNormalAddressServer(s, &gRPCServer{})
 9
10    reflection.Register(s)
11    if err := s.Serve(lis); err != nil {
12        log.Fatalf("failed to gRPC serve: %v", err)
13    }
14}

构建交易并首次签名

代码语言:javascript
复制
 1func issueTx(c *gin.Context) {
 2    var (
 3        params     *txParams
 4        dbMultisig MultiSig
 5        dbAddress  AddressPub
 6        inputs     []btcjson.RawTxInput
 7    )
 8
 9    // 参数校验
10    params = new(txParams) // should initialize pointer before use
11    txidsHash, err := params.signTxParams(c)
12    if err != nil {
13        ginResponseException(c, 400, err)
14        return
15    }
16
17    ormDB.Where("address = ?", params.From).First(&dbAddress)
18    ormDB.Model(&dbAddress).Related(&dbMultisig)
19
20    // 交易输入
21    txVins, err := client.constructVins(txidsHash)
22    if err != nil {
23        ginResponseException(c, 400, err)
24        return
25    }
26
27    // 构建多签交易
28    rawTx, err := client.NewMultiSigTx(dbMultisig, *params, txVins)
29    if err != nil {
30        ginResponseException(c, 400, err)
31        return
32    }
33
34    // 确认签名输入参数
35    for _, txRawResult := range txVins {
36        input := signInput(txRawResult, dbMultisig)
37        inputs = append(inputs, *input)
38    }
39
40    // gRPC 获取私钥
41    wif, err := dbAddress.grpcGetNormalAddressWif()
42    if err != nil {
43        ginResponseException(c, 400, err)
44        return
45    }
46
47    // 签名交易
48    msgTx, result, err := client.SignRawTransaction3(rawTx, inputs, []string{*wif})
49    if err != nil {
50        if err != nil {
51            ginResponseException(c, 400, err)
52            return
53        }
54    }
55
56    txHex := ""
57    if msgTx != nil {
58        // Serialize the transaction and convert to hex string.
59        buf := bytes.NewBuffer(make([]byte, 0, msgTx.SerializeSize()))
60        if err := msgTx.Serialize(buf); err != nil {
61            // return newFutureError(err)
62        }
63        txHex = hex.EncodeToString(buf.Bytes())
64    }
65
66    c.JSON(200, gin.H{
67        "status":  200,
68        "sign_tx": txHex,
69        "result":  result,
70    })
71}

最后一轮签名成功后使用 SendRawTransaction 广播交易到比特币网络

比特币 regtest 环境多重签名测试流程

首先具备比特币网络测试节点环境,详情可以 Bitcoin-core daemon and regtest install

生成地址
代码语言:javascript
复制
1// 请求不同机器生成普通地址
2curl "172.17.1.19:3000/address" // {"address":"1PnBXZzZTr7TLnr56ndBPLQANAGRAq9h4w","status":200}
3curl "172.17.1.19:3001/address" // {"address":"1KEPw2vC3NvGEcvguCt85uuKNmAGtYiuYC","status":200}
4curl "172.17.1.19:3002/address" // {"address":"1GKhpdfXHUC1mBM6WrD63tbKvMUyj9irdb","status":200}
5
6// 请求生成多签地址服务生成多签地址
7curl "172.17.1.9:3003/address?addresses=1PnBXZzZTr7TLnr56ndBPLQANAGRAq9h4w,1KEPw2vC3NvGEcvguCt85uuKNmAGtYiuYC,1GKhpdfXHUC1mBM6WrD63tbKvMUyj9irdb" //{"address":"2NBvbEGvFYiz3EAFyTsyUA8QKTmgBcJnbsb","status":200}
交易并首次签名
代码语言:javascript
复制
 1// 在 regtest 环境中给多签地址转入三笔交易生成三个 txid, 每笔 10 个币
 2bitcoin-cli -regtest sendtoaddress 2NBvbEGvFYiz3EAFyTsyUA8QKTmgBcJnbsb 10 // txid: 97adab60d7a0f71fca8f22b0007ef9b0b3f8eb1ce10341b4a5ee998d0bfbec72
 3bitcoin-cli -regtest sendtoaddress 2NBvbEGvFYiz3EAFyTsyUA8QKTmgBcJnbsb 10 // txid: 9244f24ec81630742591a15007e84d6e113db259340e5ac319e6d38440baf89f
 4bitcoin-cli -regtest sendtoaddress 2NBvbEGvFYiz3EAFyTsyUA8QKTmgBcJnbsb 10 // txid: 23a6466147c3d82fa2967dd3871b649793ee8b53f0463378ce7c0b8bcdf1278f
 5
 6// 开启挖矿确认以上三笔转账,以此我们的多签地址就有了 30 个比特币
 7bitcoin-cli -regtest generatetoaddress 10 2N8i6PbrW5nNtGbrHcPf5FJ1tNSyBou6t2b
 8/*
 9[
10  "3647fc9392ae2694b2ae6cc6336fad55f21fef4317e7b5bd13912a400d6ae84f",
11  "17acb72d5172d4d025bc3c7e953c7995d2b37fd6a50dac9dee705f3be2b83eb8",
12  "70a3c40665a20920bd25718ea80488e9dd8f9880d393a1b309b16be3cd84ddad",
13  "77abc300678788290a6ac054893c69877bbca6bb1c0010dae0afd578491dd67f",
14  "64d1087a723910a485989ffb15df7032617c06ae752f853af52868e08bcd4fe5",
15  "272f1761f1fcb6f8095775f200edf5e039f7dce36c166caa48f53fc821aafbf2",
16  "2740af50876e3b940b575455aecd014820b2515f15f126d6ef84ed384704c51f",
17  "050689882db8a2f55a3afb27a5083ddcc7951b93b379db165d8500785d0ccf2a",
18  "3c8b335bbcc7dc83fec5aa12e4ec2a881bd3067387b192806979bcd9c27ba18a",
19  "6cc259b0200d77c4a86255d3e19c02c47048c86933c2712fdbfae37cfd019f04"
20]
21*/
22
23// 在 regtest 环境中生成普通地址接收,用以接多签地址即将转出的币
24bitcoin-cli -regtest getnewaddress receiveaddress // 2Mu43Qw5pngjAmtu7n7evdkXE2E9ocXCft1
25
26// 生成多签地址的其中某个普通地址发起交易
27curl "192.168.7.44:3004/issue?txid=97adab60d7a0f71fca8f22b0007ef9b0b3f8eb1ce10341b4a5ee998d0bfbec72,9244f24ec81630742591a15007e84d6e113db259340e5ac319e6d38440baf89f,23a6466147c3d82fa2967dd3871b649793ee8b53f0463378ce7c0b8bcdf1278f&from=1KEPw2vC3NvGEcvguCt85uuKNmAGtYiuYC&to=2Mu43Qw5pngjAmtu7n7evdkXE2E9ocXCft1&amount=21"
28
29/*
30
31生成交易并返回首次签名结果
32{
33  "result":false,
34  "sign_tx":"020000000372ecfb0b8d99eea5b44103e11cebf8b3b0f97e00b0228fca1ff7a0d760abad9701000000fd150100483045022100b277e07d37f98f1c97dccf92f7c6bb7093622301d33bee48c57bb6fda687c068022066f1cafe7296fb57053577c1c3705b39dcfaa9f010c9699b20ad1cd98f0c5496014cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff9ff8ba4084d3e619c35a0e3459b23d116e4de80750a19125743016c84ef2449200000000fd14010047304402203062597d764932cd85ec9e5f82a6d471984d0d03ab1268ea4651343624387679022026203223c9a2968530f2af4a16bb079fee2905cc5cbba258f1f823603e57c895014cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff8f27f1cd8b0b7cce783346f0538bee9397641b87d37d96a22fd8c3476146a62301000000fd14010047304402206390095bade6a4159ad036d9cfe7e7f0004024da09d460784d8bb45806664e62022059d21c421e1ddcdb17d70998617af6fc85589b35f6bd7c423d5443da4ec48642014cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff0200752b7d0000000017a91413d2d93195352467f94a12a3def1e4c09d15ac278778d5a4350000000017a914cce437c88256ca0a9fa1eed83e5b192f4dcc39f18700000000",
35  "status":200
36}
37 */
38
39 // 第二个普通地址进行第二次签名
40 curl "192.168.7.44:3004/confirm?txid=97adab60d7a0f71fca8f22b0007ef9b0b3f8eb1ce10341b4a5ee998d0bfbec72,9244f24ec81630742591a15007e84d6e113db259340e5ac319e6d38440baf89f,23a6466147c3d82fa2967dd3871b649793ee8b53f0463378ce7c0b8bcdf1278f&from=1PnBXZzZTr7TLnr56ndBPLQANAGRAq9h4w&signtx=020000000372ecfb0b8d99eea5b44103e11cebf8b3b0f97e00b0228fca1ff7a0d760abad9701000000fd150100483045022100b277e07d37f98f1c97dccf92f7c6bb7093622301d33bee48c57bb6fda687c068022066f1cafe7296fb57053577c1c3705b39dcfaa9f010c9699b20ad1cd98f0c5496014cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff9ff8ba4084d3e619c35a0e3459b23d116e4de80750a19125743016c84ef2449200000000fd14010047304402203062597d764932cd85ec9e5f82a6d471984d0d03ab1268ea4651343624387679022026203223c9a2968530f2af4a16bb079fee2905cc5cbba258f1f823603e57c895014cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff8f27f1cd8b0b7cce783346f0538bee9397641b87d37d96a22fd8c3476146a62301000000fd14010047304402206390095bade6a4159ad036d9cfe7e7f0004024da09d460784d8bb45806664e62022059d21c421e1ddcdb17d70998617af6fc85589b35f6bd7c423d5443da4ec48642014cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff0200752b7d0000000017a91413d2d93195352467f94a12a3def1e4c09d15ac278778d5a4350000000017a914cce437c88256ca0a9fa1eed83e5b192f4dcc39f18700000000"
41
42/*
43{
44  "result":false,
45  "sign_tx":"020000000372ecfb0b8d99eea5b44103e11cebf8b3b0f97e00b0228fca1ff7a0d760abad9701000000fd5f01004830450221009c1518665cdb11e4e0d55e23fcbb19030c22ceaec081f646be0e8d062622df4c022037364e73584aee4fa9b8d26311039408f1d272b6e4955f0aaa377dc1090b87bb01483045022100b277e07d37f98f1c97dccf92f7c6bb7093622301d33bee48c57bb6fda687c068022066f1cafe7296fb57053577c1c3705b39dcfaa9f010c9699b20ad1cd98f0c549601004cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff9ff8ba4084d3e619c35a0e3459b23d116e4de80750a19125743016c84ef2449200000000fd5d0100473044022010ad85ee4f66b63c7765ccbdee57c66c9c37dee0965be4c5934e3e7f9b453e5102205089c146899a6228ba9acb12e714fb15f50619fccb99fe279d7aaa90489f39380147304402203062597d764932cd85ec9e5f82a6d471984d0d03ab1268ea4651343624387679022026203223c9a2968530f2af4a16bb079fee2905cc5cbba258f1f823603e57c89501004cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff8f27f1cd8b0b7cce783346f0538bee9397641b87d37d96a22fd8c3476146a62301000000fd5e0100483045022100b8e4ebf749ab4bba66e55e857a07b834558a16aeecd93d6e007811456d78d0b302205a8cbcc8f63f118536f938894f3a27236c353a177c43c0ef9987b29bac3227ef0147304402206390095bade6a4159ad036d9cfe7e7f0004024da09d460784d8bb45806664e62022059d21c421e1ddcdb17d70998617af6fc85589b35f6bd7c423d5443da4ec4864201004cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff0200752b7d0000000017a91413d2d93195352467f94a12a3def1e4c09d15ac278778d5a4350000000017a914cce437c88256ca0a9fa1eed83e5b192f4dcc39f18700000000",
46  "status":200
47}
48*/
49
50// 第三个普通地址进行第三次签名并广播交易
51curl "192.168.7.44:3004/confirm?txid=97adab60d7a0f71fca8f22b0007ef9b0b3f8eb1ce10341b4a5ee998d0bfbec72,9244f24ec81630742591a15007e84d6e113db259340e5ac319e6d38440baf89f,23a6466147c3d82fa2967dd3871b649793ee8b53f0463378ce7c0b8bcdf1278f&from=1GKhpdfXHUC1mBM6WrD63tbKvMUyj9irdb&signtx=020000000372ecfb0b8d99eea5b44103e11cebf8b3b0f97e00b0228fca1ff7a0d760abad9701000000fd5f01004830450221009c1518665cdb11e4e0d55e23fcbb19030c22ceaec081f646be0e8d062622df4c022037364e73584aee4fa9b8d26311039408f1d272b6e4955f0aaa377dc1090b87bb01483045022100b277e07d37f98f1c97dccf92f7c6bb7093622301d33bee48c57bb6fda687c068022066f1cafe7296fb57053577c1c3705b39dcfaa9f010c9699b20ad1cd98f0c549601004cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff9ff8ba4084d3e619c35a0e3459b23d116e4de80750a19125743016c84ef2449200000000fd5d0100473044022010ad85ee4f66b63c7765ccbdee57c66c9c37dee0965be4c5934e3e7f9b453e5102205089c146899a6228ba9acb12e714fb15f50619fccb99fe279d7aaa90489f39380147304402203062597d764932cd85ec9e5f82a6d471984d0d03ab1268ea4651343624387679022026203223c9a2968530f2af4a16bb079fee2905cc5cbba258f1f823603e57c89501004cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff8f27f1cd8b0b7cce783346f0538bee9397641b87d37d96a22fd8c3476146a62301000000fd5e0100483045022100b8e4ebf749ab4bba66e55e857a07b834558a16aeecd93d6e007811456d78d0b302205a8cbcc8f63f118536f938894f3a27236c353a177c43c0ef9987b29bac3227ef0147304402206390095bade6a4159ad036d9cfe7e7f0004024da09d460784d8bb45806664e62022059d21c421e1ddcdb17d70998617af6fc85589b35f6bd7c423d5443da4ec4864201004cc9534104362119e29a90c958c89efc186a23bb859c2d5de57cb0a6a9480ea47087f508d9fe0eceeaa42aec7d0757049c5395aaa1aeebc6b2babd3d1a9ca09122b8890f4c4104cc1f24bb27e7897c483e73d39542f578ec458f33ceea96cfed59ec5ae1b8474cbb3f96badd66caa134cdbc3c8d67ee4c424ea779414ad74383974761a8386a3541045b64a0d78f107a2525beaf4ede77b4bbabba671a86bfc37bc425382c85abb06c5cc4251cef05fd793491c4184db4601b69697eec12a4cb5199dc11f5a772ac6953aeffffffff0200752b7d0000000017a91413d2d93195352467f94a12a3def1e4c09d15ac278778d5a4350000000017a914cce437c88256ca0a9fa1eed83e5b192f4dcc39f18700000000"
52
53/*
54{
55  "result":true,
56  "sign_tx":"21ba06597c14339d7819511e5b4aa07834b503f1bce1d2141964a00c9a16d26e",
57  "status":200
58}
59*/
60
61// regtest 环境开启挖矿,确认多签交易
62bitcoin-cli -regtest generatetoaddress 10 2N8i6PbrW5nNtGbrHcPf5FJ1tNSyBou6t2b
63
64// regtest 查询 receiveaddress 地址余额
65bitcoin-cli -regtest getbalance  receiveaddress // 21.00000000

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 生成普通地址
  • 生成多签地址
  • 构建交易并首次签名
  • 比特币 regtest 环境多重签名测试流程
    • 生成地址
      • 交易并首次签名
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档