当前位置: 首页 > 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.dtcms.com/a/314216.html

相关文章:

  • Linux 文件与目录属性管理总结
  • 设备能力指标(CP/CPK)
  • C盘空间清理
  • JVM学习日记(十六)Day16——性能监控与调优(三)
  • AgxOrin平台JetPack5.x版本fix multi-cam race condition 补丁
  • 【Conda】常用指令操作
  • 机器学习——决策树(DecisionTree)+ 过采样 + 交叉验证 案例:电信客户流失数据
  • VAE学习笔记
  • Linux 网络深度剖析:传输层协议 UDP/TCP 原理详解
  • 【STM32】GPIO的输入输出
  • 正点原子STM32MP257开发板移植ubuntu24.04根文件系统(带桌面版)
  • Android的UI View是如何最终绘制成一帧显示在手机屏幕上?
  • Android Espresso 测试框架深度解析:从入门到精通
  • imx6ull-驱动开发篇8——设备树常用 OF 操作函数
  • 力扣热题100——哈希表
  • 大模型×垂直领域:预算、时间、空间三重夹击下的生存法则
  • 基于ensp的防火墙安全策略及认证策略综合实验
  • Flink CDC 介绍
  • PHP-分支语句、while循环、for循环
  • 深入理解Spring中的循环依赖及解决方案
  • 鸿蒙南向开发 编写一个简单子系统
  • 机器学习——学习路线
  • MySQL进阶:(第八篇)深入解析InnoDB存储架构
  • 高效洗牌:Fisher-Yates算法详解
  • 软考 系统架构设计师系列知识点之杂项集萃(118)
  • 直播 app 系统架构分析
  • 如何在 Ubuntu 24.04 LTS 上安装 Docker
  • 计算机网络:
  • 团购商城 app 系统架构分析
  • (五)系统可靠性设计