NodeJS全栈WEB3面试题——P2智能合约与 Solidity

2.1 简述 Solidity 的数据类型、作用域、函数修饰符。

  • 数据类型:

    • 值类型(Value Types)uint, int, bool, address, bytes1bytes32, enum

    • 引用类型(Reference Types)array, struct, mapping

    • 特殊类型string(动态字节数组)

  • 作用域(Scope):

    • 状态变量(State variables):存储在区块链上的合约存储中,合约生命周期内存在。

    • 局部变量(Local variables):函数内部声明的变量,生命周期仅限于函数调用。

    • 全局变量(Global variables) :Solidity提供的如msg.sender, block.timestamp等,访问链上信息。

  • 函数修饰符(Function Modifiers):

    用于改变函数行为的代码片段,可以控制访问权限、前置条件、后置操作等。常见如onlyOwner限制调用者,payable允许函数接收以太币等。修饰符可以复用代码,提高合约安全性。


2.2 require、assert、revert 区别?使用场景?

  • require(condition, message):

    用于输入校验和外部条件判断。失败时回退交易并返还剩余Gas。常用于验证用户输入、状态或权限。

  • assert(condition):

    用于检查不变量(程序内部错误)。失败时消耗所有Gas,通常表示合约出现严重BUG。

  • revert(message):

    显式回退交易,通常用于复杂的错误处理流程。与require类似,但可嵌套调用并提供错误信息。

总结:

  • require验证外部输入和条件,防止错误操作。

  • assert检测不应发生的内部错误。

  • revert做复杂错误处理或在条件不满足时回退。


2.3 什么是重入攻击(Reentrancy)?如何防御?

  • 重入攻击指攻击者在一个合约调用过程中,通过递归调用同一合约的漏洞函数,重复利用尚未更新状态的合约逻辑,窃取资产。最经典的例子是The DAO攻击。

  • 防御方法:

    1. "检查-效果-交互"模式:先修改合约状态,再调用外部合约。

    2. 使用ReentrancyGuard修饰器(如OpenZeppelin库),防止函数被重入调用。

    3. 限制调用次数和控制流

    4. 减少对外部合约的依赖


2.4 如何通过 Node.js 与 Solidity 合约交互?

  • 主要借助 web3.jsethers.js 这两个库。流程如下:

    1. 通过ABI和合约地址创建合约实例。

    2. 配置钱包私钥和Provider(如Infura、Alchemy或本地节点)。

    3. 调用合约的读取方法(call)或写入方法(send),写入需签名交易。

    4. 监听交易回执和事件。

示例代码(用ethers.js):

复制代码
const { ethers } = require("ethers");
const provider = new ethers.providers.InfuraProvider("homestead", "INFURA_API_KEY");
const wallet = new ethers.Wallet("PRIVATE_KEY", provider);
const contractABI = [...]; // 合约ABI
const contractAddress = "0xYourContractAddress";
const contract = new ethers.Contract(contractAddress, contractABI, wallet);

async function transferTokens(to, amount) {
  const tx = await contract.transfer(to, amount);
  await tx.wait();
  console.log("Transfer successful:", tx.hash);
}

2.5 写一个简单的ERC-20或ERC-721合约,并用 JavaScript 发起转账交易。

示例:一个简单的ERC-20合约

复制代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleToken {
    string public name = "SimpleToken";
    string public symbol = "STK";
    uint8 public decimals = 18;
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;

    event Transfer(address indexed from, address indexed to, uint256 value);

    constructor(uint256 _initialSupply) {
        totalSupply = _initialSupply * 10 ** decimals;
        balanceOf[msg.sender] = totalSupply;
    }

    function transfer(address _to, uint256 _value) public returns (bool) {
        require(balanceOf[msg.sender] >= _value, "Insufficient balance");
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        emit Transfer(msg.sender, _to, _value);
        return true;
    }
}

JavaScript 发送转账交易示例(用ethers.js):

复制代码
const { ethers } = require("ethers");

const provider = new ethers.providers.JsonRpcProvider("https://mainnet.infura.io/v3/YOUR_INFURA_ID");
const privateKey = "YOUR_PRIVATE_KEY";
const wallet = new ethers.Wallet(privateKey, provider);

const contractAddress = "YOUR_CONTRACT_ADDRESS";
const abi = [
  "function transfer(address to, uint amount) public returns (bool)",
];

const contract = new ethers.Contract(contractAddress, abi, wallet);

async function sendToken(to, amount) {
  const decimals = 18;
  const amountInWei = ethers.utils.parseUnits(amount.toString(), decimals);
  const tx = await contract.transfer(to, amountInWei);
  console.log("Transaction hash:", tx.hash);
  await tx.wait();
  console.log("Transfer confirmed");
}

sendToken("0xRecipientAddress", 10).catch(console.error);

相关推荐
远行者25 分钟前
深入解析 Solana DeFi 应用中的 useInitConnection 钩子
web3
好学且牛逼的马3 小时前
北大区块链技术与应用 笔记
区块链
TechubNews7 小时前
RWA与DeFi(去中心化金融)的关系是什么?RWA在DeFi中扮演什么角色?
人工智能·区块链
sheep88888 小时前
AI与区块链Web3技术融合:重塑数字经济的未来格局
人工智能·区块链
数据与人工智能律师18 小时前
数字迷雾中的安全锚点:解码匿名化与假名化的法律边界与商业价值
大数据·网络·人工智能·云计算·区块链
sheep888821 小时前
Web3与区块链深度融合:重塑互联网基础设施的2025革命
区块链
YSGZJJ1 天前
上证50指数分红和股指期货有什么关系?
区块链
Sui_Network1 天前
探索 Sui 上 BTCfi 的各类资产
大数据·人工智能·科技·游戏·区块链
软件工程小施同学1 天前
计算机学报 2025年 区块链论文 录用汇总 附pdf下载
pdf·区块链
AIMercs1 天前
零知识证明
区块链·零知识证明