Javacard----区块链电子钱包

 

一.     需求分析

总体需求:建立一个比特币钱包程序,能够完成获取学号、获取学号、挖矿、生成钱包这四个功能。

(1)  获取学号:使用10个ASCII码表示学号,由卡片向终端返还。

(2)  获取姓名:使用GB2312编码表示姓名,由卡片向终端返还。

(3)  挖矿:使用者发送一条数据,其中包含挖矿难度和交易数据两条信息。卡片在接收到命令后,进行工作量证明算法,向终端返还满足要求的数字。

(4)  生成钱包:使用者向卡片发送一条数据,其中包含公钥。卡片接收到命令后,对公钥地址进行双哈希算法,并将结果进行Base58编码,生成比特币地址并返还终端。

 

二.     程序设计

1.    总体框架:

Javacard----区块链电子钱包_第1张图片

    

    final static byte myBTC_CLA = (byte) 0x80;

    final static byte myBTC_NUMBER=(byte)0x81;

    final static byte myBTC_NAME=(byte)0x82;

    final static byte myBTC_DIG=(byte)0x83;

    final static byte myBTC_PURSE=(byte)0x84;

 

 

2. 获取学号:

        Javacard----区块链电子钱包_第2张图片

 

(1)通过ASCII码对照表,将学号对应表示为:

    byte[ ] mynumber={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x38,0x38};      

 

(2)将学号逐位放入APDU通信缓冲区,设置方向为卡片到终端后,设置数据发送长度,发送数据。

 

3. .获取姓名:

Javacard----区块链电子钱包_第3张图片

(1)  通过网络中的在线编码工具,转化为许下形式:

byte[ ] myname={0x0c,0x0e,0x0e,0x02,0x0c,0x0b,0x0b,0x06} ;

 

(2)将姓名逐位放入APDU通信缓冲区,设置方向为卡片到终端后,设置数据发送长度,发送数据。

 

4. 挖矿:    

Javacard----区块链电子钱包_第4张图片

挖矿的总体思路很简单:

step1:从命令中获取挖矿难度和数据。

Step2:写一个计数器,从0开始计数。

Step3:将该数添加到数据的末尾,组成一个新的数组。

Step4:把这个新的数组进行SHA-1加密,获得20位的哈希值。

Step5:如果这个哈希值的前x位(x为难度,由p1送入)都是0,那么挖矿成功,返回这个计数值;否则,进入计数器的计数加1,重复(3)(4)直至挖矿成功或计数器上限溢出。

       

       受javacard支持的数据格式的限制,只能够使用byte,short类型的变量或数组,给上述思路的实现带来了困难:

(1)  计数器的进位问题

计数器需要找到一个满足工作量证明的随机数,但byte型数据只有8bit,仅仅支持0x00~0xff的数字大小,显然是不够的。我们需要使用一个byte数组来存放这个随机数。此时产生了如何表示计数器进位的问题。

因为计数器位数固定为了4byte,所以降低了进位的表示难度。通过对几种低位计数到0xff时的临界状态的判定,解决进位问题。从最低位开始,到最高位,依次进行如下判断:当低位小于0xff时,低位加1;当低位需要进位时,高位加1,低位置0.

(2)  如何判断哈希值前x位为0的问题

hash值是用16进制数的形式来表示的,没办法简单的通过与固定的数做比较的方式确定0的个数。此处采用以循环左移位的方式,将哈希值与0x80相与。如果结果为0则说明该哈希值第一个bit为0。如此循环x位,便可得出前x位0的个数。设置一个变量用来记录0的个数,当相与结果为0时,该数加1;若有一个不为0的结果,该变量清0,退出循环,重新寻找随机数。

 

 

5. 生成钱包:

Javacard----区块链电子钱包_第5张图片

 

 

 

思路概述:

钱包的生成过程如流程图所示,在对公钥地址进行双哈希加密后获得公钥哈希,在对公钥哈希进行Base58Check编码,获得比特币地址。

在钱包的设计过程中,需要注意所用到的SHA-1、RIPEMD160、Base58checkd函数的输入输出数组的位数和格式。

具体流程如下:

(1)数组的说明

设置几个256byte的数组用于存储中间过程:

byte[ ] temp ,byte[ ] key, byte[ ] keytemp1, byte[ ] keytemp2

将最后的结果,及比特币地址存入byte[ ] keyfinal。

(2)生成流程

1.把buffer的data读进temp,对temp进行SHA-1存入key;

2.把key赋值给temp,并将temp补位至32位,进行temp,得到20位结果存入keytemp1;

3.在temp首位补0,之后放keytemp1的20位,对这21位进行SHA1,生成20位结果,存入key;

4.对key进行SHA1,结果存入keytemp2;

5.temp首位赋值00,跟上20位keytemp1,在加上keytemp2的前4位,组成25位;

6.对temp进行base58,结果存入keyfinal。

 

 

三.关键代码

1.工作量证明

Javacard----区块链电子钱包_第6张图片

Javacard----区块链电子钱包_第7张图片

 

(2)钱包生成过程

Javacard----区块链电子钱包_第8张图片

Javacard----区块链电子钱包_第9张图片

 

四、测试结果

(1)获取学号

Javacard----区块链电子钱包_第10张图片

(2)获取姓名

Javacard----区块链电子钱包_第11张图片

(3)挖矿

Javacard----区块链电子钱包_第12张图片

(4)生成钱包

Javacard----区块链电子钱包_第13张图片

 

五. 感谢

    感谢 EdiblE 为本次程序提供的Javacard版的 RIPE160 和 Base58check 函数。

    感谢 Mr. Chen 在修改bug方面提供的技术支持。

    

    

你可能感兴趣的:(javacard)