比特幣技術(shù)進級的三篇文章

作者 Kevin

簡介:“比特幣技術(shù)進階”由知名比特幣技術(shù)專家Kevin原創(chuàng)的三篇文章《比特幣交易構(gòu)成》、《時間戳服務與存在證明》芦倒、《工作證明與挖礦》組成,對于那些想要探究比特幣工作原理卻又不想費力分析源代碼的朋友,這篇文章是您或不可缺的進階指南。

一恒序、工作證明與挖礦

工作證明

工作證明(Proof Of Work,簡稱POW)谁撼,顧名思義歧胁,即工作量的證明。通常來說只能從結(jié)果證明彤敛,因為監(jiān)測工作過程通常是繁瑣與低效的与帆。

比特幣在Block的生成過程中使用了POW機制了赌,一個符合要求的Block Hash由N個前導零構(gòu)成墨榄,零的個數(shù)取決于網(wǎng)絡的難度值。要得到合理的Block Hash需要經(jīng)過大量嘗試計算勿她,計算時間取決于機器的哈希運算速度袄秩。當某個節(jié)點提供出一個合理的Block Hash值,說明該節(jié)點確實經(jīng)過了大量的嘗試計算逢并,當然之剧,并不能得出計算次數(shù)的絕對值,因為尋找合理hash是一個概率事件砍聊。當節(jié)點擁有占全網(wǎng)n%的算力時背稼,該節(jié)點即有n/100的概率找到Block Hash。

工作證明機制看似很神秘玻蝌,其實在社會中的應用非常廣泛蟹肘。例如,畢業(yè)證俯树、學位證等證書帘腹,就是工作證明,擁有證書即表明你在過去投入了學習與工作许饿。生活大部分事情都是通過結(jié)果來判斷的阳欲。

挖礦

挖礦即不斷接入新的Block延續(xù)Block Chain的過程。

挖礦為整個系統(tǒng)的運轉(zhuǎn)提供原動力,是比特幣的發(fā)動機球化,沒有挖礦就沒有比特幣秽晚。挖礦有三個重要功能:

  1. 發(fā)行新的貨幣(總量達到之前)

  2. 維系貨幣的支付功能

  3. 通過算力保障系統(tǒng)安全

金礦消耗資源將黃金注入流通經(jīng)濟,比特幣通過“挖礦”完成相同的事情筒愚,只不過消耗的是CPU時間與電力爆惧。當然,比特幣的挖礦意義遠大于此锨能。

Block Hash算法

Block頭部信息的構(gòu)成:

字段名 含義 大小(字節(jié))
Version 版本號 4
hashPrevBlock 上一個block hash值 32
hashMerkleRoot 上一個block產(chǎn)生之后至新block生成此時間內(nèi)扯再,
交易數(shù)據(jù)打包形成的Hash 32
Time Unix時間戳 4
Bits 目標值,即難度 4
Nonce 隨機數(shù) 4

nHeight+1) % nInterval != 0) {
// 未達到周期個數(shù)址遇,無需調(diào)節(jié)
return pindexLast->nBits;
}

// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
for (int i = 0; pindexFirst && i < nInterval-1; i++) pindexFirst = pindexFirst->pprev;

// 計算本次2016個塊的實際產(chǎn)生時間
// Limit adjustment step
int64 nActualTimespan = pindexLast->GetBlockTime() – pindexFirst->GetBlockTime();
// 限定幅度熄阻,最低為1/4,最高為4倍
if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan4)
nActualTimespan = nTargetTimespan
4;

// 根據(jù)最近2016個塊的時間倔约,重新計算目標難度
// Retarget
CBigNum bnNew;
bnNew.SetCompact(pindexLast->nBits);
bnNew *= nActualTimespan;
bnNew /= nTargetTimespan;

if (bnNew > bnProofOfWorkLimit)
bnNew = bnProofOfWorkLimit;

return bnNew.GetCompact();
Block字段詳解

  1. Version秃殉,版本號,很少變動浸剩,一般用于軟件全網(wǎng)升級時做標識

  2. hashPrevBlock钾军,前向Block Hash值,該字段強制多個Block之間形成鏈接

  3. hashMerkleRoot绢要,交易Hash樹的根節(jié)點Hash值吏恭,起校驗作用,保障Block在網(wǎng)絡傳輸過程中的數(shù)據(jù)一致性重罪,有新交易加入即發(fā)生變化

  4. Time樱哼,Unix時間戳,每秒自增一剿配,標記Block的生成時間搅幅,同時為block hash探尋引入一個頻繁的變動因子

  5. Bits,可以推算出難度值呼胚,用于驗證block hash難度是否達標

  6. Nonce茄唐,隨機數(shù),在上面數(shù)個字段都固定的情況下蝇更,不停地更換隨機數(shù)來探尋

最為關(guān)鍵的字段是hashPrevBlock沪编,該字段使得Block之間鏈接起來,形成一個巨大的“鏈條”簿寂。Block本是稀松平常的數(shù)據(jù)結(jié)構(gòu)漾抬,但以鏈式結(jié)構(gòu)組織起來后卻使得它們具有非常深遠的意義:

  1. 形成分支博弈,使得算力總是在主分支上角逐

  2. 算力攻擊的概率難度呈指數(shù)上升(泊松分布)

每個block都必須指向前一個block,否則無法驗證通過。追溯至源頭,便是高度為零的創(chuàng)世紀塊(Genesis Block)德挣,這里是Block Chain的起點平绩,其前向block hash為零圈匆,或者說為空。

新block誕生過程

下面是一個簡單的步驟描述捏雌,實際礦池運作會有區(qū)別跃赚,復雜一些:

  1. 節(jié)點監(jiān)聽全網(wǎng)交易,通過驗證的交易進入節(jié)點的內(nèi)存池(Tx Mem Pool)性湿,并更新交易數(shù)據(jù)的Merkle Hash值

  2. 更新時間戳

  3. 嘗試不同的隨機數(shù)(Nonce)纬傲,進行hash計算

  4. 重復該過程至找到合理的hash

  5. 打包block:先裝入block meta信息,然后是交易數(shù)據(jù)

  6. 對外部廣播出新block

  7. 其他節(jié)點驗證通過后肤频,鏈接至Block Chain叹括,主鏈高度加一,然后切換至新block后面挖礦

由于hashPrevBlock字段的存在宵荒,使得大家總是在最新的block后面開挖汁雷,稍后會分析原因。

主鏈分叉

從block hash算法我們知道报咳,合理的block并不是唯一的侠讯,同一高度存在多個block的可能性。那么暑刃,當同一個高度出現(xiàn)多個時厢漩,主鏈即出現(xiàn)分叉(Fork)。遇到分叉時稍走,網(wǎng)絡會根據(jù)下列原則選舉出Best Chain:

  1. 不同高度的分支袁翁,總是接受最高(即最長)的那條分支

  2. 相同高度的柴底,接受難度最大的

  3. 高度相同且難度一致的婿脸,接受時間最早的

  4. 若所有均相同,則按照從網(wǎng)絡接受的順序

  5. 等待Block Chain高度增一柄驻,則重新選擇Best Chain

94b6ba76-f621-11e2-95b0-febc373535b7

按照這個規(guī)則運作的節(jié)點狐树,稱為誠實節(jié)點(Honest Nodes)。節(jié)點可以誠實也可以不誠實鸿脓。

分支博弈

我們假設所有的節(jié)點:

  1. 都是理性的抑钟,追求收益最大化

  2. 都是不誠實的,且不惜任何手段獲取利益

所有節(jié)點均獨自挖礦不理會其他節(jié)點野哭,并將所得收益放入自己口袋在塔,現(xiàn)象就是一個節(jié)點挖一個分支。由于機器的配置總是有差別的拨黔,那么算力最強的節(jié)點挖得的分支必然是最長的蛔溃,如果一個節(jié)點的分支不是最長的,意味其收益存在不被認可的風險(即零收益)。為了降低贺待、逃避此風險徽曲,一些節(jié)點肯定會聯(lián)合起來一起挖某個分支,試圖成為最長的分支或保持最長分支優(yōu)勢麸塞。

一旦出現(xiàn)有少量的節(jié)點聯(lián)合秃臣,那么其他節(jié)點必然會效仿,否則他們收益為零的風險會更大哪工。于是奥此,分支迅速合并匯集,所有節(jié)點都會選擇算力更強的分支雁比,只有這樣才能保持收益風險最小得院。最終,只會存在一個這樣的分支章贞,就是主干分支(Best/Main Chain)祥绞。

對于不誠實節(jié)點來說,結(jié)局是無奈的:能且只能加入主干挖礦鸭限。不加入即意味被拋棄蜕径,零收益;加入就是老實干活败京,按占比分成兜喻。

Hash Dance

Block hash的計算是隨機概率事件,當有節(jié)點廣播出難度更高的block后赡麦,大家便跑到那個分支朴皆。在比特幣系統(tǒng)運行過程中,算力經(jīng)常在分支間跳來跳去泛粹,此現(xiàn)象稱為Hash Dance遂铡。一般情況下,分支的高度為1~2晶姊,沒有大的故障很難出現(xiàn)高于2的分支扒接。

Hash Dance起名源于Google Dance.

算力攻擊的概率

算力攻擊是一個概率問題,這里作簡單敘述:

  • p = 誠實節(jié)點挖出block概率

  • q = 攻擊者挖出block概率们衙,q = 1 – p

  • qz = 攻擊者從z個block追上的概率

a22dae50-fb92-11e2-95aa-3e346efdab40

我們假設p>q钾怔,否則攻擊者掌握了一半以上的算力,那么概率上永遠是贏的蒙挑。該事件(攻擊者勝出)的概率是固定宗侦,且N次事件之間是相互獨立的,那么這一系列隨機過程符合泊松分布(Poisson Distribution)忆蚀。Z個塊時矾利,攻擊者勝出的期望為lambda:

e386fa6c-fc20-11e2-8376-73d9a367bf98

攻擊者在攻擊時已經(jīng)偷偷的計算了k個塊懊悯,那么這k個塊概率符合泊松分布(下圖左側(cè)部分),若k<=z梦皮,那么追趕上后續(xù)z-k個塊的概率為(q/p)z-k炭分,即:

d08dfcca-fc21-11e2-9740-907f2a89de88

展開為如下形式:

b08c63ec-fc23-11e2-8f43-c932daec9f7c

計算該過程的C語言代碼如下:

include double AttackerSuccessProbability(double q, int z)

{
double sum = 1.0;
double p = 1.0 – q;
double lambda = z * (q / p);
int i, k;
for (k = 0; k <= z; k++) {
double poisson = exp(-lambda);
for (i = 1; i <= k; i++)
poisson *= lambda / i;
sum -= poisson * (1 – pow(q / p, z – k));
}
return sum;
}
我們選取幾個值,結(jié)果如下:

e6c5ed84-fc23-11e2-9334-ca8e768c5aa0

可以看到剑肯,由于block的鏈式形式捧毛,隨著塊數(shù)的上升,攻擊者贏得的概率呈指數(shù)下降让网。這是很多應用等待六個甚至六個以上確認的原因呀忧,一旦超過N個確認,攻擊者得逞的可能微乎其微溃睹,概率值快速趨近零而账。

當攻擊者的算力超過50%時,便可以控制Block Chain因篇,俗稱51%攻擊泞辐。

算力攻擊的危害

攻擊者算出block后,block&Txs必須能夠通過驗證竞滓,否則其他節(jié)點都會拒掉咐吼,攻擊便無意義。攻擊者無法做出下列行為:

  1. 偷盜他人的幣商佑。消費某個地址的幣時锯茄,需要對應的ECDSA私鑰簽名,而私鑰是無法破解的茶没。

  2. 憑空制造比特幣肌幽。每個block獎勵的幣值是統(tǒng)一的規(guī)則,篡改獎勵幣值會導致其他節(jié)點會拒絕該block抓半。

唯一的益處是可以選擇性的收錄進入block的交易喂急,對自己的幣進行多重消費(Double Spending)。

過程是這樣的:假設現(xiàn)在block高度為100琅关,攻擊者給商戶發(fā)了一個交易10BTC煮岁,記作交易A,通常這筆交易會被收錄進高度101的block中涣易,當商戶在101塊中看到這筆交易后,就把貨物給了攻擊者冶伞。此時新症,攻擊者便開始構(gòu)造另一個高度為101的block,但用交易B替換了交易A响禽,交易B中的輸入是同一筆徒爹,使得發(fā)給商戶的那筆錢發(fā)給他自己荚醒。同時,攻擊者需要努力計算block隆嗅,使得他的分支能夠趕上主分支界阁,并合并(Merge)被大家接受,一旦接受胖喳,便成功地完成了一次Double Spending泡躯。

攻擊難度呈指數(shù)上升,所以成功的Double Spending通常是一個極小概率事件丽焊。

算力巨頭

全網(wǎng)算力的上升對比特幣是極其有利的较剃,這是毫無疑問的。但目前大礦池與礦業(yè)巨頭使得算力高度集中化技健,這與中本聰所設想的一CPU一票(one-CPU-one-vote)的分散局面背道而馳写穴,或許是他未曾預料的。

挖礦是一項專業(yè)勞動雌贱,最后必然會交給最專業(yè)的人或團隊啊送,因為這樣才能實現(xiàn)資源配置最優(yōu),效率最高欣孤。普通投資人通過購買算力巨頭的股票:1. 完成投資删掀;2. 分享算力紅利〉冀郑看似中心化的背后其實依然是分散的:

  1. 礦業(yè)公司的背后是無數(shù)分散的投資人

  2. 礦池背后是無數(shù)分散的個體算力

既得利益使得算力巨頭傾向于維護系統(tǒng)而不是破壞披泪,因其收益均建立在比特幣系統(tǒng)之上,既得利益者斷然不會搬石頭砸自己腳搬瑰。甚至很多巨頭在達到一定算力占比后會主動控制算力增長款票,使得低于某閾值內(nèi)。

后記

本篇幾乎都在講挖礦泽论,因為挖礦對于比特幣系統(tǒng)來說實在是太重要了艾少。需要了解:1.

block是基于工作量證明的。2. block以鏈式結(jié)構(gòu)存在時的深遠意義翼悴。

二缚够、比特幣交易構(gòu)成

簡介

交易(Transaction)是比特幣系統(tǒng)的信息載體,最小單元鹦赎。而塊(Block)就是將這些基礎單元打包裝箱谍椅,貼上封條,并串聯(lián)起來古话。巨大算力保障了塊的安全雏吭,也就保障了單個交易的安全。

類型

交易有三種常見類型:產(chǎn)量交易(Generation)陪踩,合成地址交易(Script Hash)杖们,通用地址交易(Pubkey Hash)悉抵。該分類并非嚴格意義的,只是根據(jù)交易的輸入輸出做的簡單區(qū)分摘完。

Generation TX

每個Block都對應一個產(chǎn)量交易(Generation TX)姥饰,該類交易是沒有輸入交易的,挖出的新幣是所有幣的源頭孝治。

Script Hash TX

該類交易目前不是很常見列粪,大部分人可能沒有聽說過,但是非常有意義荆秦。未來應該會在某些場合頻繁使用篱竭。該類交易的接受地址不是通常意義的地址,而是一個合成地址步绸,以3開頭(對掺逼,以3開頭的也是比特幣地址!)瓤介。三對公私鑰吕喘,可以生成一個合成地址。在生成過程時指定n of 3中的n刑桑,n范圍是[1, 3]氯质,若n=1,則僅需一個私鑰簽名即可花費該地址的幣祠斧,若n=3闻察,則需要三把私鑰依次簽名才可以。

<a name="t17" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: normal; outline: none;"></a>Pubkey Hash TX

該類是最常見的交易類型琢锋,由N個輸入辕漂、M個輸出構(gòu)成。

數(shù)據(jù)結(jié)構(gòu)

交易中存放的是貨幣所有權(quán)的流轉(zhuǎn)信息吴超,所有權(quán)登記在比特幣地址上(Public Key)钉嘹。這些信息是全網(wǎng)公開的,以明文形式存儲(比特幣系統(tǒng)里的所有數(shù)據(jù)都是明文的)鲸阻,只有當需要轉(zhuǎn)移貨幣所有權(quán)時跋涣,才需要用私鑰簽名來驗證。

字段大小 描述 數(shù)據(jù)類型 解釋
4 version, 版本 uint32_t 交易數(shù)據(jù)結(jié)構(gòu)的版本號
1+ tx_in count, 輸入數(shù)量 var_int 輸入交易的數(shù)量
41+ tx_in tx_in[] 輸入交易的數(shù)組鸟悴,每個輸入>=41字節(jié)
1+ tx_out count, 輸出數(shù)量 var_int 輸出地址的數(shù)量
9+ tx_out tx_out[] 輸入地址的數(shù)組陈辱,每個輸入>=9字節(jié)
4 lock_time, 鎖定時間 uint32_t 見下方解釋

lock_time是一個多意字段,表示在某個高度的Block之前或某個時間點之前該交易處于鎖定態(tài)遣臼,無法收錄進Block性置。

含義
0 立即生效
< 500000000 含義為Block高度,處于該Block之前為鎖定(不生效)
>= 500000000 含義為Unix時間戳揍堰,處于該時刻之前為鎖定(不生效)

若該筆交易的所有輸入交易的sequence字段鹏浅,均為INT32最大值(0xffffffff),則忽略lock_time字段屏歹。否則隐砸,該交易在未達到Block高度或達到某個時刻之前,是不會被收錄進Block中的蝙眶。

示例

為了演示方便季希,我們讀取稍早期的塊數(shù)據(jù),以高度116219 Block為例幽纷。

~ bitcoind getblock 0000000000007c639f2cbb23e4606a1d022fa4206353b9d92e99f5144bd74611

{
“hash” : “0000000000007c639f2cbb23e4606a1d022fa4206353b9d92e99f5144bd74611″,
“confirmations” : 144667,
“size” : 1536,
“height” : 116219,
“version” : 1,
“merkleroot” : “587fefd748f899f84d0fa1d8a3876fdb406a4bb8f54a31445cb72564701daea6″,
“tx” : [
"be8f08d7f519eb863a68cf292ca51dbab7c9b49f50a96d13f2db32e432db363e",
"a387039eca66297ba51ef2da3dcc8a0fc745bcb511e20ed9505cc6762be037bb",
"2bd83162e264abf59f9124ca517050065f8c8eed2a21fbf85d454ee4e0e4c267",
"028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743",
"3a06b6615756dc3363a8567fbfa8fe978ee0ba06eb33fd844886a0f01149ad62"
],
“time” : 1301705313,
“nonce” : 1826107553,
“bits” : “1b00f339″,
“difficulty” : 68977.78463021,
“previousblockhash” : “00000000000010d549135eb39bd3bbb1047df8e1512357216e8a85c57a1efbfb”,
“nextblockhash” : “000000000000e9fcc59a6850f64a94476a30f5fe35d6d8c4b4ce0b1b04103a77″
}
該Block里面有5筆交易式塌,第一筆為Generation TX,解析出來看一下具體內(nèi)容:

~ bitcoind getrawtransaction be8f08d7f519eb863a68cf292ca51dbab7c9b49f50a96d13f2db32e432db363e 1

{
“hex” : “01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff070439f3001b0134ffffffff014034152a010000004341045b3aaa284d169c5ae2d20d0b0673468ed3506aa8fea5976eacaf1ff304456f6522fbce1a646a24005b8b8e771a671f564ca6c03e484a1c394bf96e2a4ad01dceac00000000″,
“txid” : “be8f08d7f519eb863a68cf292ca51dbab7c9b49f50a96d13f2db32e432db363e”,
“version” : 1,
“l(fā)ocktime” : 0,
“vin” : [
{
"coinbase" : "0439f3001b0134",
"sequence" : 4294967295
}
],
“vout” : [
{
"value" : 50.01000000,
"n" : 0,
"scriptPubKey" : {
"asm" : "045b3aaa284d169c5ae2d20d0b0673468ed3506aa8fea5976eacaf1ff304456f6522fbce1a646a24005b8b8e771a671f564ca6c03e484a1c394bf96e2a4ad01dce OP_CHECKSIG",
"hex" : "41045b3aaa284d169c5ae2d20d0b0673468ed3506aa8fea5976eacaf1ff304456f6522fbce1a646a24005b8b8e771a671f564ca6c03e484a1c394bf96e2a4ad01dceac",
"reqSigs" : 1,
"type" : "pubkey",
"addresses" : [
"1LgZTvoTJ6quJNCURmBUaJJkWWQZXkQnDn"
]
}
}
],
“blockhash” : “0000000000007c639f2cbb23e4606a1d022fa4206353b9d92e99f5144bd74611″,
“confirmations” : 145029,
“time” : 1301705313,
“blocktime” : 1301705313
}
Generation TX的輸入不是一個交易友浸,而帶有coinbase字段的結(jié)構(gòu)峰尝。該字段的值由挖出此Block的人填寫,這是一種“特權(quán)”:可以把信息寫入貨幣系統(tǒng)(大家很喜歡用系統(tǒng)中的數(shù)據(jù)結(jié)構(gòu)字段名來命名站點收恢,例如blockchain武学、coinbase等,這些詞的各種后綴域名都被搶注一空)伦意。中本聰在比特幣的第一個交易中的寫入的coinbase值是:

“coinbase”:”04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73″

將該段16進制轉(zhuǎn)換為ASCII字符火窒,就是那段著名的創(chuàng)世塊留言:

The Times 03/Jan/2009 Chancellor on brink of second bailout for banks

接下來展示的是一個三個輸入、兩個輸出的普通交易:

~ bitcoind getrawtransaction 028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743 1

{
“hex” : “0100000003c9f3b07ebfca68fd1a6339d0808fbb013c90c6095fc93901ea77410103489ab7000000008a473044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af0141048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbeffffffffc9f3b07ebfca68fd1a6339d0808fbb013c90c6095fc93901ea77410103489ab7010000008a47304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d0141042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026affffffffc98620a6c40fc7b3a506ad79af339541762facd1dd80ff0881d773fb72b230da010000008b483045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d014104a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2fffffffff0200bd0105000000001976a914634228c26cf40a02a05db93f2f98b768a8e0e61b88acc096c7a6030000001976a9147514080ab2fcac0764de3a77d10cb790c71c74c288ac00000000″,
“txid” : “028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743″,
“version” : 1,
“l(fā)ocktime” : 0,
“vin” : [
{
"txid" : "b79a4803014177ea0139c95f09c6903c01bb8f80d039631afd68cabf7eb0f3c9",
"vout" : 0,
"scriptSig" : {
"asm" : "3044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af01 048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbe",
"hex" : "473044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af0141048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbe"
},
"sequence" : 4294967295
},
{
"txid" : "b79a4803014177ea0139c95f09c6903c01bb8f80d039631afd68cabf7eb0f3c9",
"vout" : 1,
"scriptSig" : {
"asm" : "304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d01 042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026a",
"hex" : "47304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d0141042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026a"
},
"sequence" : 4294967295
},
{
"txid" : "da30b272fb73d78108ff80ddd1ac2f76419533af79ad06a5b3c70fc4a62086c9",
"vout" : 1,
"scriptSig" : {
"asm" : "3045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d01 04a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2f",
"hex" : "483045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d014104a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2f"
},
"sequence" : 4294967295
}
],
“vout” : [
{
"value" : 0.84000000,
"n" : 0,
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 634228c26cf40a02a05db93f2f98b768a8e0e61b OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a914634228c26cf40a02a05db93f2f98b768a8e0e61b88ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"1A3q9pDtR4h8wpvyb8SVpiNPpT8ZNbHY8h"
]
}
},
{
“value” : 156.83000000,
“n” : 1,
“scriptPubKey” : {
“asm” : “OP_DUP OP_HASH160 7514080ab2fcac0764de3a77d10cb790c71c74c2 OP_EQUALVERIFY OP_CHECKSIG”,
“hex” : “76a9147514080ab2fcac0764de3a77d10cb790c71c74c288ac”,
“reqSigs” : 1,
“type” : “pubkeyhash”,
“addresses” : [
"1Bg44FZsoTeYteRykC1XHz8facWYKhGvQ8"
]
}
}
],
“blockhash” : “0000000000007c639f2cbb23e4606a1d022fa4206353b9d92e99f5144bd74611″,
“confirmations” : 147751,
“time” : 1301705313,
“blocktime” : 1301705313
}
字段hex記錄了所有相關(guān)信息驮肉,后面顯示的是hex解析出來的各類字段信息熏矿。下面把逐個分解hex內(nèi)容(hex可以從上面的直接看到):
01000000 // 版本號,UINT32
03 // Tx輸入數(shù)量离钝,變長INT票编。3個輸入。

/*** 第一組Input Tx ***/
// Tx Hash奈辰,固定32字節(jié)
c9f3b07ebfca68fd1a6339d0808fbb013c90c6095fc93901ea77410103489ab7
00000000 // 消費的Tx位于前向交易輸出的第0個栏妖,UINT32,固定4字節(jié)
8a // 簽名的長度, 0x8A = 138字節(jié)
// 138字節(jié)長度的簽名奖恰,含有兩個部分:公鑰+簽名
47 // 公鑰長度吊趾,0×47 = 71字節(jié)
3044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af01
41 // 簽名長度,0×41 = 65字節(jié)
048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbe
ffffffff // sequence瑟啃,0xffffffff = 4294967295论泛, UINT32, 固定4字節(jié)

/*** 第二組Input Tx。與上同理蛹屿,省略分解 ***/
c9f3b07ebfca68fd1a6339d0808fbb013c90c6095fc93901ea77410103489ab7010000008a47304402206b993231adec55e6085e75f7dc5ca6c19e42e744cd60abaff957b1c352b3ef9a022022a22fec37dfa2c646c78d9a0753d56cb4393e8d0b22dc580ef1aa6cccef208d0141042ff65bd6b3ef04253225405ccc3ab2dd926ff2ee48aac210819698440f35d785ec3cec92a51330eb0c76cf49e9e474fb9159ab41653a9c1725c031449d31026affffffff

/*** 第三組Input Tx ***/
c98620a6c40fc7b3a506ad79af339541762facd1dd80ff0881d773fb72b230da010000008b483045022040a5d957e087ed61e80f1110bcaf4901b5317c257711a6cbc54d6b98b6a8563f02210081e3697031fe82774b8f44dd3660901e61ac5a99bff2d0efc83ad261da5b4f1d014104a7d1a57e650613d3414ebd59e3192229dc09d3613e547bdd1f83435cc4ca0a11c679d96456cae75b1f5563728ec7da1c1f42606db15bf554dbe8a829f3a8fe2fffffffff

02 // Tx輸出數(shù)量屁奏,變長INT。兩個輸出错负。

/*** 第一組輸出 ***/
00bd010500000000 // 輸出的幣值坟瓢,UINT64勇边,8個字節(jié)。字節(jié)序需翻轉(zhuǎn)折联,~= 0x000000000501bd00 = 84000000 satoshi
19 // 輸出目的地址字節(jié)數(shù), 0×19 = 25字節(jié)粒褒,由一些操作碼與數(shù)值構(gòu)成
// 目標地址
// 0×76 -> OP_DUP(stack ops)
// 0xa9 -> OP_HASH160(crypto)
// 0×14 -> 長度,0×14 = 20字節(jié)
76 a9 14
// 地址的HASH160值诚镰,20字節(jié)
634228c26cf40a02a05db93f2f98b768a8e0e61b
// 0×88 -> OP_EQUALVERIFY(bit logic)
// 0xac -> OP_CHECKSIG(crypto)
88 ac

/*** 第二組輸出 ***/
c096c7a603000000
19
76 a9 14 7514080ab2fcac0764de3a77d10cb790c71c74c2 88 ac

00000000 // lock_time奕坟,UINT32,固定4字節(jié)
Tx Hash清笨,俗稱交易ID月杉,由hex得出:Tx Hash = SHA256(SHA256(hex))。由于每個交易只能成為下一個的輸入抠艾,有且僅有一次苛萎,那么不存在輸入完全相同的交易,那么就不存在相同的Tx Hash(SHA256碰撞概率極小跌帐,所以無需考慮Hash碰撞的問題首懈,就像無需考慮地址私鑰被別人撞到一樣)。

即便如此谨敛,在系統(tǒng)里依然產(chǎn)生了相同的Tx Hash究履,是某位礦工兄弟挖出Block后,打包Block時忘記修改Generation Tx coinbase字段的值脸狸,幣量相同且輸出至相同的地址最仑,那么就構(gòu)造了兩個完全一模一樣的交易,分別位于兩個Block的第一個位置炊甲。這個對系統(tǒng)不會產(chǎn)生什么問題泥彤,但只要花費其中一筆,另一個也被花費了卿啡。相同的Generation Tx相當于覆蓋了另一個吟吝,白白損失了挖出的幣。該交易ID為e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468颈娜,第一次出現(xiàn)在#91722剑逃,第二次出現(xiàn)在#91880。

b01dc7da-3edf-11e3-86eb-d015037e9440

<a name="t19" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: normal; outline: none;"></a>交易簽名

簽名是對所有權(quán)的驗證官辽,節(jié)點收到交易廣播后蛹磺,會對交易進行驗證,通過后則收錄進內(nèi)存同仆、打包進Block萤捆,否則,丟棄之。簽名就類似傳統(tǒng)紙質(zhì)合同蓋章俗或、簽字過程市怎,合法轉(zhuǎn)移所有權(quán)的保證手段。

簽名類型

由于一個交易的輸入蕴侣、輸出都可能具有多個焰轻,那么簽名也具有多種類型臭觉,目前共三類:SIGHASH_ALL, SIGHASH_NONE, SIGHASH_SINGLE昆雀。

SIGHASH_ALL

該簽名類型為默認類型,也是目前絕大部分交易采用的蝠筑,顧名思義即簽名整單交易狞膘。首先,組織所有輸出什乙、輸入挽封,就像上文分解Hex過程一樣,每個輸入都對應一個簽名臣镣,暫時留空辅愿,其他包括sequence等字段均須填寫,這樣就形成了一個完整的交易Hex(只缺簽名字段)忆某。然后点待,每一個輸入均需使用私鑰對該段數(shù)據(jù)進行簽名,簽名完成后各自填入相應的位置弃舒,N個輸入N個簽名癞埠。簡單理解就是:對于該筆單子,認可且只認可的這些輸入聋呢、輸出苗踪,并同意花費我的那筆輸入。
SIGHASH_NONE

該簽名類型是最自由松散的削锰,僅對輸入簽名通铲,不對輸出簽名,輸出可以任意指定器贩。某人對某筆幣簽名后交給你颅夺,你可以在任意時刻填入任意接受地址,廣播出去令其生效磨澡。簡單理解就是:我同意花費我的那筆錢碗啄,至于給誰,我不關(guān)心稳摄。

SIGHASH_SINGLE

該簽名類型其次自由松散稚字,僅對自己的輸入、輸出簽名,并留空sequence字段胆描。其輸入的次序?qū)漭敵龅拇涡蛱毕耄热巛斎胧堑?個,那么簽名的輸出也是第三個昌讲。簡單理解就是:我同意花費我的那筆錢国夜,且只能花費到我認可的輸出,至于單子里的其他輸入短绸、輸出车吹,我不關(guān)心。

<a name="t24" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: normal; outline: none;"></a>交易的構(gòu)造、簽名與廣播

上篇介紹了交易結(jié)構(gòu)、簽名等脓斩,為了更直觀的認識比特幣,借助bitcoind演示手動構(gòu)造并廣播交易的完整過程乐埠。

普通交易

. 找出未花費的幣(unspent output)

通過命令:listunspent [minconf=1] [maxconf=9999999] ["address",...]列出某個地址未花費的幣(交易),minconf/maxconf表示該筆收入交易的確認數(shù)范圍囚企,如果需要列出還未確認的交易丈咐,需將minconf設置為0。

執(zhí)行:

bitcoind listunspent 0 100 ‘["1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3"]‘

輸出:

[

{
"txid" : "296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156",
"vout" : 0,
"address" : "1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3",
"account" : "",
"scriptPubKey" : "76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac",
"amount" : 0.19900000,
"confirmations" : 1
}
]
我們找到該地址的一個未花費交易龙宏,位于交易296ea7bf981b4499…9f0a41e589132156的第0個位置棵逊。
創(chuàng)建待發(fā)送交易

創(chuàng)建待發(fā)送交易,由命令:createrawtransaction [{"txid":txid,"vout":n},...] {address:amount,…}來完成烦衣。我們將 0.1 BTC發(fā)送至 1Q8s4qDRbCbFypG5AFNR9tFC57PStkPX1x 歹河,并支付 0.0001 BTC做為礦工費。輸入交易的額度為 0.199 花吟,輸出為 0.1 + 0.0001 = 0.1001 秸歧,那么還剩余: 0.199 – 0.1001 = 0.0989 ,將此作為找零發(fā)回給自己衅澈。

執(zhí)行:

bitcoind createrawtransaction
‘[{"txid":"296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156","vout":0}]‘
‘{“1Q8s4qDRbCbFypG5AFNR9tFC57PStkPX1x”:0.1, “1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3″:0.0989}’
輸出:

010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000

通過命令:decoderawtransaction <hex string>键菱,可以將此段十六進制字符串解碼。

執(zhí)行:

bitcoind decoderawtransaction ’010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000′

輸出:
{
“txid” : “54f773a3fdf7cb3292fc76b46c97e536348b3a0715886dbfd2f60e115fb3a8f0″,
“version” : 1,
“l(fā)ocktime” : 0,
“vin” : [
{
"txid" : "296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156",
"vout" : 0,
"scriptSig" : {
"asm" : "",
"hex" : ""
},
"sequence" : 4294967295
}
],
“vout” : [
{
"value" : 0.10000000,
"n" : 0,
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 fdc7990956642433ea75cabdcc0a9447c5d2b4ee OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"1Q8s4qDRbCbFypG5AFNR9tFC57PStkPX1x"
]
}
},
{
“value” : 0.09890000,
“n” : 1,
“scriptPubKey” : {
“asm” : “OP_DUP OP_HASH160 d6c492056f3f99692b56967a42b8ad44ce76b67a OP_EQUALVERIFY OP_CHECKSIG”,
“hex” : “76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac”,
“reqSigs” : 1,
“type” : “pubkeyhash”,
“addresses” : [
"1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3"
]
}
}
]
}
至此今布,一個“空白交易”就構(gòu)造好了经备,尚未使用私鑰對交易進行簽名,字段scriptSig是留空的部默,無簽名的交易是無效的侵蒙。此時的Tx ID并不是最終的Tx ID,填入簽名后Tx ID會發(fā)生變化傅蹂。

在手動創(chuàng)建交易時纷闺,務必注意輸入算凿、輸出的值,非常容易犯錯的是忘記構(gòu)造找零輸出(如非必要勿手動構(gòu)造交易)犁功。曾經(jīng)有人構(gòu)造交易時忘記找零氓轰,發(fā)生了支付 200 BTC 的礦工費的人間慘劇,所幸的是收錄該筆交易的Block由著名挖礦團隊“烤貓(Friedcat)”挖得浸卦,該團隊非常厚道的退回了多余費用署鸡。

. 簽名

交易簽名使用命令:

signrawtransaction <hex string> \

[{"txid":txid,"vout":n,"scriptPubKey":hex,"redeemScript":hex},...] [<privatekey1>,...]
[sighashtype="ALL"]
第一個參數(shù)是創(chuàng)建的待簽名交易的十六進制字符串;
第二個參數(shù)有點類似創(chuàng)建交易時的參數(shù)限嫌,不過需要多出一個公鑰字段scriptPubKey靴庆,其他節(jié)點驗證交易時是通過公鑰和簽名來完成的,所以要提供公鑰萤皂;如果是合成地址撒穷,則需要提供redeemScript;
第三個參數(shù)是即將花費的幣所在地址的私鑰裆熙,用來對交易進行簽名,如果該地址私鑰已經(jīng)導入至bitcoind中禽笑,則無需顯式提供入录;
最后一個參數(shù)表示簽名類型,在上一篇里佳镜,介紹了三種交易簽名類型僚稿;
簽名之前需要找到scriptPubKey,提取輸入交易信息即可獲取(也可以根據(jù)其公鑰自行計算)蟀伸,由命令:getrawtransaction <txid> [verbose=0]完成蚀同。

執(zhí)行:

bitcoind getrawtransaction 296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156 1

輸出:

{

“hex” : “01000000010511331f639e974283d3909496787a660583dc88f41598d177e225b5f352314a000000006c493046022100be8c796122ec598295e6dfd6664a20a7e20704a17f76d3d925c9ec421ca60bc1022100cf9f2d7b9f24285f7c119c91f24521e5483f6b141de6ee55658fa70116ee04d4012103cad07f6de0b181891b5291a5bc82b228fe6509699648b0b53556dc0057eeb5a4ffffffff0160a62f01000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000″,
“txid” : “296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156″,
“version” : 1,
“l(fā)ocktime” : 0,
“vin” : [
{
"txid" : "4a3152f3b525e277d19815f488dc8305667a78969490d38342979e631f331105",
"vout" : 0,
"scriptSig" : {
"asm" : "3046022100be8c796122ec598295e6dfd6664a20a7e20704a17f76d3d925c9ec421ca60bc1022100cf9f2d7b9f24285f7c119c91f24521e5483f6b141de6ee55658fa70116ee04d401 03cad07f6de0b181891b5291a5bc82b228fe6509699648b0b53556dc0057eeb5a4",
"hex" : "493046022100be8c796122ec598295e6dfd6664a20a7e20704a17f76d3d925c9ec421ca60bc1022100cf9f2d7b9f24285f7c119c91f24521e5483f6b141de6ee55658fa70116ee04d4012103cad07f6de0b181891b5291a5bc82b228fe6509699648b0b53556dc0057eeb5a4"
},
"sequence" : 4294967295
}
],
“vout” : [
{
"value" : 0.19900000,
"n" : 0,
"scriptPubKey" : {
"asm" : "OP_DUP OP_HASH160 d6c492056f3f99692b56967a42b8ad44ce76b67a OP_EQUALVERIFY OP_CHECKSIG",
"hex" : "76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac",
"reqSigs" : 1,
"type" : "pubkeyhash",
"addresses" : [
"1Lab618UuWjLmVA1Q64tHZXcLoc4397ZX3"
]
}
}
],
“blockhash” : “000000000000000488f18f7659acd85b2bd06a5ed2c4439eea74a8b968d16656″,
“confirmations” : 19,
“time” : 1383235737,
“blocktime” : 1383235737
}
scriptPubKey位于”vout”[0]–>“scriptPubKey”–>“hex”,即: 76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac 啊掏。

簽名使用ECDSA算法蠢络,對其,“空白交易”簽名之迟蜜,執(zhí)行:

bitcoind signrawtransaction \

“010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e290000000000ffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000″
‘[{"txid":"296ea7bf981b44999d689853d17fe0ceb852a8a34e68fcd19f0a41e589132156","vout":0,"scriptPubKey":"76a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac"}]‘
輸出:

{

“hex” : “010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e29000000008c493046022100f9da4f53a6a4a8317f6e7e9cd9a7b76e0f5e95dcdf70f1b1e2b3548eaa3a6975022100858d48aed79da8873e09b0e41691f7f3e518ce9a88ea3d03f7b32eb818f6068801410477c075474b6798c6e2254d3d06c1ae3b91318ca5cc62d18398697208549f798e28efb6c55971a1de68cca81215dd53686c31ad8155cdc03563bf3f73ce87b4aaffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000″,
“complete” : true
}
簽名后刹孔,簽名值會填入上文所述的空字段中,從而得到一個完整的交易娜睛∷柘迹可通過上文介紹的命令decoderawtransaction <hex string>解碼查看之。

最后一步畦戒,就是將其廣播出去方库,等待網(wǎng)絡傳播至所有節(jié)點,約10~60秒廣播至全球節(jié)點障斋,取決與你的節(jié)點的網(wǎng)絡連接狀況纵潦。稍后一些時刻,就會進入Block中。廣播由命令sendrawtransaction <hex string>來完成酪穿。如果沒有運行節(jié)點凳干,可以通過公共節(jié)點的API進行廣播,例如:blockchain.info/pushtx被济。

執(zhí)行:

bitcoind sendrawtransaction \

“010000000156211389e5410a9fd1fc684ea3a852b8cee07fd15398689d99441b98bfa76e29000000008c493046022100f9da4f53a6a4a8317f6e7e9cd9a7b76e0f5e95dcdf70f1b1e2b3548eaa3a6975022100858d48aed79da8873e09b0e41691f7f3e518ce9a88ea3d03f7b32eb818f6068801410477c075474b6798c6e2254d3d06c1ae3b91318ca5cc62d18398697208549f798e28efb6c55971a1de68cca81215dd53686c31ad8155cdc03563bf3f73ce87b4aaffffffff0280969800000000001976a914fdc7990956642433ea75cabdcc0a9447c5d2b4ee88acd0e89600000000001976a914d6c492056f3f99692b56967a42b8ad44ce76b67a88ac00000000″
輸出:

b5f8da1ea9e02ec3cc0765f9600f49945e94ed4b0c88ed0648896bf3e213205d

返回的是Transaction Hash值救赐,即該交易的ID。至此只磷,交易構(gòu)造经磅、簽名、發(fā)送的完整過程完成了钮追。
合成地址交易

合成地址以3開頭预厌,可以實現(xiàn)多方管理資產(chǎn),極大提高安全性元媚,也可以輕松實現(xiàn)基于比特幣原生的三方交易擔保支付轧叽。一個M-of-N的模式:

m {pubkey}…{pubkey} n OP_CHECKMULTISIG

M和N需滿足:

1<=N<=3
1<=M<=N
可以是1 of 1,1 of 2刊棕,2 of 3等組合炭晒,通常選擇N=3:

1 of 3,最大程度私鑰冗余甥角。防丟私鑰損失网严,3把私鑰中任意一把即可簽名發(fā)幣,即使丟失2把都可以保障不受損失嗤无;
2 of 3震束,提高私鑰冗余度的同時解決單點信任問題。3把私鑰任意2把私鑰可簽名發(fā)幣当犯,三方不完全信任的情形垢村,即中介交易中,非常適用灶壶;
3 of 3肝断,最大程度解決資金信任問題,無私鑰冗余驰凛。必須3把私鑰全部簽名才能發(fā)幣胸懈,適用多方共同管理重要資產(chǎn),但任何一方遺失私鑰均造成嚴重損失恰响;
合成地址的交易構(gòu)造趣钱、簽名、發(fā)送過程與普通交易類似胚宦,這里只介紹如何創(chuàng)建一個合成地址首有。大神Gavin Andresen已經(jīng)演示過燕垃,下面內(nèi)容摘自其gist.

首先,需要三對公鑰井联、私鑰卜壕。公鑰創(chuàng)建地址、私鑰用于簽名烙常。

No.1

0491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f86 / 5JaTXbAUmfPYZFRwrYaALK48fN6sFJp4rHqq2QSXs8ucfpE4yQU

No.2

04865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec6874 / 5Jb7fCeh1Wtm4yBBg3q3XbT6B525i17kVhy3vMC9AqfR6FH2qGk

No.3

048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46213 / 5JFjmGo5Fww9p8gvx48qBYDJNAzR9pmH5S389axMtDyPT8ddqmw
使用命令:createmultisig <nrequired> <’["key","key"]‘>來合成轴捎,其中key為公鑰,創(chuàng)建地址時僅需公鑰蚕脏。創(chuàng)建類型是2 of 3.

輸入:

bitcoind createmultisig 2 \

‘["0491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f86","04865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec6874","048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d46213"]‘
輸出:

{

“address” : “3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC”,
“redeemScript” : “52410491bba2510912a5bd37da1fb5b1673010e43d2c6d812c514e91bfa9f2eb129e1c183329db55bd868e209aac2fbc02cb33d98fe74bf23f0c235d6126b1d8334f864104865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac09ef122b1a986818a7cb624532f062c1d1f8722084861c5c3291ccffef4ec687441048d2455d2403e08708fc1f556002f1b6cd83f992d085097f9974ab08a28838f07896fbab08f39495e15fa6fad6edbfb1e754e35fa1c7844c41f322a1863d4621353ae”
}
得到的合成地址是:3QJmV3qfvL9SuYo34YihAf3sRCW3qSinyC侦副,該地址沒有公鑰,僅有redeemScript驼鞭,作用與公鑰相同秦驯。后續(xù)的構(gòu)造、簽名挣棕、發(fā)送過程與上文普通地址交易類似译隘,略去。

三穴张、時間戳服務與存在證明

存在證明

存在證明就是向第三方證明某個物品/事件细燎,在過去的某個時刻存在過。

這是一件很簡單的事情皂甘,提供票據(jù)、通信記錄之類的就可以辦到悼凑。但這些并不嚴格偿枕,因為這些證據(jù)都是非常易偽造或銷毀。要完成證明户辫,必須依賴強有力的證據(jù)鏈渐夸,這個必須是任何人都無法偽造與銷毀的,或者說偽造成本極其高昂近乎不可能渔欢。

回憶一下墓塌,電影里經(jīng)常出現(xiàn)的綁匪鏡頭,他們?yōu)榱俗C明在某個時間確實擁有人質(zhì)奥额,而不是事前拍攝的視頻苫幢,通常會用當天的發(fā)行量很大的報紙來輔助證明。當香港媒體誤報“成龍高樓墜亡”時垫挨,成龍也不得不拿報紙來證明自己的存在:

0f6c4fcc-fcdc-11e2-8770-b72819e92915

報紙之所以能夠成為有效的時間證明系統(tǒng)是因為:

  1. 不可偽造性韩肝。新聞等信息是無法預測的,尤其是證券大盤數(shù)據(jù)九榔,報紙上大量充滿這樣的信息哀峻,所以無人能夠提前偽造涡相。

  2. 公開且不可銷毀。報紙通常擁有很大的發(fā)行數(shù)量剩蟀,受眾廣泛催蝗,一旦發(fā)布出去就分散到各個角落,很難再次收集齊全并全部銷毀育特。通常圖書館也會存檔數(shù)十年期限的報紙丙号。

  3. 具有時間特征。報紙具有很強時間特征且预,版面到處可見的是時間標記槽袄。

借助報紙可以完成某個時間之后的存在證明,但無法完成某個時間之前的锋谐。例如遍尺,你拿9月1號的報紙拍攝進照片,那么僅能證明其在9月1號之后拍攝涮拗,可能是9月1號乾戏,也可能是9月15號。

時間戳服務

比特幣本質(zhì)是構(gòu)造了一個永不停息三热、無堅不摧的時間戳系統(tǒng)鼓择。

5281de94-fce1-11e2-83be-e80533cae1e9

然后該系統(tǒng)上添加若干特性后使得具有貨幣的功能。報紙從另一個角度講也是一種時間戳服務就漾。

比特幣具有下列優(yōu)良的特性可以更完美的用于存在證明:

  1. 不可預測/偽造呐能。因block的計算是隨機事件,其hash值是一個32字節(jié)的隨機大數(shù)(2256)抑堡。想蒙對該數(shù)的概率實在是太低了摆出。

  2. 不可銷毀/修改。Block Chain擁有巨大的算力在維護與延續(xù)首妖,對于N個確認的block偎漫,想篡改是不可能的。

  3. block具有天然時間特性有缆。timestamp是block meta字段之一象踊。

  4. block可以存儲信息。對于block meta信息棚壁,是無法控制的杯矩。但block會收錄交易,而交易是可以”寫入”自己的數(shù)據(jù)灌曙。

數(shù)字摘要

簡單來說菊碟,對一串數(shù)據(jù)進行Hash運算,得到的Hash值稱為數(shù)字摘要在刺。除了Hash函數(shù)逆害,還有其他方式头镊,如密鑰簽名等也可以得到。Hash值通常是一個非常巨大的數(shù)魄幕,例如用SHA256時相艇,Hash值區(qū)間非常大:1~2256。數(shù)字摘要的計算過程不可逆纯陨,那么可以認為:

  • 欲證明你擁有某個文件坛芽,提供該文件的Hash值(及Hash函數(shù))即可。第三方可以輕易驗證文件的Hash值來判斷之翼抠。

比特幣做存在證明

時間點后向證明

因為block hash的不可偽造性咙轩,能提供Block Hash即可證明存在于該Block時刻之后。例如阴颖,你在拍照的時候活喊,拿著打印有block hash的紙即可證明:你在該block時刻之后進行的拍攝。

時間點前向證明

前向證明需要精心構(gòu)造一個包含數(shù)字摘要的交易量愧,待該交易進入block中钾菊。便可以證明你在該block時刻之前擁有該數(shù)字摘要。前向證明的關(guān)鍵是能把信息寫入時間戳服務載體偎肃。

時間區(qū)間證明

有時候煞烫,僅僅證明時間點之前或之后是不夠的,需要能夠確認到某一個時刻累颂。將上述方式綜合即可完成:

  1. 將block A的hash值添入數(shù)據(jù)文件滞详,并制作文件數(shù)字摘要。(時間點后向證明)

  2. 將摘要信息構(gòu)造至交易中紊馏,廣播之茵宪。(時間點前向證明)

  3. 當交易被block B收錄進去,那么即可證明瘦棋,該文件于block A與B的時間間隔中存在。

如果交易給了足夠的礦工費(Transaction Fee)暖哨,具有較高優(yōu)先級的話赌朋,便很有可能被緊隨其后的block收錄。連續(xù)的block約10分鐘篇裁,那么就在一個相對小的時間內(nèi)作了證明沛慢,可以近似認為是時間點。

構(gòu)造特殊交易

帶有數(shù)字摘要的交易如何構(gòu)造呢达布?下面以32字節(jié)的數(shù)字摘要為例团甲,提出數(shù)個可行方法,其他長度的可變換得出黍聂。

方式一:交易額承載信息

32字節(jié)可以分割為16個雙字節(jié)躺苦,每個雙字節(jié)的數(shù)值范圍是:0~65535身腻。比特幣的現(xiàn)行單位可以分割至小數(shù)點后八位,那么我們可以利用最后的5位來存放一個數(shù)值匹厘,一共需要16個輸出(Tx output)即可完成32字節(jié)的信息存儲嘀趟。中間涉及比特幣最大數(shù)量為:

.00065535 * 16 = .0104856 btc
需要的比特幣數(shù)量很少,約0.01Btc愈诚,且輸出依然發(fā)回給自己的地址她按,唯一的代價就是付出礦工費(Tx Fee)。任何人都可以使用之炕柔。

種子文件時間證明

著名站點SatoshiDice就是采用這種方式為其服務端種子文件做時間前向證明的酌泰。下面演示一下步驟。服務端的種子文件為hash.keys匕累,我們對其做SHA256運算陵刹,得到hash值,32個字節(jié)哩罪。

$ sha256sum hash.keys

hash of file “hash.keys”, in hex:

9b0d87ac871518cfd8601aa456b58fa74c01194cfeb25e7f3eecf43759d6ccb4 hash.keys
將該hash轉(zhuǎn)為16個10進制數(shù)值:

9b0d = 39693
87ac = 34732
8715 = 34581
18cf = 6351
d860 = 55392
1aa4 = 6820
56b5 = 22197
8fa7 = 36775
4c01 = 19457
194c = 6476
feb2 = 65202
5e7f = 24191
3eec = 16108
f437 = 62519
59d6 = 22998
ccb4 = 52404
將這16個數(shù)除以108授霸,作為輸出額度,構(gòu)造交易:

555dc5de-0352-11e3-8cf9-c7d8de72adbe

交易被收錄际插,證明完成碘耳。

方式二:數(shù)字摘要的Hash作地址輸入

回顧一下地址的生成算法(下圖是一個未壓縮公鑰生成地址的過程,公鑰是否壓縮對該證明過程沒有影響):

47602d38-0356-11e3-8fa7-ba59e99eee85

我們用數(shù)字摘要的Hash值代替圖中紅色框中的值框弛,然后得到一個地址辛辨,我們把0.00000001 btc打入該地址,形成交易瑟枫,收錄后完成證明斗搞。驗證時,需要首先得到數(shù)字摘要hash值慷妙,再生成對應的地址僻焚,核對地址是否一致即可。

這個方法有個缺點膝擂,打入該地址的幣永遠消失了虑啤,因為沒有其對應的私鑰。雖然可以只需1聰架馋,目前價值幾乎忽略不計狞山,但畢竟浪費了。該方法可以進一步衍生一些類似的方法叉寂。曾有個網(wǎng)站使用之萍启,后來該網(wǎng)站關(guān)閉了。

方式三:數(shù)字摘要的Hash作私鑰

大小介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之間的數(shù),都可以認為是一個合法的私鑰勘纯,其大小為32字節(jié)局服。那么,可以把數(shù)字摘要的Hash作私鑰屡律,并推算出公鑰和地址腌逢。

將任意幣值輸出至該地址構(gòu)成交易,交易收錄后超埋,通過私鑰再轉(zhuǎn)移走即可搏讶。這樣便在block chain里留下了這個地址。驗證時重復該過程霍殴,檢查地址是否一致即可媒惕。

該方法不會像方法二那樣形成浪費,也比較容易操作来庭。我們依然SatoshiDice的種子文件為例妒蔚,種子數(shù)字摘要的Hash為:9b0d87ac871518cfd8601aa456b58fa74c01194cfeb25e7f3eecf43759d6ccb4。

借助bitaddress.org月弛,輸入私鑰(種子hash)后:

30cc9c38-035a-11e3-98da-590a87880173

得到兩把公鑰肴盏,分別對應兩個地址。證明時將幣打入任何一個地址即可帽衙,建議使用未壓縮公鑰地址菜皂,因為并不是所有客戶端都對壓縮公鑰支持良好。然后將該私鑰導入任何一個客戶端厉萝,再把該地址的錢轉(zhuǎn)移到一個安全的地方恍飘。最后,公開私鑰和對應收錄地址的交易谴垫。

<a name="t43" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: normal; outline: none;"></a>總結(jié)

方法二浪費章母,應避免使用。方法一繁瑣翩剪,需要工具輔助轉(zhuǎn)換乳怎。方法三相對容易,門檻低一些前弯,大部分客戶端都支持舞肆,私鑰公鑰地址的推導也有很多工具支持。

就這樣比特幣系統(tǒng)輕松的完成了存在證明博杖,安全穩(wěn)固,公信力遠勝任何第三方筷登、機構(gòu)剃根、政府。過程極其簡單前方,使得任何一人都可以輕易地做出存在證明狈醉,其意義非常重大廉油。可以預見苗傅,未來將比特幣作為存在證明會得到廣泛的應用抒线。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市渣慕,隨后出現(xiàn)的幾起案子嘶炭,更是在濱河造成了極大的恐慌,老刑警劉巖逊桦,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件眨猎,死亡現(xiàn)場離奇詭異,居然都是意外死亡强经,警方通過查閱死者的電腦和手機睡陪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匿情,“玉大人兰迫,你說我怎么就攤上這事【娉疲” “怎么了汁果?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長转砖。 經(jīng)常有香客問我须鼎,道長,這世上最難降的妖魔是什么府蔗? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任晋控,我火速辦了婚禮,結(jié)果婚禮上姓赤,老公的妹妹穿的比我還像新娘赡译。我一直安慰自己,他們只是感情好不铆,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布蝌焚。 她就那樣靜靜地躺著,像睡著了一般誓斥。 火紅的嫁衣襯著肌膚如雪只洒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天劳坑,我揣著相機與錄音毕谴,去河邊找鬼。 笑死,一個胖子當著我的面吹牛涝开,可吹牛的內(nèi)容都是我干的循帐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼舀武,長吁一口氣:“原來是場噩夢啊……” “哼拄养!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起银舱,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤瘪匿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纵朋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柿顶,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年操软,在試婚紗的時候發(fā)現(xiàn)自己被綠了嘁锯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡聂薪,死狀恐怖家乘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情藏澳,我是刑警寧澤仁锯,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站翔悠,受9級特大地震影響业崖,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蓄愁,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一双炕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撮抓,春花似錦妇斤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至乖酬,卻和暖如春死相,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咬像。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工媳纬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留双肤,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓钮惠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親七芭。 傳聞我的和親對象是個殘疾皇子素挽,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

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