手把手教你实现区块链,弄懂区块链原理

虞双齐, 登链学院合伙人,首席讲师,深受广大读者喜欢的《以太坊技术与实现》的作者。前国信香港证券 IT 运维经理, 前 Nerthus 区块链 CTO。 活跃于登链学院社区的区块链技术爱好者,致力于推导区块链技术在国内的发展。 是百万阅读电子书《以太坊技术与实现》的作者,是视频课程《说透以太坊技术》的讲师。https://learnblockchain.cn/course/1

文章正文

导读

当前,区块链技术应用场景空间广阔,区块链技术落地场景已从金融领域延伸至覆盖医疗、社交、能源、公益慈善、农业、泛娱乐等实体经济领域。未来,随着区块链和大数据、5G、物联网等技术的融合深化,区块链技术必将推动商业的演变进化,助推产业发展,激发实体经济的转型增长。就像人民日报点评的那样,“区块链技术将极大拓展人类协作的广度和深度。也许,区块链不只是下一代互联网技术,更是下一代合作机制和组织形式!”

虽然许多开发者已经了解或者看过许多关于区块链的科普文章,但是如果能手把手教你代码实现区块链,是否能让你更容易、更深刻了解区块链技术呢?

通过本文的学习,你将会获得以下知识:

  1. 掌握区块链不可篡改背后的原理
  2. 掌握区块链挖矿,到底是在挖什么
  3. 掌握区块链是如何实现加密货币不增发的
  4. 能手写实现一个简单区块链模型

适合人群:希望能了解区块链原理的开发者。

项目演示

下图是,你在完成本文的手把手指导后,能获得的区块链演示效果。我已经部署在这里,来在线体验一把!

在这里插入图片描述

程序架构设计说明

也许,你听过对区块链的不同解释。每种对区块链的诠释也许都是正确的,毕竟每个人都有自己的理解和见地。但是否有权威的区块链定义呢?下面,我直接引用维基百科对区块链的描述。

区块链(英语:blockchain 或 block chain)是借由密码学串接并保护内容的串连文字记录(又称区块)。每一个区块包含了前一个区块的加密散列、相应时间戳记以及交易数据(通常用默克尔树(Merkle tree)算法计算的散列值表示),这样的设计使得区块内容具有难以篡改的特性。用区块链技术所串接的分布式账本能让两方有效纪录交易,且可永久查验此交易。

从上面的定义中,可以抽离一些信息:

  1. 区块链由若干的区块组成
  2. 区块中有父区块(前一个区块)的哈希值(加密散列值)、时间戳和交易数据哈希值
  3. 区块内容难以篡改
  4. 交易可校验

区块链的核心是处理交易,在区块中记录交易。下图是交易处理流程图,流程说明如下:

在这里插入图片描述

  1. 创建交易:用户节点使用自己的账户私钥创建一笔交易。
  2. 广播交易:交易在本地存储后将广播到网络中去。
  3. 接收交易:交易在网络广播后,将很快被矿工节点接收到。
  4. 校验交易:矿工不能信任任何别人所发送的交易,将校验交易的合法性。
  5. 交易暂存排队:如果交易合法,将会存放在队列中,排队等候处理。
  6. 创建新区块:当矿工已经开启矿工时。每次开始挖矿,都需要基于末尾的区块创建一个新的区块。
  7. 处理交易:从交易队列中拉取可处理交易,进行一些处理后。可以将交易写入新区块中。
  8. 挖矿:一个完整有效的区块最后一步是需要进行工作量证明,需要求解一道数学题目,俗称“挖矿”。
  9. 广播新区块:一旦解题成功,就会立刻存储并广播到网络中。争取获得该区块的记账权,从而得到奖励。
  10. 校验区块/交易完成:在用户节点接收到这个新区块后,将校验区块的完整性。如果合法,则存储在本地。该区块中的交易则表示已经成功上链,交易完成。

本文将围绕此流程,来是实现打造一条能够处理交易的区块链。所涉及的模块包括:账户管理、交易管理、挖矿管理、区块链管理、UI 交互。

注意事项:

  1. 数据 ID,通过哈希算法生成。ID 即为数据的哈希值,为了加速计算,使用 hashFnv32a 哈希算法计算。
  2. 数据存储在浏览器中,离线存储。每次打开网页即可在从本地加载数据。

开发环境准备

用什么语言来实现合适呢?我想,虽然我擅长 Go 语言,但不知道你能不能搞定啊,我可不想逼迫你去学习一门新语言!纠结啊!!!算了,还是用 JavaScript 和 HTML 吧,通过网页手写区块链!

本实战将在在 VS Code 中操作,用 Chrome 浏览器浏览。下面是环境准备步骤,要一个一个操作哈!

  1. 安装 VS Code(如果有,可跳过)。
  2. 安装 VS Code 插件:Live Server,用于实时浏览 HTML 网页。
  3. 下载项目初始代码:BlockChainStudy ,将得到 index.html 和 app.js 文件。
  4. 使用 VS Code 打开 BlockChainStudy 文件夹。
  5. 使用 VS Code 编辑 index.html。
  6. 右键 index.html 页面内容,点击“open with live server”右键菜单项。
  7. 此时将自动打开浏览器,index.html 界面展示如下。(不一样的话,记得检查哦)

在这里插入图片描述

第一步:实现数据存储

打开 app.js 文件,在 APP 对象中,添加 initDB 方法。并在 App.init 方法中执行它。

init: () => {
    App.initDB();
},
// 初始化数据库
initDB: () => {
    var db = new Dexie(dbName);
    db.version(1).stores({//注意,这里只记录索引字段
        transactions: "id,sender,blockID",
        wallets: "name,address",
        blocks: "id,no,pid,number",
        outputs: "id,receiver,spend,tx",
        inputs: "id,txid,vout,tx",
    })
    db.open().catch(App.onError);
    window.db = db;//转变为全局
},

Dexie 是对浏览器内置的 indexedDB 的封装,提供了丰富的操作接口。初始化 DB 将在浏览器中创建名为 dbName 的数据库,其中包含交易表(Transactions)、钱包账户表(wallets)、区块表(blocks )、交易输出表(outputs)和交易输入表(inputs)。

各表的定义如下:

交易表(Transactions):

字段 类型 说明
id Hash 交易唯一标识符
sender 地址 交易的发送者
inputsID Hash 交易输入的多个 input 的哈希值
outputsID Hash 交易输出的多个 output 的哈希值
createTime 时间戳 交易创建时间
no 数字 sender 的第几笔交易
blockID Hash 如果交易被处理,则记录存在于哪个区块中
index 数字 交易在区块中的第几笔交易

钱包账户表(wallets):

字段 类型 说明
name 字符串 账户的简化显示,为 A,B,C……
address Hash 账户的地址,自动通过账户私钥推导而成。
privateKey Hash 账户私钥(注意:在本演示项目中使用明文存储,不考虑安全问题)

区块表(blocks):

作者正在撰写中...
隐藏内容 支付可见
内容互动
写评论
加载更多
评论文章
¥9.9 购买
× 订阅 Java 精选频道
¥ 元/月
订阅即可免费阅读所有精选内容
字段 类型 说明