探路以太坊
关键字:以太坊,加密货币,crowdsale,geth,console,web3.js
以太坊简介
一句话简介:以太坊是一个基于功能齐全的编程语言构建的众多去中心化区块链应用的平台。
下面来解读一下这句话:
- 平台:首先以太坊是一个平台,这个平台上面有很多应用。
- 应用:这些应用是是去中心化的,基于区块链技术。所以这些应用可以实现永不停歇,因为它是分布式的,去中心化的,基于P2P网络的,这些应用被管理在以太坊钱包上面。
- 钱包:以太坊钱包,本质上以太坊钱包也是其中一个应用,它是一个网关,可以管理所有基于以太坊平台的应用,它可以让你持有或者保护以太币或其他建立在以太坊上的加密资产。以太坊钱包也可以实现直接对智能合约的写入、部署以及使用。
- 区块链:以太坊区块链是一条强大的,分享型的,全球性的基础设施,用来证明财产的归属者以及财产的交易流向。通过这一条链,可以实现众多应用,开发者可以创建交易所、存储债务登记以及证实各种允诺等应用玩法。这些应用可以对各种实体期货进行交易,避免中间人攻击以及交易对方欺骗。
- 智能合约:这些应用是使用一个功能齐全的编程语言构建的,这个语言指的是智能合约,而智能合约无疑是采用Go语言开发的。智能合约是这些应用的“驱动”,通过智能合约,应用可以完全按照编程所写去执行,而不会涉及downtime,审查,欺骗以及第三方干扰。
关于以太坊钱包,官方有一句话是 It allows you to hold and secure other crypto-assets built on Ethereum, 以太坊允许你持有和保护基于以太坊的加密资产,那么第一个问题这个加密资产是否可以自行创建?加密资产是否也可以是类似于以太币的电子货币?是的是的,完全可以,下面我们将具体介绍。
加密货币
使用智能合约的一种新语言Solidity,设计并发行你自己的加密货币。
上面讲到了各种实体期货以及以太币等资产,那么如果我想在以太坊平台上建立一个应用,应用内部的交易使用我自己的加密货币呢?这个加密货币可以代表真实世界的商品。这种加密货币会调用以太坊统一的虚拟币接口,从而让基于自定义货币的合同均可以兼容以太坊钱包,其他合同和交易也均采用这套接口。接着,对于你发行的加密货币是可以设置一个固定的总数或者一个基于某写规则而浮动的数量。在以太坊中,你可以:
- 构建一种货币可以交易,同时可设定他们的发行量。
- 构建一个中心化银行来发行货币。
- 设计一种基于难题的加密货币。
请参考详细开发文档
众募
如果你已经有想法并准备在以太坊上面做点什么,但是缺乏启动资金。同样可以使用以太坊,创建一个合同来募集贡献者的资金直到达成某种目标。根据成果,这笔钱要么被发放到项目拥有者手里要么原路返还给贡献者们。所有的过程不需要中间的仲裁人,票据交换所或者不确信的对他人的信任。对了,你甚至可以使用上面你自己创建的加密货币来追踪对贡献者的报酬。通过以太坊,你可以:
- 通过预售一件产品募集到一笔资金,哪怕这个产品还仅是在雏形阶段。
- 通过出售一个区块链组织里的虚拟分享来募集资金。
- 拍卖有限数量的物品。
请参考详细开发文档
众筹crowdfund和众募crowdsale的区别?
Crowdfunding简单点就是你有个想法,然后通过团购和预售(一些实际商品或者一些承诺把你名字放在电影啥的等)的方式募集项目资金。
crowdsale 也叫ICO (Initial Coin Offering)是很多区块链项目, 在项目正式推出之前销售token,旨在为这个项目的开发筹集资金,也可以拿来测试大众对产品的兴趣。在许多情况下,在crowdsale买了token后会被拿到公开市场上购买和出售,会获得独立于应用程序自己的市场价值。这也是吸引早期adopter的一种方法,他们相信这个token的价值,有升值空间. 还有和Crowdfunding不一样的是,crowdsale能够让那些投资者很快将持有的token在数字货币交易所中进行交易。而且token流动性极强的优势也会导致项目估值产生更好的溢价。区块链行业中最有名的Crowdsale是2014年9月的以太坊,大概筹集了价值1800万美元的比特币。
引用自知乎
民主
实际上就是一个投票系统。
创建一个自治组织,有规则来约束如何花钱以及帮助你或者其他投资者做决定。
现在,你有了自己的想法和有担保的资金,也有了自己发行的货币,你可能是时候需要雇佣一个可信的财务官来帮助你管理账户,组织董事会以及一堆的文书工作。然而,你可以将这些工作全都交给以太坊智能合约,它将收集你的支持者们的提议书,并通过一个完全透明可信的投票流程提交他们。
这相当于你拥有了一个机器人来帮助你打理一切,这其中最重要的一个好处就是:
可以免疫外部影响,只会依照你自己编写的程序代码坚决执行。而且因为以太坊网络的去中心化特性,你将能够获得7*24小时百分百的全时线上服务保证。
通过以太坊,你可以实现:
- 一个虚拟的组织,组员们可以公平投票来处理问题。
- 一个透明的协会基于股东们的投票。
- 你自己的国家,拥有一个不变的宪法。
- 一个更好的协商民主。
以太坊环境搭建
这里通过github下载源码进行搭建,ethereum地址:
git clone https://github.com/ethereum/go-ethereum && cd go-ethereum
构建geth命令:
make geth
构建所有工具:
make all
完整工具包包括:abigen bootnode ethereumwallet evm faucet geth mist puppeth rlpdump swarm wnode
安装工具
sudo ln -s $PWD/build/bin/* /usr/local/bin/
将编译好的所有工具软连接到/usr/local/bin目录下,该目录本身就在PATH环境变量下,所以我们可以在任意位置使用这些刚刚编译好的工具了。
每次对工具的编译,尤其是geth,都是调试的方式。
geth(go ethereum)
以太坊主要的命令行客户端工具。它是以太坊网络(可以是私有、公有或者测试网络)的一个入口点。能够作为一个完整的节点(默认)、存档节点(保存所有历史状态)或一个轻型节点(检索存活数据)。它可以被其他进程通过在JSON RPC在HTTP、WebSocket或IPC传输协议顶端暴露端点,作为进入以太坊网络的网关。
abigen(ABI生成器)
ABI(Application Binary Interface) 应用二进制接口,在以太坊生态系统中,它是一个标准的用来与合约交互的方式。交互包括区块链外部以及合约之间的交互。数据依据它的类型会被编码,正如本规范中的描述那样。编码不是自我描述,因此需要一个模式来解码。
源码生成以太坊合约定义转变为易于使用,编译时类型安全的Go包。它可以操作在以太坊Solidity用于扩充功能。然而它也接受Solidity源文件,让开发更加流水线化。记住abigen就是与Solidity相关的工具命令。Solidity上面也提到过,是设计并发行自己的加密货币的一种语言。
bootnode(轻型引导节点)
精简版的以太坊客户端实现,只加入网络节点发现协议,但不能运行其他更高级别的应用协议了。它可以被用作一个轻型的引导节点,旨在私有网络中寻找节点。
evm(以太坊虚拟机)
开发者工具版本的以太坊虚拟机。通过一个可配置的环境和执行模式,能够运行字节码片段。它的目的在于允许完全孤立不影响其他,细粒度地调试操作码。例如evm --code 60ff60ff --debug
gethrpctest(geth rcp test工具)
开发实用工具,支持我们的以太坊/RPC测试套件。这些套件能够校验基线符合以太坊JSON RPC规范。详情请参阅测试套件的readme。
rlpdump(RLP转储)
转储请参考之前的一篇博文
开发实用工具,可将二进制RLP(递归长度前缀)转储(以太坊协议网络以及共识使用的数据编码)至用户友好的分层表示(例如,rlpdump --hex CE0183FFFFFFC4C304050583616263)
swarm
swarm 是一个分布式存储平台和内容分发服务。
swarm守护程序和工具。这是一个swarm网络的入口点。通过swarm --help可以查看命令行选项以及子命令。 详情参见swarm文档
puppeth
一个CLI(Command Line Interface for batch scripting,命令行界面)的向导程序,旨在创建一个新的以太坊网络。
geth详解
geth是以太坊最主要的一个客户端命令行交互接口,由以太坊源码编译而成,直接运行在客户端终端(我们一般都会将geth命令放到PATH里,在任何位置都可以使用该命令)。
geth都可以干嘛呢?下面看一下geth都有什么子命令。
- account: 账户管理
- attach: 连接到JavaScript交互环境
- bug: 打开一个新窗口报告geth库的bug
- console: 开启一个JavaScript交互环境
- copydb: 从一个目标莲数据文件夹拷贝到本地的链上
- dump: 从存储中删除掉一个指定的区块
- dumpconfig: 显示配置值
- export: 导出区块链到文件
- import: 从文件导入区块链
- init: 通过一个向导初始化一个新的创世区块(genesis block!)
- js: 执行一个指定的JavaScript文件
- license: 展示许可信息
- makecache: 生成ethash校验缓存(用于测试),ethash是以太坊的计划性的PoW(工作量证明)算法。
- makedag: 生成ethash挖矿DAG(用于测试),DAG是一个比特币的扩容方案
- monitor: 监控使节点权值可视化
- removedb: 除去区块链和状态数据库
- version: 打印版本号
- wallet: 管理以太坊预售钱包
上面提到了一个重要的信息:JavaScript交互环境。
JavaScript交互环境
console命令可以进入一个JavaScript交互环境,也可以使用geth --exec选项加入要执行的JavaScript命令在外部执行。
这里主要介绍直接进入JavaScript控制台的操作,在这个控制台中,你可以使用web3.js的方法通过JSON RPC调用所有的以太坊API
- web3.js 是以太坊源码中提供的一套基于JS的SDK,开发者可以在终端JavaScript控制台亦可以在自己的浏览器网页中调用web3.js,可以执行以太坊所有的相关操作。
- geth自己的管理API,是在JavaScript控制台中可以直接使用并且自带命令提示的一套工具。
注意:管理API实际上只是web3.js的部分成员的外露而已,这些成员包括admin,debug,miner,personal,txpool五个命令,实际上对应的就是web3.(admin,debug,miner,personal,txpool)。
JSON-RPC
JSON-RPC是一个无状态轻量级的RPC远程程序调用协议。web3.js是通过该协议直接调用了源码的api方法。
由此可知,我们不必太关心已封装好的JSON-RPC协议的内容(除非你想了解细节),在使用geth console的时候:
- 如果涉及到admin,debug,miner,personal,txpool五个命令,可以查看geth管理API即可。
实际上我们只要看web3.js的文档就足够了,因为geth管理API也包含在其中。
除了介绍的这些子命令外,geth命令以及各种子命令都有自己的选项属性,下面简介一些geth命令使用的选项组合。
建立在以太坊主网的完整节点
目前为止,用户希望通过一种交互手段在以太坊主网上面进行一些操作,例如建立账户,转账,部署与调用智能合约。对于这些个别的用法,用户并不在意历史数据,所以我们可以快速同步到当前网络中去,命令如下:
geth --fast --cache=512 console
这条命令可以做以下三件事:
- --fast: 使用fast模式打开geth的客户端交互控制台。fast模式下,只会下载与转账相关的区块,而不是完全下载所有的区块链历史。
- --cache: 将数据库的内存限额调到512MB,可以显著增加同步时间,尤其是机械硬盘用户。这个参数是可选的,512的值你也可以设定高一些或者低一些,建议在512MB - 2GB之间。
- console: 启动geth内置的可交互的JavaScript控制台,进入该控制台,你可以调用所有的web3.js的函数(它与geth自己的API)。
通过下面的命令你可以随时加入一个已经在运行的geth实例:
geth attach
建立在以太坊测试网络的完整节点
面向开发者,如果你想试试创建一个以太坊合约,你肯定需要用假的货币交易来测试你的代码,直到你将你的合约真正发布到以太坊主网上。换句话说,你不会加入以太坊主网,而是你想让你的节点加入一个测试网络,这个测试网络的环境与以太坊主网是完全一样的,只是使用的是假的以太币。加入测试网络的命令如下:
geth --testnet --fast --cache=512 console
参数fast和cache,子命令console在上面主网络都介绍过,这些内容在测试网络与主网络完全一样。下面仔细研究一下--testnet参数,它会重新配置你的geth实例。
- 正常主网络的会使用默认地址:/.ethereum,而测试网络使用的默认地址为:/.ethereum/testnet。
注意这里面在使用geth attach的时候,linux需要改为geth attach
/testnet/geth.ipc。
- 不会连接到以太坊主网络上,客户端将连接到测试网络,测试网络使用的是不同的P2P向导节点,不同的网络ID以及不同的genesis状态。
源码api
经过查看,源码的api位置有很多,包括:
- node/api.go
- eth/api.go
- eth/downloader/api.go
- eth/filters/api.go
- consensus/clique/api.go
- contracts/chequebook/api.go
- internal/debug/api.go
- whisper/whisperv2/api.go
- whisper/whisperv5/api.go
- whisper/whisperv6/api.go
- swarm/api/api.go
- internal/ethapi/api.go
通过这些api文件,我们可以找到所有的web3.js(开放了一部分给geth管理API)调用的相关方法。
测试环境
- github下载相应版本源码,make all或者仅make geth
- 本地找一个位置统一管理本地node(例如我的是work/node/lwbtestnode目录)
- geth --datadir node0(自定义节点名) account new ,通过这条命令连续创建两个node
- 本地采用刚刚建好的node进入测试网络,geth --datadir node0 --testnet --fast --cache=512 console,(注意,当你启动第二个节点的console的时候,会提示你端口已占用,此时要再加入一个参数--port 30001指定一个其他的端口号即可)
- 现在两个节点都在本地以太坊测试环境启动了console,让我们先来查看各自的一些信息并相互添加peer,admin.nodeInfo.enode命令查看当前节点的enode信息,在另一个节点的console也查出该信息,然后使用admin.addPeer("刚查到的另一个节点的enode"),然后使用命令net来查看peer数量,为1即正确。
- 然后再查一下当前节点的eth信息,以太币余额命令为:web3.fromWei(eth.getBalance(eth.accounts[0])),wei是以太币最小的单位,如果要转换成以太币,需要使用web3.fromWei函数来处理。
- 经过以上操作,两个新节点已经互为peer,同时他们的余额都是0,下面让其中一个进行挖矿工作:miner.start(),可以看到随着挖矿顺利进行,另一个console中也在不断地同步(共识)区块消息。
- 停止挖矿,查看当前节点的余额,已经不再是0了,我这边是停在了80个以太币(这个以太币都是测试用的,不是真的以太币),另一个节点由于没有挖矿余额还是0。
- 下面我们来做转账操作,转账操作是在余额为80的账户里做:
var sender = eth.accounts[0]
var receiver = "另一个节点的eth.accounts[0]"
var amount = web3.toWei(9,"ether") //转9个以太币,但是是通过Wei来做
personal.unlockAccount(eth.accounts[0]) //交易前先将转账发送账户解锁
eth.sendTransaction({from:sender, to:receiver, value:amount})// 正式转账事务提交
10,此时转账事务已提交但未生效,所以我们查看两个节点的余额仍未发生变化。
11,下面继续挖矿,(注意,挖矿是记账的机制,但挖矿不完全为了记账,而记账必须通过挖矿,所以挖矿是记账的必要非充分条件)
12,当前状态下,启动挖矿的第一个区块就应该包含了我们上面的转账记录,所以不必挖矿太久即可停止。我们再看一下当前余额为86。
为什么不是80-9=71呢,是因为后来挖矿又产生了新的以太币报酬,所以余额反而增加了。
13,那么如何验证我们的转账是否正确呢?我们去看另一个原来余额是0的节点,检查当前余额为9,说明它作为转账接收者已成功接到了以太币。
总结
本文针对以太坊进行了初步的研究,包括背景概念,环境搭建,源码跟踪,事务处理等。而关于挖矿源码实现、共识算法,p2p网络源码以及发布自己的web3接口,都是中级篇需要研究的内容。
参考资料
- 文中出现的各种链接。