《Nodejs开发加密货币》之十九:签名和多重签名
前言加密货币是1种数字资产,随着区块链等相干技术的创新和突破,很多有形或无形资产实现了去中心化。比如我们这里分享的 亿书 就是要把数字出版物版权进行保护,实现去中心化,解决业界多年来版权保护不力的困难。 不管数字资产,还是数字出版版权,都是有明确所有权的,当前实现数字资产所属的技术手段就是本篇要介绍的 源码主要源码地址: signatures.js https://github.com/Ebookcoin/ebookcoin/blob/v0.1.3/modules/signatures.js multisignatures.js https://github.com/Ebookcoin/ebookcoin/blob/v0.1.3/modules/multisignatures.js 解读签名(1)签名的作用和特点 名字的解释。 签名的作用。平常生活中,凡是需要确认归属的(是签名人的,不是其他的),都需要所有者进行签名。比如,我签名了1份文件,出了问题,责任我负,我签名了1个支票,就代表将由我支付。我们普通老百姓最多见的场景,就是去银行办业务,银行职员会让你反复签1大堆的单据,想必每一个人都会有深入的印象。 签名的特点。人的字迹是很个性化的,越熟练的字体,个性特点越固定,因此1个人的名字,不同的人写出完全相同字迹的几率非常小,即使是专业模仿也能够通过技术鉴别出来,这样1来,人的 签名的验证如果,你拿着1张支票去银行兑换,银行职员会对支票上的签名和印章仔细比对,确保印章大小、样式,和付款人签名等,与银行保存的信息1致,才会给你兑付,这就是 (2)比特币客户端签名功能 数字资产需要签名。类比人类签名,比特币也有签名功能。如果了解比特币钱包(客户端软件),就会发现它提供了1个消息签名的功能,可以用来对其他用户通过比特币网络以外的信息进行签名和验证。我个人使用的是 比特币官方网站 提供的比太钱包,如图: 这个功能干甚么用的呢?有好多小火伴不清楚,这里举个简单的例子解释1下,具体使用的时候绝不限于这些利用。 Alice开了1个网店,但没有直接接入比特币网络,不能自动确认和验证支付者。客户Imfly购买了她的产品,并用比特币支付了全部货款。由于比特币地址和交易都是公然匿名的,为了避免冒充冒领实,Alice需要确认Imfly提供的那个付款地址确切是imfly本人的,否则不能发货。这时候候,就需要Imfly先把支付货款的比特币地址和相干交易 想象1下,如果没有 (3)电子签名 通过上述分析,可以理解的是, 具体开发设计中,就是加密技术代替人的字迹,不然任何签名方法都会被模仿,而且模仿的本钱极低,相反,验证的本钱却很高。具体的加密或验证技术,请参考前面的章节,这里我们介绍亿书是如何使用签名技术的。 亿书也具有签名能力,只不过,目前没有单独提供 (4)亿书的支付密码
我们还是从Api开始,代码以下: // modules/signatures.js文件
// 179行
router.map(shared,{
"get /fee": "getFee","put /": "addSignature"
});
// 188行
library.network.app.use('/api/signatures',router); 通过上面的代码,可以了解 get /api/signatures/fee -> shared.getFee
put /api/signatures/ -> shared.addSignature //签名操作 明显,最核心的方法也就是 // 215行
shared.addSignature = function (req,cb) {
...
library.scheme.validate(body,{
properties: {
...
},required: ["secret","secondSecret"]
},function (err) {
...
library.balancesSequence.add(function (cb) {
if (body.multisigAccountPublicKey && body.multisigAccountPublicKey != keypair.publicKey.toString('hex')) {
modules.accounts.getAccount({publicKey: body.multisigAccountPublicKey},function (err,account) {
...
try {
var transaction = library.logic.transaction.create({
type: TransactionTypes.SIGNATURE,// 297行
sender: account,keypair: keypair,requester: keypair,secondKeypair: secondKeypair,});
} catch (e) {
return cb(e.toString());
}
...
} 毫无疑问, 多重签名上面我们提到,比特币的匿名性,使交易处于不可信当中,终究致使用户不敢交易。有了签名功能,就有了确认双方信息的有效手段,问题总算有了解决方案。聪明的小火伴会发现,签名和验证进程除繁琐,并没有让我们觉得比使用第3方平台更有效、更安全。有无更好的解决方案呢?回答是:有,那就是多重签名。 (1)基本概念 多重签名,可以简单的理解为1个数字资产的多个签名。签名标定的是数字资产所属和权限,多重签名预示着数字资产可由多人安排和管理。在加密货币领域,如果要动用1个加密货币地址的资金,通常需要该地址的所有人使用他的私钥(由用户专属保护)进行签名。那末,多重签名,就是动用这笔资金需要多个私钥签名,通常这笔资金或数字资产会保存在1个多重签名的地址或帐号里。这就好比,我们工作中有1份文件,需要多个部门签署才能生效1样。 在实际的操作进程中,1个多重签名地址可以关联n个私钥,在需要转账等操作时,只要其中的m个私钥签名就能够把资金转移了,其中m要小于等于n,也就是说m/n小于1,可以是2/3,3/5等等,是要在建立这个多重签名地址的时候肯定好的。 (2)工作原理 数字资产在某种情况下,需要多人安排。换句话说,在某些特定条件下,数字资产如果没法确认归属某个特定的人,那末最好让相干人共同签署它的所有权。 依然举上面的例子,在Alice发货以后,Imfly收到货之前,这笔钱应当由第3方信誉比较高的中介暂时保存,这个阶段,这笔钱要末是Alice的,要末是Imfly的,终究的归属要看Imfly是不是收到货。所以,这个第3方,不管如何都是应当有的,不然Imfly就要承当大部份风险(由于比特币的单向不可逆,Imfly发送以后就没有办法收回了) 这样1来,这笔钱的所属关系,在交易进程中触及到Alice、Imfly和平台第3方(虽然不属于它,但它有权裁定资金去向),那末就应当由他们3方签名,因此网上购物就是典型的多重签名的例子。其多重签名模型就是2/3,也就是说只要他们中的两个签名,资金就能够被转移。 具体到这个例子,Imfly把钱打给1个关联3方私钥的多重签名地址,如果全部交易进程顺利,只要Alice和Imfly两个签名,这笔钱就会顺利到达Alice手里。如果不顺利,他们任何1人提出仲裁,平台第3方调查以后,通过签名就可以把这笔钱转给Alice或退回Imfly。这非常类似淘宝和京东的模式,但是比他们更加便捷和安全,最少不用担心第3方倒闭、挪用资金或携款跑路。 (3)利用场景 很明显,多重签名给了加密货币腾飞的翅膀,让它单1单项支付的能力更具吸引力,让加密货币技术利用到各行各业成为可能。这里简单的罗列几个利用场景,供探索和思考:
多重签名的设计,让各种业务去中心化充满无穷可能。 (4)亿书的多重签名
实现Api的代码以下: // 318行
router.map(shared,{
"get /pending": "pending",// Get pending transactions
"post /sign": "sign",// Sign transaction
"put /": "addMultisignature",// Add multisignature
"get /accounts": "getAccounts"
});
// 329行
library.network.app.use('/api/multisignatures',router); 解析1下,最后产生的Api以下: get /api/multisignatures/pending -> shared.pending // 查询等待中的交易
post /api/multisignatures/sign -> shared.sign // 签名交易
put /api/multisignatures/ -> shared.addMultisignature // 创建多重签名帐号
get /api/multisignatures/accounts -> shared.getAccounts // 取得关联的帐号(对应者用户私钥) 提供的功能很明显,包括:待交易查询、关联帐号列表查询,用户签名交易,创建多重签名帐号等4个核心功能。我们先从创建多重签名帐号开始,这个Api使用的是http的 看看 // modules/multisignatures.js文件
shared.addMultisignature = function (req,cb) {
var body = req.body;
library.scheme.validate(body,{
...
// 732行
required: ['min','lifetime','keysgroup','secret']
},function (err) {
...
library.balancesSequence.add(function (cb) {
modules.accounts.getAccount({publicKey: keypair.publicKey.toString('hex')},account) {
...
// 767行
try {
var transaction = library.logic.transaction.create({
type: TransactionTypes.MULTI,// 769行
sender: account,min: body.min,keysgroup: body.keysgroup,lifetime: body.lifetime
});
} catch (e) {
return cb(e.toString());
}
...
}; 从732行可知,创建1个多重签名,必须’min’,‘lifetime’,‘keysgroup’,‘secret’这4参数(其实,1个默许参数就是当前帐号),min代表上面讲到的 经过1系列的验证以后,作为1个交易(交易类型TransactionTypes.MULTI,769行)保存到数据库(区款链)里。创建成功的帐号,可以显示多重帐号菜单,对交易进行操作。接下来,自然应当能够查看全部关联的帐号(请看shared.getAccounts方法),查看 如果用户同意交易,就能够对 // 586行
shared.sign = function (req,{
...
required: ['transactionId',function (err) {
...
// 632行
function done(cb) {
library.balancesSequence.add(function (cb) {
// 634行
var transaction = modules.transactions.getUnconfirmedTransaction(body.transactionId);
if (!transaction) {
return cb("Transaction not found");
}
// 640行
transaction.signatures = transaction.signatures || [];
transaction.signatures.push(sign);
library.bus.message('signature',{
signature: sign,transaction: transaction.id
},true);
cb();
},function (err) {
if (err) {
return cb(err.toString());
}
cb(null,{transactionId: transaction.id});
});
}
...
}; 这个方法,相比单独的签名方法,不同的是单独的签名方法相当于1个新建交易,而这里的多重签名的用户签名,明显仅仅是对未确认交易(634行)进行签名确认(640行保护了1个签名数组,641行的push方法把用户签名写入数组)。而且,相比独立签名,验证也更复杂,我们将在下1篇《交易》1文中集中讨论验证问题。您也能够结合下1篇的内容,浏览和理解这里的签名方法。 总结在加密货币里,每个交易都触及到使用私钥签名,用于确认每笔资金所有人。肯定了所有人,自然就肯定了资金转移的条件、目标和方向,就为我们下1步进行资金转移操作奠定了基础。很自然的,该研究1下亿书的交易了,请看下1篇:《交易》。 链接本系列文章即时更新,若要掌握最新内容,请关注下面的链接 根源文地址: https://github.com/imfly/bitcoin-on-nodejs 首发区块链俱乐部: http://chainclub.org 亿书官方网站: http://ebookchain.org 亿书开发QQ群: 185046161 (亿书为开源项目,欢迎各界小火伴参与) 参考亿书白皮书 http://ebookchain.org/ebookchain.pdf (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |