首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

区块链系列四:Hello Ethereum!

本文介绍以太坊开发的基础知识。

为啥不讲比特币呢

很少有基于比特币做开发的, 如果大家有兴趣可以看下面几个资料:

Mastering Bitcoin 2nd Edition

Bitcoin and Cryptocurrency Technologies Coursera上课程 课程资料

Bitcoin官网

只需要看上面三个资料来源即可, 不用看太多资料。

Ethereum基础概念介绍

P2P网络

区块链底层是一个P2P网络,全球有很多电脑节点连在这个网络上, 没有中心节点, 每个节点互相通信, 各自保留一份完整的账本。

客户端

就是P2P网络中的一个节点, 包含有一些功能以支持整个P2P网络的运行。 比如转账, 记录账本, 挖矿等, 还有一个完整的虚拟机EVM, 可以在上面执行智能合约。

官方支持三种语言的客户端, 分别是:

Go语言版本的Geth

C++语言版本Eth

python语言版本的pyethapp

另外社区还开发了各种语言版本的客户端, 可以看Ethereum Clients。

RPC

客户端通过JSON RPC暴露了一些API给用户使用, 比如生成账户、查看自己账户余额、部署智能合约等。 用户可以用curl或者postman工具调用RPC来实现功能, 但是一般还是通过一些SDK去做RPC调用,用的较多的有web3.js,其他语言版本的可以参考Connecting to Ethereum Clients。

RPC、客户端、以太坊网络三者的关系如下:用户通过RPC调用客户端功能, 客户端通过EVM执行智能合约以及跟整个以太坊P2P网络连接。

账户

Ethereum有两种类型的账户, 一种叫External owned account,可以简单理解为人控制的账户, 里面有“币”ether, 需要提供secret key,即可转账等。 一定要保护好自己的密钥, 不要让别人知道了(相当于把银行卡密码告诉了别人)否则钱就没了(被别人取走了); 也不要自己给搞丢了, 因为没有“找回密码”的功能, 记得经常备份, 也可以拿纸记下来存放在保险柜里, 但是小心别被火烧了哈(谁都不能用这笔钱了)。。。 本质上而言账号就是一个公钥-私钥对, 可以通过之前提到的各种客户端生成任意数量的EOA, 具体可以看Account Management。

另一种叫Contract account, 其实是存储在blockchain上的一些代码和数据, 可以类比为面向对象语言里面的一个对象, 可以被EOA调用修改其中的状态。 代码执行需要花费一定数量的Gas。

Gas

为了避免以太坊网络被滥用或者攻击, 在EVM中执行的代码(contract)需要执行一定的费用,这就是gas了。 gas对应现实生活中的燃油费, 是驱动整个加密经济体系运转的动力。 gas涉及到三个概念:

gasUsed, 每一条EVM指令都对应一定数量的gas, gasUsed表示整个contract执行完需要的gas总和

gasPrice, 调用contract的用户愿意支付的单价

执行一个contract的总花费 = gasUsed * gasPrice。

想想自己一不小心写出个死循环把自己几个亿的ether给用光了是什么感觉! 所以我们一般会设置gasLimit,即最大花费。 如果花费超过了gasLimit则contract执行过的操作会回滚,然后停止执行。 如果花费没有达到gasLimit, 则剩下的会原路退回。 客户端可以帮你估计一个contract大概的花费, 便于合理设置gasLimit。 问大家个问题, 如果花费超过了gasLimit会回滚contract操作, 那么还会扣掉gas么?为什么?

更多资料可以看Account Types, Gas, and Transactions。

智能合约

前面多次提到contract, 到底是啥呢? 说白了,就是一段代码以及相关的一个状态, 智能表示能自动执行。 比如你跟小明打赌, 说明天下不下雨,如果下雨你输10块给他。 结果第二天真的下雨了, 然后你赖账了。。。。为了避免赖账, 我们可以建一份智能合约, 里面一开始存储的状态是“你有10块钱, 小明有10块钱”,以及一段代码“如果明天下雨, 你的10块钱归小明, 反之亦然”。 然后第二天下雨了, 合约就自动执行,然后状态变成了“你有0块钱, 小明有20块钱”。

EVM

以太坊的虚拟机, 执行智能合约, 类似于JVM。 EVM是一个隔离的沙盒, 里面不能访问网络、文件系统等。EVM支持的功能是图灵完备的。 注意图灵完备不代表能做任何事情, 比如不能访问网络等。

Solidity

EVM上执行的智能合约是底层的二进制, 但是我们开发要用高级语言呢。 Solidity就是开发智能合约的一门高级语言, 类似于javascript, 通过solidity的编译器编译成二进制。

Hello Ethereum!

安装客户端

这里我们选择安装geth, 最简单的方式是下载压缩包, 直接解压即可。 安装其他客户端可以参考GETH & ETH。 为了在任何路径都能执行geth, 可以将其加入系统PATH中。

安装好之后执行如下命令启动geth:

geth提供了一个console,整合了web3.js,我们可以在里面直接写javascript代码进行操作, 比如生成账户、转账等, 通过如下命令进入console:

另外也可以单独执行把客户端启动起来, 然后在新的终端里面执行打开一个新的console。进入之后执行:

会发现返回的是空数组, 我们用下面命令生成一个新账号:

运行测试网络TestNetwork

直接用启动客户端, geth进去的是主网络(main network),也就是说任何操作都会真实进入以太坊P2P网络,比如转账、部署智能合约等。当然,我们账户里面没钱, 所以也没法转账和部署智能合约。 为了便于测试,我们可以建立一个私有测试网络。

区块链第一块叫创世块(Genesis block),建立私有测试链需要提供genesis block的配置,简单如下:

保存为,然后执行下面命令:

其中是网络名称。 表示开启RPC功能。 是这个私有网络的数据存储目录,避免覆盖主网数据。 表示不要被其他节点发现。 是网络id, 随便设置一个数即可, 默认为1(即主网)。

--networkid value Network identifier (integer, 1=Frontier, 2=Morden (disused), 3=Ropsten, 4=Rinkeby) (default: 1)

更多命令行选项可以执行查看, 或者访问go ethereum Command Line Options。

然后执行下面命令,启动geth:

连接客户端:

注意, 这里直接用连不上客户端, 因为不是用的默认配置。并且如果是用http方式attach的, 虽然连上了, 但是创建新账号的时候会报错:

只有通过IPC连接上的客户端, 才认为足够安全, 才允许创建账号。 当然也可指直接用创建账号:

注意,必须加上,否则创建的账号在默认目录, 不能访问。然后在里看, 确实有两个账号了:

刚创建的账号, 肯定都没钱嘛:

start之后几秒钟, CPU飚到800%, 风扇狂转, 赶紧关掉, 然后发现, 已经挖到55个以太坊了, 按照目前市值400刀一个, 我们挖到了价值22000刀的以太坊, 可惜都是测试环境的, 哈哈哈。

编写智能合约Solidity

solidity是编写以太坊智能合约的高级语言, 首先需要安装编译器, 参考Installing the Solidity Compiler。当然, 最简单的当然是直接用online版本Remix。

复制下列代码到remix编辑器中:

然后执行编译, 之后可以查看编译结果, 如下图:

部署智能合约Web3.js

将前面图中代码部分代码复制下来, 给变量一个值, 直接复制到geth的console中, 或者保存到文件比如,然后在console中执行即可。

其中data就是编译之后的二进制。

额, 我们需要先解锁我们的主账户

然后再加载加载脚本即可:

这时候合约并没有入链的:

想想也对, 这会儿没有miner干活呢, 那我们来自己挖一下吧:

可以看到, contract已经计入blockchain了, 另外,我们又挖到了30个eth哈哈哈。我们可以通过contract的address找到代码,当然,是二进制:

然后我们就可以执行合约了:

别人也能访问我们deploy的智能合约, 只要他们知道代码的地址以及接口类型(ABI (Application Binary Interface)))。 ABI是干嘛的呢, 基本就是告诉你前面的二进制代码要怎么调用, 因为估计没人能看了那串二进制就知道它是干嘛的吧。我们新开一个console:

像上面这样获取到contract的代码然后直接调用,其实是在本地的EVM上调用, 不会修改blockchain上的状态的(因此也不用花费ether)。如果需要修改blockchain上的状态,需要通过调用。 我们先在一个没有ehter的账户上调用一下试试:

看来,没钱真的不行啊。那我们在之前有ether的账户(之前有85ether,不过由于每次都交易都需要挖矿入链, 又多产生了一些,最后另外新开了一个账号来mine,才让pa0这个账号没有新增ether)上试一下呢:

可以看出来,每次都需要消费个wei,wei是以太坊的最小单位,, 所以执行一次交易,需要花费个ether,现在差不多1快rmb了。 我们可以看到,字符串确实存到blockchain上了:

如果我们最后不需要这个合约了, 我们可以把他删除, 避免占用blockchain的空间:

注意之后要mine才可以修改blockchain上的状态。也可以看出,kill也是需要花费gas的,当然,远比执行contract要低, 相当于网络进行了补贴, 否则估计就没人愿意删除合约了,这样会导致网络膨胀。 注意, 只有contract的owner才可以kill掉此contract, 其他人也能调用kill方法, 但是是没办法删掉contract的, 而且还扣了gas(貌似还比较高)。

ok,我们已经实现了一个Ethereum版本的, 后面我们就来考虑自己发一个币吧。

参考资料

https://www.ethereum.org

http://www.ethdocs.org

https://github.com/ethereum/go-ethereum/wiki/

https://solidity.readthedocs.io

http://web3js.readthedocs.io/en/1.0/index.html

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180403G1KRHM00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券