0%

前言

最近更新公司的網站,除了 UI 以外也改了架構上的東西
專案不僅要分成 testnet, staging, mainnet 三種環境
在每個環境下又要支援不同鏈的切換,進而顯示不同內容

專案中還放一個策略設定檔,用來顯示該鏈所有策略的資料
這個設定檔的特別之處在於不能納入 build
因為希望之後等網站部署好,其他人(例如marketing)能夠藉由別的方式去修改server上的設定檔
這樣未來無論我們新增了多少策略,都不需要透過前端我更新網頁,也不需要重跑CICD的流程
以達到前端的最終型態

public 資料夾

public 資料夾是 react 專案中特別的存在
在不做其他額外設定之下
裡面的檔案不會經過 compile, 而是在 build 之後被原封不動地放到 BUILD_DIR 中

根據 react 的建議
如果你希望檔案在 build 之後維持檔名,就可以把它放進 public 裡面
或者是你需要動態讀檔(也就是我現在需要的),就必須讓檔案名稱維持在某個規則

機密資料怎麼辦

當我好不容易想好一個架構後,我的主管卻點出我把太多資訊放進 public 資料夾了
因為 public 是一個完全赤裸的空間
不只檔名不會變,檔案結構也會保留下來
等於是會把過多資訊公開到網路上
於是他請我再修改一下

但我左思右想,都想不到要怎麼把比較機密的資料藏起來
例如 RPC URL、測試站網址等等
就連各大網站如 uniswap, mStable, beefy 我都能從 dev tool 裡面輕鬆找到 他們每條鏈所用的 rpc url
那這樣我到底應該藏到什麼程度才夠呢?

我發現很多文章跟影片都會說要把 api key 放進.env才不會外洩
但這不是對的
基本上只要網頁會用到的東西
都能透過 dev tool 或某種方式看到
真正能藏 api key 的方法,是利用 proxy 的方式
把呼叫 api 的人(程式)從前端移到後端的 proxy server
然後利用 cors 或其他方式去限制能呼叫的 domain
可以參考本文最後面的參考資料

結論

最後我去告訴主管前端沒辦法把這些資料隱藏起來
我才知道是我會錯意了
他只是希望我把 public 盡量簡化
採用中性的名稱,例如不要特別在檔名上寫 stagine/testnet
並且不要在正式站暴露測試站的資訊
這樣就夠了

不過現在我更加清楚在前端隱藏「會用到的資料」其實是沒有意義的
因為終究要用在瀏覽器上,也就終究有辦法被看到
而且經過這次 code review 我也見識到主管在架構設計上的能力
我花了兩天想出來的結構,除了沒考慮到安全性,用起來也很複雜
但主管花了一個小時左右跟我一起研究出的架構就十分有邏輯
感覺我在這塊還需要訓練一下(他就是這麼跟我說的XD)

參考資料

How to store Ethereum JSON-RPC node API Key in a React app

How can one secure Web3 JSON-RPC API endpoint?

How do I hide an API key in Create React App?

前言

之前在面試期間稍微碰了一下 web3.js
當時只有照做的感覺,對區塊鏈的運作還很不熟
但至少對怎麼跟小狐狸互動有點概念

後來有幸進到區塊鏈公司,第一件事主管就請我先研究 ethers.js 和 web3modal
我發現 web3 和 ethers 是兩個很類似的套件
都是在處理錢包、智能合約互動之類的事情

整體來說
web3 背後有比較多人在維護,網路上的教學也比較多
ethers 則輕量很多,支援用 ENS name 來呼叫合約,state(provider) 和 key(wallet) 分開管理
另外 ethers 有一個好用的框架:wagmi,真的是方便很多,以後有機會來介紹
現在就筆記一下 Ethers.js 的常用功能吧

延伸閱讀

  1. Announcing ethers.js — a web3 alternative
  2. Web3.js vs Ethers.js 實際應用上的區別

Ethers.js

Install

npm install ethers

Terms

名詞 說明
Provider 與區塊鏈對接,負責提供「唯讀」資訊給網頁
Signer 權限比 Provider 更高,除了讀取還可以寫入區塊鏈
Contract 智能合約的實例化物件,可以用類似 ORM 的方式跟合約互動

Wallet Connection

這邊示範如何連接瀏覽器的 MetaMask 擴充套件
以及如何利用 web3Modal 來連接錢包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import ethers from 'ethers'
import Web3Modal from 'web3modal'

// Connect with MetaMask
// window.ethereum 是 MetaMask plug-in inject 到網頁的物件
const provider = new ethers.providers.Web3Provider(window.ethereum)

// Connect with web3Modal
const web3Modal = new Web3Modal({
cacheProvider: true,
providerOptions: {} // 這邊可以設定能支援什麼錢包,會在跳出 modal 的時候
})
const instance = await web3Modal.connect()
const provider = ethers.providers.Web3Provider(instance)

// Disconnect
// ethers cannot disconnect wallet programmically
// You can clear cached provider and reset the related states to null to pretend disconnection.
// see https://ethereum.stackexchange.com/q/83914

Get Accounts

可用listAccount()取得帳號陣列
不知道為什麼是陣列,難道說可以同時連接不同帳號嗎?

1
2
3
4
5
6
7
// 方法 1
const accounts = await provider.listAccounts()
console.log(account[0])

// 方法 2
const accounts = await provider.send('eth_requestAccounts',[])
console.log(accounts[0])

Get Balance

return <BigNumber>

1
2
3
4
const balance = await provider.getBalance(currentAccount)

const balanceInEther = ethers.utils.formatEther(balance)
console.log(balanceInEther)
  • 回傳 BigNumber,單位是 Wei,顯示時記得換算成容易看的單位,並轉換成 string。
    ethers.utils.formatEther : BigNumber ⇒ string(in Ether)
    ethers.utils.parseEther : string(in Ether) ⇒ BigNumber
    可參考這裡

  • 如果用 walletconnect 必須加上 blocktag pending
    getBalance(currentAccount, ‘pending’)
    否則可能不會抓到最新的數值

Get Network

return <Network> : {name: string, ensAddress: string, chainId: number}
Ethereum mainnet 會顯示 homestead

1
2
const network = await provider.getNetwork(currentAccount)
console.log(network.name)

用戶隨時能夠切換網路(Mainnet or Testnet),如果網頁沒有做相對應的反應,很容易讓用戶疑惑,甚至下錯單,造成金錢上的損失
Best Practice: 偵測到網路改變時,直接 reload 頁面,確保所有的 state 被重置

Network Changes Guideline
https://github.com/ethers-io/ethers.js/issues/866

Get Signer

1
const signer = provider.getSigner(account: string)

小結

以上是一些常用的 function
還有如何讀取 native token
下一篇會介紹如何與合約互動

突然發現前面不小心忽略了 web3modal
web3modal 是一個整合了各大錢包的接口
未來你想要多支援什麼 coinbase, walletconnect 等奇奇怪怪的錢包
只要 web3modal 有支援,都可以很快的添加進來
目前有 v1, v2 兩個版本

10 月底著手研究時,
v2 還在 early alpha,因此先跳過
但寫這篇文章的當下(12/13),已經進展到 beta.9 了
有稍微試用一下,很多當初要花一個禮拜研究的東西他都幫我做好了…
之後可能會再專案用的升級到v2吧哈哈
好 其他細節留到未來某個篇章再紀錄吧

前言

延續上一篇去參加 MOPCON 的心得
這篇比較會著重在我個人的部分
其實在來之前就有設立一些小目標
要盡可能地去達成
才不會辜負這趟旅程
(啊雖然說單純聽演講也是非常值得啦)

重大任務1: 見 Nic

幾個月前 SITCON 的時候
就有打算去看 Nic 演講,地點是在中研院那邊
但當時太晚知道,票已經賣完了
再加上演講主題是 Ruby
就沒特別去蹲轉讓了

後來過了一陣子,也開始思考應該為自己去技術會議
選定了 MOPCON,Nic 正好也公告說他會去演講,主題是 Web3
覺得是絕佳的機會,一定要去聽然後拍個照

Day1 的下午就有短暫看到 Nic 本人
但沒有馬上過去找他拍照,一不留神就消失了XD

Day2 的第一場演講才聽到一半我就開始去C3會廳找位子
越接近尾聲,人群就越往前移動
所以我也開始不斷地往前面的位置坐XD
最後居然讓我坐到超前面又正前方的位置辣!!!
我沒了

所以也很榮幸能清楚出現在Nic的自拍裡
成為他未來 google meet 的背景

會後的 QA 環節真的是人滿為患
好多人排隊拍照、問問題
我主要是想排在比較後面順邊聽聽別人都問什麼
發現有不少人也是正在轉職的階段,希望能獲得心態上或技術上的建議
也有些人是來問區塊鏈的相關問題
Nic 真的都很認真回答,回答很久哈哈
快輪到我的時候真的超挫,一邊想著到底要說什麼,但又不想要問技術相關的問題
最後決定跟他分享心路歷程

我就說我從2020年就開始看他的頻道了
然後經過這段期間的自學,不僅這禮拜上架了自己的app
甚至也拿到一些offer
其中還有 web3 領域的公司
一直以來從他的頻道學到很多軟硬實力的東西
給了我非常大的勇氣繼續向前

一邊講一邊抖XDD 因為實在是太興奮哈哈
Nic 聽了也是非常興奮+開心
馬上伸出手跟我握手,恭喜我的努力有了回報
也鼓勵我繼續像今天這樣來參加技術會議
未來也希望我有一天能站上台跟大家分享更多東西
我實在是太感動了QQQQ

最後到了拍照的階段,我問能不能和 Nic 跟 Doris 一起拍
因為兩位都是我很崇拜的對象
而且我和女友也是工程師+設計師的組合
可惜 Josie 這天沒辦法來,不然好想要四個人一起合照啊~~~

最後的最後,我也和他們分享了這禮拜剛上架的 App
他們覺得做得很棒,希望我能繼續保持前進的動力

有一段話記得很清楚,當時我心跳還是很快,手一直抖
Nic:「我看你應該也是蠻敢講話的,可以趁這個機會多跟別人交流」
我說:「其實我平常很內向不敢講話啦,現在還在抖XD 但覺得既然都來了就應該豁出去」
Nic:「我也是啦,我剛剛在台上也是挫嘎袂係,你可以試著多跟攤位互動問問題,慢慢提出自己的想法,漸漸認識更多的人,這對未來會很有幫助」
我:「對! 我覺得人脈很重要~」
Nic:「人脈真的很重要!」

於是這段對話成了我能夠完成下一個目標的強心針

重大任務2: 認識新朋友

就如前一篇一開始提到的,我身邊沒什麼寫程式的朋友
少數的那幾位也都不算很熟,沒辦法有什麼深度的討論
所以從去年開始我就去參加一些 FB 社團,試著在裡面回答問題,參與討論
但效果不彰,如果問題太難我連討論都不行
可能只能參與一些極度新手的問題
但用文字描述真的很難傳達給對方,不然就是必須打超大一篇
花了很多時間在這上面
後來漸漸變成用增廣見聞的心態潛水…

也有參加學校的資訊研究社
但步調真的很慢,成員之間的聯繫也蠻疏遠的
所以始終沒有感受到自己在工程師圈子裡的感覺
才會想要來參加線下的技術會議

來了是來了但到底要怎麼認識新朋友啊哈哈
有在 ViewSonic 遇到比我大幾屆的師大圖傳系學姊
真的是他鄉遇故知欸 頓時有種溫馨感QQ
但是沒有互相進一步認識就是了

後來也發現以前天文社的朋友居然也有來
大概有8年左右沒見了,真的是好久 天哪
在這陌生人海中還能有這一點小溫馨,實在很開心

到了 Day2
在下午的某場演講開始前
有個男生問我旁邊的位置有沒有坐人,然後就坐在旁邊
這個時候 Nic 的「人脈真的很重要」這句話一直迴盪在耳邊
恩… 拼了啦!!!

我終於開口跟陌生人講話了嗚嗚嗚
超重大突破!!! 交到新朋友啦
互相問一下對方是在做什麼的,然後也很尷尬的加了一下好友XD
後來的幾場演講也都一起聽,真的是有伴真好
下面這張是回家前的合照
以及他舉手提問後獲得的比特幣XDD

對方很好奇地問了我的轉職歷程
聽完之後,他感到很欽佩,覺得我能走到這個階段很不簡單
畢竟要放掉大學加研究所投入的心力
他本身雖然算本科系的碩一,但對未來還是很迷惘
沒有什麼能拿出的 side project,因為大多都是產學合作,不太方便
我也是給了他一些鼓勵(哇我現在是過來人了嗎)
建議他可以把產學合作案子的敏感資料抽出來,保留邏輯的部份看看能做什麼延伸
這樣應該還是很有機會的

原來這就是我夢寐以求的互相交流啊!
聊下來真的很開心,獲得了一位能互相勉勵的夥伴QQ

會後心得

整體下來
很慶幸自己有來參加 MOPCON
收穫非常多,拿到的禮物也非常多XD
以後也會參加其他的技術會議,尤其是在北部的
這次來回一趟北高,加上門票費,快要四千塊QQ
真的快吃土了哈哈

這個禮拜真的完成很多里程碑
找工作、JapanGo、MOPCON、收到 Nic 和 Doris 的鼓勵
簡直是人生的巔峰
未來一定要好好加油

另外也意外發現 LinkedIn 的好處
因為在這種場合,跟別人互加好友很容易冒犯到對方
相較於其他社交平台比較私人,LinkedIn 是比較工作取向,加好友也不失禮貌
像我就因此加到 Doris 啦! 開心~