以太坊开发技术基础
以太坊概述
以太坊是可编程的区块链,是业内公认的区块链 2.0 代表项目。可以将以太坊理解为一个操作系统,使用 Solidity 等语言编写智能合约发布应用到链上,使用 Go、Java、Python、JavaScript 等语言在链下调用链上的智能合约读写区块链数据,通过这种方式实现各种各样的区块链应用。
比特币的总上限是2100万,而以太坊的内置代币以太币(Ether)没有确切的总量上限。目前以太坊大概每15秒出一个新块,一个新块奖励矿工 3 ETH 。以太坊的设计者认为随着时间流逝总会发生因为粗心和死亡等原因带来的币的遗失,假设币的遗失是每年货币供应量的一个固定比例,则最终总的流通中的货币供应量会稳定在一个等于年货币发行量除以遗失率的值上,使得供应量会趋于稳定。
比特币缺少图灵完备性,尽管比特币脚本语言可以支持多种计算,但是它不能支持所有的计算,如不支持 for 循环。以太坊是准图灵完备的,之所以增加“准”,是因为智能合约在以太坊区块链上执行时是受限的。在以太坊区块链上执行交易(转账、调用智能合约)需要消耗 Gas ,一般来说操作步骤越复杂需要的 Gas 越多,而一个块有 Gas 上限(目前约为 800万)。向普通账户做1次转账操作目前消耗 2.1 万 Gas。
在块 Gas 上限为 800 万时,假设调用一个智能合约中某个函数时会向400个账户转账,因为会至少消耗 400 * 2.1 万 = 820 万 Gas,超出块的 Gas 上限 800 万,合约调用会失败。
关于以太坊更详细的介绍可以参考:以太坊白皮书和以太坊黄皮书。
Solidity
Solidity 是一种在语法上类似 JavaScript 的高级语言,编译 Solidity 代码可以生成以太坊虚拟机代码。Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。使用 Solidity 可以很容易创建投票、众筹、封闭拍卖、多重签名钱包、谜恋猫游戏之类的智能合约。
由于以太坊区块链的限制,在链上无法读取链下数据,使用 Solidity 你也无法来调用传统的 API,例如你无法调用某天气网站提供的天气 API。另外在以太坊区块链上,无法让程序在指定时间自动运行。
谜恋猫游戏为了真实性,在猫怀孕后不是立即生出小猫,而是需要在满足一定条件后由外部来触发生猫函数为猫提供接生服务,一些开发者根据游戏的这个特性还可以赚猫的接生费,后文会有详细说明。
etherscan.io 提供了验证程序源码的服务。原理是使用公开的代码及指定的编译器版本再编译一次程序,然后和发布到区块链的以太坊的二进制代码做比对,如果一致说明公开的代码就是在区块链上运行的那份代码。下图是一份通过验证的代码截图。
可以访问这里,进一步了解 Solidity。
ERC-20 和 ERC-721
ERC-20 和 ERC-721 都是以太坊 EIP(Ethereum Improvement Proposal,以太坊改进协议),更多 EIP 见这里。
ERC-20 定义了一份代币标准,可以理解为定义了一个接口类,在实现具体的 ERC-20 代币时,要给出各个接口的具体实现,如获取代币名称、代币符号、总供应量、小数位数、转账等。使用 ERC-20,可以大幅度降低发币成本,发币方无需开发钱包和区块链浏览器,交易所也可以轻松支持新的代币充值提现等操作。
ERC-20 币是同质的,你的一个币和我的一个币是等价的。ERC-721 是非同质代币(Non-fungible Tokens),每个 ERC-721 有唯一的 ID,转账时,不再是转多少币,而是转某个tokenId,如 transferFrom:
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
谜恋猫实现了 ERC-721 规范,每个猫有一个唯一的 ID,玩家花 ETH 买猫时,智能合约会调用 transferFrom 修改猫的所有者。
搭建以太坊全节点
为了更方便、更快速的调用相关 API,建议在本地服务器上搭建一个以太坊全节点,并保持同步到最新区块高度。如果想通过程序买卖猫但又不想自己搭建全节点,可以使用 MetaMask 的节点,API 地址请访问这里,使用 MetaMask 的节点 API,监听事件可能会受到影响,一个方法是遍历某个区块的所有交易信息,然后选择自己关注的交易信息再做相关处理。
谜恋猫系统结构
谜恋猫 DApp
谜恋猫智能合约
谜恋猫在以太坊区块链上一共有4个智能合约:
以玩家挂单卖猫为例,说明相关步骤:
用户卖猫后,在页面上不是立即可以看到猫处于在售中,而是需要等待一会儿才能看到,整个过程是异步的。这也为懂技术的玩家留下机会,可以在猫刚开卖还未在页面上显示出售中就能立即买下猫,详细方法见后文。
谜恋猫游戏规则
以太坊钱包就是用户的 ID
一般涉及到用户数据的网站或 App,都会要用户注册帐号,哪怕是使用第三方授权。而对于谜恋猫游戏,即使你之前从未访问过网站,只要有你的以太坊钱包地址,其他人就可以给你送猫。
安装 MetaMask 插件后第一次登陆网站,需要你按提示点击一个消息签名按钮,以便验证当前用户身份。原理是椭圆曲线加密算法,相关函数为 web3.eth.sign(address, dataToSign)、ecRecover,具体用法可以搜索下。
买猫
在谜恋猫页面,点击顶部导航“猫市”,默认就是待收养的猫猫。点击“筛选猫咪”可以通过多种方式做筛选,找到自己的目标猫咪。初期玩建议按价格从低到高排序,选两三只便宜的猫咪。搜索功能并不是直接从区块链读取数据的,而是通过同步区块链数据后在中心化服务器中建立的索引。
点击一只猫咪后,进入单个猫咪页面,再点击“立即购买”就可以买猫了。
在点击“立即购买”按钮时,会调用 web3js,触发弹出 MetaMask 插件窗口。MetaMask 插件中会显示 Amount(转账额度)、GasLimit(燃料上限)、GasPrice(燃料价格)等参数,部分数据做了隐藏,如购买猫调用的是 bid(uint256 _tokenId) 函数。
点击“submit”按钮后,MetaMask 会将交易数据提交到以太坊网络,等待矿工打包确认,当矿工将交易数据打包到某个区块中才算真正完成相关函数执行。但成功打包到区块中不一定能成功买到猫,因为交易过程是异步的,在这个过程中也可能有其他人购买同一只猫,如果他人的交易比你的交易优先被矿工打包,你就买不到猫了。另外,卖家也可以取消卖猫。