使用golang一步步教你在比特幣上刻字

from:https://blog.csdn.net/u010662978/article/details/79195284

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

https://www.blocktrail.com/tBCC/tx/a63edbbfa17e45b0890520ca30fce6d8eacd41635d1c447418fcfedffa14d914打開這個鏈接, 滑到最后, 會看如圖所示的文字

這是怎么做到的? 這是一個比特幣的交易, 怎么能附上中文呢? 本文就一步步教 你怎么在比特幣交易上添加文字. 因為比特幣的交易具有不可篡改性, 且永久存在區(qū)域鏈上, 那么其附帶的文字就有這個屬性, 這就好像是一個誓言! 誓言記存, 多有意義!!

第一步: 買一定的比特幣

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

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

下面這段代碼包含生成測試和正式地址, 你可以運行得到測試地址.

[plain]?view plain?copy

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()?//?測試地址??

???//?wifKey,?address,?_?:=?GenerateBTC()?//?正式地址??

???fmt.Println(address,?wifKey)??

}??

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

地址: mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd

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

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

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

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

[javascript]?view plain?copy

{??

"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"??

??????????]??

????????}??

??????],??

//?以下幾個值比較重要??

"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"??

????????}??

??????]??

????}??

??]??

}??

記住第一筆的這幾個值:

tx_hash 48eea09764713f3dadcfed29490ab5e288299e01e571e1f7a1396a75ce38e067

tx_output_n 0

script: 76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac

value 65000000

我們接下來會用到這個未花費交易

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

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

[plain]?view plain?copy

address?:=?"mt4p3rZpJE5fXEqvGzNBk9HxYXcWKpPJSd"??

var?balance?int64?=?65000000?//?余額??

var?fee?int64?=?0.001?*?1e8?//?交易費??

var?leftToMe?=?balance?-?fee?//?余額-交易費就是剩下再給我的??


//?1.?構(gòu)造輸出??

outputs?:=?[]*wire.TxOut{}??


//?1.1?輸出1,?給自己轉(zhuǎn)剩下的錢??

addr,?_?:=?btcutil.DecodeAddress(address,?&chaincfg.SimNetParams)??

pkScript,?_?:=?txscript.PayToAddrScript(addr)??

outputs?=?append(outputs,?wire.NewTxOut(leftToMe,?pkScript))??


//?1.2?輸出2,?添加文字??

comment?:=?"這是一個留言,?哈哈"??

pkScript,?_?=?txscript.NullDataScript([]byte(comment))??

outputs?=?append(outputs,?wire.NewTxOut(int64(0),?pkScript))??

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

[plain]?view plain?copy

//?2.?構(gòu)造輸入??

prevTxHash?:=?"48eea09764713f3dadcfed29490ab5e288299e01e571e1f7a1396a75ce38e067"??

prevPkScriptHex?:=?"76a91489a7f0117eaf47d8b4af740c66116e35ffe1bea988ac"??

prevTxOutputN?:=?uint32(0)??


hash,?_?:=?chainhash.NewHashFromStr(prevTxHash)?//?tx?hash??

outPoint?:=?wire.NewOutPoint(hash,?prevTxOutputN)?//?第幾個輸出??

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,??

}??

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

[plain]?view plain?copy

//?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ò)上

[plain]?view plain?copy

//?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

下面給出完整源碼:

[plain]?view plain?copy

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?//?交易費??

????var?leftToMe?=?balance?-?fee?//?余額-交易費就是剩下再給我的??


????//?1.?構(gòu)造輸出??

????outputs?:=?[]*wire.TxOut{}??


????//?1.1?輸出1,?給自己轉(zhuǎn)剩下的錢??

????addr,?_?:=?btcutil.DecodeAddress(address,?&chaincfg.SimNetParams)??

????pkScript,?_?:=?txscript.PayToAddrScript(addr)??

????outputs?=?append(outputs,?wire.NewTxOut(leftToMe,?pkScript))??


????//?1.2?輸出2,?添加文字??

????comment?:=?"這是一個留言,?哈哈"??

????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)?//?第幾個輸出??

????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??

????}??

}??

通過以上的方法, 比特幣刻字我已在?www.ibitlin.com?上實現(xiàn), 歡迎使用!!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吊宋,一起剝皮案震驚了整個濱河市变屁,隨后出現(xiàn)的幾起案子循衰,更是在濱河造成了極大的恐慌蟋座,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稍走,死亡現(xiàn)場離奇詭異袁翁,居然都是意外死亡,警方通過查閱死者的電腦和手機婿脸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門粱胜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人狐树,你說我怎么就攤上這事焙压。” “怎么了抑钟?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵涯曲,是天一觀的道長。 經(jīng)常有香客問我在塔,道長幻件,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任蛔溃,我火速辦了婚禮绰沥,結(jié)果婚禮上篱蝇,老公的妹妹穿的比我還像新娘。我一直安慰自己徽曲,他們只是感情好零截,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秃臣,像睡著了一般涧衙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奥此,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天弧哎,我揣著相機與錄音,去河邊找鬼稚虎。 笑死傻铣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祥绞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼鸭限,長吁一口氣:“原來是場噩夢啊……” “哼蜕径!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起败京,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤兜喻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赡麦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朴皆,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年泛粹,在試婚紗的時候發(fā)現(xiàn)自己被綠了遂铡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡晶姊,死狀恐怖扒接,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情们衙,我是刑警寧澤钾怔,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站蒙挑,受9級特大地震影響宗侦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜忆蚀,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一矾利、第九天 我趴在偏房一處隱蔽的房頂上張望姑裂。 院中可真熱鬧,春花似錦梦皮、人聲如沸炭分。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽捧毛。三九已至,卻和暖如春让网,著一層夾襖步出監(jiān)牢的瞬間呀忧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工溃睹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留而账,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓因篇,卻偏偏與公主長得像泞辐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子竞滓,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容