数字资产钱包开发丨如何生成比特币钱包地址?
以比特币为首的加密货币从诞生发展至今,融入了多项先进技术,区块链技术的应用不仅保障了加密货币的流通便利性,更发挥其加密性、不可篡改两大优势,赋能于加密货币的交易,使之更加安全。
区块链钱包的出现,更是为加密资产便捷流通的同时,增添了一份安全保障。区块链钱包指的是利用区块链技术开发的虚拟数字货币产品的管理工具,它应具备虚拟币可交易的特点,即收付款功能。
比特币钱包是基于BTC存在的,目的是让BTC存储更加安全,有效的避免黑客攻击,而且利用比特币钱包中随机生成的比特币地址,可以与其他人进行账户上的比特币转账。
如何生成比特币钱包地址?
Bitcoin地址作为一个随机查找的十六进制字符串,在Bitcoin网络中用于发送和接收Bitcoin。它属于公私不对称ECDSA密钥的公共部分。相对应的私钥用于签署Bitcoin交易,作为交易时来自用户的确认和证明。
从技术层面理解,Bitcoin地址是由ECDSA密钥的公共部分生成的,使用SHA-256和RIPEMD-160进行hash,如下文演示文稿所述,经过处理获取结果hash,最终应用Base58校验编码对密钥进行编码。
接下来一起了解如何使用JCE(java加密扩展),Bouncy Castle(RIPEMD-160)以及最后在bitcoin库中使用Base58编码功能来完成所有这些工作。
生成ECDSA密钥对
BTC使用ECDSA代替RSA作为关键算法。生成如下:
为Elliptic Curve算法创建KeyPairGenerator。
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
利用指定椭圆曲线是secp256k1。
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
keyGen.initialize(ecSpec);
只要获取KeyPairGenerator,就能创建KeyPair即密钥对,从而得到公钥以及私钥。
KeyPair kp = keyGen.generateKeyPair();
PublicKey pub = kp.getPublic();
PrivateKey pvt = kp.getPrivate();
ECDSA私钥
开发者能够对密钥的私有部分进行存储,毕竟从私钥能够派生出公钥。
ECPrivateKey epvt = (ECPrivateKey)pvt;
String sepvt = adjustTo64(epvt.getS().toString(16)).toUpperCase();
System.out.println("s[" + sepvt.length() + "]: " + sepvt);
静态方式adjustTo64()只对包含前导0的十六进制字符串经行填充,所以总长度达到64个字符。
static private String adjustTo64(String s) {
switch(s.length()) {
case 62: return "00" + s;
case 63: return "0" + s;
case 64: return s;
default:
throw new IllegalArgumentException("not a valid key: " + s);
}
}
以上便是根据代码生成获取的示例私钥。
s[64]: 024C8E05018319CED4BB04E184C307BFF115976A05F974C7D945B5151E490ADE
上述这个值一般来说是由数字钱包存储的值。
ECDSA公钥
上述生成得到的密钥的公共部分被编码为BTC地址。第一步,ECDSA密钥根据椭圆曲线上的点表示。椭圆曲线上点的X和Y坐标包括公钥,在开头与“04”连接在一块表示公钥。
ECPublicKey epub = (ECPublicKey)pub;
ECPoint pt = epub.getW();
String sx = adjustTo64(pt.getAffineX().toString(16)).toUpperCase();
String sy = adjustTo64(pt.getAffineY().toString(16)).toUpperCase();
String bcPub = "04" + sx + sy;
System.out.println("bcPub: " + bcPub);
# prints
bcPub: 04CAAA5C0BDDAA22C9D3C0DDAEC8550791891BB2C2FB0F9084D02F927537DE4F443ACED7DEB488E9BFE60D6C68596E6C78D95E20622CC05474FD962392BDC6AF29
执行SHA-256和RIPEMD-160 harsh
因此当前必须在公钥上执行SHA-256,之后是RIPEMD-160。
MessageDigest sha = MessageDigest.getInstance("SHA-256");
byte[] s1 = sha.digest(bcPub.getBytes("UTF-8"));
System.out.println(" sha: " + bytesToHex(s1).toUpperCase());
# prints
sha: 7524DC35AEB4B62A0F1C90425ADC6732A7C5DF51A72E8B90983629A7AEC656A0
当前运用Bouncy Castle为执行RIPEMD-160提供程序,毕竟JCE并无实现这种算法。
MessageDigest rmd = MessageDigest.getInstance("RipeMD160", "BC");
byte[] r1 = rmd.digest(s1);
其次,有必要在哈希开头添加一个0x00的版本字节。
byte[] r2 = new byte[r1.length + 1];
r2[0] = 0;
for (int i = 0 ; i < r1.length ; i++) r2[i+1] = r1[i];
System.out.println(" rmd: " + bytesToHex(r2).toUpperCase());
# prints
rmd: 00C5FAE41AB21FA56CFBAFA3AE7FB5784441D11CEC
重复SHA-256哈希2次
咱们当前要对上述结果执行2次SHA-256哈希。
byte[] s2 = sha.digest(r2);
System.out.println(" sha: " + bytesToHex(s2).toUpperCase());
byte[] s3 = sha.digest(s2);
System.out.println(" sha: " + bytesToHex(s3).toUpperCase());
得出的第2次散列结果的前4个字节用来作为地址校验和。它需要附加到上述的RIPEMD160哈希。得到25字节的BTC地址。
byte[] a1 = new byte[25];
for (int i = 0 ; i < r2.length ; i++) a1[i] = r2[i];
for (int i = 0 ; i < 5 ; i++) a1[20 + i] = s3[i];
运用Base58对地址执行编码
当前需要运用bitcoinj库内的Base58.encode()方式来从而得到最后的的BTC地址。(此演示文稿的代码仅用于学习,请勿将BTC发送到由该代码生成的BTC地址)
System.out.println(" adr: " + Base58.encode(a1));
# prints
adr: 1K3pg1JFPtW7NvKNA77YCVghZRq2s1LwVF
在这篇演示文稿中,可以生成btc地址的流程,即首先生成一个ECDSA密钥对,运用SHA256和RIPEMD160哈希密钥的公共部分。然后,根据执行SHA256 2次并选择前4个字节用来计算校验和,该字节附加到上面的RIPEMD160哈希。结果运用Base58执行编码。
随着数字货币的火热,市面上出现了5000+币种,Bitcoin钱包在币种资产存储、转账、支付等功能上无法满足用户多样化的需求,特别是交易所这种业务型系统,对于钱包功能性、token 支持以及地址管理、余额归集上要求更高,优盾钱包作为全球领先的企业级数字资产管理系统,支持全token,多资产多地址一键归集,实现了国际领先的防内鬼和防黑客技术,深受交易所、商城、游戏项目方的好评。
- 免责声明
- 世链财经作为开放的信息发布平台,所有资讯仅代表作者个人观点,与世链财经无关。如文章、图片、音频或视频出现侵权、违规及其他不当言论,请提供相关材料,发送到:2785592653@qq.com。
- 风险提示:本站所提供的资讯不代表任何投资暗示。投资有风险,入市须谨慎。
- 世链粉丝群:提供最新热点新闻,空投糖果、红包等福利,微信:juu3644。