26 Feb 2022
於terminal輸入:
find . -name .DS_Store -print0 | xargs -0 git rm -f --ignore-unmatch
輸入以下指令將.DS_Store加入.gitignore
echo .DS_Store >> .gitignore
commit .gitignore file
git add .gitignore
git commit -m '.DS_Store banished!'
資料來源
29 Jan 2022
書籍這裡買:天瓏、博客來
- 區塊鏈使用私鑰加密交易紀錄,節點用公鑰解密–>數位簽章,公鑰即像亂碼的錢包地址
- 主流公鏈如比特幣、以太坊的非對稱式加密透過橢圓公式ECC
- 區塊鏈的不可能三角:去中心化、安全、效能,只能三取二
- CBC是區塊鏈的前身!!區塊鏈因為鏈會分岔,所以也有重放攻擊,藉由讓鏈有獨立ID避免此問題
主流鏈
Bitcoin
“Be your own bank”
- 發明者中本聰
- 節點要挖礦也要接收外部請求,中本聰一開始也是以socket & thread 完成資料的接收與處理,一個thread 處理socket的連接,另一個處理接收後的資訊
- 區塊容量上限 1MB –> 3.3-7 TPS(transaction per seconds), visa : 1700 TPS
- 每2016個block調整一次difficulty,盡量10分鐘出一個block
- BIP
- UXTO(Unspent Transaction Output) 架構–>用支票的方式交易
- 每一張支票只能被使用一次–>可對抗雙花攻擊
- 帳戶目前餘額:所有持有UXTO的金額總和
- 優點:擴充性佳、隱私性提升
- 三次重大版本更新
- 多重簽名
Pay to Multi Signature(P2MS)/Pay to Script Hash(P2SH)
- 隔離驗證(Segregaed Witness, Segwit)
可以提升兩倍交易量,擴充區塊大小其實也可以,但區塊大傳播慢
- 閃電網路(Lightning Network)
- 鏈下擴容,微小的支付並不會馬上上鏈,而是去鏈上開閃電支付的通道,接著到鏈下把牽過的交易資訊給對方,等到要結算再統一上鏈
- 只要與閃電網路任何一個節點開啟支付通道,那就可以與節點連接的所有閃電網路進行無延遲無手續費的交易
- 要先抵押資產,就像要刷悠遊卡之前要先儲值
Ethereum
- 具圖靈完備性
- 用Gas機制限制運算量、手續費,手續費上限=Gas Limit*Gas Price
- Gas
- Gas Price:願意為每個Gas付多少錢(Gwei)
- Gas Limit:願意為了這筆交易買多少Gas
- 每個區塊的Gas上限:800萬Gas,誰出的Gas Price高,礦工就販售位置給誰,所以出的Gas Price越高,交易越快被打包進區塊。
- 約15秒出一次塊
- EIP
- Ethereum的改善協議
- 以太坊基金會開發維護,會基於EIP發出相對應的ERC讓大家討論 ex.ERC20
- Account 架構–>像是銀行簽帳卡
- 每筆交易都有一個遞增的nonce值,值越小越優先執行–>避免雙花攻擊
- 優點:簡單、效率,不用產生額外UXTO
共識
拜占庭將軍問題
整個Bitcoin全節點可以視作一種純P2P網路,為了保持各個節點間資料一致性,傳播資料要考慮有假造的節點,如何確保資料同步、一致性,形成共識?–>要對抗女巫攻擊(惡意使壞的節點)
- 問題背景:
有很多將軍,要投票達成一致策略,要撤離或是要進攻城市,投票過程每位將軍要把自己的決定通知給其他所有將軍,總計自己的決定和收到的其他將軍的決定,就可以推算出共同結果。 但將軍裡可能有叛徒,會有以下問題
- 故意投不好的策略、不照最後決定行動
- 假其他將軍之名傳假訊息給別人
- 送信的信使被攔截
證明自己有廣播/投票權利
- 工作量證明 POW(Proof Of Work)
- 手中必須持有運算力,不斷找nonce
- 缺點:區塊鏈發展被礦池把持
- 權益證明 POS(Proof Of Stake)
實用拜占庭容錯(PBFT)
考慮視域變化(view-change),分為三階段:
- pre-prepare
- prepare
- commit
分岔
有時候分岔不是因為技術、惡意節點、駭客,而是因為社群意見的分裂。
- 暫時性分岔
因為網路延遲造成短時間不同步的現象
- 孤兒塊Orphan Block : 鏈長較短被捨棄的區塊、交易不算、沒獎勵
- Ethereum因為出塊時間比較短,會產生的孤兒塊也比較多,所以改用叔塊機制
- 叔塊Uncle Block : 必須在出現暫時性分岔後的六代內被納進主鏈,間隔越多代,出塊獎勵越少
以下兩種跟軟體升級、程式碼或協定更動有關
- 軟分岔 Soft Fork
- 更新完還是可以接受與過去版本間形成部分的共識–>向後相容
- 新舊版本可以共存同個鏈
- 以功能的更新居多
- 硬分岔 Hard Fork
- 更新後完全無法與舊版本形成共識
- 新舊版本不可共存於同個鏈上
- 通常是共識規則的更新
- Ex.
Ethereum Classic(ETC) 自 Ethereum 分岔出
Bitcoin Cash(BCH) 自 Bitcoin 分岔出
隱藏交易細節
零知識證明
- 不提供任何有關訊息的資料,仍可以說服對方該筆訊息是正確的
- 不讓礦工知道所有交易明細,但要說服對方這筆交易合法合規
- 核心:同態隱藏 Homomorphic Hidings
主流匿蹤貨幣
- ZEC
- Monero(XMR)
- Dash
- 有master node機制,並非去中心化的(decentralized)
其他技術
- Socket
- Stream socket (TCP)
- Datagram socket (UDP)
其他專有名詞
Initial Coin Offering(ICO)
Initial Exchange Offering(IEO)
Initial Fork Offering(IFO)
Security Token Offering(STO)
網站
21 Jan 2022
Useful example
Style Guide 值得注意的地方
參考網址
Value Type
bool
: 包括constants true
and false
- Integer:
int
/ unit
- Fixed Point Numbers :
fixed
/ ufixed
- Address
address
: Holds a 20 byte value (size of an Ethereum address).
address payable
: Same as address, but with the additional members transfer and send.可以接收Ether.
- 可做Implicit和Explicit conversion.參考
- 如果計畫要接收Ether,最好一開始就宣告
address payable
- Members of Address Types
- ex.
balance
and transfer
address payable x = payable(0x123);
address myAddress = address(this);
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
call
, delegatecall
and staticcall
- 注意: All contracts can be converted to address type, so it is possible to query the balance of the current contract using
address(this).balance
.
- Fixed-size byte arrays
- The value types
bytes1
, bytes2
, bytes3
, …, bytes32
hold a sequence of bytes from one to up to 32.
- Dynamically-sized byte array像是
bytes
,string
Not a value-type!
- String Literals and Types
- They do not imply trailing zeroes as in C; “foo” represents three bytes, not four.
"foo" "bar"
is equivalent to "foobar"
–>遇到超長string的時候有用
- enum
- default:第一個成員
- Using
type(NameOfEnum).min
and type(NameOfEnum).max
you can get the smallest and respectively largest value of the given enum.
- Enums can also be declared on the file level, outside of contract or library definitions.
Reference Types
- Structs, Arrays and Mappings.
- Use a reference type, you always have to explicitly provide the data area where the type is stored:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
contract C {
// The data location of x is storage.
// This is the only place where the
// data location can be omitted.
uint[] x;
// The data location of memoryArray is memory.
function f(uint[] memory memoryArray) public {
x = memoryArray; // works, copies the whole array to storage
uint[] storage y = x; // works, assigns a pointer, data location of y is storage
y[7]; // fine, returns the 8th element
y.pop(); // fine, modifies x through y
delete x; // fine, clears the array, also modifies y
// The following does not work; it would need to create a new temporary /
// unnamed array in storage, but storage is "statically" allocated:
// y = memoryArray;
// This does not work either, since it would "reset" the pointer, but there
// is no sensible location it could point to.
// delete y;
g(x); // calls g, handing over a reference to x
h(x); // calls h and creates an independent, temporary copy in memory
}
function g(uint[] storage) internal pure {}
function h(uint[] memory) public pure {}
}
Arrays
- An array of 5 dynamic arrays of uint is written as
uint[][5]
–> 和其他語言相反
- 宣告
uint[][5] memory x
後
* access the seventh uint in the third dynamic array using x[2][6]
* access the third dynamic array, usex[2]
X[3]
is always an array containing three elements of type X, even if X is itself an array –> 和其他語言不同
- Allocating Memory Arrays
uint[] memory a = new uint[](7);
- As opposed to storage arrays, it is not possible to resize memory arrays (e.g. the
.push
member functions are not available)
Array Literals
- 複雜
[1, 2, 3]
is uint8[3] memory
, because the type of each of these constants is uint8
. If you want the result to be a uint[3]
memory type, you need to convert the first element to uint
. ex. [uint(1), 2, 3]
[1, -1]
is invalid,因為第一個是uint8
,而第二個是int8
,應該寫成[int8(1), -1]
- Fixed size memory arrays cannot be assigned to dynamically-sized memory arrays
uint[] memory x = [uint(1), 3, 4];
–>錯
- 正確:分開assign值
uint[] memory x = new uint[](3);
x[0] = 1;
x[1] = 3;
x[2] = 4;
Array Members
- length
- push()
- push(x)
- pop
Special array
Mapping Types
mapping(_KeyType => _ValueType) _VariableName
- 可以想成hash table
- the key data is not stored in a mapping, only its
keccak256
hash is used to look up the value. 所以對key沒有長度的限制
- The _KeyType can be any built-in value type,
bytes
, string
, or any contract or enum type. Other user-defined or complex types, such as mappings, structs or array types are not allowed.
- _ValueType can be any type, including mappings, arrays and structs.
- You cannot iterate over mappings, i.e. you cannot enumerate their keys. 但可以自己實作
delete
delete a
assigns the initial value for the type to a.
uint x = data;
delete x; // sets x to 0, does not affect data
delete data; // sets data to 0, does not affect x
uint[] storage y = dataArray;
delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also
// y is affected which is an alias to the storage object
// On the other hand: "delete y" is not valid, as assignments to local variables
// referencing storage objects can only be made from existing storage objects.
- 如果delete a[x],會刪除index x的element,造成array中間有個Gap.
Function Type
function (<parameter types>) {internal|external} [pure|constant|view|payable] [returns (<return types>)]
-
預設:internal,所以internal |
external可省略 |
- External (or public) functions 的members:
.address
returns the address of the contract of the function.
.selector
returns the ABI function selector
{gas: ...}
and {value: ...}
to specify the amount of gas or the amount of wei sent to a function, respectively.
Visibility and Getters
external
- Part of the contract interface
- means they can be called from other contracts and via transactions.
- An external function f cannot be called internally (i.e.
f()
does not work, but this.f()
works).
public
- Part of the contract interface
- can be either called internally or via messages
- For public state variables, an automatic getter function (see below) is generated.
internal
- can only be accessed internally (i.e. from within the current contract or contracts deriving from it),without using this.
private
- are only visible for the contract they are defined in and not in derived contracts.
getter function
- The compiler automatically creates getter functions for all public state variables.
- The mapping and arrays (with the exception of byte arrays) in the struct are omitted because there is no good way to select individual struct members or provide a key for the mapping
State Mutability
view
Functions can be declared view in which case they promise not to modify the state.
下面行為被認為是 modifying the state:
Special Functions
Receive Ether Function
- 一個合約只能有一個receive function
- 宣告使用
receive() external payable { ... }
* 不用function
keyword
* 不能有arguments
* 不能return東西
*一定要有external visibility and payable state mutability
Fallback Function
- 一個合約只能有一個fallback function
- 宣告使用
fallback () external [payable]
or
fallback (bytes calldata _input) external [payable] returns (bytes memory _output)
* 不用function
keyword
* 不能有arguments
* 不能return東西
*一定要有external visibility
Error handling: Assert, Require, Revert and Exceptions
參考網址
- The
assert
function creates an error of type Panic(uint256)
.
- The
require
function either creates an error without any data or an error of type Error(string)
.
- The
revert
statement takes a custom error as direct argument without parentheses:
revert CustomError(arg1, arg2);
try/catch
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.1;
interface DataFeed { function getData(address token) external returns (uint value); }
contract FeedConsumer {
DataFeed feed;
uint errorCount;
function rate(address token) public returns (uint value, bool success) {
// Permanently disable the mechanism if there are
// more than 10 errors.
require(errorCount < 10);
try feed.getData(token) returns (uint v) {
return (v, true);
} catch Error(string memory /*reason*/) {
// This is executed in case
// revert was called inside getData
// and a reason string was provided.
errorCount++;
return (0, false);
} catch Panic(uint /*errorCode*/) {
// This is executed in case of a panic,
// i.e. a serious error like division by zero
// or overflow. The error code can be used
// to determine the kind of error.
errorCount++;
return (0, false);
} catch (bytes memory /*lowLevelData*/) {
// This is executed in case revert() was used.
errorCount++;
return (0, false);
}
}
}
Self Destruct
參考網址
The only way to remove code from the blockchain is when a contract at that address performs the selfdestruct
operation.
很危險!如果其他人傳送Ether到已經被移除的合約地址,Ether會被永久遺失。
其他
- 可以返回多個return值
- 可以overloading–A contract can have multiple functions of the same name but with different parameter types
- 和c一樣有struct