Hi there 👋

Create & Create2

Create create在用的時候主要是根據 sender address sender address’s nonce 這兩個東西來產生address 產生的公式如下 keccak256(rlp.encode(senderAddress, senderAddressNonce))[12:] go-ethereum(v1.9.23)裡面是這樣實作的 // CreateAddress creates an ethereum address given the bytes and the nonce func CreateAddress(b common.Address, nonce uint64) common.Address { data, _ := rlp.EncodeToBytes([]interface{}{b, nonce}) return common.BytesToAddress(Keccak256(data)[12:]) } Create2 後來新加入的opcode,擺脫了nonce的限制,讓address可以更加靈活的被運用。像是可以有如BTC一般產生一堆收款地址,等待想要回收時,再自己部署一個合約的code回收那些錢即可。create2的必要元素如下: sender address the hash of byte code being deployed a random salt (32 byte string), supplied by the creator keccak256(0xff ++ deployingAddr ++ salt ++ keccak256(bytecode))[12:] go-ethereum(v1....

Ethereum Virtual Machine操作

本篇使用go-ethereum Version: 1.9.23-stable 概述 EVM跑起來就像是一個stack machine,stack整體是 1024 * 256 bit 個空間。 運作期間可以對Storage或是Memory做儲存或是讀取的操作。 至於各個OPCODE的操作可以搭配參照這裡。 1 + 1 首先我們來執行一個小小的程式 1 + 1 ❯ evm --code 6001600101 --debug run 0x #### TRACE #### PUSH1 pc=00000000 gas=10000000000 cost=3 PUSH1 pc=00000002 gas=9999999997 cost=3 Stack: 00000000 0000000000000000000000000000000000000000000000000000000000000001 ADD pc=00000004 gas=9999999994 cost=3 Stack: 00000000 0000000000000000000000000000000000000000000000000000000000000001 00000001 0000000000000000000000000000000000000000000000000000000000000001 STOP pc=00000005 gas=9999999991 cost=0 Stack: 00000000 0000000000000000000000000000000000000000000000000000000000000002 #### LOGS #### 這邊的code可以拆成三個部分來看,分別是6001 6001 01 所對應到的指令會像是這樣 00000: PUSH1 0x01 // PUSH 1 byte長度的數值 0x01 00002: PUSH1 0x01 // PUSH 1 byte長度的數值 0x01 00004: ADD // 相加Stack最上面的兩個元素後,把結果放在頂端 如上面的debug最後一個步驟,我們可以看到0x02就在stack的頂端。...

Go: setInterval

記錄一下Golang的setInterval方法 package main import ( "log" "time" ) func main() { ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() for ; true; <-ticker.C { log.Println("hello") } } Ref: https://stackoverflow.com/questions/32705582/how-to-get-time-tick-to-tick-immediately...

C3 linearization

C3 linearization演算法可以拿來解決多重繼承的方法優先呼叫順序(Method Resolution Order)。 以下是經典的diamond problem A / \ B C \ / D B繼承A, C繼承A, D繼承B, C。 由於在C++內沒有實作,所以這樣寫是會產生錯誤的。 #include <iostream> using namespace std; class A { public: void foo() { cout << "I'm A" << endl; } }; class B: public A { public: void foo() { cout << "I'm B" << endl; } }; class C: public A { public: void foo() { cout << "I'm C" << endl; } }; class D: public B, C {}; int main() { D d = D(); d....

Go: 邏輯運算子

在Go的規格書裡面有寫到以下敘述 && conditional AND p && q is "if p then q else false" || conditional OR p || q is "if p then true else q" ! NOT !p is "not p" 這是一種叫做Short-circuit evaluation的優化方法 以p && q來說,如果p是false的話其實就保證這個結果一定是false,這時候就不用特別再去看q了。反過來說p || q也是一樣的,如果p是true,q是什麼值都不會影響最終結果。 package main import "fmt" func TrueHere() bool { fmt.Println("call TrueHere") return true } func FalseHere() bool { fmt.Println("call FalseHere") return false } func main() { fmt.Println("&&") if FalseHere() && TrueHere() {} /* output: && call FalseHere */ fmt....

Go: 讀取相對檔案路徑

檔案結構 ❯ tree . . ├── config │ └── config.go ├── config.yml └── main.go 1 directory, 3 files 理論上會把讀取相關檔案的邏輯寫在config/config.go, 這時候的路徑如果能以呼叫的地方為出發點會比較不容易搞混 main.go package main import ( "log" ) func main() { err := config.LoadConfig("./config.yml") if err != nil { log.Fatal(err) } } config/config.go package config import ( "fmt" "io/ioutil" "path/filepath" "runtime" ) func LoadConfig(path string) error { _, file, _, _ := runtime.Caller(1) content, err := ioutil.ReadFile(filepath.Join(filepath.Dir(file), path)) if err != nil { return err } fmt....