Web3-0 開發入門

前言

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

區塊鏈簡介

區塊鏈架構

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

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

可以在 https://www.blockchain.com/explorer 上查看比特幣的區塊鏈交易數據,可以在 https://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)

其中:

函數 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 主要特點的總結如下:

Web 2.0 與 Web 3.0 開發範式對比

Web 2.0 開發範式:

Web 3.0 開發範式:

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

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

安裝客戶端 & 生成賬戶

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

brew tap ethereum/ethereum
brew install ethereum
mkdir -p geth-config/keystore
clef newaccount --keystore geth-config/keystore  # 運行兩次,創建兩個測試賬戶
clef newaccount --keystore geth-config/keystore

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

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 attach http://127.0.0.1:8545   # 新開一個terminal tab運行該命令,運行該命令後terminal tab會被block住,需要到運行clef服務的tab去授權,授權完geth attach命令就會進入一個交互式的頁面,該頁面可以使用web3.js api進行交互

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

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);
}
brew install solidity
solc --bin --abi HippoCoin.sol  # 在代碼目錄下執行

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'})

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

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

開發前端頁面

請求連接錢包:

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],
  });

爲了讓大家對 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]

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

[2]

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

[3]

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

[4]

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

[5]

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

[6]

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

[7]

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

[8]

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

[9]

MetaMask: https://metamask.io/

[10]

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

[11]

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

[12]

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

[13]

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

[14]

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

[15]

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

[16]

Web 3.0 架構不僅是去中心化的,更是模塊化的 - 今日頭條: https://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 生態全解析:顛覆性的技術變革 - 今日頭條: https://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: https://ethereum.org/en/web3/

[19]

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

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

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/vWbZJiVrcnwd8HeLI3b93A