Web3.0開發入門

語言: CN / TW / HK

       

前言

Web 3.0 的概念是由以太坊聯合創始人 Gavin Wood 在 2014 年提出的,指基於區塊鏈的去中心化在線生態系統,它代表了下一代互聯網時代。目前 Web 3.0 仍處於起步階段,但是發展非常迅猛,其去中心化、抗審查等特點使得人們更容易建設一個開放的網絡生態。本文會先對 Web3.0 的底層區塊鏈做個簡單介紹,然後再介紹 Web3.0 的整體架構,最後通過一個簡單的例子來介紹 Web3.0 開發常用的一些技術。本文只是一個引子,讓大家對 Web3.0 不再陌生,文中提到的一些技術感興趣的同學可以再自行深入瞭解。

區塊鏈簡介

區塊鏈架構

區塊鏈是一個去中心化的分佈式賬本,可以在數字世界中進行價值的表示和轉移。區塊鏈的架構自下而上分為六層,分別是數據層、網絡層、共識層、激勵層、合約層和應用層。

  • 數據層

區塊鏈是通過區塊(block)存儲數據,每個數據節點之間都包含所有數據,即分佈式賬本。每個區塊都包括了區塊的大小、區塊頭、區塊所包含的交易數量及部分或所有的近期新交易。數據層主要是解決這些數據以什麼樣的形式組合在一起,形成一個有意義的區塊。區塊鏈的數據結構中包括兩種哈希指針,它們均是不可篡改特性的數據結構基礎。一個是形成“區塊+鏈”(block+chain)的鏈狀數據結構,另一個是哈希指針形成的梅克爾樹(如下圖所示)。鏈狀數據結構使得對某一區塊內的數據的修改很容易被發現;梅克爾樹的結構起類似作用,使得對其中的任何交易數據的修改很容易被發現。

可以在http://www.blockchain.com/explorer上查看比特幣的區塊鏈交易數據,可以在http://cn.etherscan.com/上查看以太坊的區塊鏈交易數據。

  • 網絡層

區塊鏈使用的是去中心化的網絡架構,沒有中心化服務器,依靠用户點對點交換信息,主要包括 P2P 組網機制、數據傳播和驗證機制。正是由於節點的 P2P 特性,數據傳輸是分散在各個節點之間進行的,部分節點或網絡遭到破壞對其他部分影響很小。節點指的是區塊鏈客户端軟件(比如比特幣客户端、以太坊客户端),一般分為全節點和輕節點,全節點包含了所有區塊鏈的區塊數據,輕節點僅包括與自己相關的數據。

  • 共識層

共識層的功能是讓高度分散的節點在 P2P 網絡中,針對區塊數據的有效性達成共識,決定了誰可以將新的區塊添加到主鏈中(挖礦機制)。

工作量證明共識機制(PoW),礦工需要將網絡中未確認的交易按梅克爾樹組裝成候選區塊,在候選區塊的頭部有一個 32 位的隨機數區域,礦工需要反覆調整隨機數並計算,目標是讓整個區塊的哈希值小於一個“目標值”,誰先完成這個目標誰就有權力將交易記錄到區塊鏈分佈式賬本中並獲得一定的獎勵。挖礦的過程比拼的就是各個礦工節點的算力,可以變相認為誰的算力高誰的工作量就高,就有權力記賬和獲得獎勵。比特幣使用的是 PoW 機制;以太坊開始使用的是 PoW 機制,後來改成了 PoS 機制,原因是該機制交易速度更快、資源消耗更低。這種挖礦計算是非對稱的,挖礦可能需要經過許多次哈希計算,而要驗證的確找到有效的隨機數,只需要一次計算就可以,因此其他節點能夠很快驗證交易是否已經被記入賬本。

  • 激勵層

激勵層的功能主要是提供一些激勵措施,鼓勵節點參與記賬,保證整個網絡的安全運行。通過共識機制勝出取得記賬權的節點能獲得一定的獎勵。

目前比特幣的激勵措施是新區塊產生時系統會獎勵礦工一定的比特幣(系統產生的新比特幣,也會記錄在分佈式賬本,來源地址是 0,因此整個過程叫挖礦),獎勵最初是 50 個比特幣,每四年減半一次,分別為 25 個、12.5 個,以此類推。當比特幣數量達到 2100 萬枚的上限後(2140 年),激勵就全靠交易的手續費了。以太坊交易是靠 gas 手續費來激勵礦工。

  • 合約層

合約層封裝了各類腳本、算法和智能合約,使得區塊鏈具有可編程能力。例如, 比特幣的腳本 [1] 中就規定了比特幣的交易方式和過程中的種種細節,不過這種腳本使用不夠便捷且不是圖靈完備的。以太坊提出了智能合約的解決方案,提供了一種圖靈完備的高級編程語言來編寫智能合約,並使智能合約能夠運行在分佈式的以太坊虛擬機 EVM 上。智能合約就是存儲在區塊鏈上的一段代碼,它們可以被區塊鏈上的交易所觸發,觸發後,這段代碼可以從區塊鏈上讀取數據或者向區塊鏈上寫入數據。區塊鏈系統(比特幣、以太坊)可以認為是一個分佈式狀態機,通過交易觸發合約(腳本、智能合約)運行來改變狀態機的狀態。

  • 應用層

應用層封裝了區塊鏈的各種應用場景,具體應用可參見 90+ #Ethereum Apps You Can Use Right Now [2]

以下為一筆比特幣轉賬交易的過程:

以太坊簡介

因為我們將要在以太坊上開發一個 Web3.0 demo 應用,所以先簡單介紹一下以太坊的一些基本概念。

賬户和錢包

以太坊賬户分為外部賬户和合約賬户。外部賬户是擁有私鑰的賬户,擁有私鑰意味着控制對以太幣或合約的訪問。合約賬户具有地址但是沒有私鑰,合約賬户具有智能合約代碼,而外部賬户不具有。智能合約代碼是在合約賬户創建時由以太坊區塊鏈記錄的軟件程序,由 EVM 執行。

錢包是用來管理以太坊賬户的軟件應用程序 ,它控制對以太幣的訪問、管理私鑰和地址、跟蹤賬户的餘額、創建並簽名交易。可以説,以太坊錢包是通往以太坊世界的大門。一個針對以太坊錢包的常見誤解是認為錢包中包含以太幣或者代幣。實際上,錢包中只保存了密鑰。以太幣和其他各種代幣都保存在以太坊區塊鏈上。

當創建一個以太坊外部賬户的時候,會用非對稱加密算法生成一對公鑰與私鑰,並保存在錢包裏,而地址是公鑰的哈希值。交易的簽名和驗證過程如下(橢圓曲線數字簽名算法):

Sig=Fsig(Fkeccak256(m) , k)

其中:

  • k 是用於簽名的私鑰

  • m 是經過 RLP 編碼的交易數據包

  • Fkeccak256 是 Keccak-256 哈希函數

  • Fsig 是簽名算法

  • Sig 是輸出的數字簽名

函數 Fsig 生成了一個簽名,這個簽名包含兩部分內容,通常稱為 r 和 s: Sig=(r, s)

簽名驗證算法的輸入包括交易數據包(其實是交易的哈希值的一部分)、簽名方的公鑰和簽名(r 和 s 值),如果針對消息和公鑰的簽名驗證成功,算法會返回 true。

以太幣和 gas

以太坊的貨幣單位稱為 ether,也常使用 ETH 表示,例如 1 ether 或者 1 ETH。以太幣可以被拆分成更小的單元,最小單元稱為 wei,1 ether = 10^18 wei。以太幣的面額和單位名稱如下所示:

以太坊交易過程使用的是 gas 來支付手續費。gas 並不是以太幣,它是一種獨立的虛擬貨幣,跟以太幣之間存在匯率關係。gas 獨立於以太幣,是為了在以太幣價格大幅度波動的情況下,仍舊保護系統的靈活性,保證 gas 的價值相對穩定。

gas 的另一個作用是控制交易對資源的使用。交易數據會包含 gasPrice(交易發起方願意支付的 gas 價格)和 gasLimit(交易發起方願意為這個交易支付的最大 gas 數量)兩個參數,而每一條智能合約代碼語句的運行都會消耗對應的 gas,當運行過程中累計的 gas 消耗超過了 gasLimit,合約就會終止執行,交易失敗。失敗的交易仍舊會被作為一次失敗的嘗試而記錄在案,執行所花費的 gas 將從發起賬户中被扣除,除此之外,它不會對合約或者賬户狀態產生任何其他影響。

客户端

Geth 是官方提供的 go 語言實現的以太坊客户端。客户端可以以全功能節點的方式運行,也可以以遠程調用的方式運行。全功能節點會下載全部的區塊數據,對系統的網絡和存儲有較高的要求。從遠程調用以太坊的客户端不在本地保存區塊鏈數據,也不參與區塊和交易驗證,這樣的客户端提供錢包功能,也可以創建並廣播交易。以太坊客户端會對外提供 API(例如 web3.js API、JSON-RPC API)來訪問以太坊網絡。

智能合約

智能合約是運行在以太坊的虛擬機上的計算機程序,一旦部署之後,智能合約的代碼就不能被更改,但是可以刪除。把合約註冊到區塊鏈上需要通過一個特殊的交易,這個交易的目標地址是 0x0000000000000000000000000000000000000000,也被稱為零地址。

當交易目標是合約地址時,它會導致該合約在 EVM 中運行,使用交易和交易的數據作為其輸入。由於合約賬户沒有私鑰,因此無法啟動交易。只有外部賬户才能啟動交易,但合約可以通過調用其他合約,構建複雜的執行路徑來對交易做出反應。智能合約永遠不會“自動運行”,或者“在後台運行”。

常用的以太坊智能合約編程語言為 solidity。

token/代幣/通證

token、代幣、通證指的都是同一種東西。區塊鏈上的代幣是指基於區塊鏈的一種抽象資產,可以被持有並且用來代表資產、現金或訪問權限。

代幣與以太幣不同,因為以太坊協議本身跟代幣完全沒有任何關聯。發送以太幣是以太坊平台的內在動作,但發送或擁有代幣並不是以太坊協議中定義的內容。以太坊賬户的以太幣餘額在協議級別處理,而以太坊賬户的代幣餘額在智能合約級別處理。要在以太坊上創建新代幣,你必須創建一個新的智能合約。部署後,智能合約將處理所有內容,包括所有權,轉移和訪問權限。

代幣有可替代性代幣和不可替代性代幣,標準分別是 ERC20 [3]ERC721 [4] ,目前市面上比較火爆的 NFT 就是一種不可替代性代幣。

Web3.0 簡介

從信息互聯網到價值互聯網

1989 年,Tim Bernes-Lee 撰寫了一篇題為“Information Management: A Proposal”的論文,其中他將“網絡”一詞描述為一個由超文本鏈接相互連接而成的信息系統網絡,這就是 Web 1.0。Web 1.0 發生在 1990 至 2004 年間,Netscape、谷歌、Yahoo、Amazon、eBay、Java 和 AOL 等公司憑藉其瀏覽器和搜索引擎主導了互聯網,這些平台是 Web 1.0 時代的內容創造者,而上面的絕大多數用户是內容的消費者。

隨着社交媒體平台的出現,Web 2.0 時期開始於 2004 年。在 Web 2.0 時代,用户能夠上傳自己的文本、圖片和視頻等內容到平台上,不再是內容的被動接受者,而是可以創造內容並與其他人進行交流。在 Web 2.0 時代,人們變成各種應用程序的用户,並在這些產品上創造大量的內容,這些數據被一箇中心化的平台所掌控。

Web 3.0 的概念是由以太坊聯合創始人、 Polkadot 創造者 Gavin Wood 在 2014 年提出的,代表了下一代的去中心化互聯網,並賦予了個體價值。Web 3.0 關注的是通過區塊鏈等去中心化技術形成的“誰創造,誰擁有”的關係價值。

以太坊官網 [5] 對 Web 3.0 主要特點的總結如下:

  • Web3 is decentralized:instead of large swathes of the internet controlled and owned by centralized entities, ownership gets distributed amongst its builders and users.

  • Web3 is permissionless : everyone has equal access to participate in Web3, and no one gets excluded.

  • Web3 has native payments:it uses cryptocurrency for spending and sending money online instead of relying on the outdated infrastructure of banks and payment processors.

  • Web3 is trustless : it operates using incentives and economic mechanisms instead of relying on trusted third-parties.

Web 2.0 與 Web 3.0 開發範式對比

Web 2.0 開發範式:

  • 需要開發登錄、註冊功能,讓用户綁定郵箱、綁定手機,需要搭建數據庫來存儲用户註冊信息以及用户交互數據

  • 使用前端代碼語言(JavaScript, HTML, CSS)來開發頁面邏輯,需要搭建一個服務器來部署前端頁面

  • 使用後端代碼語言(像 Node.js, Java, Go 等)來開發業務邏輯,並需要搭建一個服務器來部署後端服務,並需要運維服務

  • 所有代碼、數據都部署在中心化的服務器上,所有控制權歸開發者

Web 3.0 開發範式:

  • 不需要用户綁定郵箱,綁定手機,可以直接通過錢包登錄,也不需要存儲用户信息

  • 可以不需要搭建前端服務器,用户可通過 IPFS 或 arweave 存儲前端頁面,並進行訪問

  • 不需要搭建後端服務器,後端邏輯是用智能合約編寫的,運行在 EVM 上的

  • 不需要搭建數據庫,歷史數據與數據庫操作通過 TheGraph 來實現

實戰:去中心化的 HPC 代幣交易系統

下面我們將基於以太坊開發一種遵循 ERC20 [6] 標準的可替代性代幣,叫做 HPC,並提供一個簡單的頁面進行 HPC 代幣的交易。

安裝客户端&生成賬户

根據官網http://geth.ethereum.org/docs/指導安裝geth客户端並生成兩個測試賬號。

  • Mac 下安裝 geth

brew tap ethereum/ethereum
brew install ethereum
  • 安裝完 geth 後會同時提供一個錢包工具 Clef,可用於賬號管理和進行交易簽名

mkdir -p geth-config/keystore
clef newaccount --keystore geth-config/keystore # 運行兩次,創建兩個測試賬户
clef newaccount --keystore geth-config/keystore

創建完賬户後可以看到 geth-config/keystore 目錄下多了兩個賬號的配置文件,後續也可以利用這兩個文件將賬户導入其他錢包

  • 以輕節點模式啟動 geth,我們使用 Goerli 區塊鏈網絡(一個以太坊測試網絡)來進行測試,Goerli 區塊鏈網絡的 id 是 5

clef --keystore geth-config/keystore --configdir geth-config/clef --chainid 5 #先啟動clef,後續交易需要使用clef來簽名
geth --datadir geth-config --signer=geth-config/clef/clef.ipc --goerli --syncmode light --http --http.api "eth,debug" # 新開一個terminal tab,啟動geth
  • 啟動 geth 後,geth 默認會在 127.0.0.1:8545 上啟動一個 http 服務,可以使用 geth attach 命令連接該服務進入到一個 js console 環境,並可以使用 web3.js api 與區塊鏈主網進行交互

geth attach http://127.0.0.1:8545   # 新開一個terminal tab運行該命令,運行該命令後terminal tab會被block住,需要到運行clef服務的tab去授權,授權完geth attach命令就會進入一個交互式的頁面,該頁面可以使用web3.js api進行交互
  • 獲取測試以太幣,從http://goerlifaucet.com/或者http://goerli-faucet.mudit.blog/獲取goerli測試網絡的以太幣

開發智能合約(類比服務端代碼)

  • 使用 solidity [7] 語言進行開發,根據 ERC20 [8] 標準智能合約需要實現以下接口,同時在代碼中設定智能合約的擁有者可以調用 mint 函數進行挖礦產生代幣,完整項目代碼參見http://github.com/watchsky/hpc_eth_coin/tree/master/contracts

pragma solidity ^0.5.2;

interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
  • 安裝 solidity 編譯器,Mac 系統使用 brew 安裝

brew install solidity
  • 編譯合約

solc --bin --abi HippoCoin.sol  # 在代碼目錄下執行
  • 部署智能合約,在 js console 環境下使用 web3.js api 進行部署

  • 在 geth js console 環境下對我們的智能合約進行測試

hpcContract = new eth.Contract(abi, '0x74fe09b3ba8adea31f6448f4c742e9148a262d9b')  # 獲取合約實例
hpcContract.mint('0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709', 200000, {from: '0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709'}) # 0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709是創建合約的地址,在合約代碼裏將其設為了owner,可以進行挖礦
hpcContract.mint('0xee45cE18A60C2Df0B092185Ca4C0B483018FB07B', 500000, {from: '0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709'})
hpcContract.transfer('0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709', 500, {from: '0xee45cE18A60C2Df0B092185Ca4C0B483018FB07B'})

查看交易記錄http://goerli.etherscan.io/address/0x74fe09b3ba8adea31f6448f4c742e9148a262d9b

代幣詳情http://goerli.etherscan.io/token/0x74fe09b3ba8adea31f6448f4c742e9148a262d9b

開發前端頁面

  • 因為需要通過頁面來進行 HPC 代幣的交易,因此需要使用一個 web 錢包來進行交易的簽名和發送。這裏我們使用 MetaMask [9] 錢包,它支持通過 瀏覽器插件 [10] 的方式運行。為了測試,我們將前面創建的兩個賬户(0xee45cE18A60C2Df0B092185Ca4C0B483018FB07B 和 0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709)導入 MetaMask,如下圖所示

  • 開發前端代碼,主要邏輯是要跟 MetaMask 錢包交互,當安裝了 MetaMask Chrome 插件後會在頁面上註冊一個 window.ethereum 對象,通過該對象可以使用到錢包提供的功能,發送交易時需要對數據進行編碼,使用的是 ethers 庫,完整代碼參見http://github.com/watchsky/hpc_eth_coin/tree/master/src,以下列出請求連接錢包和發送交易的代碼

請求連接錢包:

export const requestMetamaskAccount = async () => {
if (!ethereum) {
return;
}

const accounts = await ethereum.request({ method: "eth_accounts" });

if (accounts.length === 0) {
currentAccount = null;
} else if (accounts[0] !== currentAccount) {
currentAccount = accounts[0];
}

return currentAccount;
};

發送交易:

  const toAddress = document.getElementById("toAddress").value.trim();
const amount = document.getElementById("amount").value.trim();

const contractAddress = '0x74FE09B3bA8AdEa31f6448f4c742e9148A262d9b';
const abiInterface = new utils.Interface(abi);
const functionData = abiInterface.encodeFunctionData("transfer", [
toAddress,
parseInt(amount),
]);
const transactionParameters = {
nonce: "0x00", // ignored by MetaMask
gasPrice: "0x94810dee", // customizable by user during MetaMask confirmation.
gas: "0x8a82", // customizable by user during MetaMask confirmation.
to: contractAddress, // Required except during contract publications.
from: account, // must match user's active address.
value: "0x00", // Only required to send ether to the recipient from the initiating external account.
data: functionData,
chainId: "0x5", // Used to prevent transaction reuse across blockchains. Auto-filled by MetaMask.
};

const txHash = await ethereum.request({
method: "eth_sendTransaction",
params: [transactionParameters],
});
  • 對靜態資源使用 webpack 打包構建,然後通過 ipfs 將頁面資源部署到去中心化的網絡中

  • 頁面效果 http://ipfs.io/ipfs/QmQDnUK2X1XQLFkQJeiqocseWiq4bE6SWRo65U6sd7J2Wn?filename=index.html

為了讓大家對 Web3.0 常用的一些底層技術有所瞭解,本文的案例沒有使用任何框架來開發,但實際開發中我們可以利用一些工具來幫助開發提效,例如 Home - Truffle Suite [11]Embark into the Ether. | Embark [12]Fleek: Build on the New Internet [13]Remix - Ethereum IDE [14]

參考資料

《精通以太坊:開發智能合約和去中心化應用》

區塊鏈是什麼?超級詳細,看了無師自通! [15]

Web 3.0 架構不僅是去中心化的,更是模塊化的-今日頭條 [16]

Web 3.0 生態全解析:顛覆性的技術變革-今日頭條 [17]

What is Web3 and why is it important? | ethereum.org [18]

Ethereum Provider API | MetaMask Docs [19]

參考資料

[1]

比特幣的腳本: http://bitcoindev.network/bitcoin-script-101/

[2]

90+ #Ethereum Apps You Can Use Right Now: http://consensys.net/blog/news/90-ethereum-apps-you-can-use-right-now/

[3]

ERC20: http://ethereum.org/en/developers/docs/standards/tokens/erc-20/

[4]

ERC721: http://ethereum.org/en/developers/docs/standards/tokens/erc-721/

[5]

以太坊官網: http://ethereum.org/en/web3/

[6]

ERC20: http://ethereum.org/en/developers/docs/standards/tokens/erc-20/

[7]

solidity: http://docs.soliditylang.org/en/v0.8.13/

[8]

ERC20: http://ethereum.org/en/developers/docs/standards/tokens/erc-20/

[9]

MetaMask: http://metamask.io/

[10]

瀏覽器插件: http://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn

[11]

Home - Truffle Suite: http://trufflesuite.com/

[12]

Embark into the Ether. | Embark: http://framework.embarklabs.io/

[13]

Fleek: Build on the New Internet: http://fleek.co/

[14]

Remix - Ethereum IDE: http://remix.ethereum.org/

[15]

區塊鏈是什麼?超級詳細,看了無師自通!: http://c.biancheng.net/view/1884.html

[16]

Web 3.0 架構不僅是去中心化的,更是模塊化的-今日頭條: http://www.toutiao.com/article/7092936458687742475/?app=news_article&timestamp=1652096170&use_new_style=1&req_id=2022050919361001021119802307017D5D&group_id=7092936458687742475&share_token=D5DCA805-267F-4D38-B4D0-485CBF53FBE3&tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share

[17]

Web 3.0 生態全解析:顛覆性的技術變革-今日頭條: http://www.toutiao.com/article/7078869546806805028/?app=news_article&timestamp=1652096188&use_new_style=1&req_id=2022050919362801021204403917017E3F&group_id=7078869546806805028&share_token=FEF1EEB9-321E-4E21-A91E-B1922C8DC64C&tt_from=copy_link&utm_source=copy_link&utm_medium=toutiao_ios&utm_campaign=client_share

[18]

What is Web3 and why is it important? | ethereum.org: http://ethereum.org/en/web3/

[19]

Ethereum Provider API | MetaMask Docs: http://docs.metamask.io/guide/ethereum-provider.html

:heart: 謝謝支持

以上便是本次分享的全部內容,希望對你有所幫助^_^

喜歡的話別忘了 分享、點贊、收藏 三連哦~。

歡迎關注公眾號 ELab團隊 收穫大廠一手好文章~

我們來自字節跳動,是旗下大力教育前端部門,負責字節跳動教育全線產品前端開發工作。

我們圍繞產品品質提升、開發效率、創意與前沿技術等方向沉澱與傳播專業知識及案例,為業界貢獻經驗價值。包括但不限於性能監控、組件庫、多端技術、Serverless、可視化搭建、音視頻、人工智能、產品設計與營銷等內容。

歡迎感興趣的同學在評論區或使用內推碼內推到作者部門拍磚哦

字節跳動校/社招投遞鏈接:

http://job.toutiao.com/s/FCbeMRg

內推碼: JFXXMTJ