基础知识
gas
gas是衡量执行某些操作所需的计算量的单位,用来计算为了执行操作而需要支付给网络的费用数额。 通俗理解,Gas 是给矿工的佣金,并以 ETH 支付,无论是交易、执行智能合约并启动 DApps,还是支付数据存储费用,都需要用到 Gas。 Gas的目的是限制执行交易所需的工作量,同时为执行支付费用。当EVM执行交易时,Gas将按照特定规则被逐渐消耗,无论执行到什么位置,一旦Gas被耗尽,将会触发异常。当前调用帧所做的所有状态修改都将被回滚, 如果执行结束还有Gas剩余,这些Gas将被返还给发送账户。 每笔交易都包含gas limit和gas price。矿工可以有选择的打包这些交易并收取这些费用。gasprice 会影响到该笔交易被打包所需等待的时间。如果该交易的操作所使用的gas数量小于或等于所设置的gas limit,交易会被处理。但如果gas总消耗超过gas limit,所有的操作都会被重置,但手续费依旧会被收取。
以太坊客户端
若想使用以太坊提供的服务,不论是转账还是部署合约,都需要用以太坊客户端加入到以太坊网络中,说白了以太坊客户端就是实现了以太坊协议的软件,其概念可类比平时使用的P2P下载客户端。以太坊客户端可概述为:
全节点客户端 全节点客户端加入到以太坊网络时,会把以太坊全部的区块链数据都同步到本地,因此对配置的要求比较高。全节点支持的功能非常齐全,并且其安全性比较高,因为是直接和以太坊网络交互,中间不需要经过第三方。
轻节点客户端 轻节点客户端不会同步整个以太坊网络,它通过连接到其它的全节点来提供服务,因此其提供的服务往往有限,常常用于钱包场景。
Ether 和 Wei
交易是用ether支付的。 1ether等于 10^18wei
Solidity 中有 3 种类型的变量 local 在函数内部声明 不存储在区块链上 state 在函数外声明 存储在区块链上 global(提供有关区块链的信息) 例如msg.sender
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Variables {
// 状态变量存储在区块链上。
string public text = "Hello";
uint public num = 123;
function doSomething() public {
// 局部变量不会保存到区块链中。
uint i = 456;
// 下面是一些全局变量
uint timestamp = block.timestamp; // 当前区块时间戳
address sender = msg.sender; // 发送者的地址
}
}
常量是不能被修改的变量。 它们的值是硬编码的,使用常数可以节省gas成本。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Constants {
// 编码惯例为大写的常量变量
// 类似js里面的const
address public constant MY_ADDRESS = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc;
uint public constant MY_UINT = 123;
}
不可变变量就像常量。不可变变量的值可以在构造函数中设置,但之后不能修改。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Immutable {
// coding convention to uppercase constant variables
address public immutable MY_ADDRESS;
uint public immutable MY_UINT;
constructor(uint _myUint) {
MY_ADDRESS = msg.sender;
MY_UINT = _myUint;
}
}
你需要为一笔交易支付多少gas? 你要支付花费的gas = gas spend * gas price,其中ether一个计算单位 gas消耗是交易中使用的gas总量 gas price是你愿意为每个gas支付多少ether的单价 gas price较高的交易有较高的优先权被纳入一个区块中。 未消耗的gas将被退还。 Gas limit 你可以花费的gas量有两个上限
gas limint(你愿意为你的交易使用的gas,由你设定)
block gas limit(一个区块中允许的最大gas,由网络设置)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Gas {
uint public i = 0;
// Using up all of the gas that you send causes your transaction to fail.
// State changes are undone.
// Gas spent are not refunded.
function forever() public {
// Here we run a loop until all of the gas are spent
// and the transaction fails
while (true) {
i += 1;
}
}
}
支持if/else 也支持 三元运算符
函数后面 pure/view 表示不需要花费gas
pure:不能读取也不能写入存储链上的数据 view:能读取状态,但是不能写入
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract IfElse {
function foo(uint x) public pure returns(uint){
if(x < 10){
return 0;
} else if (x <20) {
return 1;
} else {
return 2;
}
}
function ternary(uint _x) public pure returns(uint) {
return _x < 10 ? 1: 2;
}
}
Solidity 支持 for、while 和 do while 循环。 不要编写无界循环,因为这可能会达到 gas 限制,从而导致您的交易失败。 由于上述原因,很少使用 while 和 do while 循环。
Mapping
映射的创建语法是mapping(keyType => valueType)。 keyType可以是任何内置的值类型,字节,字符串,或任何合约。 valueType可以是任何类型,包括另一个映射或一个数组。 映射是不可迭代的。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Mapping {
mapping(address => uint) public myMap;
// 得到映射
function get(address _addr) public view returns(uint){
return myMap[_addr];
}
// 更新映射
function set(address _addr, uint _i) public {
myMap[_addr] = _i;
}
function remove(address _addr) public {
delete myMap[_addr];
}
}
Event 事件
Event允许记录到以太坊区块链。Event的一些用例是: 1.监听事件和更新用户界面 2.一种费用更低的存储方式
Solidity中的事件(event)是EVM上日志的抽象,它具有两个特点:
响应:应用程序(ether.js (opens new window))可以通过RPC接口订阅和监听这些事件,并在前端做响应。
经济:事件是EVM上比较经济的存储数据的方式,每个大概消耗2,000 gas;相比之下,链上存储一个新变量至少需要20,000 gas
事件的声明由event关键字开头,然后跟事件名称,括号里面写好事件需要记录的变量类型和变量名。以ERC20代币合约的Transfer事件为例:
event Transfer(address indexed from, address indexed to, uint256 value);
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract Event {
// 事件声明,前面带 event
// 最多可以索引 3 个参数。
// 被索引的参数可以帮助你通过被索引的indexed来过滤日志,查询更快
event Log(address indexed sender, string message);
event AnotherLog();
function test() public {
emit Log(msg.sender, "Hello World!");
emit Log(msg.sender, "Hello EVM!");
emit AnotherLog();
}
}
输出日志如下
[
{
"from": "0x9D7f74d0C41E726EC95884E0e97Fa6129e3b5E99",
"topic": "0x0738f4da267a110d810e6e89fc59e46be6de0c37b1d5cd559b267dc3688e74e0",
"event": "Log",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "Hello World!",
"sender": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"message": "Hello World!"
}
},
{
"from": "0x9D7f74d0C41E726EC95884E0e97Fa6129e3b5E99",
"topic": "0x0738f4da267a110d810e6e89fc59e46be6de0c37b1d5cd559b267dc3688e74e0",
"event": "Log",
"args": {
"0": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"1": "Hello EVM!",
"sender": "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4",
"message": "Hello EVM!"
}
},
{
"from": "0x9D7f74d0C41E726EC95884E0e97Fa6129e3b5E99",
"topic": "0xfe1a3ad11e425db4b8e6af35d11c50118826a496df73006fc724cb27f2b99946",
"event": "AnotherLog",
"args": {}
}
]
标签:以太,Gas,solidity,gas,笔记,uint,address,public
From: https://www.cnblogs.com/lyr-2000/p/18648589