為什么要學點區塊鏈知識?看看馬雲在剛剛過去的第二屆世界智能大會上怎么說。
言歸正傳。
提起區塊鏈,人們自然會想到比特幣。比特幣或許是泡沫或許不是,但比特幣背后的區塊鏈技術絕不是泡沫,且極具顛覆力。今天各大科技巨頭 都在積累區塊鏈技術和專利。山雨欲來風滿樓,區塊鏈技術應用場景的爆發即使不在當下,也近在眼前。區塊鏈開發人員的薪水也已登上了金字塔尖,這才是我們要學習區塊鏈技術的真正原因。
本文將首先介紹比特幣和區塊鏈背后的關鍵技術點,然后解釋以太坊智能合約對區塊鏈技術的改進,最后講解如何使用超級賬本項目創建簡易的區塊鏈銀行轉賬系統。
該區塊鏈銀行轉賬系統已同步發布在了 [ 行雲趣碼開發雲平台 ] 的應用商店,在開始接下來的閱讀之前,您可以先登錄平台部署並感受一下該系統。
http://mart.cloudtogo.cn/app/detail.html?appId=A18060706112077200000010143570 (PC瀏覽更美好!)
從拜占庭將軍說起
拜占庭將軍(Byzantine Generals Problem)問題,是 Leslie Lamport 1982 年提出用來解釋一致性問題的一個虛構模型。拜占庭是古代東羅馬帝國的首都,由於地域寬廣,守衛邊境的多個將軍(系統中的多個節點)需要通過信使來傳遞消息,達成某些一致的決定。但由於將軍中可能存在叛徒(系統中節點出錯),這些叛徒將努力向不同的將軍發送不同的消息,試圖會干擾一致性的達成。
拜占庭問題即為在此情況下,如何讓忠誠的將軍們能達成行動的一致。這是分布式系統核心問題之一。拜占庭問題之所以難解,在於任何時候系統中都可能存在多個提案(因為提案成本很低),並且要完成最終的一致性確認過程十分困難,容易受干擾。但是一旦確認,即為最終確認。
比特幣網絡中的礦機
比特幣網絡的唯一功能就是"轉賬",該系統中比特幣的上限被設定為2100萬個。這些比特幣是如何被"挖"出來的呢?答案是記賬獎勵。比特幣網絡中的礦機(計算機)就是記賬員,記賬員每完成一次記賬就能獲得一定的比特幣獎勵,俗稱挖礦收入。
比特幣產生速度每4年減半,所以挖礦獲得的比特幣會越來越少,直到零。之后需要從轉賬者那里收取轉賬手續費維系礦機的運轉,就像普通商業銀行收取用戶轉賬的手續費。
比特幣網絡中的礦機,其角色等同於拜占庭問題中的將軍。當用戶發起比特幣轉賬時,礦機就會試圖就該交易達成共識,就像拜占庭將軍們一樣,達成共識需要有礦機發起提案,有礦機進行表決(背書),在比特幣網絡中只有發起提案的礦機才能獲得挖礦收入。誰會獲得發起提案的機會呢?
比特幣的區塊鏈網絡在設計時提出了創新的 PoW(Proof of Work)算法思路。一個是限制一段時間內整個網絡中出現提案的個數(增加提案成本),另外一個是放寬對最終一致性確認的需求,約定好大家都確認並沿着已知最長的鏈進行拓寬。系統的最終確認是概率意義上的存在。這樣,即便有人試圖惡意破壞,也會付出很大的經濟代價(付出超過系統一半的算力)。
礦機都在爭奪提案的機會,他們同時求解同一道數學題,最先交卷的礦機將贏得本次提案的機會。數學題(示意版)如下:
hash (上一個區塊的hash值 + 隨機數) < 00000000000FFFFFFFFFFFFFFFFFFFFF
比賽開始后,礦機把上一個區塊的hash值加上不斷嘗試的隨機數,重新計算hash,直到hash的結果小於某個值時,求解成功。比特幣網絡會自動調整求解難度,即調整不等式右邊hash值的大小,把提案頻率控制在10分鍾左右。
以太坊的智能合約
智能合約(Smart Contract)是以太坊中最為重要的一個概念,即以計算機程序的方式來締結和運行各種合約。最早在上世紀 90 年代,Nick Szabo 等人就提出過類似的概念,但一直依賴因為缺乏可靠執行智能合約的環境,而被作為一種理論設計。區塊鏈技術的出現,恰好補充了這一缺陷。
智能合約作為運行在以太坊虛擬機(Ethereum Virtual Machine,EVM)中的應用,可以接受來自外部的交易請求和事件,通過觸發運行提前編寫好的代碼邏輯,進一步生成新的交易和事件,可以進一步調用其它智能合約。智能合約的執行結果可能對以太坊網絡上的賬本狀態進行更新。這些修改由於經過了以太坊網絡中的共識,一旦確認后無法被偽造和篡改。
比特幣網絡中的轉賬和以太坊的智能合約,類似功能機和智能手機,前者只能運行預置的軟件(比特幣網絡的轉賬),后者可以安裝各種APP (以太坊的智能合約)。智能手機帶來的顛覆無需贅言,同樣,只需看一下ICO市場的躁動就能窺見智能合約帶來的改變。
私有鏈和超級賬本項目
由IBM和Linux基金會主導的超級賬本(Hyperledger)項目,是開發私有鏈和聯盟鏈的不二之選。該項目下有很多子項目,比如最重要的Fabric項目,提供區塊鏈運行的基礎支撐;Composer項目簡化了智能合約(Hyperledger中稱為chaincode)的開發和部署。
在剛剛結束的ThoughtWorks技術雷達峰會上,ThoughtWorks也將Hyperledger列為推薦的框架。
使用超級賬本搭建區塊鏈銀行轉賬系統
該系統的區塊鏈網絡部分包括一個CA節點(證書頒發和管理體系),一個Orderer節點(分布式決策中的Proposer),三個Peer節點(用作信用背書)以及三個對應的數據庫(存儲World State)。另外包含兩個業務節點,負責定義並實現業務,並將業務部署在Fabric網絡中,同時提供RESTful接口和UI。該系統出於技術演示的目的而創建,所以不具備完整銀行應用中的諸多功能,比如賬戶、密碼等權限等。如下圖所示:
該區塊鏈系統已同步發布在了 [ 行雲趣碼開發雲平台 ] 的應用工廠,在開始接下來的閱讀之前,您可以創建項目並在模板中選擇“區塊鏈銀行系統”,只需要幾分鍾,就可將一切部署到雲端,快速地感受一下基於區塊鏈技術所構建的應用。
http://factory.cloudtogo.cn/
以下是該系統開發的具體步驟。
一、安裝Fabric和Composer
准備一台Ubuntu16.04虛擬機,以非root用戶執行下面的腳本,安裝Fabric和Composer依賴的運行環境。
#!/bin/bash
#./prereqs-ubuntu.sh
# Exit on any failure
set -e
# Array of supported versions
declare -a versions=('trusty' 'xenial' 'yakkety');
# check the version and extract codename of ubuntu if release codename not provided by user
if [ -z "$1" ]; then
source /etc/lsb-release || \
(echo "Error: Release information not found "; exit 1)
CODENAME=${DISTRIB_CODENAME}
else
CODENAME=${1}
fi
# check version is supported
if echo ${versions[@]} | grep -q -w ${CODENAME}; then
echo "Installing Hyperledger Composer prereqs for Ubuntu ${CODENAME}"
else
echo "Error: Ubuntu ${CODENAME} is not supported"
exit 1
fi
# Update package lists
echo "# Updating package lists"
sudo apt-add-repository -y ppa:git-core/ppa
sudo apt-get update
# Install Git
echo "# Installing Git"
sudo apt-get install -y git
# Install nvm dependencies
echo "# Installing nvm dependencies"
sudo apt-get -y install build-essential libssl-dev
# Execute nvm installation script
echo "# Executing nvm installation script"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
# Set up nvm environment without restarting the shell
export NVM_DIR="${HOME}/.nvm"
[ -s "${NVM_DIR}/nvm.sh" ] && . "${NVM_DIR}/nvm.sh"
[ -s "${NVM_DIR}/bash_completion" ] && . "${NVM_DIR}/bash_completion"
# Install node
echo "# Installing nodeJS"
nvm install --lts
# Configure nvm to use version 6.9.5
nvm use --lts
nvm alias default 'lts/*'
# Install the latest version of npm
echo "# Installing npm"
npm install npm@latest -g
# Ensure that CA certificates are installed
sudo apt-get -y install apt-transport-https ca-certificates
# Add Docker repository key to APT keychain
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# Update where APT will search for Docker Packages
echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu ${CODENAME} stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# Update package lists
sudo apt-get update
# Verifies APT is pulling from the correct Repository
sudo apt-cache policy docker-ce
# Install kernel packages which allows us to use aufs storage driver if V14 (trusty/utopic)
if [ "${CODENAME}" == "trusty" ]; then
echo "# Installing required kernel packages"
sudo apt-get -y install linux-image-extra-$(uname -r) linux-image-extra-virtual
fi
# Install Docker
echo "# Installing Docker"
sudo apt-get -y install docker-ce
# Add user account to the docker group
sudo usermod -aG docker $(whoami)
# Install docker compose
echo "# Installing Docker-Compose"
sudo curl -L \
"https://github.com/docker/compose/releases/download/1.13.0/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Install python v2 if required
set +e
COUNT="$(python -V 2>&1 | grep -c 2.)"
if [ ${COUNT} -ne 1 ]
then
sudo apt-get install -y python-minimal
fi
# Install unzip, required to install hyperledger fabric.
sudo apt-get -y install unzip
# Print installation details for user
echo ''
echo 'Installation completed, versions installed are:'
echo ''
echo -n 'Node: '
node --version
echo -n 'npm: '
npm --version
echo -n 'Docker: '
docker --version
echo -n 'Docker Compose: '
docker-compose --version
echo -n 'Python: '
python -V
# Print reminder of need to logout in order for these changes to take effect!
echo ''
echo "Please logout then login before continuing.”
上述腳本執行完成后,退出並重新登錄。執行下面的腳本,安裝Composer(Composer會安裝並啟動Fabric網絡)。
#!/bin/bash
#./install-composer.sh
npm install -g composer-cli
npm install -g composer-rest-server
npm install -g generator-hyperledger-composer
npm install -g yo
npm install -g composer-playground
mkdir ~/fabric-dev-servers && cd ~/fabric-dev-servers
curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz
tar -xvf fabric-dev-servers.tar.gz
cd ~/fabric-dev-servers
./downloadFabric.sh
./startFabric.sh
./createPeerAdminCard.sh
此時執行docker ps可以看到Fabric網絡運行的容器。
二、創建業務網絡、編寫業務代碼(chaincode)並打包
1. 規划業務網絡
$ yo hyperledger-composer
> Y
> Business Network
> test-bank
> Basic Bank App
> jack
> jack@cloudtogo.cn
> [ enter ]
> test
> No: generate a populated sample network
$ cd ~/test-bank
$ rm test/logic.js
2. 編寫業務代碼,把的內容修改成models/test.cto的內容修改成
namespace test
asset Account identified by accountId {
o String accountId
--> Customer owner
o Double balance
}
participant Customer identified by customerId {
o String customerId
o String firstName
o String lastName
}
transaction AccountTransfer {
--> Account from
--> Account to
o Double amount
}
把lib/logic.js的內容修改成:
function accountTransfer(accountTransfer) {
if (accountTransfer.from.balance < accountTransfer.amount) {
throw new Error ("Insufficient funds");
}
accountTransfer.from.balance -= accountTransfer.amount;
accountTransfer.to.balance += accountTransfer.amount;
return getAssetRegistry('test.Account')
.then (function (assetRegistry) {
return assetRegistry.update(accountTransfer.from);
})
.then (function () {
return getAssetRegistry('test.Account');
})
.then(function (assetRegistry) {
return assetRegistry.update(accountTransfer.to);
});
}
3. 更新ACL並打包成可部署的格式
$ vim permissions.acl
> :%s/SampleParticipant/Customer/g
> :%s/SampleTransaction/AccountTransfer/g
> :%s/SampleAsset/Account/g
> :qw
$ composer archive create -t dir -n .
三、部署到Fabric網絡
$ composer network install --card PeerAdmin@hlfv1 --archiveFile test-bank@0.0.1.bna
$ composer network start --networkName test-bank --networkVersion 0.0.1 \
--card PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw --file networkadmin.card
$ composer card import --file networkadmin.card
$ composer network ping --card admin@test-bank
四、生成RESTful API
$ composer-rest-server
> admin@test-bank
> always use namespaces
> N
> N
> Y
> N
至此整個區塊鏈銀行轉賬系統部署完成,訪問http://vmip:3000/explorer即可創建用戶和賬戶以及發起轉賬操作。 本文在編寫過程中參考了如下文章,在此對作者深表感謝。
-
https://www.hyperledger.org/projects/fabric
-
https://www.hyperledger.org/projects/composer
-
https://medium.freecodecamp.org/ultimate-end-to-end-tutorial-to-create-an-application-on-blockchain-using-hyperledger-3a83a80cbc71
-
https://medium.com/hyperlegendary/setting-up-a-blockchain-business-network-with-hyperledger-fabric-composer-running-in-multiple-bfbe4e38b6c6
-
https://medium.com/kokster/simpler-setup-for-hyperledger-fabric-on-kubernetes-using-docker-in-docker-8346f70fbe80
-
https://chainhero.io/2018/03/tutorial-build-blockchain-app-2/#install-instantiate-the-chaincode