作用:
-
1、备份更容易。按照比特币的原则,尽量不要使用同一个地址,一个地址只使用一次,这样会导致频繁备份钱包。hd钱包只需要在创建时保存主密钥,通过主密钥可以派生出所有的子密钥。
-
2、私钥离线更安全。主私钥离线存储,主公钥在线使用,通过主公钥可以派生出所有的子公钥。例如:给每个商品提供一个收款地址。
-
3、利于管理,权限控制。树状结构类似于公司的组织架构,可以给各个部门指定一个密钥分支。
-
4、记账。只使用公钥即可记账。
bip39
bip39:将seed 用方便记忆和书写的单字表示。一般由 12 个单字组成,称为 mnemonic code(phrase),中文称为助记词或助记码。例如: average green proud remember advance trick estate oblige trouble when cube person
bip43
bip43对bip32树结构增加了子索引标识purpose的拓展m/purpose’/*
bip32的索引:m/0’/*
bip44的索引:m/44’/*。
bip44
bip44:基于bip32和bip43,赋予树状结构中的各层特殊的意义。让同一个 seed 可以支援多币种、多帐户等。各层定义如下:
m / purpose’ / coin_type’ / account’ / change / address_index
- purporse’: 固定值44’, 代表是bip44
- coin_type’: 这个代表的是币种, 可以兼容很多种币, 比如btc是0’, eth是60’, 例如:btc一般是 m/44’/0’/0’/0, eth一般是 m/44’/60’/0’/0
- account’:账号
- change’: 0表示外部链(external chain),用户接收比特币,1表示内部链(internal chain),用于接收找零
- address_index:钱包索引
钱包最佳实践
- 使用助记词(bip39)
- 使用层级确定性钱包(hd wallets)(bip32)
- 使用多目的hd wallets(bip43)
- 使用多币种,多账号的hd wallets (bip44)
比特币钱包地址创建过程
1、生成128bit~256bit作为私钥
2、通过secp256k1椭圆曲线算法得到私钥对应的公钥
3、将公钥进行sha-256,得到公钥hash
4、将3的结果进行rimemd-160
5、将4中结果添加1个字节版本号
6、将5中结果进行两次sha-256,取前4个字节作为checksum
7、将6中结果添加到5中结果的末尾
8、将7中结果进行base58,结果为比特币地址
bitcoinj创建钱包
bitcoinj是比特币协议java版本实现的库。
添加依赖:
dependencies {
implementation ‘org.bitcoinj:bitcoinj-core:0.14.7’
implementation ‘org.slf4j:slf4j-api:1.7.25’
implementation ‘com.squareup.okhttp3:okhttp:3.10.0’
implementation ‘com.squareup.okhttp3:logging-interceptor:3.10.0’
implementation ‘com.google.zxing:core:3.3.3’//二维码
}
android最大方法数的限制,60k 开启multidexenabled
android {
compilesdkversion 28
defaultconfig {
multidexenabled true
}
}
dependencies {
implementation ‘com.android.support:multidex:1.0.3’
}
创建新钱包
file walletfile = activity.getfilestreampath(“wallet-protobuf”);
//创建钱包
wallet = new wallet(constants.network_parameters);
//创建walletfiles,设置自动保存wallet
walletfiles walletfiles = wallet.autosavetofile(walletfile, 3 * 1000, timeunit.milliseconds, null);
//立即保存
walletfiles.savenow();
钱包创建源码分析:
-
wallet
-
keychaingroup
-
deterministickeychain
-
deterministicseed
protected deterministickeychain(deterministicseed seed, @nullable keycrypter crypter) {
this.seed = seed;
basickeychain = new basickeychain(crypter);
if (!seed.isencrypted()) {
rootkey = hdkeyderivation.createmasterprivatekey(checknotnull(seed.getseedbytes()));
rootkey.setcreationtimeseconds(seed.getcreationtimeseconds());
addtobasicchain(rootkey);
hierarchy = new deterministichierarchy(rootkey);
for (int i = 1; i <= getaccountpath().size(); i++) {
addtobasicchain(hierarchy.get(getaccountpath().sublist(0, i), false, true));
}
initializehierarchyunencrypted(rootkey);
}
// else…
// we can’t initialize ourselves with just an encrypted seed, so we expected deserialization code to do the
// rest of the setup (loading the root key).
}
获取钱包地址
address address = wallet.currentaddress(keychain.keypurpose.receive_funds);
address.tostring();
在获取地址的过程中会调用rimemd-160算法处理公钥hash:
//utils.java
public static byte[] sha256hash160(byte[] input) {
byte[] sha256 = sha256hash.hash(input);
ripemd160digest digest = new ripemd160digest();
digest.update(sha256, 0, sha256.length);
byte[] out = new byte[20];
digest.dofinal(out, 0);
return out;
}
处理公钥hash后会进行base58算法:
//versionedchecksummedbytes.java
public final string tobase58() {
// a stringified buffer is:
// 1 byte version + data bytes + 4 bytes check code (a truncated hash)
byte[] addressbytes = new byte[1 + bytes.length + 4];
addressbytes[0] = (byte) version;
system.arraycopy(bytes, 0, addressbytes, 1, bytes.length);
byte[] checksum = sha256hash.hashtwice(addressbytes, 0, bytes.length + 1);
system.arraycopy(checksum, 0, addressbytes, bytes.length + 1, 4);
return base58.encode(addressbytes);
}
从文件中加载钱包
//读取钱包文件
file walletfile = activity.getfilestreampath(“wallet-protobuf”);
if (walletfile.exists()) {
inputstream inputstream = new fileinputstream(walletfile);
//反序列化
wallet = new walletprotobufserializer().readwallet(inputstream);
//设置自动保存
wallet.autosavetofile(walletfile, 3 * 1000, timeunit.milliseconds, null);
//清理钱包
wallet.cleanup();
}
创建地址二维码
string s = bitcoinuri.converttobitcoinuri(address, null, null, null);
bitmap bitmap = qr.bitmap(s);
bitmapdrawable bitmapdrawable = new bitmapdrawable(getresources(), bitmap);
bitmapdrawable.setfilterbitmap(false);
mqrimageview.setimagedrawable(bitmapdrawable);
public static bitmap bitmap(final string content) {
try {
final hashtable<encodehinttype, object> hints = new hashtable<encodehinttype, object>();
hints.put(encodehinttype.margin, 0);
hints.put(encodehinttype.error_correction, errorcorrectionlevel.h);
final bitmatrix result = qr_code_writer.encode(content, barcodeformat.qr_code, 0, 0, hints);
final int width = result.getwidth();
final int height = result.getheight();
final byte[] pixels = new byte[width * height];
for (int y = 0; y < height; y++) {
final int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = (byte) (result.get(x, y) ? -1 : 0);
}
}
final bitmap bitmap = bitmap.createbitmap(width, height, bitmap.config.alpha_8);
bitmap.copypixelsfrombuffer(bytebuffer.wrap(pixels));
return bitmap;
} catch (final writerexception x) {
log.info(“problem creating qr code”, x);
return null;
}
}
bitcoin钱包收款和转账
比特币钱包余额需要统计所有钱包地址对应的utxo
simplified payment verification (spv):节点无需下载所有的区块数据,而只需要加载所有区块头数据(block header的大小为80b),即可验证这笔交易是否曾经被比特币网络认证过。
布隆过滤器(bloom filter):过滤掉那些不包含有目标地址的交易信息,这一步能避免掉大量不相关的数据下载。
创建区块链
//创建区块链文件
file blockchainfile = new file(getdir(“blockstore”, context.mode_private), “blockchain”);
//创建spvblockstore,管理区块数据
blockstore = new spvblockstore(constants.network_parameters, blockchainfile);
//加载检查点
final inputstream checkpointsinputstream = getassets().open(“checkpoints-testnet.txt”);
checkpointmanager.checkpoint(constants.network_parameters, checkpointsinputstream,
blockstore, earliestkeycreationtime);
//创建区块链对象
blockchain = new blockchain(constants.network_parameters, wallet, blockstore);
同步区块链
//添加网络权限:
private void startup() {
log.d(tag, "startup: ");
peergroup = new peergroup(constants.network_parameters, blockchain);
peergroup.setdownloadtxdependencies(0); // recursive implementation causes stackoverflowerror
peergroup.addwallet(wallet);//设置钱包,重要
try {
packageinfo packageinfo = getpackagemanager().getpackageinfo(getpackagename(), packagemanager.get_activities);
peergroup.setuseragent(user_agent, packageinfo.versionname);
} catch (packagemanager.namenotfoundexception e) {
e.printstacktrace();
}
peergroup.setmaxconnections(8);
int connecttimeout = (int) (15 * dateutils.second_in_millis);
peergroup.setconnecttimeoutmillis(connecttimeout);
int discoverytimeout = (int) (10 * dateutils.second_in_millis);
peergroup.addconnectedeventlistener(mpeerconnectedeventlistener);
peergroup.adddisconnectedeventlistener(mpeerdisconnectedeventlistener);
peergroup.adddiscoveredeventlistener(mpeerdiscoveredeventlistener);
peergroup.setpeerdiscoverytimeoutmillis(discoverytimeout);
//添加节点探索器,重要
peergroup.addpeerdiscovery(new peerdiscovery() {
private final peerdiscovery normalpeerdiscovery = multiplexingdiscovery
.forservices(constants.network_parameters, 0);
@override
public inetsocketaddress[] getpeers(final long services, final long timeoutvalue,
final timeunit timeoutunit) throws peerdiscoveryexception {
return normalpeerdiscovery.getpeers(services, timeoutvalue, timeoutunit);
}
@override
public void shutdown() {
normalpeerdiscovery.shutdown();
}
});
peergroup.startasync();
peergroup.startblockchaindownload(null);
}
比特币收款
获取测试用比特币:testnet.manu.backend.hamburg/faucet 刚收到的币可能需要几分钟后才能使用
//监听比特币接受事件
wallet.addcoinsreceivedeventlistener(mwalletlistener);
//刷新余额
coin balance = wallet.getbalance(wallet.balancetype.estimated);
比特币转账
比特币测试链转账查询 创建一个tx,对tx进行签名,对tx进行p2p网络广播
address address = address.frombase58(constants.network_parameters, to);
//转账金额,以mbtc为单位
coin coin = monetaryformat.mbtc.parse(amount);
//创建请求
sendrequest sendrequest = sendrequest.to(address, coin);
try {
//创建transaction
transaction transaction = wallet.sendcoinsoffline(sendrequest);
//通过p2p广播
blockchainservice.broadcasttransaction(bitcoinwalletactivity.this, transaction);
} catch (insufficientmoneyexception e) {
toast.maketext(this, e.getlocalizedmessage(), toast.length_short).show();
e.printstacktrace();
}
public static void broadcasttransaction(context context, transaction transaction) {
intent intent = new intent(action_broadcast_transaction, null, context, blockchainservice.class);
intent.putextra(action_broadcast_transaction_hash, transaction.gethash().getbytes());
context.startservice(intent);
}
@override
public int onstartcommand(intent intent, int flags, int startid) {
log.d(tag, "onstartcommand: ");
if (intent != null) {
byte[] txhash = intent.getbytearrayextra(“tx”);
if (txhash != null) {
sha256hash sha256hash = sha256hash.wrap(txhash);
transaction transaction = bitcoinwalletmanager.getinstance().getwallet().gettransaction(sha256hash);
peergroup.broadcasttransaction(transaction);
log.d(tag, "onstartcommand: " + sha256hash.tostring());
}
}
return super.onstartcommand(intent, flags, startid);
}
以太坊钱包
以太坊钱包功能与比特币钱包功能类似,获取用户余额,管理地址和密钥,转账、智能合约调用。以太坊钱包一般不用在本地维护区块链数据,只需要使用json-rpc访问
钱包文件
keystore = 私钥 + 密码
如果使用imtoken创建钱包,创建了助记词,密码用来加密钱包地址对应的子私钥,加密的结果就是keystore.
{
“address”: “001d3f1ef827552ae1114027bd3ecf1f086ba0f9”,
“crypto”: {
“cipher”: “aes-128-ctr”,
“ciphertext”: “233a9f4d236ed0c13394b504b6da5df02587c8bf1ad8946f6f2b58f055507ece”,
“cipherparams”: {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、oppo等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面v无偿领取!(备注android)
学习分享,共勉
android高级架构师进阶之路
题外话,我在阿里工作多年,深知技术改革和创新的方向,android开发以其美观、快速、高效、开放等优势迅速俘获人心,但很多android兴趣爱好者所需的进阶学习资料确实不太系统,完整。今天我把我搜集和整理的这份学习资料分享给有需要的人,若有关android学习进阶可以与我在android终极开发交流群一起讨论交流。 点击这里前往我的git领取资料 的同时,还可以加入一个好的学习交流圈,何乐而不为呢?加入我们和我们一起吧!!
- android进阶知识体系学习脑图
- android进阶高级工程师学习全套手册
- 对标android阿里p7,年薪50w+学习视频
- 大厂内部android高频面试题,以及面试经历
分享给有需要的人,若有关android学习进阶可以与我在android终极开发交流群一起讨论交流。 点击这里前往我的git领取资料 的同时,还可以加入一个好的学习交流圈,何乐而不为呢?加入我们和我们一起吧!!
- android进阶知识体系学习脑图
[外链图片转存中…(img-htdcct7g-1710901256682)]
- android进阶高级工程师学习全套手册
[外链图片转存中…(img-b11dcjod-1710901256682)]
- 对标android阿里p7,年薪50w+学习视频
[外链图片转存中…(img-bypqlhfb-1710901256682)]
- 大厂内部android高频面试题,以及面试经历
发表评论