《精通以太坊》( Mastering Ethereum )
https://github.com/ethereumbook/ethereumbook
《以太坊白皮书》(A Next一Generation Smart Contract andDecentralized Application Platform)
https://github.com/ethereum/wiki/wiki/White-Paper
《以太坊黄皮书》( 《以太坊:一种安全去中心化的通用交易账本拜占庭版本》)
以太坊官方文档( Ethereum Homestead Documentation )
http://www.ethdocs.org/en/latest/index.html
Solidity官方文档
https://solidity.readthedocs.io/en/latest/
涉及工具
以太坊是一个平台,使用者可以自定DApp,而本身具有交易功能
P2P网络
以太坊在以太坊主网络.上运行,该网络可在TCP端口30303.上寻址,并运行一个名为DEVp2p的协议。
交易(Transaction)
以太坊交易是网络消息,其中包括发送者(sender),接收者(receiver),值(value)和数据的有效载荷(payload)。
以太坊虚拟机(EVM)
以太坊状态转换由以太坊虚拟机(EVM)处理,这是一个执行字节码(机器语言指令)的基于堆栈的虚拟机。
数据库( Blockchain )
以太坊的区块链作为数据库(通常是Google的LevelDB)本地存储在每个节点上,包含序列化后的交易和系统状态。
客户端
以太坊有几种可互操作的客户端软件实现,其中最突出的是Go一Ethereum ( Geth)和Parity。
账户( Account)
包含地址,余额和随机数,以及可选的存储和代码的对象。
一普通账户(EOA),存储和代码均为空
合约账户(Contract) ,包含存储和代码
地址( Address)
一般来说,这代表一个EOA或合约,它可以在区块链上接收或发送交易。更具体地说,它是ECDSA公钥的keccak散列的最右边的160位。
交易(Transaction)
一可以发送以太币和信息
一向合约发送的交易可以调用合约代码,并以信息数据为函数参数
一向空用户发送信息,可以自动生成以信息为代码块的合约账户
gas
以太坊用于执行智能合约的虚拟燃料。以太坊虚拟机使用核算机制来衡量gas的消耗量并限制计算资源的消耗。执行智能合约需要消耗以太币
区块奖励( Block rewards)
每产生一个新区块就会有一笔固定的奖励给矿工,初始是5个以太币,现在是3个。
叔块奖励(Uncle rewards)
有些区块被挖得稍晚一些,因此不能作为主区块链的组成部分。比特币称这类区块为“孤块”,并且完全舍弃它们。但是,以太币称它们为“叔块”(uncles) ,并且在之后的区块中,可以引用它们。如果叔块在之后的区块链中作为叔块被引用,每个叔块会为挖矿者产出区块奖励的7/8。这被称之为叔块奖励。
叔块引用奖励(Uncle referencing rewards )
矿工每引用一个叔块,可以得到区块奖励的1/32作为奖励(最多引用两个叔块)
这样的一套基于POW的奖励机制,被称为以太坊的“幽灵协议”
随着以太坊发展,以太币供应量均匀上涨
普通区块收入
一固定奖励(挖矿奖励),每个普通区块都有
一区块内包含的所有程序的gas花费的总和
一如果普通区块引用了叔块,每引用一个叔块可以得到固定奖励的1/32
叔块收入
叔块收入只有一项,就是叔块奖励,计算公式为:
叔块奖励=(叔块高度+8一引用叔块的区块高度)*普通区块奖励/ 8
也就是一个区块引用叔块,获得3/32的区块奖励,而被应用的叔块自身获得3*(7/8)的奖励
为了防止无限循环的出现,采纳gas消耗机制
同时,以太坊可以构建去中心化应用
以太币单位:wei,1ether = 10^18wei
其他单位
值(wei) | 指数 | 通用名称 | SI名称 |
---|---|---|---|
1 | 1 | wei | wei |
1,000 | 10^3 | babbage | Kilowei or femtoether |
1,000,000 | 10^6 | lovelace | megawei or picoether |
1,000,000,000 | 10^9 | shannon | gigawei or nanoether |
1,000,000,000,000 | 10^12 | szabo | microether or micri |
1,000,000,000,000,000 | 10^15 | finney | milliether or milli |
1,000,000,000,000,000,000 | 10^18 | ether | ether |
1,000,000,000,000,000,000,000 | 10^21 | grand | kiloether |
1,000,000,000,000,000,000,000,000 | 10^24 | megaether |
私钥、公钥和地址
私钥(Private Key)
以太坊私钥事实上只是一个256位的随机数,用于发送以太的交易中创建签名来证明自己对资金的所有权。
公钥( Public Key)
公钥是由私钥通过椭圆曲线加密secp256k1算法单向生成的512位(64字节)数。
地址( Address )
地址是由公钥的Keccak一256 单向哈希,取最后20个字节(160位)派生出来的标识符。
私钥丢失会导致账户丢失,keystore文件是存储的私钥,要设置强密码
助记词可以导出私钥
一些以太坊环境
Main Network (NetworkID: 1 )
主要的、公共的、以太坊区块链。真正的ETH,真正的价值,真正的结果
Ropsten Test NetWork(Network ID:3)
以太坊公共测试区块链和网络,使用工作量证明共识(挖矿)。该网络上的ETH没有任何价值。
Kovan Test Network ( NetworkID: 42)
以太坊公共测试区块链和网络,使用“Aura”协议进行权威证明POA共识(联合签名)。该网络上的ETH没有任何价值。此测试网络仅由Parity支持。
Rinkeby Test Network ( Network ID: 4)
以太坊公共测试区块链和网络,使用“Clique"协议进行权威证明POA共识(联合签名)。该网络上的ETH没有任何价值。
Localhost 8545
连接到与浏览器在同一台计算机上运行的节点。该节点可以是任何公共区块链(main或testnet)的一部分,也可以是私有testnet。
Custom RPC
允许将Metamask连接到任意兼容geth的RPC接口的节点。该节点可以是任何公共或私人区块链的一部分。
gas price不能为0
无函数名为回退函数,也就是上面代码不执行就执行回退函数
通过科学上网工具登录remix工具可以进行合约的编写和部署
测试geth
geth --datadir ./data
搭建私链步骤
在geth/bin路径下创建genesis.json,我的路径是/usr/local/Cellar/ethereum/1.9.18/bin
然后在json文件中添加如下信息
{
"config": {
"chainId": 15
},
"difficulty": "2000",
"gasLimit": "2100000",
"alloc": {
"7df9a875a174b3bc565e6424a0050ebc1b2d1d82": { "balance": "300000" },
"f41c74c9ae680c1aa78f42e5647a62f353b7bdde": { "balance": "400000" }
}
}
然后在bin目录下新建一个dir,名为chain
执行命令
geth --datadir "/usr/local/Cellar/ethereum/1.9.18/bin/chain" init genesis.json
执行成功
geth --datadir . --networkid 15
执行自己的私链geth --datadir . --networkid 15 console 2>output.log
tail -f output.log
//动态打印log
eth.getBalance("0x58A8404CA64a9314e17Cf5F6B90F354b08d2a735")
//获取账户余额
web3.fromWei(eth.getBalance("0x58A8404CA64a9314e17Cf5F6B90F354b08d2a735"),'ether')
//查看多少wei
eth.blockNumber
//查看区块数
personal.newAccount()
//创建新账户
//输入密码后输出
`Your new key was generated address=0x05E07008dbba53Dd9201f63FafC0d0C2efeC13Ed`
> personal.unlockAccount(eth.accounts[0])
Unlock account 0x05e07008dbba53dd9201f63fafc0d0c2efec13ed
Passphrase:
true
eth.sendTransaction([from: "0x58A8404CA64a9314e17Cf5F6B90F354b08d2a735", to:eth.accounts[0], values:100000})
//这里报错因为from要从自己的accounts中取值
//应该如下
>eth.sendTransaction({from:eth.accounts[0],to:"0x58A8404CA64a9314e17Cf5F6B90F354b08d2a735",value:web3.toWei(10,'ether')})
"0x8f8a1b7a761db527a0d076121281a63a3fe86eeb6a6d3a86fed89b459f32a7c6"
miner.start(1)
//程序会一直挖块,在控制台输出
//想要停止挖块
miner.stop()
web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')
常用算法
personal.newAccount():创建账户;
personal.unlockAccount():解锁账户;
eth.accounts:列出系统中的账户;
eth.getBalance():查看账户余额,返回值的单位是Wei;eth.blockNumber:列出当前区块高度;
eth.getTransaction0:获取交易信息;
eth.getBlock():获取区块信息;
miner.start():开始挖矿;
miner.stop():停止挖矿;
web3.fromWei(): Wei换算成以太币;
web3.toWei():以太币换算成Wei;
如果想直接使用dev环境,可以执行以下命令
geth --datadir . -dev console 2>output.log
eth.getTransaction("0x1ed46e2c4c3c6f4dd5c691e60f7ef7e3a6e0064aeea88d9f34899f906bfdd6ed")
{
blockHash: "0xef95f308638afcc7be090fe1cb8410c68c62f546219d32c8db6d3707fcf78bc0",
blockNumber: 1,
from: "0x8ab2a77dcd76c69aa97a2516a0379a962c56cb32",
gas: 21000,
gasPrice: 1,
hash: "0x1ed46e2c4c3c6f4dd5c691e60f7ef7e3a6e0064aeea88d9f34899f906bfdd6ed",
input: "0x",
nonce: 0,
r: "0x9067606bee846798ba97180b336867293812c3849853d9688985f83d17fc0345",
s: "0x69e7a2281e685a04d752015323c832dd4ea8fc94378db879a4b341a95f05fa73",
to: "0x227a1e3efe2dd8e6fe4a633288b823f4f8179e21",
transactionIndex: 0,
v: "0xa96",
value: 10000000000000000000
}
//curl请求命令,与js交互的结果相同
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"web_clientVersion","params":[],"id":1}' http://localhost:8545
以太坊状态机:存储所有账户的基本信息
比特币UTXO可以提供更高程度的隐私
以太坊账户模式可以节省大量空间、更加简单,具有更好的替代性