Solidity
2022/05/25
Solidity
基本语法
Pragma
一般开头都是一句pragma开头,表示所用的solidity版本。从0.6开始solidity一直有breaking change,所以这个版本还挺重要的。
pragma solidity ^0.5.2;
并且,这个版本是可以用大小于号的:
pragma solidity >=0.4.22 <0.9.0;
Contract
一个Contract一般以contract
标识符开头,像class。也有constructor
State Variable Visibility
public, 允许其他contract读取value,但不能直接修改。
internal, 只能从contract内部获取,默认的state variable权限
private, 不可被衍生的contract读取
Function Visibility
external 可以在其他的contract 和transaction中被call. 如果要在内部调用,不能用f(),而要用this.f()
public 可以内部或外部调用
internal 只能当前contract调用
private 不可被衍生的contract读取
当然,因为区块链的世界一切都是透明的,这个private和internal实际上只是运行时的概念,其他人还是能看到这个变量的。
Getter function
getter是external visibility的,也就是其他都能访问。访问的时候像这样:
contract C {
uint public data;
function x() public returns (uint) {
data = 3; // internal access
return this.data(); // external access
}
}
Modifier
modifier可以自定义一个函数的预判断条件等,如
contract owned {
constructor() { owner = payable(msg.sender); }
address payable owner;
// This contract only defines a modifier but does not use
// it: it will be used in derived contracts.
// The function body is inserted where the special symbol
// `_;` in the definition of a modifier appears.
// This means that if the owner calls this function, the
// function is executed and otherwise, an exception is
// thrown.
modifier onlyOwner {
require(
msg.sender == owner,
"Only owner can call this function."
);
_;
}
}
contract destructible is owned {
// This contract inherits the `onlyOwner` modifier from
// `owned` and applies it to the `destroy` function, which
// causes that calls to `destroy` only have an effect if
// they are made by the stored owner.
function destroy() public onlyOwner {
selfdestruct(owner);
}
}
Constant 和 Immutable
都是运行时不可变,区别在于constant是编译时确定,再也无法更改,而Immutable可以在constructor中被赋值。
Return 多个values
return (v0, v1, ..., vn)
Pure functions
不读取、不修改state的函数,就可以定义为pure function
修改state的情况
- 修改state variable
- 触发事件
- 创建其他contract
- selfdestruct
- 通过调用发送Ether
- 调用非view非pure得function
- 底层调用
- 汇编,含有特定的操作码
Getter methods被自动标记为view function
读取state的情况
1.读state variables
2. address(this).balance` or `<address>.balance
- Accessing any of the members of
block
,tx
,msg
(with the exception ofmsg.sig
andmsg.data
). - Calling any function not marked
pure
. - Using inline assembly that contains certain opcodes.
特殊函数
Receive Ether Function
一个contract最多只有一个,receive() external payable { ... }
(without the function
keyword),不能有arguments,不能返回值,必须有external和payable.
如果这个contract没有定义该函数,在receive Ether的时候会抛出异常,退回Ether
如果是coinbase transaction和selfdestruct的终点导致contract收到了Ether,即便没有REF,也会收到Ether。这是EVM的设计决定的
Fallback Function
当没有其他函数匹配调用时,触发该函数。也是一样,contract最多有一个
fallback () external [payable]
or fallback (bytes calldata input) external [payable] returns (bytes memory output)
(both without the function
keyword)
Events
CheatSheet
cheatsheet 常用的一些东西
2022/5/28
Blockhash()
blockhash(uint blockNumber) returns (bytes32)
: hash of the given block whenblocknumber
is one of the 256 most recent blocks; otherwise returns zero
2022/6/6
Hardhat
https://hardhat.org/tutorial/testing-contracts
Hardhat是一个很好用的js库,可以轻松在js里嵌入、deploy你的合约,并且使用它。