# 第一週作業
## **1. 請簡單描述錢包助記詞,私鑰,公鑰之間的關係**
助記詞
拿來當作錢包的帳號,private key的一種表現方式,要注意不能外漏。
建議寫在紙上,不要用電腦截圖,或是手機拍照,以防被駭客偷走。
只要擁有助記詞,就等於擁有權力使用這個錢包。
私鑰
私鑰其實就是一串隨機數,具體而言,
以太坊的私鑰是一串隨機正整數,而這個值的區間位於 1 ~ 2²⁵⁶ — 1 之間,
也就是說,它是一串隨機生成的 256 bits 序列。這個 range 是非常巨大的,
要生成兩個一樣的私鑰是一件幾乎不可能會發生的事。
私鑰可以簽署交易,就像在現實生活中需要簽名才能夠轉帳一樣,
簽署過後的交易才能夠對你的帳戶資產進行更改。
只有擁有私鑰的人才能夠簽署這筆交易,交易才能被認可和被驗證。
公鑰
在 Ethereum 中,私鑰是用來將訊息簽名的,
而公鑰是用來驗證簽名的,所有人都可以獲取你的公鑰以驗證簽名。
Ethereum 的公鑰是由私鑰經過橢圓曲線演算法 ECDSA(Elliptic Curve Digital Signature Algorithm) 算出來的,
透過私鑰轉換成公鑰非常容易,但是要透過公鑰轉換成私鑰是一件非常困難的事
## **2. 用 Remix 部署智能合約(Local London),將寫好的合約部署到 Görli / Goerli 測試鏈上,並 verify 開源程式碼**
合約地址:[0xF596AcDeB07aCd57FE79052c691B9854af5C7e2F](https://goerli.etherscan.io/address/0xf596acdeb07acd57fe79052c691b9854af5c7e2f)
```
/**
*Submitted for verification at Etherscan.io on 2023-03-05
*/
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
contract TodoList {
TodoStruct[] private todos; //代辦事項草稿區
TodoStruct[] private pendings; // 代辦事項待送區
TodoStruct[] private completeds; // 代辦事項已完成區
uint256 private limitSec = 30; // Pending超過多少秒不給回ToDo
//建構式
constructor() {}
//ToDo Object
struct TodoStruct {
string todoText; //代辦事項
uint256 timestamp; //時間戳記
}
//Result Object
struct ResultStruct {
string code; //回傳代碼
string desc; //回傳說明
}
// 永久儲存是storage,短暫使用就用memory,calldata傳入後只能參考不能改變的data type
// =========== 代辦事項草稿區 =========== //
// 新增代辦事項草稿文件
function setTodo(string memory todo)
external
returns (ResultStruct memory)
{
todos.push(TodoStruct(todo, this.getTime()));
return ResultStruct("0000", "Success");
}
// 取得所有代辦事項草稿文件
function getTodos() external view returns (TodoStruct[] memory) {
return todos;
}
// 取得代辦事項草稿文件 By index
function getTodo(uint256 todosIndex)
external
view
returns (TodoStruct memory)
{
return todos[todosIndex];
}
// 刪除代辦事項草稿文件
function deleteTodos(uint256 todosIndex)
external
returns (ResultStruct memory)
{
if (!checkTodoStructIsNull(todos[todosIndex])) {
deleteAndSortAndPop(todosIndex, "todos");
return ResultStruct("0000", "Success");
} else {
return ResultStruct("0009", "TodoStruct Is Null");
}
}
// =========== 代辦事項待送區 =========== //
// 新增代辦事項待送文件
function setPending(uint256 todosIndex)
external
returns (ResultStruct memory)
{
TodoStruct memory todo = this.getTodo(todosIndex); //取得代辦事項草稿區文件
// 判斷該物件是否存在
if (!checkTodoStructIsNull(todo)) {
deleteAndSortAndPop(todosIndex, "todos");
todo.timestamp = this.getTime();
pendings.push(todo);
return ResultStruct("0000", "Success");
} else {
return ResultStruct("0009", "TodoStruct Is Null");
}
}
// 取得所有代辦事項待送文件
function getAllPending() external view returns (TodoStruct[] memory) {
return pendings;
}
// 取得代辦事項待送文件 By index
function getPending(uint256 pendingsIndex)
external
view
returns (TodoStruct memory)
{
return pendings[pendingsIndex];
}
// 代辦事項待送區文件 返回 代辦事項草稿區
function pending2Todos(uint256 pendingsIndex)
external
returns (ResultStruct memory)
{
TodoStruct memory todo = this.getPending(pendingsIndex); //取得代辦事項草稿區文件
// 判斷該物件是否存在
if (!checkTodoStructIsNull(todo)) {
//如果現在時間 - 物件儲存時間 <= 限制秒數,則可以退回todos
if (this.getTime() - todo.timestamp <= limitSec) {
deleteAndSortAndPop(pendingsIndex, "pendings");
todo.timestamp = this.getTime();
todos.push(todo);
return ResultStruct("0000", "Success");
} else {
return ResultStruct("0001", "time expired");
}
}
return ResultStruct("0009", "TodoStruct Is Null");
}
// 刪除代辦事項待送區文件
function deletePending(uint256 pendingsIndex)
external
returns (ResultStruct memory)
{
TodoStruct memory todo = this.getPending(pendingsIndex); //取得代辦事項待送區文件
// 判斷該物件是否存在
if (!checkTodoStructIsNull(todo)) {
deleteAndSortAndPop(pendingsIndex, "pendings");
return ResultStruct("0000", "Success");
} else {
return ResultStruct("0009", "TodoStruct Is Null");
}
}
// =========== 代辦事項完成區 =========== //
// 新增代辦事項完成區文件
function setCompleted(uint256 pendingsIndex)
external
returns (ResultStruct memory)
{
TodoStruct memory todo = this.getPending(pendingsIndex); //取得代辦事項待送區文件
// 判斷該物件是否存在
if (!checkTodoStructIsNull(todo)) {
deleteAndSortAndPop(pendingsIndex, "pendings");
todo.timestamp = this.getTime();
completeds.push(todo);
return ResultStruct("0000", "Success");
} else {
return ResultStruct("0009", "TodoStruct Is Null");
}
}
// 取得代辦事項完成區文件 By index
function getCompleted(uint256 completedIndex)
external
view
returns (TodoStruct memory)
{
return completeds[completedIndex];
}
// 取得所有代辦事項完成區文件
function getAllCompleted() external view returns (TodoStruct[] memory) {
return completeds;
}
function deleteAllCompleteds() external returns (ResultStruct memory) {
delete completeds;
return ResultStruct("0000", "Success");
}
// =========== 其他 =========== //
// 判斷 Struct 是否為 null
function checkTodoStructIsNull(TodoStruct memory todo)
private
pure
returns (bool)
{
if (bytes(todo.todoText).length == 0 && todo.timestamp == 0) {
return true;
} else {
return false;
}
}
// Array delete Todo And Sort And pop
function deleteAndSortAndPop(uint256 index, string memory arrStr) private {
TodoStruct[] storage arr = todos;
if (
bytes(arrStr).length == bytes("pendings").length &&
keccak256(abi.encode(arrStr)) == keccak256(abi.encode("pendings"))
) {
arr = pendings;
} else if (
bytes(arrStr).length == bytes("completeds").length &&
keccak256(abi.encode(arrStr)) == keccak256(abi.encode("completeds"))
) {
arr = completeds;
}
if (arr.length > 0) {
// 把index後面的全部替代前一格
for (uint256 i = index; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}
delete arr[arr.length - 1]; //刪除最後一格的資料
arr.pop(); //移除陣列最後一格的空間,這樣可以減少gas
}
}
//設定 Pending超過多少秒不給回ToDo 的限制秒數
function setLimitSec(uint256 sec) external {
limitSec = sec;
}
//取得現在時間
function getTime() external view returns (uint256) {
return block.timestamp;
}
}
```
###### tags: `Solidity 工程師實戰營第 5 期`
{"metaMigratedAt":"2023-06-17T23:12:59.799Z","metaMigratedFrom":"Content","title":"第一週作業","breaks":true,"contributors":"[{\"id\":\"23f0d768-b610-4bfb-b1ef-39559d3c0b50\",\"add\":7190,\"del\":84}]"}