dapp前端⾯试题
区块链与前端开发面试准备指南
钱包地址
-
钱包地址是什么?
- 区块链网络中用于标识用户账户的唯一标识符,类似于银行账号
- 由公钥经过特定算法生成,用于接收和发送加密货币或数字资产
- 通常是一串字母和数字组成的字符串,确保交易准确性和安全性
-
如何得到钱包地址?
- 生成私钥:通过密码学算法生成随机私钥(必须安全存储)
- 生成公钥:使用加密算法(如ECDSA)从私钥推导出对应公钥
- 生成钱包地址:对公钥进行哈希和编码处理生成最终地址
- 通常使用钱包软件(如MetaMask、TrustWallet)自动完成上述过程
Gas费用
什么是Gas,如何计算交易Gas费用?
- Gas是以太坊网络中衡量交易执行成本的单位
- 计算公式:
GasLimit × GasPrice = TransactionFee
- GasLimit:交易能消耗的最大gas数量
- GasPrice:每单位gas的价格
- TransactionFee:交易手续费
DApp广播流程
// 1. 对智能合约调用参数进行拼接
const params = {from: userAddress,to: contractAddress,data: contractMethod.encodeABI()
};// 2. 生成ABI
const contract = new ethers.Contract(contractAddress, abi, provider);// 3. 调用三方钱包广播交易
const txHash = await walletProvider.request({method: 'eth_sendTransaction',params: [params]
});// 4. 拿到txHash
console.log('Transaction Hash:', txHash);// 5. 轮询RPC查询交易状态
let receipt = null;
while (!receipt) {receipt = await provider.getTransactionReceipt(txHash);await new Promise(resolve => setTimeout(resolve, 2000)); // 每2秒查询一次
}
console.log('Transaction Receipt:', receipt);
WalletConnect
- 定义:开源协议,用于连接DApps与各种钱包
- 特点:
- 跨钱包兼容性
- 无缝体验(通过二维码扫描连接)
- 安全性(加密通道传输消息)
- 支持多链
- 工作原理:
- DApp生成包含连接信息的QR码
- 用户用移动钱包扫描QR码
- 建立加密WebSocket连接
- 用户在钱包中确认交易,签名后通过WalletConnect传回DApp
ERC标准
ERC20
主要方法:
totalSupply()
: 返回代币总供应量balanceOf(address _owner)
: 返回指定地址的余额transfer(address _to, uint256 _value)
: 转账transferFrom(address _from, address _to, uint256 _value)
: 从指定地址转账approve(address _spender, uint256 _value)
: 授权allowance(address _owner, address _spender)
: 查询授权额度
ERC721
主要方法:
balanceOf(address _owner)
: 返回指定地址拥有的NFT数量ownerOf(uint256 _tokenId)
: 返回NFT所有者safeTransferFrom(address _from, address _to, uint256 _tokenId)
: 安全转移NFTtransferFrom(address _from, address _to, uint256 _tokenId)
: 转移NFTapprove(address _approved, uint256 _tokenId)
: 授权getApproved(uint256 _tokenId)
: 获取授权地址
EVM方法调用
EVM通过交易数据部分识别要调用的智能合约方法:
- 数据前4个字节是方法选择器(方法签名的Keccak哈希前4字节)
- ABI(Application Binary Interface)提供解码和执行方法的信息
ABI详解:
- 定义合约与外部交互的接口规范
- 包含方法名称、参数类型、返回类型等信息
- 用于编码调用数据和解码返回数据
- 示例:
[{"inputs": [{"name": "_to", "type": "address"}, {"name": "_value", "type": "uint256"}],"name": "transfer","outputs": [{"name": "", "type": "bool"}],"stateMutability": "nonpayable","type": "function"}
]
EIP-1193
以太坊钱包与DApp通信的标准接口
关键内容:
- 统一接口
- 基本API方法
- 事件机制
主要方法和事件:
// 请求用户授权
ethereum.request({ method: 'eth_requestAccounts' }).then(accounts => console.log(accounts)).catch(error => console.error(error));// 获取已授权账户
ethereum.request({ method: 'eth_accounts' }).then(accounts => console.log(accounts)).catch(error => console.error(error));// 获取链ID
ethereum.request({ method: 'eth_chainId' }).then(chainId => console.log(chainId)).catch(error => console.error(error));// 账户变更事件
ethereum.on('accountsChanged', accounts => {console.log('Accounts changed:', accounts);
});// 链变更事件
ethereum.on('chainChanged', chainId => {console.log('Chain changed:', chainId);
});
单位转换与BigNumber处理
- 单位:
- Wei: 最小单位(1 ETH = 10^18 Wei)
- Gwei: 1 Gwei = 10^9 Wei
- Decimal: 代币小数位数
ethers.js示例:
import { ethers } from 'ethers';// 转换单位
const wei = ethers.utils.parseUnits("1.0", "ether"); // 1 ETH to Wei
const eth = ethers.utils.formatUnits(wei, "ether"); // Wei to ETH// BigNumber运算
const a = ethers.BigNumber.from("1000");
const b = ethers.BigNumber.from("2000");
const sum = a.add(b);
viem示例:
import { parseEther, formatEther } from 'viem';// 转换单位
const wei = parseEther("1.0"); // 1 ETH to Wei
const eth = formatEther(wei); // Wei to ETH// BigInt运算
const a = 1000n;
const b = 2000n;
const sum = a + b;
技术栈建议
- 重点准备React技术栈
- 熟悉ethers.js或viem库
- 了解Web3.js的基本使用
- 掌握钱包连接(如MetaMask、WalletConnect)的实现
- 熟悉智能合约交互流程