当前位置: 首页 > news >正文

Solidity全局变量与安全实践指南

1. 区块与交易属性
function getBlockData() public view returns (uint number, uint timestamp, uint gasLimit,address miner
) {return (block.number,       // 当前区块号block.timestamp,   // 区块时间戳(Unix秒)block.gaslimit,    // 当前区块的gas上限block.coinbase     // 矿工地址);
}function getTxData() public view returns (uint gasPrice,address origin
) {return (tx.gasprice,      // 当前交易的gas价格tx.origin         // 原始交易发送者(慎用!));
}
2. 消息属性 (msg)
function processPayment() public payable {// 获取调用信息address sender = msg.sender;uint value = msg.value;bytes4 selector = msg.sig;// 验证至少转账1 ETHrequire(value >= 1 ether, "Minimum 1 ETH required");// 记录交易payments[sender] += value;
}
3. 地址操作
// 安全ETH转账
function sendEther(address payable to, uint amount) public {// 检查合约余额require(address(this).balance >= amount, "Insufficient balance");// 使用call代替transfer/send (推荐)(bool success, ) = to.call{value: amount}("");require(success, "Transfer failed");
}// 调用其他合约
function callExternalContract(address contractAddr, string memory funcSig,uint param
) public {bytes memory data = abi.encodeWithSignature(funcSig, param);(bool success, bytes memory result) = contractAddr.call(data);require(success, "External call failed");// 处理返回结果...
}// 检查合约余额
function checkBalance(address addr) public view returns (uint) {return addr.balance;  // 地址的ETH余额(wei)
}
4. ABI编码/解码
// 创建函数调用数据
function createTransferData(address recipient, uint amount
) public pure returns (bytes memory) {return abi.encodeWithSignature("transfer(address,uint256)", recipient, amount);
}// 解析数据
function decodeData(bytes memory data
) public pure returns (address, uint) {(address recipient, uint amount) = abi.decode(abi.decode(data[4:]),  // 跳过函数选择器(address, uint));return (recipient, amount);
}
5. 数学与加密
// 创建唯一标识符
function createTokenId(string memory name, address owner
) public pure returns (bytes32) {return keccak256(abi.encodePacked(name, owner));
}// 签名验证
function verify(bytes32 messageHash,uint8 v,bytes32 r,bytes32 s
) public pure returns (address) {return ecrecover(messageHash, v, r, s);
}// 安全数学运算
function safeModAdd(uint a,uint b,uint mod
) public pure returns (uint) {return addmod(a, b, mod);
}
6. 错误处理
function withdraw(uint amount) public {// 检查条件require(balances[msg.sender] >= amount, "Insufficient balance");// 更新状态balances[msg.sender] -= amount;// 执行转账(bool success, ) = msg.sender.call{value: amount}("");// 自定义错误处理if (!success) {revert WithdrawFailed(msg.sender, amount);}
}// 自定义错误类型
error WithdrawFailed(address sender, uint amount);// 内部一致性检查
function validateState() public view {assert(totalSupply == calculateTotalSupply());
}
7. 合约操作
// 获取合约信息
function getContractInfo() public view returns (address contractAddress,uint balance
) {return (address(this),       // 当前合约地址address(this).balance // 合约ETH余额);
}// 安全销毁合约
function destroyContract() public onlyOwner {// 保存所有者地址address owner = owner;// 清除状态delete owner;// 销毁合约并发送余额selfdestruct(payable(owner));
}
8. Gas 操作
function optimizeGas() public {uint startGas = gasleft();// 执行复杂操作...for(uint i = 0; i < 100; i++) {// 某些操作}uint gasUsed = startGas - gasleft();emit GasConsumed(gasUsed);
}
9. 类型信息
// 获取接口ID (ERC-165)
function getERC721InterfaceId() public pure returns (bytes4) {return type(IERC721).interfaceId;
}// 检查合约支持的接口
function supportsInterface(address contractAddr,bytes4 interfaceId
) public view returns (bool) {(bool success, bytes memory result) = contractAddr.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceId));return success && abi.decode(result, (bool));
}

关键实践建议

  1. 安全转账模式
// 安全转账模板
function safeTransferETH(address to, uint value) internal {(bool success, ) = to.call{value: value}(new bytes(0));require(success, "ETH transfer failed");
}
  1. call vs delegatecall
// 普通调用:在目标合约上下文中执行
contractA.call(abi.encodeWithSignature("func()"));// 委托调用:在当前合约上下文中执行目标合约代码
contractB.delegatecall(abi.encodeWithSignature("func()"));
  1. 时间戳使用警告
// 不安全的随机数生成(容易被矿工操纵)
uint badRandom = uint(keccak256(abi.encodePacked(block.timestamp)));// 更安全的方案(但仍不完全安全)
uint betterRandom = uint(keccak256(abi.encodePacked(block.timestamp, block.difficulty,msg.sender
)));
  1. ABI编码最佳实践
// 安全:明确指定类型防止哈希碰撞
bytes32 safeHash = keccak256(abi.encode("Transfer(address,uint256)",recipient,amount
));// 危险:紧密打包可能导致不同类型数据碰撞
bytes32 unsafeHash = keccak256(abi.encodePacked("Transfer",recipient,amount
));

这些全局属性和方法是 Solidity 智能合约开发的基石,正确理解和使用它们对于编写安全、高效的合约至关重要。在实际开发中,始终优先考虑安全性,特别是处理资金转账和外部调用时。

http://www.lryc.cn/news/609874.html

相关文章:

  • [论文阅读] 人工智能 + 教学 | 从代码到职业:用机器学习预测竞赛程序员的就业潜力
  • 安全扫描:目标使用过期的TLS1.0 版协议问题
  • 【乐企板式文件】不动产销售类发票已支持
  • MySQL三大日志详解(binlog、undo log、redo log)
  • 赋能未来:数字孪生驱动能源系统智能化升级
  • 【项目实践】在系统接入天气api,根据当前天气提醒,做好plan
  • Linux(centos)安全狗
  • 【芯片设计专用执行单元:PWM如何重塑能源与智能控制】
  • sqli-labs靶场less29~less35
  • 2025.08.04 移除元素
  • 【测试工程思考】测试自动化基础能力建设
  • 使用mybatis生成器生成实体类mapper和查询参数文件,实现简单增删改查。使用log4j输出日志到控制台。使用配置文件注册Bean,配置视图解析器
  • 每天学一个Linux命令(38):vi/vim
  • Excel商业智能分析报表 【销售管理分析仪】
  • 免费MCP: JSON 转 Excel MCP
  • Vim 高效使用指南
  • Flutter 事件总线 Event Bus
  • HarmonyOS 多屏适配最佳实践:基于 ArkUI 的响应式 UI 方案
  • 计算机网络:理解路由的下一跳
  • 第四十六章:AI的“瞬时记忆”与“高效聚焦”:llama.cpp的KV Cache与Attention机制
  • C++ 中 initializer_list 类型推导
  • 2.1 vue组件
  • 【AMD】编译llama.cpp实践版
  • 【异常案例分析】使用空指针调用函数(非虚函数)时,没有崩溃在函数调用处,而是崩在被调用函数内部
  • 关于大数据的基础知识(三)——数据安全与合规
  • C++模板知识点3『std::initializer_list初始化时逗号表达式的执行顺序』
  • 1.kotlin数组、集合常用方法
  • 【iOS】渲染原理离屏渲染
  • 网络安全 | 从 0 到 1 了解 WAF:Web 应用防火墙到底是什么?
  • 国内首个开源SCA社区——OpenSCA开源社区