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

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.xdnf.cn/news/17201.html

相关文章:

  • python中的字典
  • 雷达系统工程学习:自制极化合成孔径雷达无人机
  • bypass
  • SelectDB:新一代实时数仓的核心引擎与应用实战
  • 机器学习——基本算法
  • 笛卡尔坐标
  • Java 中 BigDecimal、Float、Double 的取整与保留小数处理方法详解
  • 简要探讨大型语言模型(LLMs)的发展历史
  • Android进程基础:Zygote
  • Linux 磁盘管理与分区配置
  • 【2025WACV-最佳论文】RayGauss:基于体积高斯的光线投射,用于逼真的小说视图合成
  • (JAVA)自建应用调用企业微信API接口,设置企业可信IP
  • 前端开发(HTML,CSS,VUE,JS)从入门到精通!第五天(jQuery函数库)
  • 使用1panel将http升级至https的过程
  • 板子指示灯状态设计
  • ESDocValues机制
  • Easysearch 集成阿里云与 Ollama Embedding API,构建端到端的语义搜索系统
  • python与C++
  • web第一次作业
  • Spring Cloud Gateway 实现登录校验:构建统一认证入口
  • Kali基础知识点【2】
  • Linux 网络深度剖析:传输层协议 UDP/TCP 原理详解
  • 小实验:按键点灯(中断法)
  • 如何安装 nvm-setup.exe?Windows 安装 NVM 管理 Node.js 版本的完整流程(附安装包下载)
  • C# 类型
  • Git基础操作教程
  • Dbeaver数据库的安装和使用(保姆级别)
  • 计算机网络:理解路由的下一跳
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现路口车辆速度的追踪识别(C#代码UI界面版)
  • 【保姆级 - 大模型应用开发】DeepSeek + Faiss + langchain 搭建本地知识库 检索 | 代码实战