跳到主要内容

关键字

Solidity 中的关键字包括了

  • 可见性
  • 常量
  • 不可变量
  • 数据存储位置
  • 可支付

可见性

关键字说明
private只能被合约内部调用
public可以在任何地方调用,不管是内部还是外部
internal能被合约内部调用,还能被继承的合约调用
external只能从合约外部调用

常量

使用 constant 修饰常量,修饰的变量需要在编译期确定值, 链上不会为这个变量分配存储空间, 它会在编译时用具体的值替代, 大写变量名

address public constant MY_ADDRESS = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc;

不可变量

immutable 修饰的变量是在部署的时候确定变量的值, 它在构造函数中赋值一次之后就不在改变, 这是一个运行时赋值, 可以解除之前 constant 不支持使用运行时状态赋值的限制

// 不可变量
contract Immutable {
// coding convention to uppercase constant variables
address public immutable MY_ADDRESS;
constructor(uint _myUint) {
MY_ADDRESS = msg.sender;
}
}

数据存储位置

storagememorycalldata 修饰的变量

  • storage 变量是状态变量(存储在区块链上), 赋值时是浅拷贝
  • memory 变量在内存中, 不上链, 并且在调用函数时存在, 赋值时是深拷贝
  • calldata 变量在内存中, 不上链, 不能修改, 一般用于函数的参数。相对于 memory, 可以节省 gas
function awardItem(address _to, string memory _tokenURI) public returns(uint) {
uint newItemId = _tokenIds.current();
_mint(_to, newItemId);
_setTokenURI(newItemId, _tokenURI);

_tokenIds.increment();
return newItemId;
}

可支付

函数和地址能声明为 payable, 即可接受 ether 到智能合约

uint levelUpFee = 0.001 ether;
function levelUp(uint _zombieId) external payable {
require(msg.value == levelUpFee);
zombies[_zombieId].level++;
}

调用该函数需要支付 0.001 ether 。在你发送 ether 之后,被存储进以合约的以太坊账户中。 除非你在合约中添加一个提现函数来从合约中提取资产。

function withdraw() external onlyOwner {
// 获取合约账户的余额
uint balance = address(this).balance;
if (balance > 0) {
// 转账到 owner 账户
payable(owner()).transfer(balance);
emit Withdraw(owner(), balance);
}
}

转移合约中的资产有以下三种方式

  • payable(_to).transfer(balance);
  • bool sent = payable(_to).send(balance);
  • (bool sent, bytes memory data) = _to.call{ value: balance }('');