技术课堂丨关于唯链公链,你可能还不知道的那些事儿(一)
自2018年6月开始,唯链雷神区块链已经正式上线一年了。作为其白皮书的作者之一,我仍然觉得有一些为了区块链技术大规模应用而设计的重要特性还没有被大家所了解。本篇是“关于唯链雷神区块链,你可能还不知道的那些事儿”系列的第一篇。在这个系列里我将详细阐述这些非常有用、但尚未普及的唯链雷神区块链的特性。另外,如果你还没有了解过唯链雷神区块链的多方支付协议(MPP)和多任务交易(MTT)特性,我强烈建议你可以先读一下相关的文章。
每个区块链都必须要有唯一标示每笔交易(TX)的方法,否则它将很容易受到交易重放攻击。简单来说,重放攻击指的是攻击者通过使用账本中已有的交易来欺骗系统。
对于一个类似比特币的基于UTXO模型的区块链, 交易之间是相互关联的,我们可通过历史花费记录来验证交易。然而,对于像太坊这种基于账户体系的区块链来说,这种验证唯一性地方法不再适用。对于这类系统,我们需要在交易中加入一些额外的信息来达到交易的唯一性。
在以太坊上交易的唯一性是这样实现的,以太坊在每笔交易中加入变量AccountNonce,并且规定只有在AccounceNonce和发起交易的账户里的Nonce变量的最新值一致的情况下,交易才会被处理。请注意,Nonce的数值记录了该账户目前已经发送的交易数量。这样一来,一笔交易就能通过这个Nonce的值和发起方的账户地址唯一来标示。
不过这种设计存在不足之处,那就是从同一个账户发送的交易将被迫组成一个序列。在这个序列里,任何一笔交易的失败,都将会导致后续交易不能被以太坊系统接受。这是因为后续的交易里包含的Nonce的数值都比交易发起账户当前的Nonce数值要大,所以必然会被系统排除在外。大家可以想象一下,当你有多笔交易正在等待系统确认,而你又想发新的交易的时候,你将面临这样的风险:一旦之前的任一交易失败,新交易将会被无限延迟。
唯链雷神区块链是一个基于账户的区块链系统,它通过以下方法来实现交易的唯一性。首先,它重新定义了交易里的Nonce变量,使它成为一个完全由交易发起者决定的64位无符号整数。对于一笔交易,我们将计算两个哈希值,一个是不带签名的交易数据RLP编码的哈希值,然后我们把计算出来的第一个哈希值串联上交易发起方的账户地址,并对其做哈希运算,得到第二个哈希值。第二个哈希值的长度为256位,在唯链雷神区块链上用来作为这笔交易的唯一标示(TXID)。值得注意的是,TXID的计算是不需要私钥来为交易签名的。
为什么这个设计很重要?👉首先,一笔交易的唯一性完全取决于它的内容。它是否会被节点处理完全取决于计算出来的TXID是否已经在区块链上存在,而不是取决于发起方账户的状态(例如它的Nonce值)以及由这个账户发起的其他待确认的交易。显然这样的改变对于dApps开发者是很大的利好,因为当他们编写涉及与区块链交互以及处理交易失败的代码时,他们所要考虑的问题被大大简化了。
这一设计对企业用户来说具有同样重要的意义👉假设你是一个工厂的负责人,你想要在区块链上注册产品,从而实现产品的追溯以及物流信息的可被验证性。如果是基于以太坊的交易唯一性方案,当你的产品被源源不断地生产出来,并通过发送交易到区块链来试图注册它们的时候,任何一个交易的失败将导致后续所有交易被系统拒绝,产品注册失败。这对于你的工厂来说是灾难性的,是不可接受的。如果是基于唯链雷神区块链的方案,整个流程将会变的流畅而且方便管理。因为你所需要做的仅仅是在发送一笔交易之前,确保它TXID没有被使用过。其余的就是单独处理那些失败的交易即可(比如重新发送它们),这是因为失败的交易不会影响到其他的交易。
为了大家能够更好的理解,我编写了一小段代码来展示TXID是如何计算的。在展示代码之前,我首先到类似 veforge(https://explore.veforge.com/) 这样的唯链雷神区块链浏览器上随机找一笔交易。我的代码会在本地重构这笔交易并计算它的TXID。最后,我会把计算出来的TXID值和浏览器上的值进行对比来验证我得出的计算结果。
以下是我随机选取的一笔交易的TXID:
0x38fac25309ab5395f1725284af46af585988983945e67b77cf9916b1ddf13d4b
这里有个问题:由于 veforge 会四舍五入交易转账值,我会需要用其他工具来找到精确的数值,来重构这笔交易。为此我打开了Sync(一个专为唯链雷神区块链打造的功能强大的dApp运行环境),点击了 “Toggle Developer Tools” 以及 “Console”(如下图所示),
然后在 console 里输入以下命令:
connex.thor.transaction('0x38fac25309ab5395f1725284af46af585988983945e67b77cf9916b1ddf13d4b').get().then(tx => console.log(tx))
下图展示了我随后得到的结果:
为了运行我的代码,你需要安装 thor-devkit.js(https://github.com/vechain/thor-devkit.js), 这是一个帮助开发者开发dApp的Typescript开源库。你可以前往 https://github.com/zzGHzz/ThorDemo1,找到我的代码。
好了,现在我来给大家讲一下代码。这里我们第一步做的是构建一个交易子句。对于那些不熟悉唯链雷声区块链交易模型的同学,我简单说一下。每个唯链雷神区块链的交易都可以包含多个子句(Clause
),每个子句包含变量to
,value
和data
,可以做通常我们定义的交易的同样的事情。有了多子句结构,我们可以让一笔交易做跟多的事情,只要是这些事情都是由同一个地址发起的。这样会大大提高效率,并且保证这些子句操作的原子性。
let clauses = [{
to: '0x564B08C9e249B563903E06D461824b5d6b7F2968',
value: "0x2a7ee2750fca8ea00000",
data: '0x'
}]
在构造完子句之后,我们需要给交易的其他变量赋值。这里我们用之前在console中得到的系统返回值来赋值:
let body: Transaction.Body = {
chainTag: 74,
blockRef: '0x002e3040a9ade438',
expiration: 720,
clauses: clauses,
gasPriceCoef: 0,
gas: 21000,
dependsOn: null,
nonce: '0x73541be64e72817c'
}
之后,我们做的是构建交易:
let tx = new Transaction(body)
并且计算交易TXID。这个计算过程分两步:1)首先计算不带签名的交易数据RLP编码的哈希值:
let signingHash = cry.blake2b256(tx.encode())
2)其次把步骤一中计算出的哈希值和发送账户地址串联起来,然后再对其计算哈希值,得到最终的交易TXID:
const origin = '0xa4d2050f24ed7EfF313B7E912D6e5BF96ce57B95'
let id = '0x' + cry.blake2b256(signingHash, Buffer.from(origin.slice(2), 'hex')).toString('hex')
好了,现在我们已经计算出了该笔交易的TXID,可以把它打印出来,与之前在 veforge 浏览器上找到的TXID进行比较了。
最后,感谢 @rogake 帮助我一起翻译了我的英文原文。
英文原文链接:
https://bbs.vechainworld.io/topic/198/what-you-might-not-know-about-vechainthor-yet-part-i-transaction-uniqueness
关于作者
周子衡博士 唯链首席科学家
周子衡博士拥有英国南安普顿大学计算机博士学位。先后以研究员和资深研究员的身份任职于英国肯特大学和芬兰奥卢大学,参与了欧盟和芬兰科学院重要科研项目,拥有十年计算机科研研发以及在国际一流学术杂志和会议上发表科研成果之经验。周子衡博士于2017年加入唯链,主要负责唯链雷神区块链的科研研发及知识产权保护等工作。
-End-
后台回复“ToolChain”,获取ToolChain相关信息;
后台回复 “白皮书”,获取中英文版《唯链白皮书及发展计划》;
后台回复 “开发者奖励”,获取开发者奖励计划以及应用程序挑战赛详情;
后台回复 “开发者信息”,获取唯链开发者资源大全;
后台回复 “VeChain App”,获取雷神钱包及VeChain Pro App下载信息;
后台回复 “合作”,获取合作联系方式;
后台回复 “节点计划”,获取X节点计划详情;
欢迎加入唯链社区,了解最新官方动态!
基金会官网
https://www.vechain.org
VeChainWorld
https://vechainworld.io/#/dapp/all
中文电报群
https://t.me/vechain_official_CN
英文电报群
https://t.me/vechain_official_english
https://twitter.com/vechainofficial
微博
https://weibo.com/u/6353774918
Medium
https://medium.com/vechain-foundation
http://www.reddit.com/r/Vechain
Github
https://github.com/vechain
Gitter
https://gitter.im/vechain/thor
点击“阅读原文”进入官网了解更多精彩内容