区块链导航系列-以太坊
磨链(mochain)区块链技术社区整理(投河自尽的鱼、虞是乎、盖盖)
区块链导航也是一个入门区块链的入门学习路线。下图是一个区块链相关内容的整理分享,内容还是比较繁琐,当然在学习区块链的过程中并不需要那么复杂。钻研琢磨某些方面可能对这个学习过程更为深刻。
(所有内容不需要科学上网,当然通过科学上网能获取更多信息,这里暂时只收录了不通过科学上网能获取的内容)
磨链社区-区块链导航目录:
以太坊相关导航
以太坊(Ethereum)是一个开源的有智能合约功能的公共区块链平台。通过其专用加密货币以太币(Ether)提供去中心化的虚拟机(“以太虚拟机” Ethereum Virtual Machine)来处理点对点合约。
下面图示以太坊相关导航:
Solidity
Solidity 是面向智能合约的高级编程语言,它的设计受 C++、Python和JavaScript影响,旨在针对以太坊虚拟机(EVM)。Solidity 是静态类型语言,支持继承,库和复杂的自定义类型等功能。
或者这么理解:Solidity是用于编写在以太坊区块链上运行的智能合约的最流行的编程语言。 它是一种高级语言,当编译转换为EVM字节码。 这与Java非常相似,其中有诸如 Scala,Groovy,Clojure,JRuby等JVM语言。所有这些编译都生成在JVM(Java虚拟机)中运行的字节码。
Remix
Remix 基于浏览器的IDE,含编译器和运行环境,无需服务端组件。以太坊官方推荐的智能合约开发IDE。
Truffle
Truffle是用于开发以太坊DApps的最常用的框架。 抽象出在区块链上编译和部署合同的许多复杂的东西。
Parity
Parity 是对以太坊协议的另一个很好的实现,并且是用Rust编程语言编写的。 这是一个由一家名为Parity Inc的公司来维护的非官方客户端。任何人都可以实现这个客户端软件,并加入以太坊网络。
Web3.js
javascript库,可以用来与一个节点进行交互。 由于它是一个 JavaScript 库,您可以使用它来构建基于Web的dapps。
网络学习资料
以太坊学习目录
以太坊简介
智能合约
内部账户与外部账户
Gas
以太坊客户端
测试网络
钱包
交易
共识算法
以太坊标准
深入理解EVM
DApps
以太坊开发环境
重点代码剖析
Solidity简介
以太坊开发实战
常见问题内容(来自ethereum.mochain.info精通以太坊)
基础相关概念
区块链基础知识
对于程序员来说并不难理解区块链(Blockchains)这个概念,这是因为大多数难懂的东西(挖矿(mining), 哈希函数(hashing), 椭圆曲线密码学(elliptic-curve cryptography), 点对点网络(peer-to-peer networks, 等等)是提供些功能和约定。你只需接受这些既有的特性功能,不必关心底层技术,就想你难懂必须知道亚马逊的 AWS 内部原理,你才能使用它吗?
交易/事务 Transactions
区块链是全球共享的事务性数据库,这意味着每个人都可加入网络来阅读数据库中的记录。如果你想改变数据库中的某些东西,你必须创建一个被所有其他人所接受的事务(Transaction)。事务一词意味着你想做的(假设您想要同时更改两个值)要么一点没完成,要么完完全全生效。此外,当你的事务被应用到数据库时,其他事务不能修改数据库。
举个例子,设想一张表,列出电子货币中所有账户的余额。如果请求从一个账户转移到另一个账户,数据库的事务特性确保了如果从一个账户扣除金额,它总被添加到另一个账户。如果由于某些原因,无法添加金额到目标账户时,源账户也不会发生任何变化。
区块 Blocks
要解决的主要难题,在比特币中被称为“双花攻击 (double-spend attack)”:如果网络存在两笔交易,都想花光同一个账户的钱时(即所谓的冲突)会发生什么情况?
简单的回答是你不必在乎此问题。交易会被排序,并打包到所谓的“块”中,然后它们将在所有参与节点中执行和分发。如果两笔交易相冲突,最后一笔交易将被拒绝,而不成为该块的一部分。
这些块按时间形成了一个线性序列,这正是“区块链”这个词的来源。区块以一定规律的时间间隔添加到链上 - 对于以太坊,这间隔大约是17秒。
作为“顺序选择机制”(也就是所谓的“挖矿”)的一部分,可能会发生这样的情况:块不时地被回滚,但只发送在区块链的“顶端”。在顶端涉及回滚区块越多,其发生的概率越小。所以你的交易有可能被回滚,甚至从区块链中抹除,但你等待的时间越长,这种情况发送的概率就越小。
以太坊虚拟机
总览
以太坊虚拟机 EVM 是智能合约的运行环境。它不仅是沙盒封装的,而且是完全隔离的,也就是说在 EVM 中运行代码是无法访问网络、文件系统和其他进程的。合约与其他合约也是只有有限接触。
账户
以太坊中有两类账户,共用同一个地址空间。外部账户,该类账户被公钥-私钥对控制(人类)。合约账户,该类账户被存储在账户中的代码控制。
外部账户的地址是由公钥决定的,而合约账户的地址是在创建该合约时确定的(这个地址由合约创建者的地址和该地址发出过的交易数量计算得到,地址发出过的交易数量也被称作”nonce”)。
无论帐户是否存储代码,这两类账户对 EVM 来说是一样的。
每个账户有一个key-value形式的持久化存储。其中key和value的长度都是256比特,名字叫做 storage。
此外,每个账户有一个以太币余额(单位是”Wei”),能够通过向它发送含以太币的交易来改变。
交易
交易即消息,从一个账户到另一个账户(这可能是相同的或零帐户,见下文)。它能包含一个二进制数据(称 payload)和以太币。
如果目标账户含有代码,此代码将以 payload 作为入参所执行。
如果目标账户是零账户(账户地址为 0),此交易将创建一个新合约。如前所说,合约地址不是零地址,而是由合约创建者的地址和该地址发出过的交易数量(被称为nonce)计算得到。此交易中的 payload 作为 EVM 字节码所执行。执行结果作为合约代码被永久存储。这意味着,为创建一个合约,你不需要向合约发送真正的合约代码,而是发送能够返回真正代码的代码。
Gas
一经创建,每笔交易都收取一定数量的 gas,目的是限制执行交易所需要的工作量和为交易支付手续费。EVM 执行交易时,gas 将按特定规则逐渐耗尽。
gas price 是被交易发送者设置的一个数值,发送者账户需要预付的手续费= gas price*gas 。交易执行后会将剩余的 gas 返还。
无论执行到什么位置,一旦 gas 被耗尽(比如降为负值),将会触发一个 out-of-gas 异常。当前调用帧所做的所有状态修改都将被回滚。
译者注:即使交易回滚, gas 不会再返还给发送者。哪怕是失败,也是消耗了计算资源。
存储,内存和栈
每个账户有一块持久化内存区被称为存储(storage)。其形式为key-value,key和value的长度均为256比特。在合约中,不能遍历账户的存储,且存储的读操作相对开销高,修改存储开销更高。一个合约只能对它自己的存储进行读写。
第二个内存区称为主存(memory)。合约执行每次消息调用时,都分配一块新的,被清除过的主存。主存是线性的,可按字节级寻址,但读被限制为256比特长度,而写可以是8比特或256比特长度。当访问(读或写)一个从未接触及的值时,主存将以256比特扩容。扩容也将消耗gas。内存越大,开销就越高(平方级别)。
EVM 不是基于寄存器的,而是基于栈的,因此所有的计算都在一个被称为statck的区域执行。 栈最大有1024个元素,每个元素256比特。对栈的访问只限于其顶端,限制方式为:允许拷贝最顶端的16个元素中的一个到栈顶,或者是交换栈顶元素和下面16个元素中的一个。所有其他操作都只能取最顶的两个(或一个,或更多,取决于具体的操作)元素,并把结果压入栈顶。当然可以把栈上的元素放到存储或主存中。但是无法只访问栈上指定深度的那个元素,除非先从栈顶移除其他元素。
指令集
EVM的指令集量尽量少,以尽可能避免可能导致共识问题的错误实现。所有的指令都是针对256比特这个基本的数据类型的操作。具备常用的算术、位、逻辑和比较操作。也可以做到有条件和无条件跳转。此外,合约可以访问当前区块的相关属性,比如它的编号和时间戳。
消息调用
合约可以通过消息调用的方式来调用其它合约或者发送以太币到非合约账户。消息调用和交易非常类似,它们都有一个源、目标、数据、以太币、gas和返回数据。事实上每个交易都由一个顶层消息调用组成,这个消息调用又可创建更多的消息调用。
一个合约可以决定剩余 gas的分配。比如内部消息调用时使用多少gas,或者期望保留多少 gas 。如果在内部消息调用时发生了 out-of-gas 异常(或者其他异常),将会把错误信息将被压如栈顶。这种情况只是内部消息调用的 gas 耗尽。在 Solidity 中,这种情况下发起调用的合约默认会触发一个辅助异常,此异常会打印出调用栈。
正如之前所说,被调用的合约(发起调用的合约也一样)会拥有崭新的主存并能够访问调用 payload - 存储在一个独立的被称为 calldata 的区域中。调用执行结束后,返回数据将被存放在调用方预先分配好的一块内存中。
调用深度被限制为 1024 ,因此对于更加复杂的操作,我们应使用循环而不是递归。
委托调用/代码调用和库
存在一种特殊类型的消息调用,被称为 委托调用(delegatecall)。除了目标地址的代码将在发起调用的合约上下文中执行,以及msg.sender 和 msg.value 不改变外,它跟消息调用一样。
这意味着一个合约可以在运行时从另外一个地址动态加载代码。存储、当前地址和余额都指向发起调用的合约,只有代码是从被调用地址获取的。
这使得 Solidity 可以实现”库“能力:可复用的代码库可以应用在一个合约的存储上,如用来实现复杂的数据结构。
日志
在区块层级上,可用一种特殊的可索引的数据结构来存储数据。这个特性被称为日志(logs),Solidity用它来实现事件(events)。合约创建之后就无法访问日志数据,但是这些数据可以从区块链外高效的访问。因为部分日志数据被存储在布隆过滤器(Bloom filter) 中,我们可以高效并且安全的搜索日志,所以那些没有下载整个区块链的网络节点(轻客户端)也可以找到这些日志。
创建
合约甚至可以通过一个特殊的指令来创建其他合约(不是简单的向零地址发起调用)。创建合约的调用create calls*)跟普通的消息调用的区别在于,payload 数据执行的结果被当作合约代码,调用者/创建者在栈上得到新合约的地址。
自毁
只有在某个地址上的合约执行自毁操作 selfdestruct 时,合约代码才会从区块链上移除。合约账户上剩余的以太币会发送给指定的目标,然后其存储和代码被移除。
一个简单的智能合约
如果你智能合约知之甚少,那从些简单的示例开始是必要的,更多细节后续再讲讲。
存储
pragma solidity ^0.4.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public constant returns (uint) {
return storedData;
}
}
首行简洁的说明该源代码为Solidity 0.4.0版本编写或兼容新版本(直到但不包含0.5.0版本)。已确保合约不会与新版编译器有突异行为。被用关键字pragma原因是,一般编译指令是告知编译器该如何对待源代码(如:pragma once(编译一次))。
一份Solidity所示合同就是一组代码(称为方法)合集和数据(称为状态),而数据位于以太坊区块链上特点地址上。行uint storedData;声明了一个类型为unit(无符号256位整数)的状态变量,名为storeData。你可将其想象为在数据库上的单个插槽,能通过调用管理数据库的代码来访问与修改。在以太坊下,它始终属于合约。这个示例中,方法set和get就能修改和获得此变量值。
为访问状态变量,无需借助这个在其他语言常见的前缀this.。
除允许任何人存储存储一个任何人都可访问的数字,而没有(可行的)方法类阻止你发布这个数字,这个合约做的还远远不够(基于以太坊建立基础设施)。当然,任何人只需再次用不同的值调用set就可覆盖这个数字。但是这个数字仍被存储在区块链的历史记录中。稍后我们来看看如何加强访问限制,以便只有你才能改变它。
提醒
所有标识符(合约名,函数名和变量名)都被限制为 ASCII 字符集。可以将 UTF-8 格式数据存储在字符串变量中。
当心 Unicode 字符
看着很像(甚至一样)的 Unicode 字符是由不同的代码表示的,因此会被编码称不同的字节数组。
子币示例
下面的合约将实现简单版加密货币。可以凭空创建币,但是只有创建这个合约的人才可这样做(实行不同的发行计划是微不足道的)。此外,任何人可以发送币到其他人而不需要使用用户名和密码注册 - 你仅需要一个以太坊密钥。
pragma solidity ^0.4.0;
contract Coin {
// The keyword "public" makes those variables
// readable from outside.
address public minter;
mapping (address => uint) public balances;
// Events allow light clients to react on
// changes efficiently.
event Sent(address from, address to, uint amount);
// This is the constructor whose code is
// run only when the contract is created.
function Coin() 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;
Sent(msg.sender, receiver, amount);
}
}
此合约涉及些新概念,让我们一个个过下。
行 address public minter; 声明一个类型为 address 的状态变量可公开访问。address类型是一个 160 比特值,不允许任何计算操作。它适合存储合约地址或外部人员的密钥对地址。关键字 public 会自动生成一个方法,允许访问外部访问此状态变量当前值。没有此关键字,其他合约就无法访问此变量。这个方法形同如下:
function minter() returns (address) { return minter; }
当然,显示地添加类似的上面的方法是行不通的,因为方法名和状态名相同。可还是望你试试 - 编译器会为你指出错误的。
下一行 mapping (address => uint) public balances; 同样是声明了一个公共的状态变量,但是是一个更复杂的数据类型。 类型将地址映射到无符号整数。mapping 可看成是一个 哈希表 ,它被虚拟初始化后使得每个键 key 都存在被映射到字节全为零的值 value。但此比喻并不严谨,因为即不能获取 mapping 下键列表,也无法获取值列表。所以要记住(或更好,保留一个列表或使用更高级的数据类型),你在添加到 mapping 或在不需要地情况下使用它,就像这个 getter function 由 public 关键字生成的访问函数将会更加复杂,其代码大致如下:
function balances(address _account) public view returns (uint) {
return balances[_account];
}
如你所见,你可使用此方法轻松查询单帐户余额。
行 event Sent(address from, address to, uint amount); 声明一个被称之为 “event” 在方法 send 中末尾行触发。客户端(当然也包括服务器应用程序)可以在没有太多成本的情况下监听在区块链上被触发的事件。一旦事件被触发,监听方就可以接受到 from、to 和 amount这些参数,可轻松跟踪交易。为监听此事件,你可这样使用:
Coin.Sent().watch({}, '', function(error, result) {
if (!error) {
console.log("Coin transfer: " + result.args.amount +
" coins were sent from " + result.args.from +
" to " + result.args.to + ".");
console.log("Balances now:\n" +
"Sender: " + Coin.balances.call(result.args.from) +
"Receiver: " + Coin.balances.call(result.args.to));
}
})
注意,在客户端中是如何调用自动生成的方法 balances。
特殊的方法 Coin 是运行创建合约的构造函数,之后就不能被调用。它会永久存储合约创建人地址: msg (以及 tx 和 block )是神奇的全局变量,包含些可访问的区块链的属性。 msg.sender 总是存放着当前(外部)方法调用方地址。
最后,真正被用户或其他合约所调用的,以完成本合约功能的方法是 mint 和 send。 如果 mint 被合约创建者外的其他人调用则什么也不发送。另一方面,send 能被任何人(已有些币的)发送币给其他人。记住,如果你使用合约发送币给一个地址,当你区块链浏览器上查看该地址时是看不到任何信息的。因为实际上你发送币和更改余额这仅仅存储在特定合约的数据存储器中。通过使用事件,我们可容易地创建一个跟踪合约的交易和余额的“区块链浏览器”。
安装基本环境
安装Go Ethereum (geth)
简介
Go Ethereum 是以太坊区块链项目的三个原始实现(以及 c++ 和 python )之一,使用 Go 语言实现,完全开源并使用开源协议 GNU LGPL v3 许可。 geth 是简称,也是可执行程序的默认名称。
项目主页:https://ethereum.github.io/go-ethereum 。
安装
可以使用多种途径安装 geth 可通过源代码或者二进制包安装。下面简要介绍安装,更多细节请浏览 geth 的英文版安装指引。
独立安装包安装
已提供 geth 各平台独立安装包软件,从官方下载安装。
从包管理器安装
在 mac 操作系统上使用 Homebrew 安装,Ubuntu 上使用 PPAs 安装。
在 Ubuntu 上安装
在 Ubuntu 上使用包管理器 PPAs 安装,先添加库:
sudo add-apt-repository -y ppa:ethereum/ethereum
此时便可安装最新稳定版的 Go Ethereum :
sudo apt-get update
sudo apt-get install ethereum
如果你想尝鲜使用开发版本,则只需执行:
sudo apt-get update
sudo apt-get install ethereum-unstable
在 Mac 上安装
在 Mac 操作系统上使用包管理器 Homebrew 安装,如果无此工具,请先安装。因为 geth 涉及到多个依赖安装,故先 tap 再安装。
brew tap ethereum/ethereum
brew install ethereum
可通过参数--devel直接安装开发版本(可选)
brew install ethereum --devel
安装完成后,可执行命令geth version查看版本信息,结果如下:
Geth
Version: 1.6.7-stable
Git Commit: ab5646c532292b51e319f290afccf6a44f874372
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.9
Operating System: darwin
GOPATH=/Users/one/Documents/dev/go
GOROOT=/usr/local/Cellar/go/1.9/libexec
下载 Docker 镜像
也可以直接使用以准备的 Go Ethereum 镜像环境,直接在 Docker 容器中运行 geth。
下面拉取 geth 镜像:
docker pull ethereum/client-go:latest
运行以太坊私有链
初始化创世区块
首先需要为私有链定义一个创世状态,使用 JSON 文件定义,例如取名为:genesis.json,内容如下:
{
"config": {
"chainId": 88,
"homesteadBlock": 0,
"eip155Block": 0,
"eip158Block": 0
},
"alloc" : {},
"coinbase" : "0x0000000000000000000000000000000000000000",
"difficulty" : "0x20000",
"extraData" : "",
"gasLimit" : "0x2fefd8",
"nonce" : "0x0000000000000042",
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
"timestamp" : "0x00"
}
保存到任意位置,例如 $HOME/genesis.json,
初始区块是区块链的起始 — 第一个区块,区块0,唯一没有指向前面区块的一个区块。协议确保其他连接你的节点必须和你的创世块一致,除非他们和你有相同的初始区块,这样你想创建多少私有测试网区块链,就可以创建多少!
执行初始化:
geth init $HOME/genesis.json
执行后,将提示成功初始化创世区。
WARN [03-10|17:50:20] No etherbase set and no accounts found as default
INFO [03-10|17:50:20] Allocated cache and file handles database=/Users/.../Library/Ethereum/geth/chaindata cache=16 handles=16
INFO [03-10|17:50:20] Writing custom genesis block
INFO [03-10|17:50:20] Successfully wrote genesis state database=chaindata hash=5e1fc7…d790e0
INFO [03-10|17:50:20] Allocated cache and file handles database=/Users/.../Library/Ethereum/geth/lightchaindata cache=16 handles=16
INFO [03-10|17:50:20] Writing custom genesis block
INFO [03-10|17:50:20] Successfully wrote genesis state database=lightchaindata hash=5e1fc7…d790e0
初始化账号
运行命令创建账户,运行时将自动提示输入密码:
geth account new
WARN [03-10|17:53:03] No etherbase set and no accounts found as default
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {eac0e62d4faa273918770205a4b0e5f271e1ce23}
创建成功后,将在末尾行显示账户地址eac0e62d4faa273918770205a4b0e5f271e1ce23。
虽然此账户可以在以太坊的JavaScript控制台中生成,但我一般直接通过命令工具生成,关于geth account命令还有更多信息:
SAGE:
geth account [options] command [command options] [arguments...]
COMMANDS:
list 汇总打印所有账号
new 创建一个新账号
update 更新已存在的账户
import 导入私钥生成新的账号
help, h 帮助
geth account list
你应该可以看到上面所创建的账号。
Account #0: {eac0e62d4faa273918770205a4b0e5f271e1ce23} keystore:///Users/ysqi/Library/Ethereum/keystore/UTC--2018-03-10T09-53-08.639057000Z--eac0e62d4faa273918770205a4b0e5f271e1ce23
表明账号的私钥保存在keystore文件夹下。
进入控制台¶
geth 提供了可交互的控制台,是一个 js 环境,可调用 geth 的一些 API。
geth --networkid 9999 console
运行命令,将进入控制台,打印出如下信息。该信息非常重要。能告诉你运行时环境与配置信息。
Allocated cache and file handles 缓存存放目录
Disk storage enabled for ethash caches 数据存放目录
Disk storage enabled for ethash DAGs DAG数据存放目录
IPC endpoint opened IPC地址,重要,关系到后续以太坊钱包的链接
INFO [09-09|10:40:36] Starting peer-to-peer node instance=Geth/v1.6.7-stable-ab5646c5/darwin-amd64/go1.9
INFO [09-09|10:40:36] Allocated cache and file handles database=/Users/one/Library/Ethereum/geth/chaindata cache=128 handles=1024
WARN [09-09|10:40:36] Upgrading chain database to use sequential keys
INFO [09-09|10:40:36] Database conversion successful
INFO [09-09|10:40:36] Initialised chain configuration config="{ChainID: 15 Homestead: 0 DAO: DAOSupport: false EIP150: EIP155: 0 EIP158: 0 Metropolis: Engine: unknown}"
INFO [09-09|10:40:36] Disk storage enabled for ethash caches dir=/Users/one/Library/Ethereum/geth/ethash count=3
INFO [09-09|10:40:36] Disk storage enabled for ethash DAGs dir=/Users/one/.ethash count=2
WARN [09-09|10:40:36] Upgrading db log bloom bins
INFO [09-09|10:40:36] Bloom-bin upgrade completed elapsed=68.449µs
INFO [09-09|10:40:36] Initialising Ethereum protocol versions="[63 62]" network=9999
INFO [09-09|10:40:36] Loaded most recent local header number=0 hash=bd0e7a…9aadd0 td=131072
INFO [09-09|10:40:36] Loaded most recent local full block number=0 hash=bd0e7a…9aadd0 td=131072
INFO [09-09|10:40:36] Loaded most recent local fast block number=0 hash=bd0e7a…9aadd0 td=131072
INFO [09-09|10:40:36] Starting P2P networking
INFO [09-09|10:40:38] UDP listener up self=enode://f28939fbbd6038c074f322b656f314250bbf7372523ee6d7d2fd6b67f86dba3f41cdf394ab3c57bd105cb96bec70337c6c19a09ca794b6f0c36c3d04119c7c39@[::]:30303
INFO [09-09|10:40:38] RLPx listener up self=enode://f28939fbbd6038c074f322b656f314250bbf7372523ee6d7d2fd6b67f86dba3f41cdf394ab3c57bd105cb96bec70337c6c19a09ca794b6f0c36c3d04119c7c39@[::]:30303
INFO [09-09|10:40:38] IPC endpoint opened: /Users/one/Library/Ethereum/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.6.7-stable-ab5646c5/darwin-amd64/go1.9
coinbase: 0xe7a614776754b7c7ef3a1ef6430d29e90411fd75
at block: 0 (Thu, 01 Jan 1970 08:00:00 CST)
datadir: /Users/one/Library/Ethereum
modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
能在控制台中执行多种命令,具体见官方文档:JavaScript-Console Wiki。 这是一个交互式的 JavaScript 执行环境,在这里面可以执行 JavaScript 代码,其中>是命令提示符。在这个环境里也内置了一些用来操作以太坊的Javascript对象,可以直接使用这些对象。这些对象主要包括:
eth:包含一些跟操作区块链相关的方法
net:包含以下查看p2p网络状态的方法
admin:包含一些与管理节点相关的方法
miner:包含启动&停止挖矿的一些方法
personal:主要包含一些管理账户的方法
txpool:包含一些查看交易内存池的方法
web3:包含了以上对象,还包含一些单位换算的方法
启动挖矿
如果你之前有部署运行过以太坊,请先将此目录下的DAG文件删除rm -rf $HOME/.ethash/。
参数说明
--nodiscover 使用这个命令可以确保你的节点不会被非手动添加你的人发现。否则,你的节点可能因为你与他有相同的创世文件和网络ID而被陌生人的区块链无意添加。
--maxpeers 0 如果你不希望其他人连接到你的测试链,可以使用maxpeers 0。反之,如果你确切知道希望多少人连接到你的节点,你也可以通过调整数字来实现。
--rpc 可激活你节点的 rpc 服务。它在 geth 中通常被默认激活。
--rpcapi "db,eth,net,web3" 决定允许哪些 API 开放 rpc 服务。在默认情况下只激活了 web3 api。
--rpcport "8080" 将8000改变为你网络上开放的任何端口。Geth的默认设置是8080.
--rpccorsdomain "https://yushuangqi.com" 这个可以指示什么URL能连接到你的节点来执行RPC定制端任务。务必谨慎,输入一个特定的URL而不是wildcard ( * ),后者会使所有的URL都能连接到你的RPC实例。
--datadir "/home/TestChain1" 这是你的私有链数据所储存在的数据目录(在nubits下)。选择一个与你以太坊公有链文件夹分开的位置。
--identity "TestnetMainNode" 这会为你的节点设置一个身份,使之更容易在端点列表中被辨认出来。这个例子说明了这些身份如何在网络上出现。
--networkid 1999 数字类型,区分与其他的网络ID,以太坊公链的网络ID=1。必须区分,以放置钱包等误认为是以太坊公链。 2=Morden (disused), 3=Ropsten, 4=Rinkeby,默认为1。
--port 30303 P2P网络监听端口,默认30303。
--fast 这个命令是 Geth1.6.0之前的,只会被改成--syncmode=fast,但该命令继续有效。配置此命令能够快速的同步区块。
--cache=1024 程序内置的可用内存,单位MB。默认是16MB(最小值)。可以根据服务器能力配置到56, 512, 1024 (1GB), or 2048 (2GB)。
如下命令启动待遇自定义配置的私有链:
geth --identity "OneTestETH" --rpccorsdomain "*" --nodiscover --rpcapi "*" --cache=1024 --networkid 9999 console
进入控制台后,可以启动矿工开始挖矿。
> miner.start(1)
这里的1表示只使用一个线程运行,如果配置过高,会导致电脑卡顿。
INFO [09-09|11:17:36] Updated mining threads threads=1
INFO [09-09|11:17:36] Transaction pool price threshold updated price=18000000000
INFO [09-09|11:17:36] Starting mining operation
null
> INFO [09-09|11:17:36] Commit new mining work number=1 txs=0 uncles=0 elapsed=134.574µs
INFO [09-09|11:17:38] Generating DAG in progress epoch=0 percentage=0 elapsed=1.051s
INFO [09-09|11:17:39] Generating DAG in progress epoch=0 percentage=1 elapsed=2.087s
INFO [09-09|11:17:40] Generating DAG in progress epoch=0 percentage=2 elapsed=3.129s
INFO [09-09|11:17:41] Generating DAG in progress epoch=0 percentage=3 elapsed=4.229s
......
INFO [09-09|11:19:24] Generating DAG in progress epoch=0 percentage=98 elapsed=1m47.287s
INFO [09-09|11:19:25] Generating DAG in progress epoch=0 percentage=99 elapsed=1m48.790s
INFO [09-09|11:19:25] Generated ethash verification cache epoch=0 elapsed=1m48.792s
INFO [09-09|11:19:29] Generating DAG in progress epoch=1 percentage=0 elapsed=1.365s
INFO [09-09|11:19:30] Generating DAG in progress epoch=1 percentage=1 elapsed=2.666s
INFO [09-09|11:19:31] Successfully sealed new block number=1 hash=19b30c…c712b6
INFO [09-09|11:19:31] 🔨 mined potential block number=1 hash=19b30c…c712b6
INFO [09-09|11:19:31] Commit new mining work number=2 txs=0 uncles=0 elapsed=421.087µs
第一次运行时将开始创建 DAG 文件,只需等待进度条到100,则将开始挖矿。 实际你看到的挖矿速度很快,这是因为我们已经在初始化创世区块时配置为:"nonce": "0x0000000000000042"。 “0x42”难度能可使得私有链上快速挖出以太币,几分钟就会有上百个以太币。
挖矿时需要指定挖矿收取奖励的以太坊账户,而系统默认使用创建的第一个账号。
如果不想停止挖矿,则执行:
> miner.stop()
停止后,可以查看将挖出不少以太币。在控制台中可查询矿工余额。
> eth.accounts
这会返回到你拥有的账户地址排列。
> eth.getBalance(eth.accounts[0])
这个控制台指令会返回到你第一个以太坊地址。因为我们只创建了一个账号,也将是矿工的账号。 而eth.getBalance()返回的余额是以太币的最小面额 wei。
> primary = eth.accounts[0]
> balance = web3.fromWei(eth.getBalance(primary), "ether");
将返回矿工的以太币余额,将 wei 转换为以太币 ether。
使用 Mist 钱包
自行下载以太坊钱包 Mist。
网友评论