全局变量
1. 什么是全局变量?
Solidity 提供了一些内置的 全局变量(Global Variables),用于访问区块链状态、交易信息等数据。这些变量不需要额外声明,可以在智能合约中直接调用。
2. 主要全局变量分类
Solidity 全局变量主要分为以下几类:
2.1 区块信息(Block Information)
示例:获取当前区块号和时间戳
contract BlockInfo {
function getBlockDetails() public view returns (uint, uint) {
return (block.number, block.timestamp);
}
}
2.2 交易信息(Transaction Information)
⚠️ 注意:tx.origin 可能导致安全漏洞,避免用于身份验证!
示例:检查交易发起者
contract TxInfo {
function getTxOrigin() public view returns (address) {
return tx.origin;
}
}
2.3 消息信息(Message Information)
示例:获取调用者地址和发送的 ETH 数量
contract MessageInfo {
function getMessageDetails() public payable returns (address, uint) {
return (msg.sender, msg.value);
}
}
2.4 以太坊环境信息(Ethereum Environment Information)
示例:获取当前合约的地址和余额
contract ContractInfo {
function getContractDetails() public view returns (address, uint) {
return (address(this), address(this).balance);
}
}
2.5 this 关键字
this 关键字用于引用当前合约的实例。它可以用于:
- 获取当前合约的地址。
- 在合约内部调用自身的函数(但会创建新的交易)。
- 访问当前合约的 balance。
示例:使用 this 关键字
contract ThisExample {
function getContractAddress() public view returns (address) {
return address(this);
}
function getContractBalance() public view returns (uint) {
return address(this).balance;
}
}
注意事项:
- this 关键字调用合约自身的函数时,会触发新的交易,因此会消耗额外的 gas。
- this.balance 获取的是合约的 ETH 余额,而 msg.sender.balance 可以用于获取调用者的余额。
2.6 其他特殊全局变量
示例:使用 keccak256 计算哈希值
contract HashExample {
function getHash(string memory input) public pure returns (bytes32) {
return keccak256(abi.encodePacked(input));
}
}
- 应用场景
✅ 随机数生成(⚠️ 仅限低安全性用途)
function getRandomNumber() public view returns (uint) {
return uint(keccak256(abi.encodePacked(block.timestamp, msg.sender))) % 100;
}
✅ 支付合约
contract Payment {
function pay() public payable {}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}
✅ 安全身份验证(避免 tx.origin)
contract Auth {
address public owner;
constructor() { owner = msg.sender; }
function isOwner() public view returns (bool) {
return msg.sender == owner;
}
}
- 总结
- Solidity 提供了许多 全局变量,可以访问 区块链状态、交易信息、消息信息等。
- this 关键字可用于引用当前合约地址、余额或调用自身函数(会消耗额外 gas)。
- 数组、哈希、加密函数 也是 Solidity 重要的全局功能。
- 在开发合约时,应 正确使用全局变量,避免 安全隐患(如 tx.origin)。
📌 问题思考
- 为什么 tx.origin 不安全?
- 如何使用 block.timestamp 生成随机数?
- gasleft() 在合约执行过程中会如何变化?