前言
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 该机制的原因是交易速度更快,资源消耗更低。这种采矿计算是不对称的。采矿可能需要多次哈希计算,只需一次即可验证有效的随机数。因此,其他节点可以快速验证交易是否已记录在账簿中。
激励层
激励层的功能主要是提供一些激励措施,鼓励节点参与簿记,以确保整个网络的安全运行。通过共识机制获胜的节点可以获得一定的奖励。
目前,比特币的激励措施是,当新区块生成时,系统将奖励矿工一定数量的比特币(系统生成的新比特币也将记录在分布式账簿中,来源地址为 所以整个过程叫挖矿),奖励最初是 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)来访问以太坊网络。
智能合约
智能合同是以太坊虚拟机上运行的计算机程序。一旦部署,智能合同的代码不能更改,但可以删除。在区块链上注册合同需要一个特殊的交易,目标地址是 0x也叫零地址。
当交易目标是合同地址时,它会导致合同 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 主要特点的总结如下:
instead of large swathes of the internet controlled and owned by centralized entities, ownership gets distributed amongst its builders and users.
everyone has equal access to participate in Web3, and no one gets excluded.
it uses cryptocurrency for spending and sending money online instead of relying on the outdated infrastructure of banks and payment processors.
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 代币的交易。
安装客户端&生成账户
根据官网https://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进行交互
获取测试以太币,从https://goerlifaucet.com/或者https://goerli-faucet.mudit.blog/获取goerli测试网络的以太币
开发智能合约(类比服务端代码)
使用solidity[7]语言进行开发,根据ERC20[8]标准智能合约需要实现以下接口,同时在代码中设定智能合约的拥有者可以调用 mint 函数进行挖矿产生代币,完整项目代码参见https://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'})
查看交易记录https://goerli.etherscan.io/address/0x74fe09b3ba8adea31f6448f4c742e9148a262d9b
代币详情https://goerli.etherscan.io/token/0x74fe09b3ba8adea31f6448f4c742e9148a262d9b
开发前端页面
因为需要通过页面来进行 HPC 代币的交易,因此需要使用一个 web 钱包来进行交易的签名和发送。这里我们使用MetaMask[9]钱包,它支持通过浏览器插件[10]的方式运行。为了测试,我们将前面创建的两个账户(0xee45cE18A60C2Df0B092185Ca4C0B483018FB07B 和 0xEC30B4dAec9B113E5009a2259e7A4f201aE1D709)导入 MetaMask,如下图所示
开发前端代码,主要逻辑是要跟 MetaMask 钱包交互,当安装了 MetaMask Chrome 插件后会在页面上注册一个
window.ethereum
对象,通过该对象可以使用到钱包提供的功能,发送交易时需要对数据进行编码,使用的是 ethers 库,完整代码参见https://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 将页面资源部署到去中心化的网络中
页面效果 https://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]
比特币的脚本: 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×tamp=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×tamp=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
- END -
关于奇舞团
奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。