---
title: 'Solidity WTF 101 5 ~ 6 單元'
lang: zh-tw
---
::::info
:date: 2024/09/24
::::
# Solidity WTF 101 5 ~ 6 單元
[TOC]
## 補充
### bytes
- 在前幾個課程中有講解到bytes,但也都只是普通看過,後來驚覺發現區塊鏈中,memory與一些bytes換算使用率很高,所以回頭做了一些補充。
- 1 bytes = 8 bits bits是傳輸數據的最小單位,通常拿來稱作是 `bits per second(bps)`,bytes通常是當作資料數據容量(KB、MB、GB)。
- 8 bits 也會等於 `1111 1111` 的二進制,如果轉成16進制會是 `FF`,詳細請點選[這裡](https://notfalse.net/17/positional-numeral-systems-conversion#google_vignette)
- 因為與錢包地址有些關係,所以回去加深了一些記憶。
## 課程內容
### Solidity
1. 引用類型
分為`Array`、`Struct`、`Mapping`,並且在聲明時要宣告使用哪種儲存數據(`Stroage`、`Memory`、`calldata`)。
```xml=
<!-- 此為範例 -->
function functionName(uint calldata _test) public pure returns (uint) {
return _test;
}
```
2. 數據位置
數據位置分為三種
* `storage` - 儲存在鍊上(Gas Fee較多)。
* `memory` - 儲存在內存。
* `calldata` - 與`memory`類似,差別在於不能修改。
3. 數據位置和賦值
把`storage`的變數內容指向給一個也為`storage`的變數,在更改之後的`storage`也會更改實際內容,<span style="color:yellow">因為指向同一位置</span>。如果把`storage`指向給`memory`(顛倒也同理),則會進行<span style="color:yellow">拷貝動作而不是指向同一位置</span>,故不會更改原本內容。
4. 變量區域
分為三種`狀態`、`函數`、`局部`,作用如下
* `狀態` : 狀態變量通常寫在合約最外層,也是Gas Fee最貴。
* `局部` : 當你離開函數則函數變量消失,但也因為此關係,所以數據都是儲存在內存不上鏈。
* `全域` : 任何地方都能使用的變量,Solidity預留的關鍵字,例如: `msg.sender`。
[全域變量的詳細列表在這](https://learnblockchain.cn/docs/solidity/units-and-global-variables.html#special-variables-and-functions)
5. 以太單位與時間單位
* 以太單位
Solidity中不存在小數點,所以會以0來代替
* `wei` : 1
* `gwei` : 1e9 = 1000000000
* `ether` : 1e18 = 1000000000000000000
::::info
:information_source: `1e9中`的`e9`代表後面有`9`個`0`
::::
* 時間單位
算法不再贅述
* `seconds`
* `minutes`
* `hours`
* `days`
* `weeks`
6. 數組
這邊與其他數組使用方式類似,但有一個自己特別需要去了解的就是`動態+可變的Array`
大致幾種的宣告方式如下 :
```xm=
<!-- 固定 -->
<!-- 你在不給值直接印出他會是{0,0,0}的情況 -->
<!-- 給予值使用 newArray1[index] = 1 的方式,以此類推到3-->
uint[3] newArray1;
<!-- 可變 -->
<!-- 印出情況是 undefined 因為你沒有給予值,他會隨著push()內容而改變-->
<!-- 移除使用pop() -->
uint[] newArray;
<!-- 動態 + 可變 -->
<!-- 前面一樣使用固定的方式給予值,超過第二個後使用psuh()的方式 -->
<!-- 可以用來表達最少有兩筆,但可以超過 -->
uint[] newArray3 = new uint[](2);
```
7.結構體
`Struct`類似`interface`,但不同於`Struct`會儲存在鏈上,以下為宣告還有幾種賦值的方式
```xm=
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
contract StudentTest {
struct Student{
uint256 id;
uint256 score;
}
Student student;
// 给结构体赋值
// 方法1:在函数中创建一个storage的struct引用
function initStudent1() external{
Student storage _student = student; // assign a copy of student
_student.id = 11;
_student.score = 100;
}
// 方法2:直接引用状态变量的struct
function initStudent2() external{
student.id = 1;
student.score = 80;
}
// 方法3:构造函数式
function initStudent3() external {
student = Student(3, 90);
}
// 方法4:key value
function initStudent4() external {
student = Student({id: 4, score: 60});
}
}
```