我們應該建立什麼區塊鏈?

整個人類歷史就是一個不斷擺脫束縛、創造新的、更強的束縛的過程。 (匿名作者)

透過分析眾多區塊鏈項目(Bitshares、Hyperledger、Exonum、以太坊、比特幣等),我了解到,從技術角度來看,它們都是建立在相同的原則之上的。 區塊鏈讓人想起房屋,儘管房屋的設計、裝飾和用途各不相同,但它們都有以某種方式相互連接的地基、牆壁、屋頂、窗戶、門。 如果您了解建築設計的基本原理並了解所用材料的特性,那麼您就可以確定特定房屋的預期用途。 目前,區塊鏈出現了一種情況,大家都聽說過它,但很少人了解它的架構和運作原理。 因此,人們對使用區塊鏈技術的原因和方式有誤解。

在本文中,我們將分析所有區塊鏈共有的屬性和原則。 接下來,讓我們來看看使用區塊鏈可以解決的問題,並強化材料,讓我們在我們的虛擬網站上建立一個小而真實的區塊鏈!

那麼,讓我們記住區塊鏈最初解決了哪些問題。

我相信很多人都會談論分散式、去中心化、公共和不可變的資料庫。 但為什麼這一切都是必要的呢?

我更喜歡透過閱讀標準來開始研究任何技術,因為有關所研究主題的所有文章和書籍都基於它們。 但目前還沒有區塊鏈標準;ISO僅創建了 委員會 為了他們的發展。 目前,每個公鏈項目都有自己的白皮書文件,本質上是一份技術規範。 第一個眾所周知的區塊鏈項目是比特幣網路。 前往該網絡的官方網站並 一切開始的地方。

區塊鏈挑戰

所以,區塊鏈在比特幣先鋒網路中解決的任務就是在沒有中介的非可信環境下進行數位資產(資產)所有權的可信轉移。 例如,在比特幣網路中,數位資產就是比特幣數位貨幣。 而比特幣和其他區塊鏈的所有技術解決方案都歸結為解決這個問題。

區塊鏈解決的問題

假設某個金融組織聲稱它已經在世界各地建立了一個網絡,借助該網絡可以將資金轉移給任何人。 你會相信她嗎? 如果這個組織是 Visa 或 MasterCard,你很可能會相信,但相對而言,如果是 AnonymousWorldMoney,你可能不會相信。 為什麼? 但因為我們非常清楚私人公司是如何製造分散式系統的,出於什麼目的,以及這會導致什麼。 讓我們仔細看看此類系統的問題以及如何使用區塊鏈技術解決這些問題。

假設在條件 AnonymousWorldMoney 中有一些有資料庫的伺服器,如果有多個伺服器位於不同的資料中心,那就太好了。 當發送者轉帳時,會註冊一筆交易,該交易會被複製到所有伺服器,然後資金到達接收者。

我們應該建立什麼區塊鏈?

在理想的情況下,這個方案效果很好,但在我們的方案中會出現以下問題:

  1. 一方面是識別參與者的問題,另一方面是交易匿名的需要。 那些。 您需要將資金轉移給特定的接收者,並且以除了交易參與者之外沒有人知道這筆交易的方式。 銀行擁有與特定個人或法人實體關聯的帳號和銀行卡,銀行保密可以保護交易資訊。 誰保證有條件的 AnonymousWorldMoney 不會將個人資料和交易資訊用於自己的目的?
  2. 如何確保收款人準確收到轉帳給他的金額? 相對而言,發送方轉帳了 100 美元,接收方收到了 10 美元。 寄件人帶著收據來到 AnonymousWorldMoney 辦公室,店員出示了他的版本,上面寫著寄件者只轉了 10 美元。
  3. 不可信環境的問題,例如,稱為雙重支出的騙局。 不道德的參與者可以多次花費他的餘額,直到付款被複製到所有伺服器。 CAP定理當然,沒有人取消,協議最終會達成,但有人不會因為所提供的服務或商品而收到金錢。 因此,如果對支付組織或交易參與者沒有完全的信任,那麼就需要建立一個不是基於信任,而是基於密碼學的網路。
  4. 有條件的 AnonymousWorldMoney 的伺服器數量有限,可能會無意或因惡意意圖而變得不可用。
  5. AnonymousWorldMoney 將收取自己的有形佣金。
  6. 控制的可能性。 事實證明,在比特幣的運作過程中,人們不僅希望互相轉賬,還希望檢查交易的各種條件、程式設計工作場景、根據條件自動執行操作等。

區塊鏈如何解決這些問題

  1. 參與者的識別是使用一對金鑰進行的:私鑰和公鑰,數位簽章演算法唯一地識別發送者和接收者,使他們的身分保持匿名。
  2. 交易被收集到區塊中,計算區塊的哈希值並將其寫入下一個區塊。 這種在區塊中記錄哈希值的序列賦予了區塊鏈技術它的名字,而且它也使得不可能在不知不覺中更改/刪除區塊或區塊中的單一交易。 因此,如果一筆交易包含在區塊鏈中,您可以確定其數據將保持不變。
  3. 透過就哪些資料被視為有效以及哪些資料被丟棄達成網路共識,可以防止雙花詐欺。 在比特幣網路中,共識是透過工作量證明(PoW)來實現的。
  4. 網路的可靠性是透過區塊鏈是公共的事實來實現的,每個參與者都可以運行自己的節點,接收區塊鏈的完整副本,此外,還可以獨立地開始檢查交易的正確性。 應該指出的是,現代區塊鏈不僅可以建立公共(開放)區塊鏈,還可以建立私有(封閉)區塊鏈,以及使用組合方案。
  5. 區塊鏈不會完全擺脫佣金,因為… 你必須付錢給支持網路的人,但在區塊鏈中,佣金的必要性被如此令人信服地證明,其必要性是毫無疑問的。
  6. 現代區塊鏈具有實現業務邏輯的能力,這在區塊鏈中被稱為智能合約。 智能合約的邏輯是用各種高階語言來實現的。

接下來,我們將更詳細地考慮這些解決方案。

區塊鏈架構

區塊鏈組件

每個參與者都可以使用區塊鏈的完整副本(完整節點)啟動自己的節點。 能夠在區塊鏈上記錄交易的全節點稱為 共識節點 (見證人)或礦工(礦工)。 只檢查交易正確性的全節點稱為 審計節點 (審計)。 輕客戶端 (輕客戶端)不儲存區塊鏈的完整副本,而是使用完整節點與網路互動。
大多數用戶使用輕客戶端或網路錢包進行交易。 所有節點都相互連接。 有了這組元素,網路架構變得更穩定:

我們應該建立什麼區塊鏈?

交易生命週期

讓我們來看看交易生命週期並將其逐一分解:

我們應該建立什麼區塊鏈?

區塊鏈技術

讓我們更詳細地討論技術解決方案及其相互之間的連結。

鑑別

每筆區塊鏈交易都必須經過數位簽署。 因此,要完成一筆交易,每個參與者都必須擁有一對金鑰:私有/公用。 有時一對鑰匙被稱為錢包,因為密鑰與參與者的唯一數字地址和餘額唯一關聯。 實際上,鍵和地址只是不同數字系統中的數字字串。 密鑰和錢包地址範例:

Private key: 0a78194a8a893b8baac7c09b6a4a4b4b161b2f80a126cbb79bde231a4567420f
Public key: 0579b478952214d7cddac32ac9dc522c821a4489bc10aac3a81b9d1cd7a92e57ba
Address: 0x3814JnJpGnt5tB2GD1qfKP709W3KbRdfb27V

為了在區塊鏈中創建數位簽名,需要使用基於橢圓曲線的演算法:橢圓曲線數位簽名演算法(ECDSA)。 為了使其正常工作,私鑰(256 位數)通常是隨機獲取的。 密鑰選項的數量是2的256次方,因此我們可以討論匹配私鑰值的實際不可能性。

接下來,透過將公鑰的值乘以位於橢圓曲線上的點的座標,從私鑰獲得公鑰,從而得到同一曲線上的新點的座標。 此操作可確保您獲得適合對交易進行數位簽章的金鑰對。 最後,錢包位址是從公鑰唯一匯出的。

有很多文章詳細介紹了區塊鏈中使用的密碼學,例如: 比特幣簡而言之——密碼學

私鑰必須嚴格保密並妥善保管。 公鑰是每個人都知道的。 如果私鑰遺失,則無法恢復對資產(硬幣)的訪問,並且資金將永遠丟失。 因此,安全儲存私鑰的任務極為重要,因為這不是一家您可以隨時攜帶護照來恢復帳戶的銀行。 有一個完整的行業來生產所謂的冷加密錢包,類似於閃存驅動器:

我們應該建立什麼區塊鏈?

或者您可以使用更可靠的方法,例如,將私鑰的值標記在令牌上:

我們應該建立什麼區塊鏈?

交易

有關交易結構的更多詳細資訊可以在文章中找到 比特幣簡而言之——交易。 對我們來說重要的是要了解每筆交易至少有以下數據:

From: 0x48C89c341C5960Ca2Bf3732D6D8a0F4f89Cc4368 - цифровой адрес отправителя
To: 0x367adb7894334678b90аfe7882a5b06f7fbc783a - цифровой адрес получателя
Value: 0.0001 - сумма транзакции
Transaction Hash: 0x617ede331e8a99f46a363b32b239542bb4006e4fa9a2727a6636ffe3eb095cef - хэш транзакции

接下來,使用私鑰對交易進行簽署並發送出去(詳細資訊請參見協議的操作) 比特幣簡而言之——協議)到區塊鏈中檢查交易有效性的所有節點。 交易驗證演算法並不簡單,包括 兩打台階.

交易區塊

檢查交易的有效性後,節點將其形成區塊。 除了交易之外,還將前一個區塊的雜湊值和數字(Nonce 計數器)寫入區塊中,並使用 SHA-256 演算法計算目前區塊的雜湊值。 哈希必須具有既定的複雜性條件。 例如,在比特幣網路中,哈希的難度每兩週自動改變一次,具體取決於網路的功率,因此大約每 2 分鐘產生一個區塊。 複雜度由下列條件決定:找到的雜湊必須小於預定數。 如果不符合這個條件,則Nonce加10,重複計算hash的工作。 要選擇哈希,請使用 Nonce 字段,因為這是區塊中唯一可以更改的資料;其餘資料必須保持不變。 有效的雜湊值必須具有一定數量的前導零,例如真正的雜湊值之一:

000000000000000000000bf03212e7dd1176f52f816fa395fc9b93c44bc11f91

成功找到哈希值就是比特幣或以太坊網路已完成工作的證明(工作量證明,PoW)。 尋找哈希值的過程稱為挖礦,類似金礦開採。 這個名字非常準確地定義了該過程的本質,因為有一個簡單的選項搜索,如果有人找到合適的哈希,那麼這真的很幸運。 這就像在成噸的廢石中找到真正的金塊一樣。 現在的區塊獎勵為 12.5 BTC,如果將其乘以目前 3900 美元的比特幣匯率,您將獲得超過一公斤的純金。 有東西值得奮鬥!

成功找到哈希後,該區塊和找到的哈希本身將作為下一個區塊寫入區塊鏈。 有關塊結構的更多詳細資訊可以在文章中找到 比特幣簡而言之——區塊鏈,下面是一個簡化的圖:

我們應該建立什麼區塊鏈?

區塊鏈從一個尚不具有前一個區塊的哈希值的區塊開始。 區塊鏈中只有一個這樣的區塊,並且有自己的名稱創世區塊。 其餘區塊具有相同的結構,僅交易數量不同。 目前在比特幣或以太坊中創建的真實交易和區塊可以在 Block Explorer.

比特幣的區塊大小限制為 1MB,一筆交易的最小資訊量約為 200 字節,一個區塊中的最大交易數量約為 6000 筆。 順便說一下,從這裡開始,遵循大家嘲笑的比特幣的性能:大約每 10 分鐘 * 60 秒 = 600 秒生成一次區塊,這給出了大約 10 TPS 的正式性能。 雖然事實上這並不是生產力,而是刻意實現的工作演算法。 在以太坊中,為了競爭,他們乾脆將區塊生成時間設定為15秒。 生產力正式飆升。 因此,在使用 PoW 作為共識的區塊鏈中,比較表現根本沒有意義,因為它直接取決於快取計算的複雜性,可以分配給任何值。

叉子

例如,如果多個節點發現滿足複雜性條件但值不同(換句話說,它們達成不同共識)的雜湊值並將區塊寫入區塊鏈,會發生什麼情況? 讓我們看看區塊鏈如何防範這種情況。 在這種情況下,就會發生所謂的分叉,區塊鏈有兩個版本的鏈:

我們應該建立什麼區塊鏈?

接下來發生什麼事? 接下來,網路的一部分開始在一條鏈上的區塊 N+2 上工作,另一部分則在另一條鏈上開始工作:

我們應該建立什麼區塊鏈?

其中一個區塊將被更早找到並發送到區塊鏈,然後根據規則,區塊鏈將不得不切換到更長的鏈並取消替代區塊中的所有交易:

我們應該建立什麼區塊鏈?

同時,可能會出現一種情況,即參與者的交易僅在一個分叉區塊中,該交易被取消。 因此,為了確保所需的交易記錄在區塊鏈中,有一個一般建議 - 在信任交易之前,您應該等到接下來的幾個區塊被添加到區塊鏈中。 不同區塊鏈等待多少個區塊的建議有所不同。 例如,對於比特幣網絡,最小為 2 個區塊,最大為 6 個。

在所謂的 51% 攻擊中,也會觀察到與區塊分叉相同的情況 - 這是一群礦工試圖開發替代區塊鏈,試圖透過詐欺交易取消該鏈。 雖然目前來說,比起欺詐,把力量花在誠實挖礦上更有利可圖。

共識

為了在區塊鏈上記錄一個區塊,網路必須達成共識。 讓我們記住在電腦通訊網路中達成共識的任務。 此問題表述為拜占庭將軍 BFT 的任務(拜占庭容錯)。 省略對拜占庭軍隊問題的生動描述,問題可以表述如下:如果某些網路節點可以故意扭曲網路節點,那麼網路節點如何能夠得出共同結果。 現有解決 BFT 問題的演算法表明,只要詐欺者少於 1/3,網路就能正常運作。 為什麼BFT共識沒有應用在比特幣網路上? 為什麼需要使用 PoW? 有以下幾個原因:

  • BFT 在一小部分固定節點上運作良好,但在公共區塊鏈中,節點數量是不可預測的,而且節點可以隨機開啟和關閉。
  • 有必要激勵人們推出區塊鏈節點。 為此,人們必須得到獎勵。 BFT 中沒有正式的獎勵,但 PoW 中的獎勵是什麼,每個人都直觀地清楚:處理器在尋找塊哈希的過程中消耗的電力。

除了 PoW 之外,現代區塊鏈中還使用了其他幾種共識,例如:

  • PoS(權益證明)-在區塊鏈上 Hyperledger
  • DPoS(委託權益證明)-在區塊鏈上 BitShares
  • BFT 的修改:SBFT(簡化 BFT)和 PBFT(實用 BFT),例如在區塊鏈中 Exonum

讓我們詳細討論一下 PoS 共識,因為… 在私有區塊鏈中應​​用最廣泛的是 PoS 及其變體。 為什麼要私下呢? 一方面,PoS的特性比PoW更好,因為為了達成共識,需要更少的運算資源,這意味著將資料寫入區塊鏈的速度提高。 但另一方面,PoS 存在更多詐騙機會,因此為了消除這一點,必須了解區塊鏈中的所有參與者。

PoS 共識是基於選擇一個節點,可以根據帳戶中的資金量(或者更確切地說,不是帳戶中的資金量,而是抵押品中的資金量)將包含交易的區塊寫入區塊鏈,即您作為抵押品的資金越多,網路就越有可能選擇您的節點來寫入區塊。 如果區塊無效,押金將不予退還。 這可以防止詐欺。 PoS 有以下幾種變體:

  • 委託權益證明(DPoS)共識將參與者分為「投票者」和「驗證者」。 代幣持有者(投票參與者)將驗證和記錄區塊鏈上交易的權力委託給其他參與者。 因此,驗證者完成所有計算工作並獲得獎勵,而投票參與者的存在保證了驗證者的誠實,因為它們可以隨時更改。
  • LPoS(租賃權益證明)共識允許您將資金出租給其他節點,以便它們有更好的機會驗證區塊。 那。 您無需參與實際的交易驗證和區塊挖礦,即可獲得交易佣金。

還有許多其他共識尚未廣泛使用,我只是在這裡列出它們以供參考,並且可以在以下文章中找到共識演算法本身的概述: 區塊鏈中的共識演算法.

  • PoET(經過時間證明)
  • PoC(容量證明)
  • PoB(燃燒證明)
  • PoWeight(重量證明)
  • PoA(活動證明)-PoW + PoS
  • PoI(重要性證明)

區塊鏈的可靠性和部署模型

公鏈

可持續發展 評價 或其他名稱 無需許可的區塊鏈 這是透過允許任何人連接並查看資訊甚至連接自己的節點來實現的,而信任是建立在 PoW 共識之上的。

私有區塊鏈

私人的私人許可的區塊鏈。 在這些區塊鏈中,只有特定的參與者群體(組織或個人)可以存取資訊。 此類區塊鏈是由組織建構的,其目標是提高整體效益或效率。 它們的可靠性是由參與者的共同目標以及 PoS 和 BFT 共識演算法來保證的。

區塊鏈聯盟

那裡 聯盟公共授權的區塊鏈。 這些是任何人都可以連接到查看的區塊鏈,但參與者只有在其他參與者的許可下才能添加資訊或連接他的節點。 此類區塊鏈是由組織建構的,目的是增加客戶或產品消費者或整個社會的信任。 在這裡,可靠性也是透過參與者之間的信任以及相同的 PoS 和 BFT 共識演算法來實現的。

智能合同

在比特幣之後實施的區塊鏈在某種程度上增加了執行智慧合約的能力。 本質上,智能合約是一種放置程式碼來執行的交易。 以太坊網路上的智慧合約在 EVM(以太坊虛擬機)中執行。 要開始執行智能合約,它必須由另一筆交易明確啟動,或必須滿足執行的先決條件。 智能合約的執行結果也將記錄在區塊鏈中。 從區塊鏈外部接收資料是可能的,但極其有限。

使用智能合約可以實現哪些業務邏輯? 事實上,沒有太多,例如,使用區塊鏈中的資料檢查條件,根據這些條件改變數位資產的所有者,將資料記錄在區塊鏈內的永久儲存中。 邏輯是用特殊的高階語言Solidity實現的。

使用智慧合約實現功能的典型例子是發行 ICO 代幣。 例如,我實現了一個智能合約來發行適度的 500 AlexToken。 經過 Etherscan 中的鏈接

Solidity 語言的智慧合約原始碼

pragma solidity ^0.4.23;
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
**/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
**/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
**/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
**/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
**/
contract Ownable {
address public owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender account.
**/
constructor() public {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
**/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
**/
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0));
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
/**
* @title ERC20Basic interface
* @dev Basic ERC20 interface
**/
contract ERC20Basic {
function totalSupply() public view returns (uint256);
function balanceOf(address who) public view returns (uint256);
function transfer(address to, uint256 value) public returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
}
/**
* @title ERC20 interface
* @dev see https://github.com/ethereum/EIPs/issues/20
**/
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public view returns (uint256);
function transferFrom(address from, address to, uint256 value) public returns (bool);
function approve(address spender, uint256 value) public returns (bool);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title Basic token
* @dev Basic version of StandardToken, with no allowances.
**/
contract BasicToken is ERC20Basic {
using SafeMath for uint256;
mapping(address => uint256) balances;
uint256 totalSupply_;
/**
* @dev total number of tokens in existence
**/
function totalSupply() public view returns (uint256) {
return totalSupply_;
}
/**
* @dev transfer token for a specified address
* @param _to The address to transfer to.
* @param _value The amount to be transferred.
**/
function transfer(address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(_value);
balances[_to] = balances[_to].add(_value);
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev Gets the balance of the specified address.
* @param _owner The address to query the the balance of.
* @return An uint256 representing the amount owned by the passed address.
**/
function balanceOf(address _owner) public view returns (uint256) {
return balances[_owner];
}
}
contract StandardToken is ERC20, BasicToken {
mapping (address => mapping (address => uint256)) internal allowed;
/**
* @dev Transfer tokens from one address to another
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
**/
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
require(_to != address(0));
require(_value <= balances[_from]);
require(_value <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_value);
balances[_to] = balances[_to].add(_value);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
*
* Beware that changing an allowance with this method brings the risk that someone may use both the old
* and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
* race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
* @param _spender The address which will spend the funds.
* @param _value The amount of tokens to be spent.
**/
function approve(address _spender, uint256 _value) public returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Function to check the amount of tokens that an owner allowed to a spender.
* @param _owner address The address which owns the funds.
* @param _spender address The address which will spend the funds.
* @return A uint256 specifying the amount of tokens still available for the spender.
**/
function allowance(address _owner, address _spender) public view returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Increase the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To increment
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _addedValue The amount of tokens to increase the allowance by.
**/
function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
/**
* @dev Decrease the amount of tokens that an owner allowed to a spender.
*
* approve should be called when allowed[_spender] == 0. To decrement
* allowed value is better to use this function to avoid 2 calls (and wait until
* the first transaction is mined)
* From MonolithDAO Token.sol
* @param _spender The address which will spend the funds.
* @param _subtractedValue The amount of tokens to decrease the allowance by.
**/
function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
uint oldValue = allowed[msg.sender][_spender];
if (_subtractedValue > oldValue) {
allowed[msg.sender][_spender] = 0;
} else {
allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
}
emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
return true;
}
}
/**
* @title Configurable
* @dev Configurable varriables of the contract
**/
contract Configurable {
uint256 public constant cap = 1000000000*10**18;
uint256 public constant basePrice = 100*10**18; // tokens per 1 ether
uint256 public tokensSold = 0;
uint256 public constant tokenReserve = 500000000*10**18;
uint256 public remainingTokens = 0;
}
/**
* @title CrowdsaleToken 
* @dev Contract to preform crowd sale with token
**/
contract CrowdsaleToken is StandardToken, Configurable, Ownable {
/**
* @dev enum of current crowd sale state
**/
enum Stages {
none,
icoStart, 
icoEnd
}
Stages currentStage;
/**
* @dev constructor of CrowdsaleToken
**/
constructor() public {
currentStage = Stages.none;
balances[owner] = balances[owner].add(tokenReserve);
totalSupply_ = totalSupply_.add(tokenReserve);
remainingTokens = cap;
emit Transfer(address(this), owner, tokenReserve);
}
/**
* @dev fallback function to send ether to for Crowd sale
**/
function () public payable {
require(currentStage == Stages.icoStart);
require(msg.value > 0);
require(remainingTokens > 0);
uint256 weiAmount = msg.value; // Calculate tokens to sell
uint256 tokens = weiAmount.mul(basePrice).div(1 ether);
uint256 returnWei = 0;
if(tokensSold.add(tokens) > cap){
uint256 newTokens = cap.sub(tokensSold);
uint256 newWei = newTokens.div(basePrice).mul(1 ether);
returnWei = weiAmount.sub(newWei);
weiAmount = newWei;
tokens = newTokens;
}
tokensSold = tokensSold.add(tokens); // Increment raised amount
remainingTokens = cap.sub(tokensSold);
if(returnWei > 0){
msg.sender.transfer(returnWei);
emit Transfer(address(this), msg.sender, returnWei);
}
balances[msg.sender] = balances[msg.sender].add(tokens);
emit Transfer(address(this), msg.sender, tokens);
totalSupply_ = totalSupply_.add(tokens);
owner.transfer(weiAmount);// Send money to owner
}
/**
* @dev startIco starts the public ICO
**/
function startIco() public onlyOwner {
require(currentStage != Stages.icoEnd);
currentStage = Stages.icoStart;
}
/**
* @dev endIco closes down the ICO 
**/
function endIco() internal {
currentStage = Stages.icoEnd;
// Transfer any remaining tokens
if(remainingTokens > 0)
balances[owner] = balances[owner].add(remainingTokens);
// transfer any remaining ETH balance in the contract to the owner
owner.transfer(address(this).balance); 
}
/**
* @dev finalizeIco closes down the ICO and sets needed varriables
**/
function finalizeIco() public onlyOwner {
require(currentStage != Stages.icoEnd);
endIco();
}
}
/**
* @title LavevelToken 
* @dev Contract to create the Lavevel Token
**/
contract AlexToken is CrowdsaleToken {
string public constant name = "AlexToken";
string public constant symbol = "ALT";
uint32 public constant decimals = 18;
}

以及網路所看到的二進位表示

60806040526000600355600060045533600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600560146101000a81548160ff021916908360028111156200006f57fe5b0217905550620001036b019d971e4fe8401e74000000600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200024a6401000000000262000b1d179091906401000000009004565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550620001986b019d971e4fe8401e740000006001546200024a6401000000000262000b1d179091906401000000009004565b6001819055506b033b2e3c9fd0803ce8000000600481905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6b019d971e4fe8401e740000006040518082815260200191505060405180910390a362000267565b600081830190508281101515156200025e57fe5b80905092915050565b611cb880620002776000396000f300608060405260043610610112576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146104c7578063095ea7b31461055757806318160ddd146105bc57806323b872dd146105e7578063313ce5671461066c578063355274ea146106a3578063518ab2a8146106ce57806366188463146106f957806370a082311461075e57806389311e6f146107b55780638da5cb5b146107cc578063903a3ef61461082357806395d89b411461083a578063a9059cbb146108ca578063bf5839031461092f578063c7876ea41461095a578063cbcb317114610985578063d73dd623146109b0578063dd62ed3e14610a15578063f2fde38b14610a8c575b60008060008060006001600281111561012757fe5b600560149054906101000a900460ff16600281111561014257fe5b14151561014e57600080fd5b60003411151561015d57600080fd5b600060045411151561016e57600080fd5b3494506101a7670de0b6b3a764000061019968056bc75e2d6310000088610acf90919063ffffffff16565b610b0790919063ffffffff16565b9350600092506b033b2e3c9fd0803ce80000006101cf85600354610b1d90919063ffffffff16565b111561024c576101f66003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b915061022e670de0b6b3a764000061022068056bc75e2d6310000085610b0790919063ffffffff16565b610acf90919063ffffffff16565b90506102438186610b3990919063ffffffff16565b92508094508193505b61026184600354610b1d90919063ffffffff16565b6003819055506102886003546b033b2e3c9fd0803ce8000000610b3990919063ffffffff16565b6004819055506000831115610344573373ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f193505050501580156102dd573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a35b610395846000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef866040518082815260200191505060405180910390a361045184600154610b1d90919063ffffffff16565b600181905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc869081150290604051600060405180830381858888f193505050501580156104bf573d6000803e3d6000fd5b505050505050005b3480156104d357600080fd5b506104dc610b52565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561051c578082015181840152602081019050610501565b50505050905090810190601f1680156105495780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561056357600080fd5b506105a2600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610b8b565b604051808215151515815260200191505060405180910390f35b3480156105c857600080fd5b506105d1610c7d565b6040518082815260200191505060405180910390f35b3480156105f357600080fd5b50610652600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610c87565b604051808215151515815260200191505060405180910390f35b34801561067857600080fd5b50610681611041565b604051808263ffffffff1663ffffffff16815260200191505060405180910390f35b3480156106af57600080fd5b506106b8611046565b6040518082815260200191505060405180910390f35b3480156106da57600080fd5b506106e3611056565b6040518082815260200191505060405180910390f35b34801561070557600080fd5b50610744600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061105c565b604051808215151515815260200191505060405180910390f35b34801561076a57600080fd5b5061079f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506112ed565b6040518082815260200191505060405180910390f35b3480156107c157600080fd5b506107ca611335565b005b3480156107d857600080fd5b506107e16113eb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561082f57600080fd5b50610838611411565b005b34801561084657600080fd5b5061084f6114ab565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561088f578082015181840152602081019050610874565b50505050905090810190601f1680156108bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156108d657600080fd5b50610915600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506114e4565b604051808215151515815260200191505060405180910390f35b34801561093b57600080fd5b50610944611703565b6040518082815260200191505060405180910390f35b34801561096657600080fd5b5061096f611709565b6040518082815260200191505060405180910390f35b34801561099157600080fd5b5061099a611716565b6040518082815260200191505060405180910390f35b3480156109bc57600080fd5b506109fb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611726565b604051808215151515815260200191505060405180910390f35b348015610a2157600080fd5b50610a76600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611922565b6040518082815260200191505060405180910390f35b348015610a9857600080fd5b50610acd600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119a9565b005b600080831415610ae25760009050610b01565b8183029050818382811515610af357fe5b04141515610afd57fe5b8090505b92915050565b60008183811515610b1457fe5b04905092915050565b60008183019050828110151515610b3057fe5b80905092915050565b6000828211151515610b4757fe5b818303905092915050565b6040805190810160405280600981526020017f416c6578546f6b656e000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b6000600154905090565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151515610cc457600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d1157600080fd5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610d9c57600080fd5b610ded826000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610e80826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610f5182600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b6b033b2e3c9fd0803ce800000081565b60035481565b600080600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508083111561116d576000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611201565b6111808382610b3990919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b8373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a3600191505092915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561139157600080fd5b60028081111561139d57fe5b600560149054906101000a900460ff1660028111156113b857fe5b141515156113c557600080fd5b6001600560146101000a81548160ff021916908360028111156113e457fe5b0217905550565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561146d57600080fd5b60028081111561147957fe5b600560149054906101000a900460ff16600281111561149457fe5b141515156114a157600080fd5b6114a9611b01565b565b6040805190810160405280600381526020017f414c54000000000000000000000000000000000000000000000000000000000081525081565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561152157600080fd5b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561156e57600080fd5b6115bf826000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b3990919063ffffffff16565b6000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611652826000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b60045481565b68056bc75e2d6310000081565b6b019d971e4fe8401e7400000081565b60006117b782600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0557600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611a4157600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6002600560146101000a81548160ff02191690836002811115611b2057fe5b021790555060006004541115611c0a57611ba5600454600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610b1d90919063ffffffff16565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015611c89573d6000803e3d6000fd5b505600a165627a7a723058205bbef016cc7699572f944871cb6f05e69915ada3a92a1d9f03a3fb434aac0c2b0029

有關智能合約的更多詳細資訊可以在文章中找到: 以太坊中的智能合約是什麼.

結論

我們列出了建立現代區塊鏈的技術以及它們如何相互連接。 現在讓我們明確哪些問題可以使用區塊鏈來解決,哪些解決方案充其量是無效的。 因此,如果滿足以下條件,則無需使用區塊鏈:

  • 交易在可信環境中進行;
  • 中介委員會的存在不會使參與者的生活惡化;
  • 參與者不擁有可以代表數位資產的財產;
  • 數位資產沒有分配,即此價值僅由一名參與者擁有或提供。

區塊鏈的未來會是怎樣? 現在我們只能推測區塊鏈技術發展的可能途徑:

  • 區塊鏈將成為與 SQL 或 NoSQL 相同的通用資料庫技術,用於解決其特定範圍的問題;
  • 區塊鏈將成為一種廣泛使用的協議,就像 HTTP 之於互聯網一樣;
  • 區塊鏈將成為地球上新的金融和政治體系的基礎!

在下一部分中,我們將了解目前存在哪些區塊鏈以及為何它們在不同行業中使用。

這只是個開始!

來源: www.habr.com

添加評論