区块链学习笔记
一 . 区块链介绍
从技术角度来说, 这加密货币的账本,如比特币可以被看作为一个状态转移的系统, 在这个系统里,有一个包含了现在所有已存在的比特币的持有者的状态,并且有一个“状态转移函数”可以使用一个状态和一个交易来产生一个新的状态。在一个标准的银行体系里, 这状态就是一个资产负债表,当一个交易要求把 X$的钱,从 A 转移到 B 时, 那么它的状态转移函数就会从 A 的账户中减去数量为$X 的金额,然后在 B 的账户中增加数量为$X 的金额。如果 A 的账户中没有$X 的钱,那么状态转
移函数就会返回一个错误。所以,我们可以做如下定义:
//使用一个状态和一个交易才生一个新状态,或者返回错误
APPLY(S,TX) -> S' or ERROR // S为状态,交易后会产生一个新的状态S‘或者ERROR
在银行系统中的表示:
APPLY( { Make:$50 , Tony:$50 } , "send $20 from Make to Tony")= APPLY( { Make:$30 , Tony:$70 } )
// 成功
APPLY( { Make:$50 , Tony:$50 } , "send $80 from Make to Tony")= ERROR
// 失败,UTXO没有被花掉的交易产出
这“状态” 在比特币中是指所有的已经被挖出的但是还没消费的硬币的集合 (技术上, “没有被花掉的交易的产出(unspent transaction outputs)” 或 UTXO) ,每个 UTXO 都有一个面值和一个持有者 (持有者是由 20 个字节组成的地址,其本质是一个加密的公钥). 一个交易包含了一个或多个输入,每一个输入都包含了对一个已存在的 UTXO 的引用,和用持有者的地址所关联着的私钥来产生的一个加密签名, 并且会产生一个或多个输出, 每一个输出包含一个用于添加到状态的新的 UTXO。这状态转移函数 APPLY(S,TX) -> S' 可以被大概的定义如下:
1. 在 TX 中的每个输入:
o 如果被引用的 UTXO 不在 S 里,返回一个错误.
o 如果提供的签名和 UTXO 的所有者匹配不上, 返回一个错误.
2. 如果所有的输入的 UTXO 的面值的和少于所有输出的 UTXO 的面值的和,返回一个错误.
3. 返回一个所有输入的 UTXO 都被移除的,所有输出的 UTXO 都被加进的新的 S' .
如果我们有一个可信任的中央服务器, 那么实现这个系统是一件很简单的事情; 就按照需求所描述的去编写代码即可,把状态记录在中央服务器的硬盘上。 然而,与比特币一样,我们试图去建立一个去中心化的货币系统, 所以,我们需要把状态转移系统和一致性系统结合起来,以确保每个人都同意这交易的顺序。比特币的去中心化的一致性处理进程要求网络中的节点连续不断的去尝试对交易进行打包,这些被打成的包就称为“区块”。 这个网络会故意的每隔 10 分钟左右就创建一个区块, 每一个区块里都包含一个时间戳,一个随机数,一个对上一个区块的引用 ,和从上一个区块开始的所有交易的列表。随着时间的推移,这会创建一个持久的,不断增长的区块链,这个区块链不断的被更新,使其始终代表着最新的比特币总账的状态。
在这个范例中,用来验证一个区块是否有效的算法如下:
1. 检查其引用的上一个区块是否存在并且有效.
2. 检查这个区块的时间戳是否大于上一个区块的时间戳 并且小于 2 小时之内
3. 检查这区块上的工作证明是否有效.
4. 让 S[0] 成为上一个区块的最末端的状态.
5.假设 TX 是这个区块的交易列表,且有 n 个交易。 做 for 循环,把 i 从 0 加到到 n-1, 设
置 S[i+1] = APPLY(S[i],TX[i]) 如果任何一个应用(APPLY)返回错误,则退出并且返回。
6. 返回 true,并且把 S[n] 设置成这个区块最末端的状态。
乍看上去,这种方法似乎效率很低,因为它需要将整个状态存储在每个块中,但在现实中,效率应该与比特币相当。原因在于,状态存储在树结构中,并且每个块后,只需要修改树的一小部分。此外,由于所有的状态信息都是最后一个区块的一部分,所以不需要存储整个区块链的历史——这一策略,如果它可以应用于比特币,那么它的磁盘空间将节省 5-20 倍。以太坊网络中交易会被验证这网络的节点收集起 来。这些“矿工”在以太坊网络中收集、传播、验证和执行交易,然后整理归档这些交易,打包成一个区块,与别的矿工竞争将区块添加到区块链中,添加成功的矿工将收到奖励。通过这样的措施,鼓励人们为区块链全网提供更多的硬件和电力支持。