区块链流程图3 交易系统实现
交易结构设计
TXInput结构
- 引用的输出索引(在vec中的位置)
- 解锁脚本(这里简化为自身公钥)
- 如果我的地址和输出索引的锁定脚本一样,证明我可以用这笔钱
TXOutput结构
- 每个output索引为vec中的位置
- 币的数量
- 锁定脚本(发送方公钥)
- 表示谁有资格使用这笔钱(我发给谁了)
Transaction结构
成员:
- Vec
- Vec
- id
方法:
new_UTXO
- find_spendable_outputs(blockchain函数)
- 找到需要使用的vec证明我可以使用这些钱
- 把全部的utxo都拿出来了,拼成input(证实自己有动用这笔钱权力)
- 把全部余额合并成一个output,发出去
- 计算要找回多少钱,发一份给自身
- 最后把vin和vout拼接成Transaction返回’
new_coinbase
- 直接生成一个tx
- input里的解锁脚本和out索引都没有,因为不需要证明就可以用(新块)
- 拼接output然后返回tx
is_coinbase
- 就判断当前tx是否只有一个input啥的就行
Block结构修改
数据结构
- 把data字段换成了Vec
方法实现
prepare_hash_data
- 把待哈希内容序列化
- 注:由于时间戳一开始就被计算出来,故并不是挖矿成功的时间戳
validate
- 调用prepare获取数据
- 注:每次要重新调用prepare是因为nonce每次都变化了
- 判断是否哈希值符合要求
run_proof_of_work
- 循环调用validata
- 每次把nonce+1,成功了则把self.hash赋值
new_block
- 获取当前时间戳
- 新创建block,赋值好前哈希,Vec
,时间戳 - 调用run_proof赋值哈希
new_genesis_block
- 直接生成
Blockchain结构优化
成员变量
- 继续删除currentHash,转移到迭代器里面
- tip最新区块的哈希值
- db
方法实现
new()构造函数
- 返回blockchain
- 打开db
- 调用get(“last”)查询
- last为存储的最后一个哈希值
- 若不存在:?表示式报错返回
- 若存在:把tip和db都赋值后返回
create_blockchain
- 调用生成创世交易函数
- 把tx传入生成创世块函数,生成创世块
- 把创世块信息等insert进数据库
find_spendable_outputs
- 在区块链中查找发送者可用的未花费输出
- 返回元组(总金额, 可用输出的map)
find_UTXO
- 把find_unspent_transactions的返回的tx提纯
- 直接返回UTXO
find_unspent_transactions
- 获取包含自身地址的所有未花费的输出
- 从新往旧遍历区块链
- 先把vout判断是否被vin引用了
- 再把当前块的vin引用的vout注册进哈希
find_spendable_outputs
- 查找可用于支付指定金额的输出
- 调用find_unspent
- 遍历所有的tx中的output,然后不断加accumulated
- 够了就返回积累值和对应的output
mine_block(原add_block)
- 从last获取新块的前哈希
- 调用new_block(data, prev.get_hash())
- 每个块都是一个键值对存储key为hash,value是块的序列化
- 插入db,并更新last和tip和curretHash
Iterator
- next
- 调用currentHash来get块
- 返回这个块,并且把curretHash赋值为前hash
CLI改进
结构修改
- 删除了blockchain成员
命令实现
run:
- 注册命令行app
- 判断是否输入了对应命令
- 删除了addblock/换成send
- 执行print_chain
- getbalance:调用find_UTXO之后遍历相加
- createblockchain:调用create_blockchain
- send:
- 解析from,to,amount
- 调用new_UTXO生成交易信息
- 调用mine_block生成区块
主程序实现
- 初始化日志系统
- 创建cli
- 调用run
评论