溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何使用Golang將誓言存在比特幣的區(qū)塊鏈上

發(fā)布時(shí)間:2021-12-15 09:44:43 來(lái)源:億速云 閱讀:168 作者:小新 欄目:云計(jì)算

這篇文章將為大家詳細(xì)講解有關(guān)如何使用Golang將誓言存在比特幣的區(qū)塊鏈上,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

大家先看一個(gè)區(qū)域鏈瀏覽器的交易鏈接:

https://www.blocktrail.com/tBCC/tx/a63edbbfa17e45b0890520ca30fce6d8eacd41635d1c447418fcfedffa14d914 打開(kāi)這個(gè)鏈接, 滑到最后, 會(huì)看如圖所示的文字

如何使用Golang將誓言存在比特幣的區(qū)塊鏈上

這是怎么做到的? 這是一個(gè)比特幣的交易, 怎么能附上中文呢? 本文就一步步教 你怎么在比特幣交易上添加文字. 因?yàn)楸忍貛诺慕灰拙哂胁豢纱鄹男? 且永久存在區(qū)域鏈上, 那么其附帶的文字就有這個(gè)屬性, 這就好像是一個(gè)誓言! 誓言記存, 多有意義!!

第一步: 買(mǎi)一定的比特幣

比特幣交易是需要手續(xù)費(fèi)的, 而當(dāng)前的手續(xù)費(fèi)并不便宜, 動(dòng)則至少上百元, 這太貴了. 所以我推薦大家先去比特幣測(cè)試網(wǎng)絡(luò)先弄一些幣來(lái)測(cè)試. 怎么在獲取比特幣測(cè)試網(wǎng)絡(luò)的免費(fèi)比特幣, 大家可以Google下, 有一些網(wǎng)站會(huì)免費(fèi)送. 比如大家可以去 https://testnet.coinfaucet.eu/en/ 這個(gè)站點(diǎn)去獲取, 當(dāng)前獲取的前提是你有一個(gè)測(cè)試網(wǎng)絡(luò)的比特幣地址, 不然不知道給誰(shuí)發(fā)幣啊. 下面教你怎么用Golang 生成比特幣測(cè)試地址:

https://github.com/btcsuite/btcd 是bitcoin的golang版實(shí)現(xiàn), 先按照它的文檔安裝, 這里假設(shè)你已經(jīng)成功安裝在本地了.

下面這段代碼包含生成測(cè)試和正式地址, 你可以運(yùn)行得到測(cè)試地址.

package main
 
import (
   "github.com/btcsuite/btcd/btcec"
   "github.com/btcsuite/btcutil"
   "github.com/btcsuite/btcd/chaincfg"
   "fmt"
)
 
func GenerateBTC() (string, string, error) {
   privKey, err := btcec.NewPrivateKey(btcec.S256())
   if err != nil {
      return "", "", err
   }
 
   privKeyWif, err := btcutil.NewWIF(privKey, &chaincfg.MainNetParams, false)
   if err != nil {
      return "", "", err
   }
   pubKeySerial := privKey.PubKey().SerializeUncompressed()
 
   pubKeyAddress, err := btcutil.NewAddressPubKey(pubKeySerial, &chaincfg.MainNetParams)
   if err != nil {
      return "", "", err
   }
 
   return privKeyWif.String(), pubKeyAddress.EncodeAddress(), nil
}
 
func GenerateBTCTest() (string, string, error) {
   privKey, err := btcec.NewPrivateKey(btcec.S256())
   if err != nil {
      return "", "", err
   }
 
   privKeyWif, err := btcutil.NewWIF(privKey, &chaincfg.TestNet3Params, false)
   if err != nil {
      return "", "", err
   }
   pubKeySerial := privKey.PubKey().SerializeUncompressed()
 
   pubKeyAddress, err := btcutil.NewAddressPubKey(pubKeySerial, &chaincfg.TestNet3Params)
   if err != nil {
      return "", "", err
   }
 
   return privKeyWif.String(), pubKeyAddress.EncodeAddress(), nil
}
 
func main()  {
   wifKey, address, _ := GenerateBTCTest() // 測(cè)試地址
   // wifKey, address, _ := GenerateBTC() // 正式地址
   fmt.Println(address, wifKey)
}

假設(shè)你得到了一個(gè)測(cè)試地址: 

  1. 地址: mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd

  2. 私鑰: cV4HmdzGF3gG7NdEtVV7sjq22yoBmZBe5MEGKUqvQTXXXXX(注意,該密鑰不是正確的,請(qǐng)不要使用)

然后, 你去https://testnet.coinfaucet.eu/en/ 領(lǐng)免費(fèi)的測(cè)試比特幣, 可以通過(guò)接口查看該地址的未花費(fèi)交易信息:

https://api.blockcypher.com/v1/btc/test3/addrs/mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd/full

總共發(fā)了兩筆, 第一筆 0.65 第二筆 1.3 總共這個(gè)地址的余額是 1.95

{
  "address": "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd",
  "total_received": 195000000,
  "total_sent": 0,
  "balance": 195000000,
  "unconfirmed_balance": 0,
  "final_balance": 195000000,
  "n_tx": 2,
  "unconfirmed_n_tx": 0,
  "final_n_tx": 2,
  "txs": [
     // 第二筆
    {
      "block_hash": "00000000000004149feebc41cfeb5a66df052f989aec60faec711caee4f93b3c",
      "block_height": 1255326,
      "block_index": 53,
      "hash": "2c56134c99b24e17f5c3852d910e2e090848652c4e7b08ee8aa7450b2e14d7c4",
      "addresses": [
        "2N48GnaEkd8eZgQ5MLTb6EGBvqfuQ94sVTv",
        "2NAwfhDByKfV5ZPr4cnLVg9hMHcx31CZbEp",
        "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"
      ],
      "total": 197064067190,
      "fees": 100000,
      "size": 140,
      "preference": "high",
      "relayed_by": "94.130.106.254:18333",
      "confirmed": "2017-12-19T02:32:36Z",
      "received": "2017-12-19T02:17:26.601Z",
      "ver": 1,
      "double_spend": false,
      "vin_sz": 1,
      "vout_sz": 2,
      "confirmations": 5672,
      "confidence": 1,
      "inputs": [
        {
          "prev_hash": "7265ffdf8310fc2ecd6277759f39de9c801149ca602c6b2236667d2af2d5dd29",
          "output_index": 1,
          "script": "1600149eb46621cceac0e393b5cd5ffb481fafa48a16fc",
          "output_value": 197064167190,
          "sequence": 4294967295,
          "addresses": [
            "2NAwfhDByKfV5ZPr4cnLVg9hMHcx31CZbEp"
          ],
          "script_type": "pay-to-script-hash",
          "age": 1255313,
          "witness": [
            "3044022034bb850d1efab224a14b7cd7565a9fce58fb89794f50471419115f1b893f626d022027a849a46f3a902944e3f01a66eb0fc489bfe8e5a7815b8644128b7e6f89ace101",
            "030916ad60b499268f909e20867b49d22e55b3864aafc896120c6daec1011ceecb"
          ]
        }
      ],
      "outputs": [
        {
          "value": 130000000,
          "script": "76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac",
          "addresses": [
            "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"
          ],
          "script_type": "pay-to-pubkey-hash"
        },
        {
          "value": 196934067190,
          "script": "a9147758cec0a445f9908186f5cfeeb52bc0077c7e1487",
          "spent_by": "5c3c00896db0ba1a7526c6e8c3495c29264df99d4a494afbd909af4f0d4df605",
          "addresses": [
            "2N48GnaEkd8eZgQ5MLTb6EGBvqfuQ94sVTv"
          ],
          "script_type": "pay-to-script-hash"
        }
      ]
    },
    // 第一筆
    {
      "block_hash": "00000000000004149feebc41cfeb5a66df052f989aec60faec711caee4f93b3c",
      "block_height": 1255326,
      "block_index": 40,
      "hash": "48eea09764713f3dadcfed29490ab5e288299e01e571e1f7a1396a75ce38e067",
      "addresses": [
        "2N4Mrw2XRMEfAuf51JiZsaQCSxr9UowxSbJ",
        "2N5CNRLZXXZt2JFxPLX9z6HF9gdgLqG3ycH",
        "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"
      ],
      "total": 196092936523,
      "fees": 100000,
      "size": 140,
      "preference": "high",
      "relayed_by": "88.196.208.18:18333",
      "confirmed": "2017-12-19T02:32:36Z",
      "received": "2017-12-19T02:17:33.267Z",
      "ver": 1,
      "double_spend": false,
      "vin_sz": 1,
      "vout_sz": 2,
      "confirmations": 5672,
      "confidence": 1,
      "inputs": [
        {
          "prev_hash": "2880f6c768afa728fa9374af0617d535a960243f2820de53992279a59b84d8a3",
          "output_index": 1,
          "script": "1600147ce118c5a9faa2fdf5bc1c7feb41ddac7084a481",
          "output_value": 196093036523,
          "sequence": 4294967295,
          "addresses": [
            "2N5CNRLZXXZt2JFxPLX9z6HF9gdgLqG3ycH"
          ],
          "script_type": "pay-to-script-hash",
          "age": 1255313,
          "witness": [
            "30440220741aa14828e97e0fd9668b9070e2ab886f3646456c33b143c291f6c47e1ec985022005f624843908a745dbc5d703361065a5fbca9aa0b1fb4aca105cd09d8e6fd09e01",
            "02fe3a6a5cfb075b84d5a0e6daa2220dc49c8a36b61f49f86111dd08141166b7fc"
          ]
        }
      ],
      // 以下幾個(gè)值比較重要
      "outputs": [
        {
          "value": 65000000,
          "script": "76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac",
          "addresses": [
            "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"
          ],
          "script_type": "pay-to-pubkey-hash"
        },
        {
          "value": 196027936523,
          "script": "a91479eab7f3bf5054cc47da2761f0b61d6cb622622a87",
          "spent_by": "dc32b80ba7f863572c8dd97508d8c7a04af35d10671c9ca3c60f0d28c552c8d1",
          "addresses": [
            "2N4Mrw2XRMEfAuf51JiZsaQCSxr9UowxSbJ"
          ],
          "script_type": "pay-to-script-hash"
        }
      ]
    }
  ]
}

記住第一筆的這幾個(gè)值:

  • tx_hash 48eea09764713f3dadcfed29490ab5e288299e01e571e1f7a1396a75ce38e067

  • tx_output_n 0

  • script: 76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac

  • value 65000000

我們接下來(lái)會(huì)用到這個(gè)未花費(fèi)交易

第二步: 構(gòu)造交易, 附上文字

下面構(gòu)造一個(gè)交易, 這個(gè)交易給自己發(fā)一筆錢(qián), 交易費(fèi)是0.001

address := "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"
var balance int64 = 65000000 // 余額
var fee int64 = 0.001 * 1e8 // 交易費(fèi)
var leftToMe = balance - fee // 余額-交易費(fèi)就是剩下再給我的
 
// 1. 構(gòu)造輸出
outputs := []*wire.TxOut{}
 
// 1.1 輸出1, 給自己轉(zhuǎn)剩下的錢(qián)
addr, _ := btcutil.DecodeAddress(address, &chaincfg.SimNetParams)
pkScript, _ := txscript.PayToAddrScript(addr)
outputs = append(outputs, wire.NewTxOut(leftToMe, pkScript))
 
// 1.2 輸出2, 添加文字
comment := "這是一個(gè)留言, 哈哈"
pkScript, _ = txscript.NullDataScript([]byte(comment))
outputs = append(outputs, wire.NewTxOut(int64(0), pkScript))

第三步: 構(gòu)造輸入

// 2. 構(gòu)造輸入
prevTxHash := "48eea09764713f3dadcfed29490ab5e288299e01e571e1f7a1396a75ce38e067"
prevPkScriptHex := "76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac"
prevTxOutputN := uint32(0)
 
hash, _ := chainhash.NewHashFromStr(prevTxHash) // tx hash
outPoint := wire.NewOutPoint(hash, prevTxOutputN) // 第幾個(gè)輸出
txIn := wire.NewTxIn(outPoint, nil, nil)
inputs := []*wire.TxIn{txIn}
 
prevPkScript, _ := hex.DecodeString(prevPkScriptHex)
prevPkScripts := make([][]byte, 1)
prevPkScripts[0] = prevPkScript
 
tx := &wire.MsgTx{
   Version:  wire.TxVersion,
   TxIn:     inputs,
   TxOut:    outputs,
   LockTime: 0,
}

第四步: 簽名交易(簽名輸入)

// 3. 簽名
privKey := "cV4HmdzGF3gG7NdEtVV7sjq22yoBmZBe5MEGKUqvQTXXXXX" // 私鑰
sign(tx, privKey, prevPkScripts)
 
// 簽名方法
func sign(tx *wire.MsgTx, privKeyStr string, prevPkScripts [][]byte)  {
   inputs := tx.TxIn
   wif, err := btcutil.DecodeWIF(privKeyStr)
 
   fmt.Println("wif err", err)
   privKey := wif.PrivKey
 
   for i := range inputs {
      pkScript := prevPkScripts[i]
      var script []byte
      script, err = txscript.SignatureScript(tx, i, pkScript, txscript.SigHashAll,
            privKey, false)
      inputs[i].SignatureScript = script
   }
}

第五步: 輸出交易原始信息, 廣播到網(wǎng)絡(luò)上

// 4. 輸出Hex
buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
if err := tx.Serialize(buf); err != nil {
}
txHex := hex.EncodeToString(buf.Bytes())
fmt.Println("hex", txHex)

將輸出的hex廣播到網(wǎng)絡(luò)上, https://tbtc.blockdozer.com/insight/tx/send

下面給出完整源碼:

package tx

import (
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcutil"
	"github.com/btcsuite/btcd/chaincfg"
	"github.com/btcsuite/btcd/txscript"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"encoding/hex"
	"fmt"
	"bytes"
)

func main() {
	address := "mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"
	var balance int64 = 65000000 // 余額
	var fee int64 = 0.001 * 1e8 // 交易費(fèi)
	var leftToMe = balance - fee // 余額-交易費(fèi)就是剩下再給我的

	// 1. 構(gòu)造輸出
	outputs := []*wire.TxOut{}

	// 1.1 輸出1, 給自己轉(zhuǎn)剩下的錢(qián)
	addr, _ := btcutil.DecodeAddress(address, &chaincfg.SimNetParams)
	pkScript, _ := txscript.PayToAddrScript(addr)
	outputs = append(outputs, wire.NewTxOut(leftToMe, pkScript))

	// 1.2 輸出2, 添加文字
	comment := "這是一個(gè)留言, 哈哈"
	pkScript, _ = txscript.NullDataScript([]byte(comment))
	outputs = append(outputs, wire.NewTxOut(int64(0), pkScript))

	// 2. 構(gòu)造輸入
	prevTxHash := "48eea09764713f3dadcfed29490ab5e288299e01e571e1f7a1396a75ce38e067"
	prevPkScriptHex := "76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac"
	prevTxOutputN := uint32(0)

	hash, _ := chainhash.NewHashFromStr(prevTxHash) // tx hash
	outPoint := wire.NewOutPoint(hash, prevTxOutputN) // 第幾個(gè)輸出
	txIn := wire.NewTxIn(outPoint, nil, nil)
	inputs := []*wire.TxIn{txIn}

	prevPkScript, _ := hex.DecodeString(prevPkScriptHex)
	prevPkScripts := make([][]byte, 1)
	prevPkScripts[0] = prevPkScript

	tx := &wire.MsgTx{
		Version:  wire.TxVersion,
		TxIn:     inputs,
		TxOut:    outputs,
		LockTime: 0,
	}

	// 3. 簽名
	privKey := "cV4HmdzGF3gG7NdEtVV7sjq22yoBmZBe5MEGKUqvQTXXXXX" // 私鑰
	sign(tx, privKey, prevPkScripts)

	// 4. 輸出Hex
	buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
	if err := tx.Serialize(buf); err != nil {
	}
	txHex := hex.EncodeToString(buf.Bytes())
	fmt.Println("hex", txHex)
}

// 簽名
func sign(tx *wire.MsgTx, privKeyStr string, prevPkScripts [][]byte)  {
	inputs := tx.TxIn
	wif, err := btcutil.DecodeWIF(privKeyStr)

	fmt.Println("wif err", err)
	privKey := wif.PrivKey

	for i := range inputs {
		pkScript := prevPkScripts[i]
		var script []byte
		script, err = txscript.SignatureScript(tx, i, pkScript, txscript.SigHashAll,
			privKey, false)
		inputs[i].SignatureScript = script
	}
}

關(guān)于“如何使用Golang將誓言存在比特幣的區(qū)塊鏈上”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI