用于存储,管理加密货币的工具。允许用户安全的发送,接收和管理数字资产
每个钱包有一个地址,可以当作是你在区块链上的账号,他是一个公开的字符串,主要用于发送和接收加密货币,就像银行卡账号
钱包类型
- 热钱包
比如 MetaMask,Trust Wallet,Coinbase Wallet。这类钱包与互联网连接,可以随时访问和使用
- 冷钱包
硬件钱包,纸钱包(公私钥记录在纸上)。不与互联网连接,安全性更高。
公钥和私钥
- 对称加密
加密和解密使用相同的密钥。意味着发送方和接收方共享这个秘钥
对称加密存在一个问题,一旦密钥泄漏,加密信息就被别人看到
- 非对称加密
为了解决对称加密的问题,诞生了非对称加密:使用一对不同的密钥,公钥和私钥。公钥和私钥需要配对使用
公钥:公开开放,任何人都可以使用公钥来加密信息
私钥:只有持有私钥的人才可以解密信息
- 数字签名
因为公钥匙公开的,所有人都可以使用它来加密信息,为了确保公钥不被滥用,诞生了数字签名
数字签名技术使用私钥进行加密,使用公钥进行解密和验证,它能够验证消息是否是指定的发送者发出
并且在传输过程中没有被篡改
交易验证
在以太坊中,数字签名技术用于交易验证,确保交易的真实性,完整性。交易验证有以下几步:
- 用户签名交易,用户将交易数据准备好,计算出交易数据的哈希值,使用椭圆曲线签名算法(ECDSA)对哈希值进行签名,将签名值(v,r,s)附加到交易数据中广播
- 矿工验证交易,矿工收到一笔交易后,先计算出交易数据(不含签名)的哈希值,再使用椭圆曲线签名算法(ECDSA),从签名和哈希值中恢复出用户公钥。最后将恢复的公钥与用户钱包地址做对比,如果两者一致,则交易验证成功
助记词
当我们在钱包中创建账户的时候,比如在 Metamask 中创建了一个数字钱包,实际上是一个复杂的过程:
- 生成种子,种子是一个随机生成的数字序列
- 生成助记词,将种子转换成一系列方便记忆的单词,在以太坊中,有一个固定的2048个单词库
- 生成私钥,用来控制钱包,使用种子通过 HMAC-SHA512 算法进行计算得到
- 生成公钥,有了私钥后,通过椭圆曲线加密算法(ECDSA)计算出对应的公钥
- 生成钱包地址,使用 Keccak-256 哈希函数计算公钥的哈希值,取哈希值最后的20个字节,就是钱包地址
连接钱包
在 Dapp 应用中,前端需要连接加密钱包,通过加密钱包和区块链进行钱包,以 MetaMask 钱包为例
当我们在浏览器中安装 MetaMask 钱包插件之后,会在浏览器中的全局对象注册一个 window.etherum 对象
// 请求用户授权访问 metamask 钱包
const accounts = await window.etherum.request({ method: "eth_requestAccounts" })
console.log("Connected wallet:", accounts[0])
// 获取账户信息和钱包余额
const provider = new ethers.providers.Web3Provider(window.ethereum);
const balance = await provider.getBalance(address);
const formateBalance = ethers.utils.formatEther(balance); // 将 Wei 转换为 ETH
// 发送交易
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const tx = await signer.sendTransaction({
to: "0xRecipientAddressHere", // 接收地址
value: ethers.utils.parseEther("0.01"), // 发送 0.01 ETH
});
console.log("Transaction hash:", tx.hash);
await tx.wait(); // 等待交易确认
// 调用合约
const contractABI = [
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [{ "name": "", "type": "string" }],
"type": "function",
},
];
const contractAddress = "0xYourContractAddressHere";
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const contract = new ethers.Contract(contractAddress, contractABI, signer);
const contractName = await contract.name(); // 调用合约的方法
可以看到,所有的操作都涉及到 provider 和 singer
Provider:负责与区块链节点进行通行,主要用于查询链上的状态信息,常见的有
- JsonRpcProvider
- WebSocketProvider
- InfuraProvider
- Web3Provider(MetaMask)
Singer:代表用户的钱包,负责签署交易或信息,主要用于写入信息,需要使用到用户的私钥(授权)