为什么需要 Keystore 文件 通过这篇文章理解开发HD 钱包涉及的 BIP32、BIP44、BIP39,私钥其实就代表了一个账号,最简单的保管账号的方式就是直接把私钥保存起来,如果私钥文件被人盗取,我们的数字资产将洗劫一空。 Keystore 文件就是一种以加密的方式存储密钥的文件,这样的发起交易的时候,先从Keystore 文件是使用密码解密出私钥,然后进行签名交易。这样做之后就会安全的多,因为只有黑客同时盗取 keystore 文件和密码才能盗取我们的数字资产。
Keystore 文件如何生成的 以太坊是使用对称加密算法来加密私钥生成Keystore文件,因此对称加密秘钥(注意它其实也是发起交易时需要的解密秘钥)的选择就非常关键,这个秘钥是使用KDF算法推导派生而出。
Demo Code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>haha</title>
</head>
<script src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
<script src="https://cdn.ethers.io/scripts/ethers-v4.min.js" charset="utf-8" type="text/javascript"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.js"></script>
<body>
<div>
<div>
<p>KeyStore导出</p>
<p>密码: <input type="text" id="password"></p>
<p>钱包地址: <span id="address"></span></p>
<p style="color: deepskyblue;"><span id="message"></span></p>
<div>
<button type="button" onclick="save_keystore()" ;> 创建钱包 </button>
</div>
</div>
<HR align=center width=100% color=#987cb9 SIZE=1>
<div>
<p>加载KeyStore文件</p>
<p>KeyStore:<input type="file" id="select_wallet_file" /></p>
<p>密码: <input type="text" id="recovery_password"></p>
<p>钱包地址: <span id="recovery_address"></span></p>
<p>私钥: <span id="recovery_privateKey"></span></p>
<p>
<span style="color: deepskyblue;" id="recovery_message"></span>
<span style="color: red;" id="recovery_error"></span>
</p>
<div>
<button type="button" onclick="select_submit_wallet()" ;> 获取私钥 </button>
</div>
</div>
</div>
<script type="text/javascript">
function save_keystore() {
const password = $("#password").val()
const privateKey = ethers.utils.randomBytes(32);
const wallet = new ethers.Wallet(privateKey);
$('#address').html(wallet.address)
$('#message').html('文件保存中...')
wallet.encrypt(password).then(function (json) {
const blob = new Blob([json], { type: "text/plain;charset=utf-8" });
$('#message').html('文件保存成功!')
saveAs(blob, "keystore.json");
})
}
function select_submit_wallet() {
const password = $("#recovery_password").val()
const fileReader = new FileReader();
const inputFile = document.getElementById('select_wallet_file')
const file = inputFile.files[0];
fileReader.readAsText(file);
fileReader.onload = function (e) {
var json = e.target.result;
$('#recovery_message').html('正在加载KeyStore文件...')
ethers.Wallet.fromEncryptedJson(json, password).then(function (wallet) {
$('#recovery_message').html('加载KeyStore文件成功')
$('#recovery_address').html(wallet.address)
$('#recovery_privateKey').html(wallet.privateKey)
}, function (error) {
$('#recovery_error').html(error)
});
};
}
</script>
</html>
</body>
</html>
测试Demo 代码简陋,见谅!
参考文档 1. Tiny熊 使用ethers.js开发以太坊Web钱包2 - 账号Keystore文件导入导出 2. ethers.js 中文文档
|