2014年3月24日 星期一

[轉貼]比特幣合同(Bitcoin Contracts)

本文簡體原文在此

本文譯自比特幣WIKI:https://en.bitcoin.it/wiki/Contracts 
譯者:申屠青春 深圳大學ATR國防科技重點實驗室博士 新浪微博 @我看比特幣
注意:本文可隨意轉發,請留下譯者信息,如果覺得本文對你有用,請給譯者捐贈,以便翻譯更多比特幣的核心資料。捐贈地址:1faVxBp2KmST98p3tJjx2MQP98JLLnF2Q


譯者前言      

  比特幣在國內已經眾所周知,但是技術研究並未有效開展,大部分人處於知道和瞭解程度,目前比特圈中許多人對比特幣能做什麼,同樣瞭解不多。一個重要原因是大多數比特幣核心資料都是英文,很少有人能靜心看完如此繁雜的英文資料。本人博士論文的研究方向是比特幣,在研究其英文技術的同時,擬對一些重要資料進行翻譯,讓更多的圈內人對比特幣有更多的理解。

       本文涉及比特幣合同,其中提及的合同是非標準交易,可以改寫Bitoind、BitCoin錢包代碼或使用bitcoinj來生成非標準交易,雖然正常錢包不會接受這些非標準交易,但是有礦池如Eligius.st接受非標準交易並且可以打入到塊鏈中,這樣有些錢包軟件就能正常處理。具體方法見:《Secure multiparty computationson Bitcoin》程序實現部分。

正文

  分佈式合同是指一種使用比特幣和別人在比特幣塊鏈上達成協議的方法,合同不會使得以前不可能的事情變成可能,但是,它們能讓你以信任最小化的方式來解決現實問題。信任最小化在合同簽訂過程中避免人類判斷,通常會使得事情變得更方便,因此可由程序實現完全的自動化。
       通過構建與比特幣交互的最低信任協議,能夠創建以下全新產品:

智能資產:能通過塊鏈自動交易和貸款的資產。
可轉移的虛擬資產:能交易但不能複製的數字資產
代理:是指自治的程序,維護着它們自己的錢包,它們用錢來購買服務器運行時間,代理通過出售服務來掙錢,如果用戶需  求超過代理的計算能力,它們能生成子代理,這些子代理能否存活要看它們能否得到足夠多的業務。
分佈式市場:是一種實現點對點債券和股票交易的方法,可使得比特幣進化成一個能與互聯網金融系統分庭抗禮的競爭者。
瑞波貨幣交易所:是一種在社交網絡上實現分佈式貨幣交易的方法。

     本文還列出了一些更小的例子。

許多底層比特幣合同的思想,由NickSzabó在他的開創性研究《Formalizing and Securing Relationships on PublicNetworks》中最先提出,本文由MikeHearn所寫,如果你有新型合同的想法,可以聯繫他。你還可以看看他在2012年倫敦比特幣會議上的視頻演講


1對內存池交易替換機制的警告

  本文是指比特幣的一種特殊機制,能使用交易數據結構中的nSequence參數替換內存池中的交易。因為考慮到有人會利用它來實施DOS攻擊,這種機制已經在2010年禁用,目前所有相關代碼被完全刪除。開發者必須注意這點,如果他們開發的程序要與目前錢包兼容,就不要創建依賴於內存池替換的合同機制。如果比特幣將來再一次允許內存池替換,本文將會更新。

2理論

  每個比特幣交易都有一個或多個輸入和輸出,每個輸入/輸出都有一個小的純函數與之相關聯,我們稱之為腳本,腳本可包含簡化形式交易的簽名。

  每個交易有一個鎖定時間,使得該交易處於特定狀態並且可被新交易替換,直至鎖定時間來臨。預定時間可以是塊索引或時間戳(這兩個因素使用同一個內存項,小於5億是塊索引,大於5億是時間戳)。當一個交易的鎖定時間到了,我們稱之為終結。

  每個交易的輸入都有一個序列號,對於正常發送幣的交易,該序列號為UNIT_MAX,鎖定時間為0。如果鎖定時間還未達到,但所有的序列號為UNIT_MAX,該交易也被認為是終結。序列號用來發佈交易的新版本,無需驗證其他輸入的簽名。例如:在一個交易中,每個輸入都來自於不同的一方,每個輸入的序列號都是0,這些序列號可以獨立增加。

  簽名驗證是很靈活的,因為交易的簽名方式可以通過SIGHASH符號控制,該符號附加在簽名後面。通過這種方式能構建特殊的合同,交易的每個輸入方只對交易的一部分簽名,因而每個輸入方能單方面改變該交易的一部分內容,而無需其他輸入方的參與。SIGHASH符號分為兩部分,一種模式和一個ANYONECANPAY指示器。

  (1)SIGHASH_ALL:這是默認模式。它指示一個交易除輸入腳本外,所有部分都被簽名。對輸入腳本進行簽名顯然是不可能的,那樣無法構建一個交易,所以腳本總是不被簽名。儘管如此,要注意的是,輸入的其他屬性如輸出、序列號等都會被簽名。直觀地說,它的意思是“我同意把我的錢放進去,如果每個人都把他們的錢放進去,並且輸出正是我想要的。”。
  (2)SIGHASH_NONE:輸出沒有被簽名,可以是任何內容。使用這種模式意味着“我同意把我的錢放進去,如果每個人都把他們的錢放進去,但我不關心輸出什麼“。這種模式使得其他輸入方可以通過改變輸入序列號來更新交易。
  (3)SIGHASH_SINGLE:像SIGHASH_NONE一樣,輸入被簽名,但序列號沒有。因而其他人可以創建交易的新版本,然而,唯一的輸出也被簽名。該模式說明”如果輸出正是我想要的,我同意放錢進去,我不關心其他人的輸入。“
ANYONECANPAY指示器可以與以上三種模式聯合使用,當設置了ANYONECANPAY時,僅僅是該輸入被簽名,其他輸入可以是任意內容。

  腳本可以包括CHECKMULTISIG操作碼,該操作碼提供了n-of-m的簽名驗證:你可以提供多個公鑰m,定義必須出現的有效簽名個數n,簽名個數n可以小於公鑰數量m。如果我們設置以下腳本,則一個輸出需要兩個簽名:
  1. 2  <pubkey1> <pubkey2> 2 CHECKMULTISIGVERIFY
複製代碼
有兩種通用方式來安全地創建合同:
  (1)在P2P網絡之外傳遞部分完成或無效的交易。
  (2)使用兩個交易:創建一個交易(合同交易),先簽名但不馬上廣播,在達成合同並且被鎖定在內存中後,廣播另一個交易(支付交易),最後再廣播合同。
  用以上方式來保證人們知道他們達成的合同內容。這些特性可以讓我們在塊鏈基礎上創建有趣的、創新的金融手段。

3示例1:提供存款證明

  想像你在一個網站(論壇或WIKI)上註冊了一個帳號,想在網站運營者處建立你的信用,但是你沒有以前的名譽來支撐你的信用。一個解決方案是向網站付點錢購買信用,但是如果你關閉帳號,可能想要回這部分錢。你對該網站的信任程度不足以讓你存錢到該網站,因為擔心網站會花掉你的錢。另一個風險是,某一天該網站有可能消失了。

  建立信用度的目的是你作出某種奉獻,讓網站知道你不是一個垃圾機器人。但是你不想網站花掉你的錢。如果網站運營者消失了,你最終想讓錢回來,而無需他們的任何許可。

  我們通過合同來解決這個問題:
  (1)用戶和網站相互發送各自新生成的公鑰
  (2)用戶創建交易TX1(支付交易),該交易支出10個BTC到網站地址,用戶創建了TX1但不廣播。
  (3)用戶把TX1交易的HASH值發送給網站。
  (4)網站使用TX1的HASH值創建交易TX2(合同),TX2花掉TX1的錢並且支付到用戶地址。注意:TX2需要雙方簽名,因而該交易不完整,nLockTime被設置成未來時間(比如六個月後),輸入的序列號為0。
  (5)最終,這個不完整的交易TX2(一半已簽名)被回送給用戶,用戶檢查合同是否如預期-六個月後10BTC最終會回到他的地址-除非情況有變,因為序列號為0,如果雙方同意,合同可以被修訂。該交易的輸入腳本不完整,因為用戶未簽名,用戶對合同簽名並且把簽名放到合適的位置。
  (6)用戶先廣播TX1,再廣播TX2。

  在這個階段,用戶和網站都不能單獨得到10BTC。六個月後,合同完成,即使網站消失了,用戶也能得到幣。

  如果用戶想提早關閉帳號,又該怎麼處理呢?網站創建新版的TX2,nLockTime設為0,並且輸入的序列號設為UINT_MAX,重新簽名,把該交易發回用戶,用戶簽名後廣播該交易,就能提早結束合同並且釋放10BTC。

  如果六個月快到了,而用戶想保留他的帳號,又該怎麼辦呢?類似的事情發生了,合同使用新的nLockTime,序列號比以前的序列號大1,雙方重新簽名,廣播2^32次。無論發生什麼,雙方都必須同意,才能真正改變合同。

  顯然,如果該用戶被證明是有惡意的(例如:垃圾郵件發送者),網站不會同意提早結束合同。如果用戶有太多的濫用行為,則網站可以要求增加存款數量,或者要求延長合同時間。

4示例2:擔保和爭端調解

  一個買家想和他不認識或不信任的某人交易,在一般情況交易正常進行時,買家不想任何第三方參與。但如果交易出現問題時,他想有一個第三方-也許是一個專業的爭端調解服務-來決定誰能拿到錢。注意:這個概念同時適用於買家和賣家。例如:調解員可向商家要求郵資證明,以判斷是否發貨。

  換句話說,某人想鎖定某些幣,在第三方同意的情況下,才能被花掉。
  (1)和商家一起引入一個調解員(如:ClearCoin)
  (2)得到商家的公鑰K1,得到調解員的公鑰K2,創建自己的公鑰K3
  (3)把K2發給商家,商家生成一個隨機數挑戰調解員,調解員用K2的私鑰簽名,用來證明K2確實屬於調解員
  (4)創建一個交易TX1,包括如下輸出腳本並且廣播該交易。
  1. 2 <K1> <K2> <K3> 3 CHECKMULTISIGVERIFY
複製代碼
現在這些幣被鎖定了,如果要解鎖這些幣,需要使用以下幾種方式:
  (1)客戶和商家同意(無論是成功的交易,還是在沒有調解的情況下商家同意回退給客戶)
  (2)客戶和調解者同意(失敗的交易,調解者認同客戶,正如退款)
  (3)調解者和商家同意(商品已經發送,儘管有爭議,商家還是得到幣)

  當對輸入簽名時,內容被設為相關聯的輸出。這樣,為了從這個交易中得到幣,客戶創建包含兩個簽名位的腳本,自己簽一個,再把未完全的交易發給商家或者調解員,請求第二個簽名。

5示例3:保證合同

  保證合同是建造公眾商品時的集資辦法,公眾商品是指,一旦建成,任何人都可以免費享受到好處。標準的例子是燈塔,所有人都認同應該建造一個,但是對於個人航海者來說燈塔太貴了,燈塔同時也會方便其他航海者。

  一個解決方案是向所有人集資,只有當籌集的資金超過所需的建造成本時,每個人才真正付錢,如果集資款不足,則誰都不用付錢。
  在保證合同集資方面,包括頻繁的、小額的、經常自動進行的集資,例如互聯網電台的資金和網頁翻譯等,比特幣優於傳統的支付方式。考慮有一個瀏覽器的插件可供你發送一點幣,它能檢測當前頁面的語言並且廣播一個集資請求,用於把該頁面翻譯成你的語言。如果使用該插件的許多用戶同時查看該頁面(例如:該頁面從高流量的網站連結過來),足夠的集資請求廣播出去,到達一定的金額時,可自動付錢給一個高質量的翻譯公司,當翻譯完成後該頁面自動在你的瀏覽器中加載。

  我們能以比特幣方式建立以下模型
  (1)主辦方創建新的捐贈地址,宣佈如果籌集資金超過1000BTC,則將建造該商品,任何人都可以捐贈。
  (2)捐贈者創建一個新交易,把一定數量的錢打到集資地址,但是他們並不廣播該交易。該交易與常規的交易相似,除了三個不同點:首先,不能做任何改變,如果你沒有正確的輸出金額1000BTC,你必須先創建一個;第二,輸入腳本要以SIGHASH_ALL|SIGHASH_ANYONECANPAY的模式簽名;最後,輸出值是1000BTC,注意這不是一個有效的交易,因為輸出值比輸入值大得多。
  (3)把交易上傳到主辦方的服務器上,他們保存到磁碟上,隨時更新捐贈的幣數量。
  (4)一旦服務器獲得了足夠的幣,它將把所有捐贈者上傳的獨立交易合併成一個新交易,該交易只有一個輸出,僅僅把錢付到捐贈地址,該輸出與每個捐贈者的交易的輸出部分相同,而輸入部分則是所有捐贈者輸入的集合。
  (5)完整的交易被廣播,發送捐贈的幣到捐贈地址中。

  這樣的場景依靠協議的幾個方面,首先使用了SIGHASH符號,SIGHASH_ALL是默認模式,意味着要簽名所有交易的內容,除了輸入腳本。SIGHASH_ANYONECANPAY是附加的指示器,意味着簽名僅覆蓋自己的輸入部分-不簽名其他人的輸入,這樣其他人的輸入可以留空。使用這些符號,我們能創建這樣一個簽名,即使在其他輸入添加進入後,該簽名依舊是有效的。但如果輸出內容或其他的交易部分被改變了,該簽名就無效了。第二,輸入值小於輸出值的交易是無效的(原因很明顯),這就意味着捐贈者把發送幣的交易發送給主辦方是安全的-因為主辦方不可能得到這些捐贈幣,除非他加上其他的輸入值等於或超過輸出值。

  不使用SIGHASH_ANYONECANPAY指示器也可以創建保證合同。不需捐贈者創建交易的集資方式有兩個步驟,一旦達到集資的總金額,主辦方就創建包含所有捐贈者輸入的交易,然後依次在捐贈者中傳遞,每個捐贈者對該交易簽名。但是,先使用SIGHASH_ANYONECANPAY指示器,然後合併交易,這樣可能更方便一些。

  保證合同可以保證下一個塊的資金網絡安全,通過這種方式,即使一個塊中的交易數量比較少,挖礦也能掙錢(因為保證合同的交易一般占用空間大,因而要付出更多的網絡轉帳費)。

Tabarrok在他的論文《The privateprovision of public goods via dominant assurance

contracts》中詳盡描述了保證合同的概念,在一個通用保證合同中,如果合同失敗了(在預定時間內集資不足),主辦方給捐贈者支付網絡轉帳費,這種類型的合同旨在鼓勵捐贈者,積極參與總是正確做法。有人提出了《A scheme for dominant assurance contracts

6示例4:使用外部狀態

  腳本被設計成純函數,它們不能訪問外部服務器,也不能導入任何會改變的外部狀態,因為攻擊者會利用該特性突破塊鏈。而且,腳本語言的功能被嚴格限制。幸運的是,我們可以以其他方式創建交易,從而與外部世界相聯繫。

  考慮一個例子,老人想讓他孫子繼承遺產,繼承時間是在他死後或者在孫子年滿18歲時,無論哪個條件先滿足,他的孫子都可以得到遺產。

  為瞭解決這個問題,老人首先給他自己發送孫子要繼承的資產數量,以便有一個正確繼承數量的唯一輸出;接着,他創建一個帶有鎖定時間的交易,該交易的意思是:在孫子18歲生日時把幣支付到孫子的地址中,老人對該交易簽名,不進行廣播,直接把該交易給了孫子。當過了孫子的18歲生日後,孫子廣播了這個交易並且得到他的幣。孫子可以在這時間之前廣播該交易,但他不會提前得到幣,有些節點會在內存池中把這種交易丟棄掉,因為鎖定時間在遙遠的將來。

  死亡條件非常難判斷,因為比特幣節點不會檢測主觀條件,我們必須依靠預言,預言是指具有密鑰對的服務器,當用戶自定義的表達式被證明是真的,它能按照要求對交易簽名。

  以下是例子,老人創建了一個交易花掉了他的幣,把輸出設為:
  1. <hash> OP_DROP2 <sons pubkey> <oracle pubkey> CHECKMULTISIG
複製代碼
這是一個預言腳本,具有與眾不同的形式-它把數據推到堆棧中,然後立即刪除。公鑰發佈在預言服務器的網站上,為公眾所知,HASH值設為用戶自定義表達式的HASH值,該表達式以預言服務器能理解的方式編寫,能確認老人已經死亡。舉個例子,可能是以下字元串的HASH值:
  1. if(has_died('johnsmith',born_on=1950/01/02))  
  2. return(10.0,1JxgRXEHBi86zYzHN2U4KMyRCg4LvwNUrp);
複製代碼
以上語言是假設的,該語言被預言服務器定義,可能是任何一種語言。返回值是一個輸出:幣數量和孫子的地址。

  再一次,老人創建了一個交易,沒有廣播而是直接給了孫子,他另外還提供了一個表達式和預言服務器的名字,HASH值被寫入交易,預言服務器則能解鎖表達式。算法如下:

(1)預言服務器接受評估請求,請求包括了用戶提供的用戶自定義表達式、輸出腳本和部分完成的交易,交易中除了scriptSig簽名之外,其他部分都已經完成,簽名僅包括了孫子的簽名,還不足以解鎖輸出。
(2)預言服務器檢查表達式,得到其HASH值,並且與交易中的HASH對照,如果兩者不一致,則返回錯誤。
(3)預言服務器評估表達式,如果表達式的結果不是交易輸出的目標地址,則返回錯誤。
(4)預言服務器簽名交易,返回簽名給用戶,注意:對一個比特幣交易簽名時,輸入腳本被設為相關聯的輸出腳本。原因是當OP_CHECKSIG操作起作用時,包含該操作碼的腳本被放到輸入,腳本並不包含簽名本身。預言服務器不知道完整的輸出,也沒必要知道,因為它知道輸出腳本、自己的公鑰和表達式的HASH值,這就足以使它檢查輸出腳本並且完成交易。
(5)用戶接受新簽名,插入到交易的scriptSig項中,廣播交易。

       若且唯若預言服務器認為老人死了,孫子才能廣播兩個交易(合同和申報)並且得到幣。
預言服務器可以評估任何事情,然而塊鏈中的輸出腳本形式總是一樣的,考慮以下可能性:
  1. today()==2011/09/25&&exchange_rate(mtgoxUSD)>=12.5&&exchange_rate(mtgoxUSD)<=13.5
複製代碼
給定一個日期,假定mtgox比特幣的美元價格在12.5-13.5之間
  1. google_results_count(site:www.google.com/hostednews'MikeHearn'
  2. Olympic gold medal)>0
複製代碼
打賭我會做一些我從來不會真正做的事情(獲得奧林匹克金牌)。
  //歐洲電視台的歌唱比賽,選擇兩個優勝者之一打賭。
  1. if(eurovision_winner()=='Azerbaijan')
  2.      return 1Lj9udBVDwptFffGSJSC2sohCfudQgSTPD;
  3. else
  4.      return 1JxgRXEHBi86zYzHN2U4KMyRCg4LvwNUrp;
複製代碼
這些條件可使預言服務器的簽名變得任意複雜,但是塊鏈僅需要包含一個HASH值即可。

6.1信任最小化:挑戰

  有許多方法可降低對預言服務器的信任程度。

  回到我們的第一個例子,預言服務器還沒看到孫子想解鎖的交易,因為該交易從沒被廣播過。這樣,它不會支持孫子贖回幣,因為它不知道該交易是否存在。人們能做到,並且也應該做到,以自動方式定期挑戰預言服務器,確保它總是按照人們想像的方式輸出。挑戰無需花費任何幣,因為要簽名的交易是無效的(例如:與一個並不存在的交易關聯),預言服務器沒法知道簽名請求是隨意的還是真實的,如何以一個尚未成真的條件來挑戰預言服務器,是一個開放的研究課題。

6.2信任最小化:多個獨立預言服務器

  如果需要,CHECKMULTISIG中的n簽名個數可以增加至能夠達到n-of-m的預言服務器模式(即m個預言服務器中需要有n個預言服務器簽名才能使交易有效),當然,檢查預言服務器是獨立的而非串通的,也是很重要的。


6.3信任最小化:可信的硬件

  使用合適的硬件,你可以進行信任計算,以INTELTXT或AMD等硬件來建立一個封閉的運行環境,然後用TPM晶片向第三方證實其可信度。第三方可判定硬件是否處於所需狀態。如果要使硬件失敗,則需要有人介入CPU程序的執行過程,甚至在極端情況下,內存匯流排沒有數據流過(如果程序足夠小,你完全可以使用緩存來運行程序) 


6.4信任最小化:亞馬遜AWS預言服務器

最終,也許目前最現實的方法是使用亞馬遜的網頁服務,截至2013年11月,最合適的預言服務器的解決方案是:《this recipefor creating a trusted computing environment using AWS》,該方案基於《this project for doing selectiveSSL logging and decryption》。基本思想是:預言服務器使用亞馬遜作為其信任根,並且能用亞馬遜API證明其是值得信任的,該預言服務器記錄在線銀行接口的加密SSL會話,如果以後產生交易爭端,會話記錄能被解密,爭端可以被解決。


7示例5:跨鏈交易

  比特幣技術可以用來創建多個獨立的貨幣,域名幣(Namecoin)就是一個例子,它與比特幣的運作規則有些不同,它可以在域名空間中租用域名。與比特幣實現理念相同的山寨幣,可以在有限信任條件下與比特幣進行自由交易。

  舉例:想像一個財團發行了歐元幣(EURCoins),一種以財團的銀行存款1:1支持的加密貨幣。這樣的貨幣與比特幣有不同的交易集:更中心化,但沒有外匯風險。人們可能希望在比特幣與歐元幣之間來回交易,

       為了實現這個想法,可以使用TierNolan提出的協議

  (1)A產生一些隨機數據X(秘密)
  (2)A產生TX1交易(支付)包含了帶跨鏈交易腳本的輸出,看下面的腳本和討論。它允許幣以A和B共同簽名的方式釋放,也可以以私密X和B簽名的方法釋放,該交易未廣播,塊鏈的釋放腳本包含了私密的HASH值,並非真正的私密X本身。
  (3)A產生TX2(合同),花掉TX1並且輸出到A的地址,該交易有個未來的鎖定時間,輸入的序列號為0,因而可以被替換。A簽名TX2並且發送給B,B給TX2簽名後發送回A。
  (4)A廣播TX1和TX2,B可以看到幣但是不能花掉它們,因為並沒有輸出到B的地址,該交易還沒終結。
  (5)B在山寨幣塊鏈上執行相同的操作,B的鎖定時間應該更大於A的鎖定時間,雙方的交易都待定但未完全。
  (6)因為A知道私密X,A能馬上申報他的幣,然而,A在申報幣的過程,向B釋放了私密X,B可以以私密X和簽名B來完成山寨幣塊鏈的交易。

       自動化交易完全以點對點的方式進行,能確保貨幣的流動性,該協議使得這種交易更靈活。跨鏈交易的腳本如下所示:
  1. IF
  2.   2 <keyA> <keyB> 2 CHECKMULTISIGVERIFY
  3. ELSE
  4.   <keyB> CHECKSIGVERIFY  SHA256 <hash of secretx> EQUALVERIFY
  5. ENDIF
複製代碼
合同輸入腳本如下所示:
  1. <sigA>  <sigB>  1
複製代碼
或者
  1. <secret x> <sigB> 0
複製代碼
例如:第一個數據元素決定使用哪個方式。
  參考《Atomic cross-chain trading》能得到更詳細的說明。

  注意:歐元幣是一個很自然的想法,還有其他方法能實現點對貨幣交易(把比特幣換成菲亞特汽車,反之亦然),看《Ripple currency exchange》得到更多信息。

  Sergio Demian-Lerner提出了P2PTradeX協議,一種塊鏈交易的解決方案,需要把一個塊鏈中的確認規則有效編碼進另一個塊鏈的確認規則。

8示例6:支付證明合同:購買任何純函數的解決方案

  在示例4中,我們看到如何基於任意程序的輸出來實現條件支付,這些程序非常有用,能做到任何常規程序實現的功能,比如獲取網頁。缺點是需要一個第三方(預言服務器),儘管我們有技術來減少預言服務器的信任度,誰都不能減少到0。

  對於受限的程序、純函數,新加密技術已經出現,這些技術能實際上減少信任度到0,無需第三方參加。這些程序不能進行任何I/O操作,但是在許多情況下,這種限制被證明並不重要,或者可以以其他方式繞過,比如給程序一個簽過名並且打過時間戳的文檔作為輸入,無需程序自己從網上下載。

可以閲讀一下該協議的解釋:《Zero KnowledgeContingent Payment》。


9示例7:特定對象的快速調整(微)支付

  
與傳統支付系統相比,比特幣交易費用非常便宜,但是還是需要費用以便被挖礦和融合到塊鏈上。有些情況下,你想快速和便宜地調整發送到某個特定地址的貨幣金額,而不會導致廣播交易的費用。

    舉個例子:考慮一個不信任的互聯網接入點,就像你從來沒有去過的咖啡屋中一個WIFI熱點一樣。每使用10K位元組流量你得向咖啡屋支付0.001BTC,無需註冊咖啡屋帳號。零信任解決方案意味着可以全自動完成整個過程,因而你在月初預先轉了一筆錢到你的手機錢包,然後你的手機會自動與AP協商並且按需給AP支付費用,咖啡屋也希望任何人付錢給它,而無需擔心被詐騙。

  為了達到這個目標,可以使用下面的協議。該協議依賴nLockTime與原設計不同的行為,從2013年開始,時間鎖定的交易被認為是非標準協議,不能進入內存池,這樣就不能在鎖定時間過期之前廣播出去。當nLockTime的行為恢復回中本聯的初始設計時,就需要修改以下討論的協議了。

  我們定義客戶端為發送向幣的那一方,服務端為接收幣的那一方,以下協議是從客戶的角度來進行的。
  (1)創建公鑰K1,向服務端請求公鑰K2
  (2)創建、簽名但不廣播交易T1,支付10BTC到輸出,需要服務端和你自己的公鑰,使用OP_CHECKMULTISIG是一個好辦法。
  (3)創建退款交易T2,與T1的輸出相關聯,發送所有幣回到你的地址。該交易有個鎖定時間,例如幾小時後,不簽名並且把該交易發送給服務端,常規來說,輸出腳本是“2 K1 K2 2 CHECKMULTISIG”
  (4)服務端用K2簽名T2,返回給客戶,注意:服務端目前還未看到T1,僅僅看到了T1的HASH值(該HASH值在未簽名的T2中)
  (5)客戶驗證服務端的簽名是否正確,如果不正確則中止。
  (6)客戶簽名T1並且把簽名返回給服務端,服務端廣播T1(如果他們雙方有聯繫的話,每一方都可以廣播T1),幣被鎖定。
  (7)客戶創建一個新交易T3,與T1相聯繫,類似於退款交易,有K1和K2兩個輸出,把所有幣分配給第一個輸出K1,它做了與退款交易相同的事情,但是沒有鎖定時間,客戶簽名T3,發送給服務端。
  (8)服務端驗證輸出到它的地址的幣數量是正確的,驗證客戶提供的簽名是正確的。
  (9)當客戶想付錢給服務端,他調整T3,向服務端的輸出增加足夠的幣,同時減少他自己的幣數量,然後重新簽名T3,發送給服務端。客戶無需發送整個交易,只需發送簽名和增加的幣數量即可。服務端調整T3內容與新的幣數量吻合,驗證客戶的簽名並且繼續。

  整個過程持續到會話結束,或者到1天時間快到來,AP簽名和廣播最終版本的交易,分配最終的幣數量給它自己。退款交易需要處理服務端消息中斷和未分配幣的情況,如果這些事件發生,一旦鎖定時間過期,客服可以廣播退款交易,拿回所有的錢。

  這個協議已經用bitcoinj實現了

  當nLockTime的交易能進入內存池、交易替換重新啟用時,本協議必須被修改。在這種情況下,無需退款交易。T3有一個序列號,每次都比前一次大1,T3的鎖定時間與以前的時間一致。每次的支付都使得序列號增加1,確保最後版本會優先發生。如果通道協議沒有被正常關閉,意味着向服務端支付幣不會成功,直到鎖定時間過期,客戶拿回所有幣。為了避免這種情況,雙方共同簽名T3交易,序列號為0xFFFFFFFF,導致立即確認,而不考慮nLockTime的值。

  鎖定時間和序列號可以避免一種攻擊,在這種攻擊中:AP提供連通性,客戶使用TX2的第一版本雙花,使幣回到他自己的地址中,阻止咖啡屋申報帳單。如果客戶嘗試這麼做,該交易不會馬上被包括進去,AP在一段時間內可以觀察到該交易被廣播,然後廣播它看到的最後一個版本,就能推翻客戶的雙花企圖。

  後一種協議依賴交易替換,具有更大的靈活性,因為在通道的生命週期中,只要客戶能收到服務端的簽名,協議就能使客戶分配給自己的幣數量越來越少。但是在許多用例中,這個功能是不必要的。交易替換一樣允許配置更複雜的超過兩方的通道,如何在這種使用情況下詳盡描述協議,就留給讀者作練習吧。

10示例8:多方去中心化彩票

使用示例6的一些技術和一些高級的腳本,使得構建無人值守的多方彩票系統成為可能。準確協議在《Secure multiparty computationson Bitcoin》中已經有詳細描述。以後可能會在WIKI中添加對這種系統的簡要解釋。




2014年3月12日 星期三

[Bitcoin] Check the zero-confirmations immediate tiny-payment security

http://jimmyscratchlab.github.io/check-tinypayment/

我做的小網頁,用來檢測比特幣安全可信賴的即時零確認交易,歡迎指教
主要的檢查規則為
  1. money<0.01BTC,小額交易較無雙花(double spend)風險,但須輸入你的收款地址
  2. no dust output,無微塵輸出(小於5430 satoshis)
  3. txFee>=0.0001BTC,附上交易費
  4. size<=1k,整筆交易大小需小於1K
  5. no Timelock,無時間鎖
  6. relayed_count > 500 and mining_nodes > 6,查看交易單在P2P網路傳播的狀況