區塊鏈學堂(第一課):區塊鏈引子 智慧合約 Solidity

NO IMAGE

區塊鏈引子

 

區塊鏈到底是什麼?

區塊鏈(英:Blockchain) 是一種分散式資料庫,起源自比特幣,區塊鏈是一串使用密碼學方法相關聯產生的資料塊,每一個資料塊中包含了若干次比特幣網路交易的資訊,用於驗證其資訊的有效性(防偽)和生成下一個區塊。(摘自wiki)

區塊鏈技術的定義:

區塊鏈是一個分散式賬本,一種通過去中心化、去信任的方式集體維護一個可靠資料庫的技術方案。

從資料的角度看:

區塊鏈是一種幾乎不可能被更改的分散式資料庫, ”分散式“有兩個含義,一個是分散式儲存,一個是所有參與者共同維護

區塊鏈技術的幾個特性

  • (1) 匿名
  • (2)不可篡改和加密安全性
  • (3)無須信任系統
  • (4)分散式去中心化
  • (5)交易透明

引用自

基於以上的幾個優點,比特幣系統實現了一個自我執行的,成交量數十億的交易系統,全球化7*24小時穩定的執行了多年。任何兩個賬戶之間的比特幣買賣都被忠實的記錄在大量冗餘的賬本上。

在比特幣網路中,任何賬號都是匿名的,任何賬號之間的交易都是不可篡改,且會被記錄在每一個節點上。然後通過對挖礦的比特幣激勵機制,實現了這個網路的自執行,無需任何中心化的交易系統。

 

以太坊

 

那麼以太坊是什麼?

以太坊是一個開源的有智慧合約功能的公共區塊鏈平臺,通過其專用加密貨幣以太幣提供去中心化的虛擬機器(EVM)來處理點對點合約(摘自wiki)

最簡單的說法就是:區塊鏈技術 智慧合約。

以太坊在繼承了區塊鏈技術的基礎上,實現了對智慧合約的支援,從而使得區塊鏈技術可以和商業化應用結合,並實現專案的落地。

在以太坊的網路中,智慧合約也被看做一個特殊的賬戶,從而使得使用者可以通過和該賬戶進行交易,實現對該賬戶中的屬性和方法的呼叫。從而從底層技術上支援了智慧合約的實現。

技術架構圖

智慧合約是什麼?

之前說過區塊鏈技術的五個特性。以太坊繼承了上面這所有的區塊鏈技術的基礎上,提供了智慧合約的支援。從而使區塊鏈技術從原來的賬戶與賬戶之間的交易功能,擴充套件為一個可以實現智慧合約的平臺。這個智慧合約可以是一個眾籌合約,也可以是一個數學公式,或者是一個完全的隨機數。

只要智慧合約 被部署到以太坊的網路上去,他就天生帶有了區塊鏈技術的5個特徵,同時因為他是由類javascript的語言撰寫,因此可以實現很多複雜的業務邏輯。

本教程主要介紹的就是對智慧合約的程式設計,通過編寫符合自己商業邏輯的智慧合約,就可以輕鬆的實現各種基於區塊鏈的專案落地。
下一章,我們將從一個最簡單的智慧合約入手,給大家快速介紹一下智慧合約長什麼樣?

 

最簡單的智慧合約

最簡單的一個智慧合約

pragma solidity 0.4.9;
contract DemoTypes {
function f(uint a) returns (uint b) {
uint result = a * 8;
return result;
}
}

以上就是一個最簡單的一個智慧合約, 該智慧合約實現了一個最基本的功能,也就是輸入N,返回8*N。
那麼我們需要如何執行他呢?這個就涉及到一個很有用的工具,browser-solidity了。

官方地址:https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.9 commit.364da425.js

注意這裡目前用到的solidity版本為0.4.9, 因此pragma solidity 後面也要跟上0.4.9版本,否則會報錯。

將我們上面的程式碼貼上去,可以看到結果如下圖所示:

這個時候點選紅色 Create按鈕

就可以將這份最簡單的智慧合約部署到區塊鏈網路上(記憶體上的)

在這裡我們可以看到幾個東西

  1. Trasaction/Execution Cost: 這個代表Create一個合約所消耗的成本,單位為Gas。Gas和Ether幣有一個兌換關係,兌換比例由Oracle決定
  2. 這裡可以看到我們的合約名稱DemoTypes, 註冊在了一個地址上面。這個代表該合約已經被挖礦出來了。
  3. 第三個就是我們上方的合約程式碼,f(n) {return 8 * n}

這個時候我們輸入100,然後點選f按鈕,我們可以看到結果

這樣的結果很清楚

  1. 結果是800,符合預期
  2. 執行f()這個function消耗的Gas Cost是21698 800

上面介紹了一個最簡單的智慧合約,下一章將給大家介紹智慧合約的語言 Solidity。也是全書的重心。

 

Solidity

在上一篇文章中,我們可以看到 pragma solidity 0.4.9;,

這裡的Solidity,就是以太坊智慧合約的核心語言Solidity,也是本教程的重點。

Solidity是什麼?

Solidity是以太坊智慧合約的程式語言,通過編譯&部署智慧合約,可以實現智慧合約的Create、執行和檢視,從而實現某些商業應用。

幾個簡單的Solidity例子

通過以下幾個智慧合約,我們可以將一些商業應用很好的區塊鏈化,從而實現去中介、去信任、高度透明的商業模型。

在之後的整個教程中,我們會逐步解析Solidity程式設計,幫助大家快速掌握Solidity這門語言,並且將區塊鏈落地到前端Web頁面上

I 實現1 2 3 .. n的求和功能

pragma solidity 0.4.9;
contract Demo1 {
/*計算從1到N的求和*/
function f(uint n) returns (uint sum) {
if (n == 0) throw; uint result = 0;
for (uint i=0; i<=n; i  ) {
result  =i;
}
return result;
}
}

II 實現一個代幣功能,並自帶挖礦和轉移代幣的功能。

pragma solidity ^0.4.0;
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping (address => uint) public balances;
// Events allow light clients to react on
// changes efficiently.
event Sent(address from, address to, uint amount);
// This is the constructor whose code is
// run only when the contract is created.
function Coin() {
minter = msg.sender;
}
function mint(address receiver, uint amount) {
if (msg.sender != minter) return;
balances[receiver]  = amount;
}
function send(address receiver, uint amount) {
if (balances[msg.sender] < amount) return;
balances[msg.sender] -= amount;
balances[receiver]  = amount;
Sent(msg.sender, receiver, amount);
}
}

III 實現一個眾籌的智慧合約,各個使用者可以籌款、籌款成功可以將所得轉讓給受益人,每個參與眾籌者可以獲得代幣。

pragma solidity ^0.4.2;
contract token { function transfer(address receiver, uint amount){  } }
contract Crowdsale4 {
address public beneficiary;
uint public fundingGoal;
uint public amountRaised;
uint public deadline;
uint public price;
token public tokenReward;
mapping(address => uint256) public balanceOf;
bool public fundingGoalReached = false;
event GoalReached(address beneficiary, uint amountRaised);
event FundTransfer(address backer, uint amount, bool isContribution);
bool public crowdsaleClosed = false;
/* data structure to hold information about campaign contributors */
/*  at initialization, setup the owner */
function Crowdsale4 (
address ifSuccessfulSendTo,
uint fundingGoalInEthers,
uint durationInMinutes,
uint etherCostOfEachToken,
token addressOfTokenUsedAsReward
) {
beneficiary = ifSuccessfulSendTo;
fundingGoal = fundingGoalInEthers * 1 ether;
deadline = now   durationInMinutes * 1 minutes;
price = etherCostOfEachToken * 1 ether;
tokenReward = token(addressOfTokenUsedAsReward);
}
/* The function without name is the default function that is called whenever anyone sends funds to a contract */
function () payable {
if (crowdsaleClosed) throw;
uint amount = msg.value;
balanceOf[msg.sender]  = amount;
amountRaised  = amount;
tokenReward.transfer(msg.sender, amount / price);
FundTransfer(msg.sender, amount, true);
}
modifier afterDeadline() { if (now >= deadline) _; }
/* checks if the goal or time limit has been reached and ends the campaign */
function checkGoalReached() afterDeadline {
if (amountRaised >= fundingGoal){
fundingGoalReached = true;
GoalReached(beneficiary, amountRaised);
}
crowdsaleClosed = true;
}
function safeWithdrawal() afterDeadline {
if (!fundingGoalReached) {
uint amount = balanceOf[msg.sender];
balanceOf[msg.sender] = 0;
if (amount > 0) {
if (msg.sender.send(amount)) {
FundTransfer(msg.sender, amount, false);
} else {
balanceOf[msg.sender] = amount;
}
}
}
if (fundingGoalReached && beneficiary == msg.sender) {
if (beneficiary.send(amountRaised)) {
FundTransfer(beneficiary, amountRaised, false);
} else {
//If we fail to send the funds to beneficiary, unlock funders balance
fundingGoalReached = false;
}
}
}
}

Solidity的簡介就到此為止了,後面我們會具體解析這些合約的奧祕

前面說過,智慧合約是部署在以太坊的網路上的,那麼如何搭建一個以太坊網路呢,就需要官方提供的工具Geth了。下一章會詳細說明。