由于版本更新比较快。过去一部分写法,现在使用0.5.10版本开发合约时,部分报错。再去翻翻官方的最新的文档。
文章目录
一、特殊变量
msg
tx
block
address
alias
type
二、ABI编码
decode
encode
encodePacked
encodeWithSelector
encodeWithSignature
三、错误处理
assert
require
revert
四、合约相关
this
super
selfdestruct
五、数学和密码学函数
addmod
mulmod
keccak256
sha256
ripemd160
一、特殊变量
msg
msg.sender(address) 消息发送者(当前调用)
msg.value (uint) 随消息发送的 wei 的数量
msg.data (bytes) 完整的 calldata
msg.gas (uint) 剩余 gas ,( 弃!)推荐使用gasleft()
msg.sig (bytes4) calldata 的前 4 字节(也就是函数标识符)
tx
tx.gasprice (uint) 交易的 gas 价格
tx.origin (address) 交易发起者(完全的调用链)
block
block.blockhash(uint blockNumber) (bytes32) 指定区块的区块哈希,仅可用于最新的 256 个区块且不包括当前区块,( 弃!)推荐使用blockhash(uint blockNumber)
block.coinbase (address): 挖出当前区块的矿工地址
block.difficulty (uint): 当前区块难度
block.gaslimit (uint): 当前区块 gas 限额
block.number (uint): 当前区块号
block.timestamp (uint): 自 unix epoch 起始当前区块以秒计的时间戳
address
<address>.balance (uint256): 以 Wei 为单位的地址类型的余额。
<address payable>.transfer(uint256 amount): 向地址类型发送数量为 amount 的 Wei,失败时抛出异常,发送 2300 gas 的矿工费,不可调节。
// transfer()成员函数
// 说明:接收币的合约,必须有fallback函数,0.6以上版本还增加了receive函数
// funtion () public payable{
// }
// 0.6以上版本有函数名
// receive() external payable {
// data = "receive call";
// }
// fallback() external payable {
// data = "fallback call";
// }
pragma solidity ^0.4.0;
contract Called{
event logdata(bytes data);
// 这是一个回退函数, 收到以太币会被调用
function() public payable {
emit logdata(msg.data); // 调用日志
}
function getBalance() public view returns (uint) {
return this.balance;
}
}
contract CallTest{
constructor() public payable {
}
function transferEther(address towho) public returns (bool) {
// towho.transfer(1 ether);
towho.send(1 ether);
return true;
}
function getBalance() public view returns (uint){
return this.balance;
}
}
<address payable>.send(uint256 amount) returns (bool):向地址类型发送数量为 amount 的 Wei,失败时返回 false,发送 2300 gas 的矿工费用,不可调节。
<address>.call(...) returns (bool): 发出低级函数 CALL,失败时返回 false,发送所有可用 gas,可调节。
<address>.callcode(...) returns (bool):已禁止使用。
<address>.delegatecall(...) returns (bool):发出低级函数 DELEGATECALL,失败时返回 false,发送所有可用 gas,可调节。
alias
now (uint): 目前区块时间戳(block.timestamp)
blockhash(uint blockNumber)returns(bytes32) 指定区块的区块哈希,限制256个之内
gasleft() returns(uint) 剩余的 gas, (msg.gas)
staticcall()
type
doc
type(C).name The name of the contract.
type(C).creationCode
type(C).runtimeCode
二、ABI编码
decode
abi.decode(bytes memory encodedData, (...)) returns (...)
解码一份已压缩的数据,类型在括号中作为第二个参数给出。
示例 (uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))
encode
abi.encode(...) returns (bytes memory)
对给定参数进行编码
encodePacked
abi.encodePacked(...) returns (bytes memory) // 若干个参数,返回bytes类型
对给定参数执行 紧打包编码
encodeWithSelector
abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)
对给定参数进行编码,并以给定的函数选择器作为起始的 4 字节数据一起返回
encodeWithSignature
abi.encodeWithSignature(string signature, ...) returns (bytes memory)
等价于 abi.encodeWithSelector(bytes4(keccak256(signature), ...)
三、错误处理
assert导致的交易失败,会扣取剩余的gas,其他的会返回剩余的gas
assert
assert(bool condition) 条件不满足,则使当前交易没有效果,用于检查内部错误。
require
require(bool condition)条件不满足则撤销状态更改,用于检查由输入或者外部组件引起的错误。
require(bool condition, string message),上同,可以同时提供一个错误消息。
revert
revert() 终止运行并撤销状态更改。
revert(string reason)终止运行并撤销状态更改,可以同时提供一个解释性的字符串。
四、合约相关
this
代表本合约的地址
super
使用继承层次结构中更高一级(父类)的合约的方法。
selfdestruct
selfdestruct(address payable recipient)
销毁合约,并把余额发送到指定地址。
五、数学和密码学函数
addmod
addmod(uint x, uint y, uint k) returns (uint)
计算 (x + y) % k,加法会在任意精度下执行,并且加法的结果即使超过 2**256 也不会被截取。从 0.5.0 版本的编译器开始会加入对 k != 0 的校验(assert)。
mulmod
mulmod(uint x, uint y, uint k) returns (uint)
计算 (x * y) % k,乘法会在任意精度下执行,并且乘法的结果即使超过 2**256 也不会被截取。从 0.5.0 版本的编译器开始会加入对 k != 0 的校验(assert)。
keccak256
keccak256(bytes memory) returns (bytes32)
计算Ethereum-SHA-3 (Keccak-256)哈希。(sha3已放弃使用)
sha256
sha256(bytes memory) returns (bytes32)
计算 SHA-256 哈希。
ripemd160
ripemd160(bytes memory) returns (bytes20)
计算 RIPEMD-160 哈希。地址本身是用这个生成的。
———————————————————————————————————————————
{
"block.chainid": "0xd05",
"block.coinbase": "0x0000000000000000000000000000000000000000",
"block.difficulty": "69762765929000",
"block.gaslimit": 160000000,
"block.number": 0,
"block.timestamp": 1646495232,
"msg.sender": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"msg.sig": "0x60e06040",
"msg.value": "0 Wei",
"tx.origin": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"block.basefee": "1 Wei (0x01)"
}
remix的debug中可以查看:
注解 |
---|
不要依赖于block.timestamp ,now 和blockhash 用作随机性的来源,除非你知道你在做什么。 |
时间戳和块哈希在一定程度上受矿工的影响。例如,挖掘社区中的坏角色可以在选定的散列上运行赌场支付函数,如果他们没有收到任何钱,只需重试一个不同的散列。 |
当前块时间戳必须严格大于最后一个块的时间戳,但唯一的保证是它将位于规范链中的两个连续块的时间戳之间的某处。 |
注解 |
---|
由于区块链是变化的,所以块哈希对于全部区块块不可用。只能访问最近256个块的散列值,所有其他区块哈希将为0。 |