比特币
起源
比特币(BitCoin)的概念最初由中本聪在2009年提出,根据中本聪的思 路设计发布的开源软件以及建构其上的P2P网络。比特币是一种P2P形式的数 字货币。点对点的传输意味着一个去中心化的支付系统。
与大多数货币不同,比特币不依靠特定货币机构发行,它依据特定算法, 通过大量的计算产生,比特币经济使用整个P2P网络中众多节点构成的分 布式数据库来确认并记录所有的交易行为,并使用密码学的设计来确保货币流通各个环节安全性。P2P的去中心化特性与算法本身可以确保无法通过大量制造比特币来人为操控币值。基于密码学的设计可以使比特币只能被真实的拥有者转移或支付。这同样确保了货币所有权与流通交易的匿名性。比特币与其他虚拟货币最大的不同,是其总数量非常有限,具有极强的稀缺性。该货币系统曾在4年内只有不超过1050万个,之后的总数量将被永 久限制在2100万个
特性
- 硬通货: 跨境交易
- 易携带: 只需一个私钥
- 隐秘性: 只需暴露钱包地址
- 无货币超发: 通货紧缩
P2P网络
拜占庭将军问题
共识机制-工作量证明
POW(Proof of Work)
- 通过付出大量的工作代价来证明自己是非恶意节点
- 计算出一个难题的随机答案(nonce),如同仍色子
- 获取记账的权利
- 打包交易并通知其他节点
理性的人都是追逐利益的,POW抑制了节点的恶意动机
比特币-BTC的产生
- 比特币由挖矿产生,通过计算出一个随机数字nonce
- 生成的BTC都被记录在矿工的名下
- BTC通过矿工的公钥hash值锁定
- 交易的输出被称为“未花费交易” UTXO-Unspent Transaction Output
区块链-一套分布式账本系统
- 共识机制: 通过挖矿证明我是善意节点,并获得生成区块的和在这个区块里记账的权利
- 基于P2P网络:每个全节点都存储了一个历史完整的比特币银行账本
- 新区块通过包含前一个区块头部的哈希值(区块的唯一标识符)建立链接关系,区块链像一列火车,每个区块都是一节车厢,每个车厢里面装满了交易记录
- 进过6个以上区块确认的交易才是安全确认的,因为篡改的成本巨大
常用术语
挖矿
- 在全网中和其他节点竞争计算过程
- 证明自己是非恶意节点
- 获得的权利和义务
- 记账权: 把交易计入区块链中
- 广播义务:把区块在全网广播
- 获得奖励
- 挖矿的奖励-12.5BTC
- 收取交易费用
创世区块
- 比特比区块链的第一个区块,所有当前区块的祖先区块
- 中本聪在2009-01-03 18:15:05挖出 区块链浏览器
key | value |
---|---|
Height | 0 (Main chain) |
Hash | 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f |
Previous Block | 0000000000000000000000000000000000000000000000000000000000000000 |
Next Blocks | 00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048 |
Time | 2009-01-03 18:15:05 |
Difficulty | 1 |
Bits | 486604799 |
Number Of Transactions | 1 |
Output Total | 50 BTC |
Estimated Transaction Volume | 0 BTC |
Size | 0.285 KB |
Version | 1 |
Merkle Root | 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b |
Nonce | 2083236893 |
Block Reward | 50 BTC |
Transaction Fees | 0 BTC |
Coinbase
挖矿产生的比特币,从每次50,25到现在的12.5枚
区块高度&区块深度
- 高度:区块链的最新长度
- 深度:交易确认区块数
交易确认
- 在当一项交易被区块收录后,就是交易确认
- 在此区块之后每产生一个区块,此项交易的确认数相应加1
- 比特币钱包对交易的确认数有相应设置
比特币交易 锁定&解锁
数字签名
未花费交易输出UTXO
Unspent TransXtion Output
- UTXO,用比特币拥有者的公钥锁定(加密)的一个数字
- UTXO==比特币
- 比特币系统里没有比特币,只有UTXO
- 比特币系统里没有账户,只有UTXO(公钥锁定)
- 比特币系统没有账户余额,只有UTXO(账户余额只是比特币钱包概念)
- UTXO存在全节点的数据库里
- 转账将消耗掉属于你自己的UTXO,同时生成新的UTXO,并用接收者的公钥锁定
交易结构
- 交易的输出(UTXO)
- 锁定的比特币的数量
- 锁定脚本(用接收者的公钥哈希)
- 交易的输入(UTXO+解锁脚本)
- 解锁脚本(签名,发送者公钥)
交易验证-基于栈的脚本语言
逆波兰表示法
- 栈
- 对栈的操作
- 逻辑运算符
- 加解密运算符
- 算数运算符
- 验证
- 锁定脚本
- OP_DUPOP_HASH160<发送者公钥哈希> OP_EQUALVERIFY OP_CHECKSIG发送者公钥哈希>
- 解锁脚本
- <发送者签名><发送者公钥> 发送者公钥>发送者签名>
- 交易验证
- 运行解锁脚本+锁定脚本=>True
- 锁定脚本
区块的生成&链接
交易的传播验证
- 交易包含两部分,n输入和m输出,n>=0, m>0
- 输入== 要被花费的UTXO+解锁脚本 (n=0时,单独挖矿获取收益)
- 输出==UTXO(币值+锁定脚本)
- 钱包软件生成交易,并向邻近节点传播
- 节点对收到的交易进行验证,并丢弃不合法交易
- 交易的size要小于区块size的上限
- 交易输入UTXO是存在的
- 交易输入UTXO没有被其他交易引用-防止双花
- 输入总金额>输出的总金额
- 解锁脚本验证
- 将合格的交易加入本地的Transaction数据库,并将合法交易转给邻近节点
区块的生成
- 矿工在挖矿前要组织区块
- 将coinbase交易打包进区块
- 将交易池中高优先级的交易打包进区块
- 优先级=交易额度*UTXO的深度/交易size
- 防止粉尘攻击
-
创建区块的头部
版本号-父区块哈希-Merkle树根-时间戳-难度值-Nonce
- 挖矿成功后,将计算出来的随机数nonce填入区块头部,向邻近节点传播
区块的验证链接
- 相邻节点收到新区块后,立即做以下检查
- 验证POW的nonce值是否符合难度值
- 检查时间戳是否小于当前时间2小时
- 检查Merkle树根是否正确
- 检查区块size要小于区块size上限
- 第一笔交易必须是coinbase交易
- 验证每个交易
- CheckBlock
Merkle Tree
- 防止数据篡改
- 快速验证某个交易是否存在
- 节点存储Hash值
- 从叶子节点构造树
区块链分叉
硬分叉&软分叉
软分叉
- 由比特币交易的数据结构改变引起,但区块的数据结构未改变
- 老节点接受新旧格式的区块,新节点只接受新区块
- 矿工激活软分叉 MASF-Miner Activated Soft Fork
- 用户激活软分叉 UASF-User Activated Soft Fork(BIP148)
- Core团队新发明,应对矿工的不合作
- 隔离见证Segwit-Segregation Witness(BIP141)
硬分叉
- 由于交易结构的变化,或区块的结构的变化引起的
- 新旧节点互相拒绝对方的区块
- 产生两个币钟,如BCC
临时分叉
- 仅发生于几乎同时爆块的情况
- 分叉是暂时的
- 根据共识机制,矿工最终切换到最长链上挖矿
- 短链上的交易全部无效,包括矿工费
隔离见证
- 隔离见证 Segwit-Segregation Witness
- 安全隐患,黑客通过改变交易签名信息改变交易ID
- 将签名部分从交易中移除,从而间接扩容
- 香港共识: 2016年2月香港会议,Core团队的代表同意在实施隔离见证后扩容到2M
- 纽约共识(Segwit2x):2017年5月纽约会议,代表全网80%的算力的矿业代表在纽约达成Segwit2x扩容
- 实现BIP141(SegWit)+BIP91(缓和折中方案)+BIP102(升级到2M)
Core团队 Vs 矿工
- Core反对原因
- 不愿意轻易更改系统,如银行仍使用COBOL语言编写的系统
- 以防个人不能运行全节点,因为每个区块太大了
- 增加2M没有什么大的作用,用闪电网络解决
- 矿工反对原因
- 闪电网络将会导致交易的中心化,违背比特币点对点交易的初衷
- 闪电网络隶属BlockStream公司,大多数Core团队成员是BlockStream的雇员
- 交易费的损失
- Core垄断了海外论坛,利用他们对社区的影响离“封杀”反对Core的开发者和社区成员
结论:Core为闪电网络铺平道路,矿工为了交易费
BCC分叉
- BU团队-Bitcoin Unlimited
- BU大方案曾获得了全网40%的算力支持
- 方案的bug太多,未能获得社区广泛支持
- BitcoinABC团队(Adjustable Blocksize Cap)
- 基于BU的代码,打造了BCC,8月1日硬分叉
- BCC没有Segwit,区块容量8M
- BCC官网
比特币钱包
比特币官方钱包
比特币地址生成
- 生成
- Base64编码
- Base58编码
比特币私钥格式 WIF
Wallet Import Format
- WIF私钥格式更短,标准格式私钥256个bit,16进制长度=256/4=64字符
- 进过Base58编码,是表示长度更短
- 未压缩格式私钥:5开头,大小是51字节,第一位存储版本信息
- 压缩格式私钥:K或L开头,大小是52字节,第一版本存放版本信息,多出的最后一个字节存放是否压缩信息
- WIF格式可以自动侦测地址错误
- 通过私钥的哈希值产生校验码
公钥-压缩格式 & 非压缩格式
- 私钥: DDasdfasdfasdsadfsdaxsas2
- 公钥由X和Y轴的值组成
- x:E9asdfasewrw89792dafa2kkdiw
- y:FB890123jkj238p9fdj9023jp12
- 未压缩公钥
- 04[x][y]
- 压缩公钥02/03开头
- 02[y]
MerklePath验证路径
轻钱包&SPV验证机制
- 轻钱包是比特币的非全节点,存储空间限制
-
只下载block header,size很小只有80字节,区块本身大小1M,1.8M
版本号-父区块哈希-Merkle树根-时间戳-难度值-Nonce
-
向邻近全节点发送请求得到UTXO信息
-
- 简单支付验证SPV-Simplified Payment Verification
- 非全节点支付验证,判断交易是否已经在区块链,多少确认数
- 向邻近全节点发送请求关于特定比特币地址和交易信息
- 邻近全节点向钱包返回Merkle path验证路径和相应block header
- 钱包根据Merkle Path计算出Merkle root,验证是否匹配block header里的Merkle root值
- 确认相应block header的深度是否大于6
生成自己的私钥和地址
- 通过某些私钥生成网站,安全性问题
- 用中文,英文或汉语拼音的哈希值
- 私钥转比特币地址
挖矿
为什么要挖矿
- 比特币系统里为什么设计挖矿
- 增加恶意行为的成本
- 争夺记账权利,获取奖励
- 每开采210,000个区块,挖矿奖励减半
- 2009-01至2012-11,奖励 50BTC
- 2012-11至2016-7,奖励 25BTC
- ……………………….
- 2040年,所有BTC被挖出,挖矿没有奖励,矿工以手续费为生
挖矿流程
难度调整
- 每2016个区块调整难度
- 新目标值=当前目标值*(过去2016区块用时分钟/20160分钟)
- 难度目标值:区块头部hash要小于的值
- 由系数和指数构成
- 难度:难度为1的难度目标值/当前难度目标数>=1
硬件军备竞赛
CPU–>GPU–>FPGA–>ASIC–>矿池
矿池
- 矿工无需运行全节点,只需安装挖矿软件
- 矿池管理员维护全节点,并把任务分段,给矿工布置挖矿任务
- 矿池分类
- PPLNS:Pay Per Last N Shares(蚁池AntPool)
- 根据过去一段时间所做贡献,获得了多少份额来获得比特币奖励
- 滞后惯性,挖矿收益会有一定的延迟
- PPS:Pay-Per-Share(蚁池AntPool,BTCC)
- 按矿工所占矿池算力的大小按比例获得比特币报酬,每天都分
- 某矿工当日所得奖励=预估矿池当日可挖到比特币数量*某矿工算力所占比例
- FPPS:在分coinbase的基础上,也分得交易费
- P2P矿池-P2Pool
- 防止托管矿池管理着作弊,基于区块链技术,去中心化的矿池管理系统
- 矿工需要自己运行全节点
- 根据矿工贡献的算力来确定分红
- 托管矿池-矿工把自己买的矿机托管到矿场,由矿场帮忙维护打理
- PPLNS:Pay Per Last N Shares(蚁池AntPool)
智能合约
- 一份电子形式合同或协议
- 以一种计算机程序的形式展现,例如App
- 通过计算机自动执行和验证,无需人为干预,例如柜台区块Vs ATM取款
- 通过淘宝下单付款后商家发货,确认收货后系统自动转钱给商家
智能合约风险案例-The DAO
- 合约一旦部署成功将很难更改,计算机程序难免出现bug
- The DAO事件
- The monther of all DAOs
- 一个智能合约形式的VC基金
- 股东通过众筹获得代币和投资投票权
- 代码漏洞,被黑客将币盗走大量代币
- 被迫分叉,分裂为ETH和ETC两种代币
以太坊主要特性
- Vitalik于2015年7月创建的区块链
- 区块链2.0,支持智能合约
- 支持图灵完备语言,Solidity
- Gas:衡量在一个计算中要求的费用单位
- 总费用=Gas limit * Gas price
- gas不够时交易处理就会被终止,回退到之前的状态,不退费
- 虚拟机:通过软件模拟计算机硬件的一套系统,运行在宿主机系统上
- 以太坊虚拟机EVM:执行智能合约的安全运行环境,通过执行合约的bytecode来执行智能合约
- 货币发行总量无上限,出块时间平均12-15秒,每个区块奖励5ETH
- 叔区块uncle block奖励
- Keccak SHA-3哈希算法,反ASIC挖矿,需要大量内存
eth常用命令
//创建用户
> personal.newAccount('123456')
"0xf5772efd26ab58ee8d93b82bb5c617c45d3fdb53"
//查看用户
> personal.listAccounts
["0xf5772efd26ab58ee8d93b82bb5c617c45d3fdb53", "0x64745b919d9beecd546e364c510d37ab7d40cc7d", "0x267d1096a2d6860b8ac63674b93d91bdb06b63d1"]
> eth.accounts
["0xf5772efd26ab58ee8d93b82bb5c617c45d3fdb53", "0x64745b919d9beecd546e364c510d37ab7d40cc7d", "0x267d1096a2d6860b8ac63674b93d91bdb06b63d1"]
//赋值
> addr0 = eth.accounts[0]
"0xf5772efd26ab58ee8d93b82bb5c617c45d3fdb53"
> addr1 = eth.accounts[1]
"0x64745b919d9beecd546e364c510d37ab7d40cc7d"
//查询账户余额
> web3.eth.getBalance(addr0)
829999999999999999800
> web3.eth.getBalance(addr1)
200
//挖矿
> miner.start(1);admin.sleepBlocks(1);miner.stop();
//转账
> amount=web3.toWei(1.5)
"1500000000000000000"
> eth.sendTransaction({from:addr0,to:addr1,value:amount})
Error: authentication needed: password or unlock
at web3.js:3143:20
at web3.js:6347:15
at web3.js:5081:36
at <anonymous>:1:1
//解锁账户
>personal.unlockAccount(addr0,'123456')
true
> eth.sendTransaction({from:addr0,to:addr1,value:amount})
INFO [06-27|10:26:46] Submitted transaction fullhash=0xe590191d2ed79f3348f1fced7d80536d921816953d111551e29f9808fc6bd325 recipient=0x64745B919D9BeeCd546E364C510D37Ab7D40CC7D
"0xe590191d2ed79f3348f1fced7d80536d921816953d111551e29f9808fc6bd325"
//获取区块总量
> eth.blockNumber
171
//获取区块
> eth.getBlock(1)
{
difficulty: 997888,
extraData: "0xd883010803846765746886676f312e31308777696e646f7773",
gasLimit: 16760833,
gasUsed: 0,
hash: "0xfda5e6e86447ec9b7db54769a32d84d25579fa938ee8d7ca64d23f6717b6d073",
logsBloom: "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000",
miner: "0xf5772efd26ab58ee8d93b82bb5c617c45d3fdb53",
mixHash: "0x02603e44bbd8906e4f8fc5b98e6a2b652a36e37bf7c03dfb217701b64b9ea6fd",
nonce: "0x0e0ecfaad45d585b",
number: 1,
parentHash: "0x026cb5467232aaacf7db0a0701b9c02553a1b2f577a268462a74d5bbecd9cefe",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 536,
stateRoot: "0x0799465bf65fadadbb2d9cfe6f3c51209641a29d89af133b639077029cde052a",
timestamp: 1529662127,
totalDifficulty: 2046464,
transactions: [],
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles: []
}
智能合约部署运行
eth.sendTransaction({from:addr0,code:'',value:web3.toWei(10,'ether')})