精通以太坊2:以太坊的基本概念
1.以太币的货币单位
以太坊的货币单位称为ether,也常用ETH或符号 Ξ(这是来自希腊文的字母“Xi",看上去像个大写的E),偶尔也会有人使用◆
1 ether,或 1 ETH,或 Ξ,或 ◆1
我们可以使用 Unicode字符 U+039E显示 Ξ,使用 U+2666显示◆
以太币最小单元为 wei.
1 ETH=1x10^18wei
(记住:以太坊是区块链系统,以太币是这个系统上的数字货币,不能叫作以太坊币)
在以太坊系统内部,以太币总是采用无符号整型数据来表示,以wei为单位,当你转账1 ether 时,转账数据中的编码是 1000000000000000000 wei
以太币有多种面额,这些面额既有才有国际单位制(SI)的标准名称,也有为了纪念计算机和密码学领域著名的科学家而发明的通俗名称。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cqLlfT2T-1582889012906)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582597000109.png)]
2.选择以太坊钱包
以太坊钱包是通往以太坊世界的大门。
它用来保存你的私钥,创建以太坊交易数据包并以你的身份在网络上广播
(选择以太坊钱包是件挺困难的事情。以太坊钱包的种类很多,各自的设计目标和功能也不尽相同。有些适合新手,有些则是面向专家的。即使你现在选中了一款钱包软件,也很有可能过了一年半载后就会改变自己的选择。以太坊平台本身处在持续变化的过程中,优秀的钱包软件会紧跟平台的变化而不断更新,但有些钱包软件则更新缓慢。)
我们不想用一个钱包了,可以很容易的更换新的以太坊钱包。只需要发起一笔交易,把旧钱包中的以太币转到新钱包的地址之下,或者可以通过导出/导入功能来迁移旧钱包中的私钥。
注意:
1.下载钱包从可信任的来源下载
2.避免将鸡蛋放在一个篮子里,让你的以太坊账号分散在几个钱包中
以下是一些供初学者使用的钱包:
MetaMask
MetaMsk是一个基于浏览器扩展的钱包,它运行在你的Web浏览器
(Chrome,Firefox、Opera或BraveBrowser)_中.使用这个钱包和各
项测试都很容易,它可以链接多种以太坊节点和测试区块链
Jaxx
Jaxx是一个支持多平台多币种的钱包,可以运行在,Android、
iOS、Windows、Mac和Linux等操作系统。简单易用适合新手。
既可以是移动钱包也可以是桌面钱包,取决于实际安装环境
MyEtherWallet(MEW)
MyEtherWallet是一个基于网页的钱包,它运行在浏览器之内。它有
很多成熟的功能,我们会在后续的实验中多次用到这个钱包
Emerald Wallet
主要用于以太坊经典(ETC)区块链配合使用,但也与其他基于以
太坊的区块链兼容。是一个开源桌面应用程序,可以在 Windos,
MAC,lINUX下运行。
Emerald Wallet可以运行完整节点或连接到公共远程节点,以“轻
模式”工作。它还有一个配套工具,可以从命令行执行所有操作。
3.MetaMask入门
1.利用·*的方式在谷歌中搜素:
https://chrome.google.com/webstore/category/extensions
2.在搜索栏中输入 MetaMask,回车
3.校验是否为真的MetaMsk插件:
· 在浏览器地址中显示的插件ID是nkbihfbeogaeaoehlefnkodbefgpgknn· 由https://metamask.io发布· 有超过1400个用户评论· 有超过1000000个用户在“验明正身”之后,点击“Add to Chrome”进行安装。
4.创建钱包
MetaMask安装完成后,你会在浏览器的工具栏上看到一个新图标(一只狐狸的头像)。点击这个图标就能开始使用MetaMask了。你需要先阅读和接受用户使用协议,然后输入密码来创建新的以太坊钱包(图2-2)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8lpwUf08-1582889012907)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582608691783.png)]
这个密码用来控制对MetaMask软件的使用,例如当他人使用你的电脑时,需要知道密码才能对MetaMask进行操作。设定密码后,MetaMask会为你生成一个钱包,并且显示包含了12个英文单词的助记词(图2-3)。这些助记词可用在所有的兼容钱包上以进行钱包恢复。如果你的MetaMask甚至是你的电脑出问题了,只需要这12个单词就可以完成钱包恢复,不需要之前设定的密码。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pJw19TGJ-1582889012908)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582608767345.png)]
[插图]把这12个助记词备份在两张纸上。把这两张纸放置在相隔较远的两个位置,例如防火的保险柜、上锁的抽屉或者安全的保管箱。这两张纸的价值等同于你在以太坊钱包内保存的数字货币的价值。如果他人获得了这12个词,就可以窃取你的数字货币。在你确定已经正确保存了助记词之后,MetaMask会显示你的以太坊账户细节(图2-4)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vgyjwr4j-1582889012909)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582608839174.png)]
你的账户页面会显示账户名称(默认是Account 1)、账户的以太坊地址(例如0x9E713…)和一个彩色图标(用于在多个账户之间进行区分)。在账户页面的顶端,你会看到当前钱包软件连接的以太坊网络(示例中是“Main Network”)。恭喜!你已经安装完成了第一个以太坊钱包!
5.切换网络
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kAaIAKdI-1582889012911)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582608984111.png)]
如同在MetaMask账户页面看到的,你可以在以太坊的多个网络之间进行切换。默认情况下,MetaMask会尝试连接到主网络。另外的几个网络包括公开的测试网络、用户自己选择的以太坊节点,或者运行在本机之上的私有以太坊区块链:
以太坊主网
以太坊的主网络,完全公开,承载了真实的以太币,以及真实的价值和交易。
Ropsten测试网络
以太坊的公开测试区块链网络,在这个网络上的以太币没有任何价值。
Kovan测试网络
以太坊的公开测试区块链网络,使用Aura协议和权威证明(PoA
federated siging)方式的共识机制。在这个网络上的以太币没有任 何价值。只有Parity客户端支持这个测试网络,其他的以太坊客户 端在权威证明时使用稍后提到的Clique协议
Rinkeby测试网络
另一个以太坊的公开测试区块链网络,使用 Clique协议和权威证明
(POA federated signing)方式的共识机制。在这个网络上的以太 币没有任何价值
Localhost 8545
通过浏览器连接到本机上运行的以太坊节点。这个节点可以是以太
坊公共区块链(无论是主网还是测试网络)的一部分。也可以是一个 完全私有的测试网络
自定义RPC
允许把MetaMsk连接到任何一个兼容 Geth RPC接口的节点。这个 节点可以是公开或者私有的区块链的一部分
MetaMask会在你所连接的所有网络上使用相同的私钥和以太币地址。在每一个网络上,你的以太币账户中的余额是不同的。与之对应,你的私钥可以操作Ropsten测试网络上的资产和合约,但并不意味之这个私钥可以在主网上做同样的事情。
6.获得测试以太币
我们的当务之急是设法给钱包“充值”。我们不会在以太坊的主网络上做这件事,因为真实的以太币需要花钱购买,而且这也需要一定的经验才能顺利和安全地完成。目前阶段,我们使用来自测试网络的以太币进行实验。
1》把MetaMask的网络切换到Ropsten Test Network,然后点击“Buy”,再点击“Ropsten Test Faucet”, MetaMask就会打开一个新的网页(图2-5)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Seh4QrfL-1582889012913)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582612027373.png)]
你会注意到这个页面已经自动包含了你的MetaMask钱包地址。MetaMask会跟包含以太坊信息的页面自动集成。MetaMask会获取页面上的以太坊地址,这样就允许用户完成诸如在线商店的付款等操作。MetaMask也会把用户的以太坊地址提供给页面上的程序,当页面上的程序需要支付时,作为对应的收款地址。在这个页面上,Faucet[插图]应用需要MetaMask提供一个地址来发送测试以太币。
点击“request 1 ether from faucet”按钮,你会在页面底部看到一个交易ID。这个应用已经创建了一笔支付到你的地址的交易。交易的ID是类似这样的一串数据:
0x81b7e08f65bdf5648606c89998a9cc8164397647
几秒钟之后,这笔交易会被Ropsten测试网络上的矿工打包,你的MetaMask钱包会显示出一个以太币的余额。点击交易ID,浏览器会打开一个区块浏览器页面,在这个页面上可以查看和浏览区块的内容、地址和交易。MetaMask使用Etherscan(https://etherscan.io)这个区块浏览器应用,这是所有区块浏览器中最流行的。我们这笔支付的交易如图2-6
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9UUJJagT-1582889012915)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582615330961.png)]
笔交易已经被记录到Ropsten的区块链上,可以在任何时间被任何人所查看,只需要简单地提供交易ID,或者访问如下链接:https://ropsten.etherscan.io/tx/0x7c7ad5aaea6474adccf6f5c5d6abed11b70a350fbc6f9590109e099568090c57。尝试访问这个链接,或者在https://ropsten.etherscan.io网站输入交易的哈希值。
7.从 MetaMsk发送以太币
从Ropsten Test Faucet中收取第一个测试以太币之后,我们来尝试发送一个以太币。我们来试试看给Faucet的地址发回一个以太币。你可以在Ropsten Test Faucet页面上看到给Faucet“捐赠”一个以太币的选项。这个选项是让人们把做实验之后剩余的以太币发回给Faucet,这样其他人就可以继续使用这些测试以太币。尽管测试以太币毫无价值,可仍旧有人抓住不放,这就让其余人很难从网络中获取测试用的以太币,这样的做法真是令人皱眉。幸运的是,我们并不是那些愿意持有测试币的人。点击“1 ether”按钮,令MetaMask创建一个给Faucet支付一个以太币的交易。MetaMask会构建一个交易,然后弹出确认窗口,如图2-7所示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxfoc9HK-1582889012916)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582628319691.png)]
你可能已经注意到了,这笔交易无法完成。MetaMask显示“Insufficient balance fortransaction”。这看上去很令人费解:我们的账户里有一个以太币,现在希望发出一个以太币,为什么MetaMask会说账户余额不足?答案是gas。每一笔以太坊交易都需要支付手续费,这些手续费支付给负责验证交易的矿工。在以太坊中,这类手续费通过一种被称为gas的虚拟货币进行收取,你得使用以太币来支付gas,作为交易的一部分。[插图]即使是测试网络,也仍旧需要支付手续费。如果没有手续费,测试网络的行为就会跟主网络不一致,这也就失去了测试网络存在的意义。手续费也保护了测试网络免受DDoS或者恶意交易(例如包含死循环的合约)的攻击,就像手续费在主网络中起到的作用一样。当你发送交易时,MetaMask计算出最近成功的交易平均手续费是每个gas等于3 gwei,即3gigawei。wei是以太币的最小计量单位,我们在之前讨论过。发送一笔普通交易需要21000个gas。因此,你需要支付的手续费是21000×3 gwei=63000 gwei=0.000063 ETH。(请注意,gas的平均价格是由矿工决定的,因此它们可能会出现涨落波动。我们会在稍后的章节中介绍如何增减gas的上限,以确保需要时你的交易可以获得优先权。)这也就意味着:为了完成一个以太币的转账,你需要至少1.000063 ETH。在交易显示的过程
中,MetaMask会把这个数字取整到1 ETH,但实际上你需要的却是1.000063 ETH,而你账户里只有1 ETH。此时,请点击“REJECT”来取消交易。我们来获取更多的测试币吧。再次点击“request 1 ether from the faucet”按钮,稍等几秒钟。不用担心,这个Faucet里有足够的测试币,你尽可放心申请。当你的余额是2 ETH时,我们再次尝试。点击“1 ether”捐赠按钮,你已经有足够的余额来完成这笔交易了。当MetaMask弹出付款确认窗口时,点击“SUBMIT”按钮。在这之后,你的账户余额为0.999937 ETH,因为你给Faucet支付了1 ETH,并且支付了0.000063 ETH作为gas开销。
8.查阅地址的交易记录
当前用 http:///cn.etherscan.com区块浏览器
9.世界计算机简介
我们安装了钱包软件,体验了以太币的接收和发送。
目前为止,我们把以太坊作为一种数字货币,但是以太坊要比数字货币的范围大得多。数字货币这个功能,只是以太坊作为去中心化智能合约平台这台世界计算机的功能中的一小部分。
设计以太币是用来支付智能合约的,智能合约是运行在以太坊虚拟机(EVM)之上的计算机程序。
EVM是一个全局性的单体,意味着它是一个无处不在的,全局唯一的单体计算机。以太坊网络的每一个节点都运行着EVM的本地副本。用于验证合约的执行。以太坊区块链则记录了这台世界计算机在处理交易和智能合约时所发生的所有状态的更改。
10.外部账户和合约账户
外部账户:
在MetaMsk钱包中创建的账户类型称为外部账户(EOA).外部账户是拥有私钥的账户,拥有私钥意味着控制对以太币或合约的访问。
合约账户:
合约账户具有智能合约代码,而外部账户不具有。
合约账户没有私钥。相反,它由智能合约代码的逻辑所拥有(并受其控制)。智能合约代码是在合约账户创建时由以太坊区块链记录的软件程序,由EVM来执行。
合约具有地址,就像外部账户一样。合约也可以发送和接收以太币。当交易目标是合约地址时,它会导致该合同在EVM中运行,使用交易和交易的数据作为其输入。除了以太币之外,交易还可以包含指示合约中要运行的特定函数以及要传递给该函数参数的数据。通过这种方式,交易可以调用合约中的函数。
注意:由于合约账户没有私钥,因此无法启动交易。只有外部账户才能启动交易,但合约可以通过调用其他合约,构建复杂的执行路径来对交易做出反应。这种情况的一个典型用途是外部账户多重签名智能合约钱包发送请求交易,将一些以太币发送到另一个地址。典型的DApp编程模式是让合约A调用合约B,以便在合约A的用户之间维持共享状态。
11.一个简单的智能合约Faucet(水笼头)
以太坊支持多种高级编程语言,所有这些语言都可以用来编写智能合约并生成对应的EVM字节码。
目前最流行的是 Solidity .由 Gavin Wood博士创立,是以太坊上应用最广的编程语言
例子:
我们编写一个合约来控制测试币的发放。我们已经通过Faucet程序在Ropsten测试网络获得了测试用的以太币。
Faucet是一个非常简单的东西:它向任何提出申请的地址发送测试以太币,并且定期被充满。我们可以通过一个由人类或者网络服务器控制的钱包来实现Faucet的功能。
代码例子:
//Our first contract is a faucet!注释
contract Faucet{
//Give out ether to anyone who asks 注释
function withdraw(unit withdraw_amount)public{
//limit withdrawal amount
require (withdraw_amount<=1000000000000000000);
//Send the amout to the adress that requested it
msg.sender.transfer(withdraw_amount);
}
//Accept any incoming amount
function()public payable{}
}
这是一个非常简单的合约,是我们能够编写的最简单地合约了。但这也是一个漏洞百出的合约,包括一堆不良的编程习惯和安全漏洞。我们会在后面章节分析。
我们可以发现Solidity 与其他主流编程语言有相似之处。
第一行
//Our first contract is a faucet!注释
第二行是实际合约代码的开始
contract Faucet{
这里声明了一个contract对象,类似于其他面向对象编程语言中声明的class
合约的定义包括花括号{}之间的所有行,这是一个定义域,类似其他编程语言中使用的花括号。
接着,我们声明了Faucet合约的第一个函数:
//Give out ether to anyone who asks 注释
function withdraw(unit withdraw_amount)public{
这个函数名称是 withdraw,它接收一个名为 withdraw_amount,类型为无符号整型(unit)的参数,这个函数被声明为公开函数,这意味着它可以被其他合约调用。这个函数的定义在接下来的花括号之间。首先是设定提币的上限:
require (withdraw_amount<=1000000000000000000);
它使用内置得Solidity函数require 来测试一个前提条件,即withdraw_amount小于或等于10000000000000000000wei,这是以太币的基本单位,相当于0.1ether.如果使用大于该数量的withdraw_amount调用withdraw函数,则此处的require函数将导致合约执行停止并因异常而失败。(solidity语句以;结尾)
这部分合约代码是测试币 发放合约的主要逻辑,它通过设定每次提币的上限来控制合约支付的数量。这是一个非常简单的控制,但是可以为你勾勒出大概的印象:可编程区块链的威力在于可以用去中心化的软件来控制资产。
接下来是实际的提币行为:
msg.sender.transfer(withdraw_amount);
msg对象是一个所有合约都可以访问的输入,它代表触发这个合约执行的交易。sender属性就是发起这个交易的发起方地址。transfer函数是一个内置函数,用来把以太币从合约转账到调用这个合约的交易地址。反过来看,这就是说将以太币转给触发这个合约执行的交易消息的发送地址。transfer函数只接收一个数额参数。
我们把之前定义的 withdraw_amount这个变量的值作为参数传递给withdraw函数。
紧接着的花括号意味着withdraw方法定义的结束
接着我们又定义了一个函数
function()public payable{}
这个函数称为回退函数或默认函数,它会在一些特殊的情况下被调用,比如:触发这个合约的交易没有指定调用哪一个具体函数,或者合约本身没有定义任何函数,再或者交易没有包含任何数据。合约可以有一个这样的默认函数(没有名字),通常也使用这个函数来接收以太币。
这也是为什么这个函数的定义包含public和payale属性。意味着这个合约可以接收以太币。如函数声明的空花括号所显示的,除了接收以太币,这个合约什么也不会做。如果我们发起一个针对合约地址的交易,就像是把合约地址当做钱包使用,这个函数就会处理。
接着默认函数的是一个花括号,它代表整个合约定义的结束。
12.编译Faucet合约
我们已经完成了第一个合约,现在需要使用Solidity编译器把Solidity代码转化为EVM字节码,这样才能够被区块链上的EVM所执行。
Solidity的编译器是一个独立的可执行程序,通常包含在各类编程框架之中,也会集成在一些IDE中,为了简单起见,我们使用Remix这个流行的IDE.
https://remix.ethereum.org
第一次加载Remix时,它会显示一个名为ballot.sol的演示性合约。我们不需要这个合约,可以关闭页面。点击页面边角上的×按钮
现在我们通过点击工具栏左侧加号按钮,添加一个新的标签页,把它命名为Faucet.sol。然后把代码粘进Faucet.sol
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnzNOW6J-1582889012917)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582637763769.png)]
13.在区块链上创建合约
我们已经有了一个合约,并且把它编译成了字节码,现在需要把这个合约注册到以太坊区块链上。我们还是使用Ropsten测试网络来测试合约,因此Ropsten就是我们需要注册合约的目标。
把合约注册到区块链上需要通过一个特殊的交易,这个交易的目标地址是0x0000000000000000000000000000000000000000,也被称为0地址,这是一个特殊的地址,用来告诉以太坊区块链用户希望通过这样的交易来注册合约。幸运的是,Remix IDE处理了所有这些细节,并且把生成的交易发送给MetaMask
首先,切换到“Run"标签页,在”Environment"下拉菜单中,选择“Injected Web3",这会建立起Remix IDE和MetaMask钱包之间的连接,并且进而通过MetaMask连接到Ropsten测试网络。
在完成这个设定后,你会在“Environment"一栏中看到Ropsten字样。同样,在账户选择的输入框中出现了你的MetaMask钱包地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sPubZncq-1582889012918)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582683562704.png)]
在确定了Run的设定之后,我们可以看到Faucet合约准备就绪,点击Deploy按钮。
Remix IDE会构建一个特殊的“creation"交易,然后MetaMask会请求你的批准。如你在MeatMask中看到的,这个合约创建的交易并没有包含以太币,它只有258字节(经过编译后的合约),这个交易的gas需要10 gwei.点击 ”SUBMIT"来批准这个交易(在区块链上注册合约)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSdbFc8U-1582889012919)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582683912119.png)]
现在稍等15–30秒,这个交易就会被Ropsten网络上的矿工确认。Remix IDE也无法加速这个过程,我们只能耐心等待。
当合约被创建后,在Run标签页底部会出现一些有关的信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uP8YYSAb-1582889012921)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582684190840.png)]
请注意,Faucet合约现在有一个属于它自己的地址,Remix中显示为
“Faucet at 0x72e…c6877“。右侧的小剪贴板图标允许你把合约地址复制到剪贴板,我们稍后就会用到这个合约地址。
14.与合约进行交互
以太坊合约时用来控制以太币的程序,它运行在名为 EVM的虚拟机之内。合约由特殊的交易创建,这个过程就是把合约的字节码保存到区块链上。在区块链上完成创建以后,合约会有一个以太坊地址,就如同钱包一样。任何时候,如果有人向这个合约地址发送交易,都会触发合约在EVM中被执行。这个交易本身,就是程序执行的输入参数。发送给合约的交易可以包括以太币或者数据,也可以同时包括这两者。如果交易包含以太币,就等于把以太币存入了合约的账户。如果交易包含数据,这个数据用来指定合约的具体函数并通过传递参数来调用它。
15.在区块浏览器中查看合约地址
现在我们已经有一个记录在区块链上的合约了,可以通过地址来查看它。
我们在https://ropsten.etherscan.io这个区块浏览器上一探究竟。点击剪贴板的图标来复制合约地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K092kELo-1582889012922)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582685097672.png)]
保持Remix窗口打开,我们稍后还会用到。现在,用浏览器打开
https://ropsten.etherscan.io,在搜索框复制合约的地址,你会看到合约的历史
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dfIU29jn-1582889012924)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582685205712.png)]
16.向合约充值
目前为止,这个合约只有一笔交易历史:它自己的合约创建交易。如你所见,这个合约也没有任何以太币(余额为0).这是因为我们没有在创建合约的交易中包含任何以太币
让我们向这个合约发送一些以太币,你的剪贴板中应该仍旧保留着合约地址(如果没有,就从Remix再复制一遍)。打开MetaMask,跟其他的转账操作一样,发送1 ether到合约地址
很快,如果你刷新Etherscan区块浏览器,会在合约地址下看到一条交易,并且账户余额更新为 1ether了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kYAgkYFx-1582889012925)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582685531159.png)]
还记得在Faucet.sol代码中那个没有名称、只有public和payable的默认函数吗?我们来看看这个:
function() public payable{}
当你发给合约地址一个交易时,如果没有指明具体调用合约的哪一个函数,他就会调用默认函数。因为我们在声明函数时添加了payable属性,这个函数就可以接收以太币并且把币存入合约余额,这个交易触发合约在EVM上被执行,并更新余额。这样就完成了充值。
17.从合约提币
接着,我们试试从合约中提取以太币。为了提币,我们需要构建一个调用withdraw函数的交易,并且传递 withdraw_amount作为参数。为了简单起见,可以使用Remix构建这个交易,然后用 MetaMask发送并取得我们的批准。
返回Remix界面,在 Run标签页找到合约。
图中标示为withdraw 并带有字段标记 unit256 withdraw_amount
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7BgIJY5B-1582889012926)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582686502692.png)]
这是合约在Remix中的界面,它允许我们构建一个交易,用来调用合约中定义的函数。我们输入一个withdraw_amount值,然后点击“withdraw”按钮来生成这笔交易。
首先,我们看withdraw_amount这个参数,我们尝试从合约中提取0.1ETH,这是合约所允许提取的最大限额。还记得以太坊内部所有的币值单位都应该使用 wei来表示吧?因此,withdraw_amount参数也必须使用 wei的格式。这里的0.1ETH,对应的就是
100000000000000000wei
然后点击 withdraw按钮
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEAHbJpt-1582889012927)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582686904759.png)]
MetaMask会弹出一个交易窗口请求你的确认,点击"SUBMIT",就可以对合约发出提币的调用了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpC4WGbx-1582889012929)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582686969409.png)]
稍等一会,刷新EtherScn区块浏览器,可以看到这笔交易已经在合约历史中反映出来了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ttj1jmBo-1582889012930)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582687028790.png)]
我们可以看到这笔交易时以合约作为地址,并且没有包含任何以太币。支出0.1ETH之后,合约的余额已经变为0.9ETH,但是很奇怪,我们没有看到一个“对外支付”的交易显示在合约地址历史记录中
这个对外支付的交易在哪里?合约地址历史记录页面中会出现一个新的区域,名为“Internal Transactions",因为0。1ETH的转账是由合约发起的,所以这类交易被称为内部交易(也称为消息)。点击”Internal Transactions"标签可看到内部交易
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PbMfd7cd-1582889012931)(C:\Users\xiaoweifeng\AppData\Roaming\Typora\typora-user-images\1582687364525.png)]
“内部交易”是由合约中的以下代码行发起的(Faucet.sol中的withdraw函数)
msg.sender.transfer(withdraw_amount);
总结:
我们从 MetaMask钱包发出了一个针对合约的withdraw函数的调用,调用中包含了值为0.1ETH的withdraw_amount参数,这个交易导致合约在EVM中被执行。在EVM执行Faucet合约的withdraw函数时,它首先调用 require来检验我们的参数是否满足要求(小于等于0.1ETH0.接着调用 transfer函数发送以太币。运行transfer会生成一个内部交易,把0.1ETH保存到调用方的钱包中。这就是在 Etherscan的“Internal Transcations"标签面上所显示的信息。
看到内部交易
[外链图片转存中…(img-PbMfd7cd-1582889012931)]
“内部交易”是由合约中的以下代码行发起的(Faucet.sol中的withdraw函数)
msg.sender.transfer(withdraw_amount);
总结:
我们从 MetaMask钱包发出了一个针对合约的withdraw函数的调用,调用中包含了值为0.1ETH的withdraw_amount参数,这个交易导致合约在EVM中被执行。在EVM执行Faucet合约的withdraw函数时,它首先调用 require来检验我们的参数是否满足要求(小于等于0.1ETH0.接着调用 transfer函数发送以太币。运行transfer会生成一个内部交易,把0.1ETH保存到调用方的钱包中。这就是在 Etherscan的“Internal Transcations"标签面上所显示的信息。
大鸟蜀黍 发布了40 篇原创文章 · 获赞 0 · 访问量 1155 私信 关注