共识机制

工作量证明(pow)

nonce++存入Block区块头做哈希,然后用Cmp方法和难度值进行比较,如果返回-1则满足条件,就可以校验交易了。

权益证明(pos)

根据币龄和代币数量调整难度值,出块概率与代币数量和币龄成正比。然后和pow一样。

股份授权证明(dpos)

股份授权证明机制是POS的一个变种,简单来说就是你手里有选票(币就相当于选票)。这时一些正在竞选超级节点的大节点们说把票都投给我把,等我当选了超级节点,我吃肉你喝汤,岂不美哉?然后你就信了,把票投给了竞选节点,这些节点竞选成功成为超级节点后会轮循的获得出块权。矿工费、通胀放出的代币也就都到了他们手里了

拜占庭容错(pbft)

  1. 客户端向主节点发送请求信息
  2. 主节点接收到客户端请求后将请求数据里的主要信息提出,并向其余节点进行preprepare发送
  3. 从节点们接收到来自主节点的preprepare,首先利用主节点的公钥进行签名认证,其次将消息进行散列(消息摘要,以便缩小信息在网络中的传输大小)后,向其他节点广播prepare
  4. 节点接收到2f个prepare信息(包含自己),并全部签名验证通过,则可以进行到commit步骤,向全网其他节点广播commit
  5. 节点接收到2f+1个commit信息(包含自己),并全部签名验证通过,则可以把消息存入到本地,并向客户端返回reply消息

加密算法

ECC椭圆曲线算法

RSA非对称加密

数字签名

  1. 发送方对原文做哈希运算得到哈希值1

  2. 发送方用私钥对哈希值1进行加密签名

  3. 发送方将原文和私钥签名发送给接收方

  4. 接收方对接收到的原文进行哈希运算得到哈希值2

  5. 接收方用公钥解密签名得到哈希值1

  6. 接收方对哈希值1和哈希值2进行比较

智能合约

Solidity

modifier:函数修饰器

constructor:构造函数

contract下的:状态变量

constant:状态常量

memory:其生命周期仅仅局限于一次函数调用

storage:状态变量存储的地方,永久存储,类似于磁盘存储

calldata:一种特殊的存储位置,用来存放外部函数调用的参数

external:以交易的方式被其他合约调用,是合约接口的一部分,要用this.函数名()的方式调用

internal:只能在当前合约或继承合约中访问

pure:不可读写

view:可读不可写

fallback:一个匿名函数,必须是external类型的,必须用payable修饰,用于接收以太坊代币

重载:相同名称的函数参数数量必须不同

event:和emit配合用于监听

ABI:ABI是智能合约公共接口的描述,DApp用这个公共接口来调用智能合约。

字节码:每个节点上的以太坊虚拟机都需要智能合约的字节码来运行智能合约。

is:继承

new:创建其他合约的实例

revert:异常处理,事后校验

require:异常处理,事前校验

Web3

window.ethereum或window.web3或web3.providers.HttpProvider(“localhost:8545”)

web3.currentProvider(返回当前通信的服务提供器)

web3.setProvider(设置服务提供器)

ERC20合约

Token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
pragma solidity ^0.4.20;

contract Token{
struct user{
address userAddress;
uint256 userTokensNum;
}
uint256 public tokensSupply;
uint256 public tokensBalance;
uint256 public tokensPrice;
mapping(address => user) public userInfo;
constructor(uint256 totalSupply , uint256 price)public {
tokensSupply = totalSupply;
tokensBalance = totalSupply;
tokensPrice = price;
}

function Buy() payable public returns(uint256){
uint256 tokensNumToBuy = msg.value/tokensPrice;
require(tokensNumToBuy <= tokensBalance);
userInfo[msg.sender].userAddress = msg.sender;
userInfo[msg.sender].userTokensNum += tokensNumToBuy;
tokensBalance -= tokensNumToBuy;
return tokensNumToBuy;
}
}

DApp开发

Geth

命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
account    管理账户
attach 启动交互式JavaScript环境(连接到节点)
bug 上报bug Issues
console 启动交互式JavaScript环境
copydb 从文件夹创建本地链
dump Dump(分析)一个特定的块存储
dumpconfig 显示配置值
export 导出区块链到文件
import 导入一个区块链文件
init 启动并初始化一个新的创世纪块
js 执行指定的JavaScript文件(多个)
license 显示许可信息
makecache 生成ethash验证缓存(用于测试)
makedag 生成ethash 挖矿DAG(用于测试)
monitor 监控和可视化节点指标
removedb 删除区块链和状态数据库
version 打印版本号
wallet 管理Ethereum预售钱包
help,h 显示一个命令或帮助一个命令列表

ETHEREUM选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
--config value          TOML 配置文件
--datadir “xxx” 数据库和keystore密钥的数据目录
--keystore keystore存放目录(默认在datadir内)
--nousb 禁用监控和管理USB硬件钱包
--networkid value 网络标识符(整型, 1=Frontier, 2=Morden (弃用), 3=Ropsten, 4=Rinkeby) (默认: 1)
--testnet Ropsten网络:预先配置的POW(proof-of-work)测试网络
--rinkeby Rinkeby网络: 预先配置的POA(proof-of-authority)测试网络
--syncmode "fast" 同步模式 ("fast", "full", or "light")
--ethstats value 上报ethstats service URL (nodename:secret@host:port)
--identity value 自定义节点名
--lightserv value 允许LES请求时间最大百分比(0 – 90)(默认值:0)
--lightpeers value 最大LES client peers数量(默认值:20)
--lightkdf 在KDF强度消费时降低key-derivation RAM&CPU使用

开发者(模式)选项:

1
2
--dev               使用POA共识网络,默认预分配一个开发者账户并且会自动开启挖矿。
--dev.period value 开发者模式下挖矿周期 (0 = 仅在交易时) (默认: 0)

ETHASH 选项:

1
2
3
4
5
6
--ethash.cachedir                        ethash验证缓存目录(默认 = datadir目录内)
--ethash.cachesinmem value 在内存保存的最近的ethash缓存个数 (每个缓存16MB ) (默认: 2)
--ethash.cachesondisk value 在磁盘保存的最近的ethash缓存个数 (每个缓存16MB) (默认: 3)
--ethash.dagdir "" 存ethash DAGs目录 (默认 = 用户hom目录)
--ethash.dagsinmem value 在内存保存的最近的ethash DAGs 个数 (每个1GB以上) (默认: 1)
--ethash.dagsondisk value 在磁盘保存的最近的ethash DAGs 个数 (每个1GB以上) (默认: 2)

交易池选项:

1
2
3
4
5
6
7
8
9
10
--txpool.nolocals            为本地提交交易禁用价格豁免
--txpool.journal value 本地交易的磁盘日志:用于节点重启 (默认: "transactions.rlp")
--txpool.rejournal value 重新生成本地交易日志的时间间隔 (默认: 1小时)
--txpool.pricelimit value 加入交易池的最小的gas价格限制(默认: 1)
--txpool.pricebump value 价格波动百分比(相对之前已有交易) (默认: 10)
--txpool.accountslots value 每个帐户保证可执行的最少交易槽数量 (默认: 16)
--txpool.globalslots value 所有帐户可执行的最大交易槽数量 (默认: 4096)
--txpool.accountqueue value 每个帐户允许的最多非可执行交易槽数量 (默认: 64)
--txpool.globalqueue value 所有帐户非可执行交易最大槽数量 (默认: 1024)
--txpool.lifetime value 非可执行交易最大入队时间(默认: 3小时)

性能调优的选项:

1
2
--cache value                分配给内部缓存的内存MB数量,缓存值(最低16 mb /数据库强制要求)(默认:128)
--trie-cache-gens value 保持在内存中产生的trie node数量(默认:120)

帐户选项:

1
2
--unlock value              需解锁账户用逗号分隔
--password value 用于非交互式密码输入的密码文件

API和控制台选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--rpc                       启用HTTP-RPC服务器
--rpcaddr value HTTP-RPC服务器接口地址(默认值:“localhost”)
--rpcport value HTTP-RPC服务器监听端口(默认值:8545)
--rpcapi value 基于HTTP-RPC接口提供的API
--ws 启用WS-RPC服务器
--wsaddr value WS-RPC服务器监听接口地址(默认值:“localhost”)
--wsport value WS-RPC服务器监听端口(默认值:8546)
--wsapi value 基于WS-RPC的接口提供的API
--wsorigins value websockets请求允许的源
--ipcdisable 禁用IPC-RPC服务器
--ipcpath 包含在datadir里的IPC socket/pipe文件名(转义过的显式路径)
--rpccorsdomain value 允许跨域请求的域名列表(逗号分隔)(浏览器强制)
--jspath loadScript JavaScript加载脚本的根路径(默认值:“.”)
--exec value 执行JavaScript语句(只能结合console/attach使用)
--preload value 预加载到控制台的JavaScript文件列表(逗号分隔)

网络选项:

1
2
3
4
5
6
7
8
9
10
11
--bootnodes value    用于P2P发现引导的enode urls(逗号分隔)(对于light servers用v4+v5代替)
--bootnodesv4 value 用于P2P v4发现引导的enode urls(逗号分隔) (light server, 全节点)
--bootnodesv5 value 用于P2P v5发现引导的enode urls(逗号分隔) (light server, 轻节点)
--port value 网卡监听端口(默认值:30303)
--maxpeers value 最大的网络节点数量(如果设置为0,网络将被禁用)(默认值:25)
--maxpendpeers value 最大尝试连接的数量(如果设置为0,则将使用默认值)(默认值:0)
--nat value NAT端口映射机制 (any|none|upnp|pmp|extip:<IP>) (默认: “any”)
--nodiscover 禁用节点发现机制(手动添加节点)
--v5disc 启用实验性的RLPx V5(Topic发现)机制
--nodekey value P2P节点密钥文件
--nodekeyhex value 十六进制的P2P节点密钥(用于测试)

矿工选项:

1
2
3
4
5
6
7
--miner.start()         打开挖矿
--miner.stop() 停止挖矿
--minerthreads value 挖矿使用的CPU线程数量(默认值:8)
--etherbase value 挖矿奖励地址(默认=第一个创建的帐户)(默认值:“0”)
--targetgaslimit value 目标gas限制:设置最低gas限制(低于这个不会被挖?) (默认值:“4712388”)
--gasprice value 挖矿接受交易的最低gas价格
--extradata value 矿工设置的额外块数据(默认=client version)

GAS价格选项:

1
2
--gpoblocks value      用于检查gas价格的最近块的个数  (默认: 10)
--gpopercentile value 建议gas价参考最近交易的gas价的百分位数,(默认: 50)

虚拟机的选项:

1
--vmdebug        记录VM及合约调试信息

日志和调试选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
--metrics            启用metrics收集和报告
--fakepow 禁用proof-of-work验证
--verbosity value 日志详细度:0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 3)
--vmodule value 每个模块详细度:以 <pattern>=<level>的逗号分隔列表 (比如 eth/*=6,p2p=5)
--backtrace value 请求特定日志记录堆栈跟踪 (比如 “block.go:271”)
--debug 突出显示调用位置日志(文件名及行号)
--pprof 启用pprof HTTP服务器
--pprofaddr value pprof HTTP服务器监听接口(默认值:127.0.0.1)
--pprofport value pprof HTTP服务器监听端口(默认值:6060)
--memprofilerate value 按指定频率打开memory profiling (默认:524288)
--blockprofilerate value 按指定频率打开block profiling (默认值:0)
--cpuprofile value 将CPU profile写入指定文件
--trace value 将execution trace写入指定文件

WHISPER实验选项:

1
2
3
--shh                        启用Whisper
--shh.maxmessagesize value 可接受的最大的消息大小 (默认值: 1048576)
--shh.pow value 可接受的最小的POW (默认值: 0.2)

弃用选项:

1
2
--fast     开启快速同步
--light 启用轻客户端模式

其他选项:

1
–help, -h    显示帮助

自己的论文

UTXO模型

解锁脚本:

1
2
3
4
5
6
7
type TXInput struct {
TXID []byte //交易ID
Index int64 //output的索引
//Address string //解锁脚本
Signature []byte //交易签名
PubKey []byte //公钥本身,不是公钥哈希
}

锁定脚本:

1
2
3
4
5
type TXOutput struct {
Value UserData //转账数据
//Address string //锁定脚本
PubKeyHash []byte //公钥哈希
}

签名

首先看是不是一笔挖矿交易,如果是挖矿交易就不需要签名。找到引用的交易,对交易id用私钥进行签名,交易id是对交易进行编码的结果,执行签名函数后会得到一个r和一个s,这是两个大数(Big.Int类型,转化为字节append得出数字签名,然后把数字签名存储到input里。

校验签名的时候根据这笔交易引用的前交易进行签名数据的还原,然后获取这笔交易的签名和公钥,进行还原,将两次还原后的数据进行对比。

Merkle根

对交易ID做递归得出Merkle根

地址生成和校验

对公钥做RIPEMD160(sha256(publicKey)),得出20字节,拼接1字节版本号,然后对这21字节的数据做两次sha256运算后取后四字节得出校验码,拼接在一起得出25字节的地址。