自以太坊在2015年中旬登上加密货币舞台以来,这项由加拿大-俄罗斯程序员Vitalik Buterin带来的革命性发明,催生了众多去中心化应用(dApp)的诞生。除了各种dApp的构建,以太坊的成功主要归功于其对智能合约的实现。
有趣的是,智能合约的概念其实早在1996年就已提出。计算机科学家Nick Szabo首次提出了“智能合约”这一术语,并做了如下解释:
“我将这些新型合约称为‘智能’,是因为它们远比那些无生命的纸质前辈功能强大。这里并不涉及人工智能的使用。智能合约是一组以数字形式定义的承诺,包含了各方履行这些承诺的协议。”
—— Nick Szabo, 1996
他的工作后来激励了许多研究人员和科学家,其中包括创建了以太坊的Vitalik。
基础概念解析
在深入本指南之前,理解两个关键概念至关重要。
什么是以太坊虚拟机(EVM)?
首先需要理解的是以太坊虚拟机(EVM)。它的唯一目的是作为基于以太坊的智能合约的运行环境。你可以将其视为运行所有智能合约的全球超级计算机。顾名思义,EVM是虚拟的,而非物理机器。
什么是Gas?
在EVM中,Gas是一种计量单位,用于为每个涉及智能合约的交易分配费用。EVM中发生的每个计算操作都需要消耗Gas。操作越复杂繁琐,执行智能合约所需的Gas就越多。
每笔交易都会指定其愿意为单位Gas支付的以太币价格,这让市场来决定以太币价格与计算操作成本(以Gas衡量)之间的关系。总费用由使用的总Gas量乘以支付的Gas价格共同决定:
交易费用 = 总消耗Gas量 * Gas价格;现在你已对智能合约及其运行方式有了基本了解,我们可以直接进入如何创建自己的智能合约了!
环境设置与准备
我们将使用一个名为Pragma的工具来创建和部署智能合约。这是一个易于使用的智能合约开发平台。
首先需要登录MetaMask钱包。如果尚未安装MetaMask,需要先进行安装和设置。
重要提示:请确保在Pragma和MetaMask中都切换到Kovan测试网络。
以太坊主网是官方的以太坊网络,更加安全,并使用具有真实货币价值的ETH。测试网络则是用于开发的 playground 网络,其中的以太币被约定为没有货币价值。开发者在将应用部署到主网供用户使用之前,会使用这些测试网络进行测试。
要通过MetaMask切换网络,只需点击MetaMask图标旁边的网络名称并选择所需网络。在本教程中,请选择Kovan测试网。
编写你的第一个智能合约
以下合约将实现最简单形式的加密货币。虽然可以凭空生成代币,但只有合约创建者能够这样做(实现不同的发行方案也很简单)。此外,任何人都可以相互发送代币,而无需注册用户名和密码——你只需要一个以太坊密钥对。
pragma solidity ^0.4.21; // 表明源代码为Solidity 0.4.21或更新版本编写
contract yourToken {
// "public"关键字使这些变量可从外部读取
address public minter;
// 事件允许轻客户端有效响应变化
mapping (address => uint) public balances;
// 这是在合约创建时仅运行一次的构造函数
event Sent(address from, address to, uint amount);
function yourToken() public {
minter = msg.sender;
}
function mint(address receiver, uint amount) public {
if(msg.sender != minter) return;
balances[receiver]+=amount;
}
function send(address receiver, uint amount) public {
if(balances[msg.sender] < amount) return;
balances[msg.sender]-=amount;
balances[receiver]+=amount;
emit Sent(msg.sender, receiver, amount);
}
}这段代码基本上允许你铸造代币并将代币发送到其他账户。
代码逐行解析
pragma solidity ^0.4.21;这表明源代码是为Solidity版本0.4.21或任何不会破坏功能的更新版本编写的。这是为了确保代码在新的编译器版本中不会出现不同的行为。
contract yourToken所有与yourToken相关的内容都放在这个合约中。本质上,Solidity中的合约是位于以太坊区块链上一个地址的函数和状态(代码和数据)的集合。
address public minter;这是铸造者的地址。“public”关键字使这些变量可以从外部读取。
event Sent(address from, address to, uint amount);事件允许轻客户端(UI)有效地响应变化。
function yourToken() public {
minter = msg.sender;
}让我们将你的以太坊地址设置为合约的铸造者。你需要通过MetaMask访问合约才能进行铸造操作。我们将在部署合约后再次讨论这一点。
function mint(address receiver, uint amount) public {
if(msg.sender != minter) return;
balances[receiver]+=amount;
}此函数允许你铸造任意数量的代币。if条件告诉系统,如果你不是在你的Token函数中设置的铸造者,就停止执行。如果你是铸造者,它就允许你铸造代币。
function send(address receiver, uint amount) public {
if(balances[msg.sender] < amount) return;
balances[msg.sender]-=amount;
balances[receiver]+=amount;
emit Sent(msg.sender, receiver, amount);
}这是一个让一个地址向另一个地址发送代币的函数。它接受两个参数:接收者和数量。它从发送者地址减少金额,并将相同金额添加到接收者地址。我们之前声明的事件Sent现在被用来执行传输。
就这样,你的合约现在已经准备好了,让我们来编译它。
编译与部署智能合约
合约编译完成后,让我们将其部署到区块链上。如前所述,我们将使用Kovan测试网来部署合约。
检查智能合约是否已成功部署。你可以在Pragma平台的合约列表下查看已部署的合约。
在Pragma中与智能合约交互
现在你可以尝试铸造1000000个代币!系统会提示你签署交易以确认操作。
成功!你已经成功将第一个智能合约部署到区块链上。
在此过程中介绍了很多新概念以及一些极其有用的工具。可能会感到有些不知所措,这完全正常!只需先理解这些概念,然后动手实践即可。
常见问题
什么是智能合约?
智能合约是一种自动执行的合约,买卖双方之间的协议条款直接写入代码行中。代码和其中包含的协议存在于跨区块链的分布式去中心化网络中,使得交易可追踪、透明且不可逆转。
为什么需要Gas费用?
Gas是以太坊网络中计算工作的计量单位。每笔交易都需要计算资源来执行,因此需要支付费用。Gas费用防止了网络滥用,并为矿工处理交易提供了激励。
测试网与主网有什么区别?
测试网是用于开发和测试的以太坊网络,使用的代币没有真实价值。主网是实际的以太坊区块链,处理具有真实经济价值的交易。开发者通常在测试网上测试他们的应用,然后再部署到主网。
学习智能合约开发需要什么背景?
虽然拥有编程背景会有帮助,但许多开发者都是从零开始学习智能合约开发的。熟悉JavaScript和面向对象编程概念会有所帮助,但Solidity有自己独特的语法和概念,任何人都可以学习。
部署智能合约后可以修改吗?
一般情况下,部署到区块链的智能合约是不可变的,这意味着一旦部署就不能更改。这就是为什么在部署前彻底测试合约如此重要的原因。不过,可以通过一些模式(如代理合约)来实现一定程度的可升级性。
如何确保智能合约的安全?
智能合约安全涉及多次审计、全面测试以及遵循最佳实践。使用像REMIX这样的开发工具可以帮助在部署前识别常见问题。许多项目还会聘请专业的安全公司进行审计。
智能合约开发是一个不断发展的领域,为区块链创新提供了无限可能。通过掌握基础知识和不断实践,你将能够创建更加复杂和有用的去中心化应用。