23-02-24

First Post:

Last Update:

2023-02-24

两种常量修饰符

constant

constant修饰的变量必须要初始化,并且不可以被修改

1
2
3
4
5
6
contract cons {
address public constant addr = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc;
function tryToChange() public {
//addr = 0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc;//error
}
}

immutable

immutable修饰的变量不需要初始化,同样不可以被修改但必须在构造函数中进行初始化

1
2
3
4
5
6
7
8
9
10
pragma solidity ^0.8.17;
//SPDX-License-Identifier: MIT
contract immu {
address private immutable immu1 ;
uint private immutable myUInt;
constructor(uint uI) {
immu1 = msg.sender;
myUInt = uI;
}
}

getter方法必须声明为view

1
2
3
4
5
6
7
8
9
10
11
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.17;
contract stateV {
uint public num;
function get() public view returns(uint){
return num;
}
function set(uint n) public {
num = n;
}
}

gas 与 gas limit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.8.17;
//SPDX-License-Identifier: MIT
contract gasAbout {
int public i = 0;
// 花光准备的gas会导致交易失败
// 状态改变会回退
// gas不会退款
function g() public {
//循环到花光所限制的gas,交易失败,i不会发生改变
while(true) {
++i;
}
}
}

参考->Gas

Gas

How much ether do you need to pay for a transaction?
You pay gas spent * gas price amount of ether, where

  • gas is a unit of computation
  • gas spent is the total amount of gas used in a transaction
  • gas price is how much ether you are willing to pay per gas

Transactions with higher gas price have higher priority to be included in a block.

Unspent gas will be refunded.

Gas Limit

There are 2 upper bounds to the amount of gas you can spend

  • gas limit (max amount of gas you’re willing to use for your transaction, set by you)

  • block gas limit (max amount of gas allowed in a block, set by the network)

试着依靠自己的理解,翻译一下:

1
2
3
4
5
6
7
8
9
10
11
12
Gas
一个交易需要支付多少?我们需要支付的以太币为 `Gas花费数量`*`Gas单价`,其中:
- Gas是计算单位
- Gas Spent是一个交易中花费的Gas数
- Gas Price是你愿意为每个Gas支付的价格
在区块中,更高的Gas单价具有更高的优先级
多出的Gas会被退回

Gas Limit
对于我们花费gas的总数有两个上限
- Gas Limit(自己设置的愿意交易Gas花费最大`数量`限额)
- Block Gas Limit(网络设置的区块Gas花费最大`数量`限额)

Map

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//SPDX-License-Identifier:MIT
pragma solidity ^0.8.17;
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];
}
}
contract NestedMapping {
mapping(address => mapping(uint=>bool)) public nested;
function get(address _addr, uint _ui) public view returns(bool) {
return nested[_addr][_ui];
}
function set(address _addr, uint _ui, bool _bool) public {
nested[_addr][_ui] = _bool;
}
function remove(address _addr, uint _ui) public {
delete nested[_addr][_ui];
}
}

数组

简单例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
pragma solidity ^0.8.17;
//SPDX-License-Identifier: UNLICENSED
contract Array {
uint[] public arr ;
uint[] public arr2 = [1, 2, 3];
uint[10] public arr3;
function get(uint i) public view returns (uint){
return arr[i];
}
function getArr() public view returns (uint[] memory) {
return arr;
}
function push(uint i) public {
arr.push(i);
}
function pop()public {
//pop会相应减少长度
arr.pop();
}
function getLength() public view returns(uint){
return arr.length;
}
function remove(uint index) public {
//delete只删除相应索引上的值
delete arr[index];
}
function examples() external {
uint[] memory a = new uint[](5);//只能生成固定长度
}

}

删除元素

与Java不同的是,solidity没有现成方法来调用进行删除某一索引上的元素,比如自行定义函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
方法一(能保留原有顺序):
pragma solidity ^0.8.17;
// SPDX-License-Identifier: MIT
contract arrShift1 {
uint[] public arr;
function remove(uint _index) public {
require(_index < arr.length, "index out of bound");
for(uint i = _index; i < arr.length-1; i++) {
arr[i] = arr[i+1];
}
arr.pop();
//自要删除的元素起,后面每一元素覆盖前面,然后删除最后的值
}
function test() external {
arr = [1,2,3,4,5];
remove(2);
assert(arr[0] == 1);
assert(arr[1] == 2);
assert(arr[2] == 4);
assert(arr[3] == 5);
assert(arr.length == 4);

arr = [1];
remove(0);
assert(arr.length == 0);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
方法二(简单粗暴,直接替换):
pragma solidity ^0.8.17;
//SPDX-License-Identifier:mit
contract arrReplace {
uint[] public arr;
function arrRepl(uint _index) public {
arr[_index] = arr[arr.length-1];
arr.pop();
}
function test() public{
arr = [1,2,3,4,5];
arrRepl(2);
assert(arr[0]==1);
assert(arr[1]==2);
assert(arr[2]==5);
assert(arr[3]==4);
assert(arr.length==4);
}
}