-
Notifications
You must be signed in to change notification settings - Fork 2
Home
这里是 Maskash 项目的 Wiki 主页
Maskash 是西安西电链融科技有限公司的区块链底层项目,使用零知识证明技术支持完全的匿名交易
以太坊交易执行(Transaction Execute)
交易和消息(Transaction and Messages)
Maskash系统设计文档 v0.0.2
本文档当前仅包含区块链账本的设计。
一、系统概述系统以“底层通用,要害离线”为原则进行设计,整体将分为四部分:1.区块链账本:实现交易的发送、验证、挖矿、存储区块的功能;2.钱包(用户终端):用户用于存储和操作自己拥有的币的独立软件,拥有可离线使用的匿名币管理与交易构造功能。进行交易需通过ipc/rpc与底层配合使用;3.监管终端:实现监管者所需功能的独立软件,拥有可离线使用的用户数据库管理功能。管理类交易通过ipc/rpc与底层组合使用(可间接发送以确保安全);4.发币终端:实现发币者所需功能的独立软件,拥有可离线使用的发币数据库管理功能。发币交易通过ipc/rpc与底层组合使用;
与原设计所述系统的主要差异:1.针对需要遍历区块进行查询所带来的效率问题建立【可通过交易重演重建的】缓存库;2.将原有“一个交易一个区块”改为“多个交易打包进一个区块”;
二、底层运行流程概述根据《一对一匿名转账交易》文档的设计,Maskash系统可分为上述的四个部分。其中,区块链账本是通用的,普通用户、发币者、监管者可以使用完全相同的底层账本,三者的权限及功能差异仅通过为三者准备的专用终端实现。
三、底层开发目标1.支持新交易数据结构的构造、验证、存储——存储将分字段、结构化地存储交易(多类交易需要妥善处理);2.支持通过重演来建立 σg、Sigpub、SN 三个库,并支持实时更新(见附录);3.支持通过重演来建立 Upk、CM 两个树,并支持随时的叶子增删和根值重算(见附录);
四、计划详解
货币结构: <v, SN, k, ρ, *> SN=H256(Usk, ρ) k=H256(Upk || ρ || v )
交易结构: <SN, k, π, E(监管信息)> // 所有CM换成对应的k MSGreg: <TypeTx ,σG , ρ, Hpk >,σG = SigG(ρ, Hpk ) 监管终端直接发布 MSGdel: <TypeTx , σG , ρ, Hpk > 监管终端直接发布 MSGmint: <Upk, kmint, π, v, ρ> 购币用户发至铸币者,链下 kmint=H256 (Upk||ρ||v) MSGmint: <IDTx ,TypeTx ,kmint, Sigpub(IDTx, kmint), G> 铸币者发送至链上 kmint与上面的相同; Sigpub是铸币者签名; G=EGpk (v, Upk ) 是用监管公钥的加密信息 MSGTx_0: <TypeTx, SNold, kRnew, kSnew, R, π, G > 用户直接发送至链上 SNold = H256(Usk, ρold) kRnew = H256(Rpk ||ρR ||vR ) kSnew = H256(Spk ||ρS ||vS ) G=EG pk(vR, Spk, Rpk ) // 监管公钥加密 R=ER pk_enc(vR, ρR ) // 非必要 MSGTx_1:<TypeTx, SNold, kR, R, π, G> 用户直接发送至链上 SNold=H256(Ssk ||ρold ) kR=H256(Rpk ||ρR ||vR ) G=EG pk(vR , Spk , Rpk ) // 监管公钥加密 R=ER pk_enc (vR , ρR ) // 非必要
字段总集: TypeTx 所有交易 σG = SigG(ρ, Hpk ) 增删用户,监管者 Sigpub(IDTx, k) 铸币,铸币者 ρ 仅监管者发起的交易中明文上链,其余的均经hash Hpk 仅监管者发起的交易中上链,常用 Upk 不直接上链,经监管者公钥加密后包含在G中上链 kmint 铸币 kR / kRnew 转账 ksnew 零币转账 SNold 转账(未使用的币不需要发送这个值,用户自己保存即可) π 转账 v 铸币 R 转账 G 除监管者本人发起的交易中都包含
Maskash构造交易所需参数:(1)交易金额:v;(2)老承诺随机数:old_r; (3)新承诺随机数:new_r; (4)发送方私钥:ask_s; (5)接收方公钥:apk_r;
总交易结构: 新增: <int TypeTx, vector<string> maskashData, CMroot, H(Upk)root>
删除: nonce,或使nonce无效。
在此结构中,对交易的处理将根据TypeTx的值来区分对待。 maskashData中将包含所有出现过的字段,当前交易中未被使用的字段值为空。
查询库使用以太坊自带的levelDB
区块结构:在原有区块中添加当块的 CMroot, H(Upk)root
五、功能设计
添加用户:监管者:【不需要查询链上数据】
所发送交易需要上链,其中签名 σg 需要矿工验证
Msk模块中没有相关实现
矿工:【需要读写链上数据】只检查签名,不检查证明
- 查询:是否有 σg (原方案中要求链上查询,现可通过快速查询库查询)
- 修改:将 Hpk 加入公钥树,算得新根值随交易上链
Msk模块中没有相关实现移除用户:
监管者:【不需要查询链上数据】 所发送交易需要上链,其中签名 σg 需要矿工验证
Msk模块中没有相关实现
矿工:【需要读写链上数据】只检查签名,不检查证明
- 查询:是否有 σg (原方案中要求链上查询,现可通过快速查询库查询)
- 修改:将 Hpk 移出公钥树,算得新根值随交易上链
Msk模块中没有相关实现购币:购币者:MSGmint: <Upk, kmint, π, v, ρ> 其中,kmint=H256 (Upk||ρ||v),Upk=H(Usk),π用于证明Upk==H(Usk) Msk模块需要的参数:Usk、ρ、v 剩余的kmint、Upk在msk模块中均能生成;发币者:MSGmint: <IDTx ,TypeTx ,kmint, Sigpub(IDTx, kmint), G> 其中,kmint与上面购币者发送来的相同; Msk模块中没有签名、加密相关实现(即Sigpub) Msk模块中没有G= EGpk(v, Upk )的生成功能。【不需要查询链上数据】
所发送交易需要上链
矿工:【需要读写链上数据】只检查签名,不检查证明
- 查询:是否有 Sigpub(原方案中要求链上查询,现可通过快速查询库查询)
- 修改:将Hmint写入CM树,算得新根值随交易上链
零币转账:用户S:<TypeTx, SNold, kRnew, kSnew, R, π, G > SNold = H256(Usk, ρold) kRnew = H256(Rpk ||ρR ||vR ) kSnew = H256(Spk ||ρS ||vS ) G=EG pk(vR, Spk, Rpk ) // 监管公钥加密 R=ER pk_enc(vR, ρR ) // 非必要
其中,SN old可查询得到,msk模块生成k需要Rpk、ρR、vR、Ssk、ρS、vS ,msk模块生成G、R需要vR, Ssk, Rpk;vR, ρR上面的Ssk传给msk模块,模块内有生成Spk的功能。【不需要查询链上数据】
对币的拆分等操作都在钱包中进行 所发送交易需要上链 将原有的一个币“重铸”为一个给R的新币和一个给自己找零的币
矿工:【需要读写链上数据】 Msk模块需要的参数:【SNold,kRnew,kSnew,G,π】
- 查询:是否有 SN^old (原方案中要求链上查询) - 修改:加入新CM并重建CM树,算得新根值随交易上链
整币转账:用户S:<TypeTx, SNold, kRnew,R, π, G > SNold = H256(Usk, ρold) kRnew = H256(Rpk ||ρR ||vR ) G=EG pk(vR, Spk, Rpk ) // 监管公钥加密 R=ER pk_enc(vR, ρR ) // 非必要 其中,SN old可查询得到,msk模块生成k需要Rpk、ρR、vR msk模块生成G、R需要vR, Ssk, Rpk;vR, ρR 上面的Ssk传给msk模块,模块内有生成Spk的功能。
【不需要查询链上数据】 对币的拆分等操作都在钱包中进行 所发送交易需要上链 将原有的一个属于自己的币“重铸”为一个给R的币
矿工:【需要读写链上数据】
Msk模块需要的参数:【SNold,kRnew,G,π】
- 链上查询:是否有 SN^old
- 修改:加入新CM并重建CM树,算得新根值随交易上链
收款:
用户S:【不需要查询链上数据】
将与广播的相同的交易信息发送给用户 R
用户R:(主动上链查询 / 被动收到广播)确认交易是否已上链(即交易成功)
重算CM,并与收到的CM^new进行比较
构造 SNr
构造 <CMr^new、vr、ρr、SNr、*> 存入自己的钱包
附:一些对该系统设计的分析1、数据存储策略——链上信息最小化 链上(需要通过网络进行传输的)数据仅有历史交易记录。需要快速读取的其他数据的总状态均通过对历史交易的重演来在各个节点独立建立(暂称为 快速查询库)。所有需要储存的、供查询的信息组成的信息库:1.用户信息库 <Upk, *> 2.购币信息库 <Upk, v, *> 3.钱包 <SN, CM, v, *> 4.用户公钥池 <PublicKey Hash Merkle Trie> 5.承诺池 <CM Hash Merkle Trie> 6.σg查询库7.Sigpub查询8.SN 查询库 <Transacted SN>
信息库来源1.数据库单方存储,直接写入,无法由交易历史重建(数据量持续增长)2.数据库单方存储,直接写入,无法由交易历史重建(数据量持续增长,应该略大于用户信息库)3.数据库单方存储,直接写入,无法由交易历史重建(数据个人保存)4.数据库多方存储,全量备份,可由历史交易记录重建5.数据库多方存储,全量备份,可由历史交易记录重建6.数据库多方存储,全量备份,可由历史交易记录重建,矿工必需7.数据库多方存储,全量备份,可由历史交易记录重建,矿工必需8.数据库多方存储,全量备份,可由历史交易记录重建,矿工必需
2、底层需要做的工作
-
查询链上历史 σg(存在交易信息中,将加入快速查询库)
-
查询链上历史 Sigpub(存在交易信息中,将加入快速查询库)
-
查询链上历史 SN(存在交易信息中,将加入快速查询库)
-
eth_Tx 传递交易信息
-
算Merkle树并将树根上链(打包一起算根,一组交易一起加入区块)
-
通过某种交易自带的特征,在已有的区块内查询该交易
-
重放查询历史Upk、CM、SN,前两者需要每通过一笔交易 / 一个块进行一次重算更新
3、一些其他问题的思考(1)猜测:《一对一匿名转账交易》文档中一块一交易的设计目的:【若一堆交易中混着添加/删除账户的操作,会因几笔交易不存在时序差异而引发潜在的交易异常】比如,一个账户几乎同时发生了两笔交易:一、转出了他所有的币;二、注销掉他自己。这两个交易如果出现在一个块里,或被打包时进了两个块但顺序恰好反了过来都会导致交易无法成功而损失所有的币。同理,一个账户几乎同时被建立和买币,在上述两种情况下都是无法正常处理的。(这几种交易没有可以用来判断它们发生顺序的特征)若无论如何都要做出来,可以考虑规定个账户冻结时间,或增加一个操作条件检测功能:规定某些交易要在满足特定条件的情况下才可被发送 / 被处理。
(2)关于原以太坊中nonce的处理问题nonce 与原以太坊的账户、交易有着较高程度的耦合,但经过分析后我认为:若要使用前面的设计,这个概念必须被彻底去除(暂时也做不到彻底去除原有的以太坊账户系统)。在以太坊交易中,每笔交易都必须填nonce,每个用户的nonce要自增,同nonce交易只会被处理一次。而每个用户在两个区块中间的时间段内,手里的nonce一定是相同的,如此一来,在使用我们设计的使用共享账户的情况下,每个区块内一定只能放一笔交易。 取消nonce,对于匿名币的操作应该没有影响——Maskash的交易验证过程中会检查SN字段(每个交易都有一个独一无二的SN值,已被处理过的交易的SN值将会被记录,第二次带有该值的交易将会被直接抛弃),可以通过 SN 缓存库来处理多次接收到同一笔交易的情况(对于两笔相同交易出现在同一个区块内的情况,可以通过对交易进行打包时跑一个验证来避免)。对于另外三种“增删买”的交易,也可以通过对历史 σg、Sigpub 的查询来避免同一个交易的重复处理。但无法处理类似上面例子中的问题——因为那几种交易没有可以用来判断它们发生顺序的特征。应该只能通过【规定冻结时间】来实现,比如设置一个【距离上次转账多少个块之内不许注销账户】的人为规则等。
4.各种操作的简化记录添加用户:
监管者:【不需要查询链上数据】
所发送交易需要上链,其中签名 σg 需要矿工验证
矿工:【需要读写链上数据】
- 查询:是否有 σg (原方案中要求链上查询,现可通过快速查询库查询)
- 修改:将 Hpk 加入公钥树,算得新根值随交易上链
移除用户:
监管者:【不需要查询链上数据】
所发送交易需要上链,其中签名 σg 需要矿工验证
矿工:【需要读写链上数据】
- 查询:是否有 σg (原方案中要求链上查询,现可通过快速查询库查询)
- 修改:将 Hpk 移出公钥树,算得新根值随交易上链
购币:
发币者:【不需要查询链上数据】
所发送交易需要上链
矿工:【需要读写链上数据】
- 查询:是否有 Sigpub(原方案中要求链上查询,现可通过快速查询库查询)
- 修改:将Hmint写入CM树,算得新根值随交易上链
零币转账:
用户S:【不需要查询链上数据】
对币的拆分等操作都在钱包中进行
所发送交易需要上链
将原有的一个币“重铸”为一个给R的新币和一个给自己找零的币
矿工:【需要读写链上数据】
- 查询:是否有 SN^old (原方案中要求链上查询)
- 修改:加入新CM并重建CM树,算得新根值随交易上链
整币转账:
用户S:【不需要查询链上数据】
对币的拆分等操作都在钱包中进行
所发送交易需要上链
将原有的一个属于自己的币“重铸”为一个给R的币
矿工:【需要读写链上数据】
- 链上查询:是否有 SN^old
- 修改:加入新CM并重建CM树,算得新根值随交易上链
收款:
用户S:【不需要查询链上数据】
将与广播的相同的交易信息发送给用户 R
用户R:(主动上链查询 / 被动收到广播)确认交易是否已上链(即交易成功)
重算CM,并与收到的CM^new进行比较
构造 SNr
构造 <CMr^new、vr、ρr、SNr、*> 存入自己的钱包
所需要的函数:
-
添加新用户过程中监管者生成签名的函数 SigG(ρ, Hpk),返回值为签名 σg;
-
Merkle Trie 生成:trieGenerate、更新trieUpdate、取根trieGetRoot;
-
公钥生成函数 generatePk(privateKey);
-
验证π的函数bool validatePi(Pi, *) // *代表与Pi所证明的东西相关的值;
-
通过所需的参数生成各类交易信息的函数makeTx(*) // *代表生成对应类型交易所需的参数,返回值是一个包含所有待发送交易信息的对象。
Maskash构造交易所需参数:构建交易所需信息:(1)交易金额:V;(2)老承诺随机数:old_r; (3)新承诺随机数:new_r; (4)发送方私钥:ask_s; (5)接收方公钥:apk_r;
文档编写思路:“功能点”驱动——将层次分块,内部结构 / 功能逐层细分,对每一层进行相应的描述。层次分块:一、各模块(宏观可见的大功能)说明;二、模块内各部分说明(交易构造、交易发送、交易验证、数据更新等);二、类说明(概述);三、函数说明(参数、返回值 / 执行效果);
文档中各处都可以添加技术重点、难点、存在的问题等
各层次中需添加的描述:
-
增加的 / 被修改的类的说明
a. 功能概述; b. 调试用输出信息说明;
-
接口说明
a. 参数的类型、名称; b. 返回值说明; c. 其他附加说明。
-
进行修改的位置
文件相对位置、行数、注释标记(规则);
-
被修改部分与其他部分的耦合情况;