海外求職完勝履歷攻略:怎麼3秒讓人資驚艷?過去職稱跟要找工作的不一樣怎麼辦?哪些資料千萬別放?
「阿雅,你看一下,覺得我的履歷好不好?」我一天通常會接到十封以上這樣的讀者來信,但很抱歉,我通常沒辦法立刻回答你。為什麼!假設我拿了兩件衣服給你看,一件是露肩小禮服、一件是阿嬤運動褲,我問「你覺得哪件好?」那你不先問我:「阿你是要穿去哪?」總不好穿個禮服去跑步!😅
什麼是好履歷?除了一些基本的格式問題,履歷本身沒有好壞,跟職缺需要的越相關越好!要是我洋洋灑灑寫了一堆過去當後台工程師的經驗,結果我要投的是業務,而履歷上完全沒有寫到相關的經驗,那當然不好!所以,不要再悶著頭寫履歷了,寫履歷 之前,先看清楚職缺說明,想想自己的背景跟職缺需要的有什麼相 關,履歷上就只寫那些相關的就對了!
如果你到家一小餐廳,餐廳菜單上有比薩、越南河粉、炸雞、炒飯、上海菜、墨西哥薄餅、小籠包,你覺得怎麼樣?大概覺得很不妙。一樣的道理,要是你好多類型的工作都會一點,但你投的是美國中大型企業的工作,記得大部分這些公司都分工細,如果你工作年份不多,選定一種類型的職務投,確保履歷從頭到尾都盡量有相關,而不是大雜燴、什麼經驗都寫,才能有效出擊! Less is More(少即是多)!
還有,寫履歷不是流水帳,是寫出自己的亮點,履歷要讓人家一看就知道你特別在哪(當然,最好是你的特長「剛好」是職缺需要的)。寫之前,先想想招募經理要收你的三個理由,為什麼招募經理應該收你,而不是其他一樣有符合條件的候選人?你跟其他做一樣工作的人比較起來,有什麼不一樣?然後在履歷上貫穿全篇地 寫出來。比如說,你申請的職位是產品經理,但特別的是需要會看 數據作分析,你就可以把過去在工作上有用到數據分析的經驗特別寫出來。
👉 履歷開頭:自我介紹。不是「我做了什麼」,而是「我要找什麼工作,而我有哪些經驗相關」
履歷的第一段開門見山地告訴別人你找什麼工作、有什麼相關經驗,特別是跟你想找的工作和產業高度相關的關鍵字。記得, 自我介紹不是「你做了什麼」,而是「我要找什麼工作,而我有哪些經驗相關」。
一個好的自我介紹要有四個部分,每個只要一到兩句話:你的職業、你的專長、你服務過的產業和公司類型、你跟別人不同的超能力。秘訣是,不是寫你想講的,而是寫面試官想看的(跟你找的 職位有相關而且你確實有的),包括你想找的工作的職缺關鍵字。
你要記得,這段內容的目的是讓看到履歷的人或是履歷系統能在幾秒鐘之內,覺得你的履歷跟職缺有高度相 關。也因此,上頭的職稱、關鍵字,要跟你想找的職稱越接近越 好,不相關的資訊每多一樣都可能會扣分。另外,這裡的重點是關 鍵資訊;不需要口語的說明,像是那種「我對什麼很有興趣,我很期待跟您面談⋯⋯」的訊息不要放在履歷上,可以放求職信(cover letter)裡。
例如,想找行銷經理的工作,你可以這樣寫:身為科技公司 的行銷經理,我擅長谷歌關鍵字廣告、搜尋引擎優化、社群媒體行 銷。我在科技業、電子商務、零售業有經驗,也在優步實習。我也 有網路廣告、電子報、公關行銷的經驗。擅長研擬行銷策略、分析 出消費者洞察、運用數據做顧客分眾、評估行銷成效。因為曾經當過業務,我特別擅長跟產品經理和業務溝通,確保行銷活動能為產 品帶來知名度和業績。
👉 關鍵技能
寫完標題,來談談「技能關鍵字」,在自我介紹下面,你可以 列出六到九個跟職缺說明相關,而且你有的技能關鍵字,這些字可以幫助人資和獵頭在履歷系統裡可以搜尋得到你,還有看到履歷的 時候,一眼發現你有相關經驗。你可以隨著職缺不同而做改變。
🎯 履歷內文:公司名字、職稱、執掌、成就
👉 公司名稱:解釋跟我說多相關、厲害
假設你過去的公司不是招聘經理聽過的,記得寫上註解,像是 「亞洲營養品相關最大生技公司」、「近年大學生最愛的服飾新創之一」、「電子業亞洲最賺錢的公司之一」、「運動 app 新創」。 比如說,你在統一企業台灣總部上班,雖然在亞洲是大公司,美國 人可能沒聽過,那你記得寫「台灣最大的食品公司之一」。如果你 服務的是小公司,你可以縮小到公司專長的領域,寫「在 XX 領域 XX 地區,知名的 XX 類型公司之一」。至於公司的年份,除非你公司都少於一年,不然我不認為需要放上月份。記得,履歷上寸土 寸金,只呈現相關、關鍵性的資訊。如果公司真的想要知道,之後 他會叫你填公司的資料系統。
👉 職稱:沒相關就括弧寫有相關
如果你的工作職稱不合業界常規,比如說,你明明做的是軟體 專案經理的工作,而且,想投的工作也是「專案經理」,但你的正 式職稱是「總經理助理」,那我建議你在後面括號「專案經理」, 如果你覺得你並沒有「專案經理」的職稱,你也可以括號寫「專案管理」。這樣面試經理才知道你的經驗有相關。
👉 執掌:你老闆同事是什麼職位、你負責什麼
每個工作下面可以用一句話介紹你的職掌。記得,「執掌」和 「成就」是不一樣的,「我是行銷經理,我帶三個社群媒體小編實 習生,年預算是 100 萬台幣,我的老闆是行銷副總監。」跟「我是 很強的行銷經理,因為我團隊和預算只有同事的一半,但我的年度 業績是其他人的兩倍。」前者是執掌,後者是成就。你的每個公司 只需要一兩句執掌,因為重點是成就。還有,寫專有名詞不如寫上 俗名,像是台北捷運 MRT 你就可以說是 subway(地鐵)。
👉 成就:你為什麼比同事好?
如上圖,執掌的下面是幾個條列式的成就,什麼是成就?就 是當有人問你:「我怎麼知道你做得很好?」時你的回答。或許是 公司業績比去年好 30%,或許是產品上市比預期快一個月,或許 是預算花得比其他專案少一半,或許是你的新流程讓品管師每週少 花 2 小時。記得引用數據。比如說,你的職責是「負責舉辦行銷活 動」,但成就則是「以少 10% 的預算辦活動,比前一年增加 50% 的業績。」投海外公司記得把業績轉成當地幣別。
👉 其他:Microsoft Office不要寫!
履歷上通常寫過去兩三個工作、過去五年的經驗就很夠了,如 果你有其他相關、但比較舊的經驗,或是實習、打工、創業經驗等非正式的工作經驗,可以寫在「更多專業經驗裡」(除非你沒有正 職,只有實習經驗,那就可以把實習寫在主內容裡。)另外,如果 你有一些特別希望招募經理知道的事情,比如說,我的經驗多半是 大公司,但希望招募公司知道我在新創領域也很有經驗,還有我在 寫部落格、出書、教書領域都很活躍,所以我特別把我那些的經驗 拉出來。如果沒有跟職缺相關的經驗,不需要寫。
如果你找的是理工、數據、財務、網站設計等重視硬技能的職 位,也可以把「技能」拉出來寫,標註你會的程式語言、專利、統 計軟體、財務證照、網站設計工具。至於現代上班族都會的東西, 像是 Microsoft Office,就不要浪費寸土寸金的履歷空間寫它了!
👉 學歷:放最後
除非你是應屆畢業生,否則學歷都是放在最後。如果你已經 有碩博士,而你的學士學校相對不有名、科系跟你想找的工作沒相關,可以把學士拿掉。如果你投的是海外工作,而你的學校召募經 理可能沒聽過,那記得括號解釋,比如說「大中華地區最好的文組大學之一」、「亞洲最好的理工類私立大學之一」。
如果你上過線上非學位的課程,但那些課程跟想申請的工作有相關,也可以把它寫上去。記得,有相關就好,沒相關就不需要!如果你畢業超過十 年以上,不想要人家知道你幾歲,免得有人覺得你太老或太年輕, 可以考慮把畢業年分拿掉。但如果你才畢業幾年,就別給人資添麻煩,學歷留著畢業年分就好了。
⛔ 履歷上不用放的資料
照片、生日、性別、詳細地址、出生地不必寫。美國公司最怕 人家告他歧視,所以跟工作無關的私人資訊不但不需要,還可能會 造成招聘經理的困擾,怕收你或拒你都被誤會是因為偏見!一收到 這樣的履歷,就知道缺乏對工作文化的認知,可是個地雷。
需要工作簽證:如果你投的是海外工作,需要工作簽證。不用 特別附註在履歷上;同樣的,如果你投海外工作,但不用簽證,也 不用放上去。人資有問再講就可以,減少歧視與偏見。至於推薦人,面試後有跟你要再給,根據你覺得哪些技能對方 特別在意,選可以佐證你在那些領域勝任的推薦人。
內容選自書摘:矽谷阿雅《追不到夢想就創一個!》從台灣記者到臉書電商產品經理的顛覆筆記 📒 博客來今天79折,滿千再9折!實體送全球,電子書台灣上市囉、海外5/28上市。https://reurl.cc/Wd86qy
範例借你抄 https://bit.ly/36wLtnr
https://bit.ly/2ZF9Ldj
同時也有984部Youtube影片,追蹤數超過4萬的網紅吳老師教學部落格,也在其Youtube影片中提到,基礎程式設計Excel and VBA(一)第2次 第3次 01_複習REPT與LEN並改為TEXT函數 02_開發人員與錄製巨集並產生按鈕 03_在巨集中加上註解與VBA環境 04_巨集註解與啟用巨集活頁簿存檔 完整影音 https://www.youtube.com/playlist?lis...
「程式註解範例」的推薦目錄:
- 關於程式註解範例 在 矽谷阿雅 Anya Cheng Facebook 的最佳解答
- 關於程式註解範例 在 Taipei Ethereum Meetup Facebook 的最佳貼文
- 關於程式註解範例 在 紀老師程式教學網 Facebook 的最佳解答
- 關於程式註解範例 在 吳老師教學部落格 Youtube 的最佳解答
- 關於程式註解範例 在 吳老師教學部落格 Youtube 的精選貼文
- 關於程式註解範例 在 吳老師教學部落格 Youtube 的最佳解答
- 關於程式註解範例 在 [翻譯] Google 建議的Python 風格指南27 - 看板Translate-CS 的評價
- 關於程式註解範例 在 程式註解如何寫| Jason note 的評價
- 關於程式註解範例 在 PHP 通用註解寫法 - gists · GitHub 的評價
- 關於程式註解範例 在 12 VBA程式註解與樞紐分析百分比 - YouTube 的評價
- 關於程式註解範例 在 #分享寫程式時該寫註解(comments) 嗎? 如果要的話該 ... - Dcard 的評價
程式註解範例 在 Taipei Ethereum Meetup Facebook 的最佳貼文
📜 [專欄新文章] Uniswap v2 實作 : 從創建交易對到Ether 換 Dai 投入 Compound
✍️ 田少谷 Shao
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
Uniswap v2 實作 : 從創建交易對到Ether 換 Dai 投入 Compound
V̶y̶p̶e̶r̶ Solidity coding time!
Image source: https://uniswap.org/
Outline
一. 前言二. 程式碼結構 1. Wrapped Ether(WETH)? 2. Impermanent Loss三. 創建交易對 - 準備 Interfaces四. 注入資金 - 注意事項五. 兌換虛擬貨幣六. 取得報價作為預言機七. 自行兌換 WETH八. 結語
一. 前言
暨上一篇解釋了 Uniswap 的演算法後,由於個人有使用 Uniswap v2 的需求,因此整理後寫成本篇,希望能幫助到其他也需要用 Uniswap 的讀者!(不熟 Uniswap 的人也可以參考區塊勢 許明恩 Astro Hsu 寫的介紹文:點我)
Uniswap 解析:恆定乘積做市商模型 Constant Product Market Maker Model 的 Vyper 實作
本文希望透過實際操作 Uniswap 我個人會用到、我認為大家比較常會用到的功能,來讓不熟悉的讀者快速了解其程式架構(v2 相較 v1 繁複)、熟悉實作方法,無法顧及全部還請見諒。
以下實作的測試環境為 Rinkeby 測試網,由於只是要講解使用方法,因此選擇在 Remix 上操作。
而 Uniswap v2 跟 v1 的差異,個人沒有很認真研究,大致列舉以下幾點,本文只會就其中幾點在後方進行較詳細的解釋:
使用 Wrapped Ether, WETH (於 二. 程式碼結構 解釋),讓 ERC20 交易對不再需要透過 Ether ,降低 gas 的消耗,但還是可以用 Ether 支付
加入時間權重的預言機,降低被操縱價格的風險,於 六. 取得報價作為預言機 中舉例說明,有興趣者可以看看 白皮書 有詳細介紹
閃電貸
使用 Solidity 而非 Vyper,因為 Solidity 功能上較齊全,於 五. 兌換虛擬貨幣 中舉例說明原因
在開始之前,本文超長,播個背景音樂吧:
二. 程式碼結構
本段落簡單描述 Uniswap 程式碼各部分的功能。若讀者要自己實作,可以參考此處得知該去哪一份程式碼找相應的功能:
Factory / UniswapV2Factory.sol : 創建交易對、查詢交易對的地址與總數;查詢、指定交易對手續費的收款地址
Pair(ERC-20) / UniswapV2ERC20.sol : Uniswap 流動性代幣 ERC20 的部分
Pair / UniswapV2Pair.sol : Uniswap 流動性代幣的其他部分;查詢交易對資訊
Router / UniswapV2Router01.sol : 注入、取出流動性/資金;兌換虛擬貨幣。此合約看似最複雜,其實只是因為收付款的單位可以是 Ether 或是 ERC20,所以有很多重複的函式
ExampleOracleSimple.sol, ExampleSlidingWindowOracle.sol : 預言機的範例程式碼
Library / UniswapV2OracleLibrary.sol : 供預言機調用的函式
Library / UniswapV2Library.sol : 供內部調用的函式
除了描述程式碼結構,為了以下的實作我們還需要知道 Wrapped Ether 是什麼,順便了解其使用原因:
1. Wrapped Ether (WETH) ?
從字面上來解釋,Wrapped Ether 是被包起來的 Ether。那為什麼好好的 Ether 不用還要創造出另一版本,嫌這小小世界的術語不夠多嗎 (ETH, WETH, Dai, aDai, cDai, sDai…)?xD
wETH | ERC20 tradable version of ETH
主因有兩個:廣泛地說,Ether 是以太坊上的原生虛擬貨幣,但它與廣為使用的 ERC20 標準並不相容( ERC20 有 approve(), transfer() 等等功能);而針對 Uniswap 的場景來說,v1 的交易對都一定有 Ether,而使用 Ether 可能會造成 Impermanent Loss,於下方解釋。
因此,就以上兩點的解決方法個別是:
部署一 ERC20 <-> Ether 的兌換合約:使用者將 Ether 付給 Wrapped Ether (ERC20) 的智能合約,合約就會給使用者同等數目的 WETH;拿回 Ether 則有點不太一樣,方法是告訴 WETH 的合約使用者要 withdraw(),WETH 的合約就會把使用者 WETH 擁有的額度設回 0 (或減少) 並返還 Ether,於 五. 兌換虛擬貨幣 中舉例說明
v2 交易對的建立不再只能是 (Ether, ERC20),可以是 (ERC20, ERC20)
2. Impermanent Loss
Impermanent loss 在 DeFi 指的是像 Uniswap 這類用演算法的去中心化交易所,如果交易對是兩幣價不相干的虛擬貨幣,例如:穩定幣 (Dai, USDC, etc) 和 Ether,流動性提供者 liquidity provider 會因為幣價的相對波動而比起直接持有兩幣還損失了一筆。
容我舉個例解釋清楚點,可以搭配我上一篇所寫的 Uniswap 的演算法 來理解:假設一開始 1 Ether 幣價為 100 Dai,只有一流動性提供者 LP 投入了 1 Ether 及 100 Dai (1 * 100 = 100 = k,k值要維持不變),總價值為 200 Dai。當 Ether 的幣價來到 200 Dai,眼尖者會發現資金池中的 Ether 價格低、有利可圖,因此會進行套利,例如:拿 33 Dai 約可以換到 0.25 Ether (0.75 * 133 ≒ 100),比起市場上要用 50 Dai 才能換到 0.25 Ether,套利者賺到了。此時,流動性提供者若將自己的資金提出,0.75 Ether 和 133 Dai 此時的總價值是 283 Dai,看似比當初的 200 Dai 還多,但其實將兩幣放著不動 1 Ether + 100 Dai 在此時就已經是 300 Dai 的價值了。於是,impermanent loss 就變成了 permanent loss :(
三. 創建交易對
- 準備 Interfaces
在開始之前,由於使用到的合約不少,所以我將全部所需整理在此:點我。其中,UniswapImplementation.sol 是本文實作的檔案。
若讀者在自己調用 Interface 時遇到版本問題,就依照 compiler 提供的指示稍作修改即可。我所整理的合約都修正過版本的差異、以下的實作也測試了可行,因此可以安心使用。
進入正題
通常大家使用的 Uniswap 資金池都是已經存在的,而如果想要上架自己的虛擬貨幣就要自己創建一組新的交易對,有兩種方式:在 Uniswap 官網上執行或是透過呼叫 Uniswap 的合約來建立,本文使用合約的方式。
首先,我們需要決定資金池為哪兩種虛擬貨幣,那就很普通地選 ETH 和 Dai 吧。雖然選了 ETH,但如同上方所述實際上必須使用 WETH,於是記下其在 Rinkeby 上的位置 。Dai 就使用 Compound 部署在 Rinkeby 上的版本,位置在 0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa。
接著,打開 IUniswapVFactory.sol,依照官方文件的指示將此合約部署在 Rinkeby 上的 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f。以下會有許多由 Uniswap 文件得知的合約地址及其他資訊等等,就不再一一附上來源或畫面截圖!
如上圖黑框所示,輸入了地址後按下藍色按鍵就完成部署了。接著,如下圖將 Dai 的地址 及 WETH 的地址輸入 createPair():
由於這個交易對我已經部署過了,因此讀者若想嘗試就麻煩去找別的 Rinkeby 上的測試幣了、或自己發一個! 完成後可以用 getPair() 輸入兩幣地址來確認交易對被建立成功:
如果想要進一步核對,可以先呼叫下圖紅框中的 allPairsLength(),得知當前總共有幾組交易對,再將 (交易對數 - 1) 輸入 allPairs(),就能得到和上圖一樣的地址。需要減 1 是因為陣列的 index 從 0 開始。
allPairsLength 的值會因為其他人的使用而增加,故日後可能會和本圖產出的 9 不同
四. 注入資金
看到標題的讀者可能會想:為何要把注入資金/流動性和上方的創建交易對分開呢?因為注入流動性這個功能被放在了 UniswapV2Router01.sol 中,所以就分開解釋。
雖然上一節只需要複製貼上按按鍵,但接下來要探討的注入資金 addLiquidity() 及虛擬貨幣的交換 swap()比起創建交易對 createPair() 是較有可能被融入到其他 DeFi 服務的功能(應該不太會有人會一直需要創建新的交易對),因此打開 UniswapImplementation.sol、要開始 Solidity coding!
如果不熟悉為何別的 DeFi 會需要在自己的服務中使用 Uniswap,可以搜尋 DeFi Money Lego/ DeFi 樂高,顧名思義就是在一個 DeFi 服務上使用另一個 DeFi 服務。實際的例子有:Aave 的新功能是可以拿往 Uniswap 注入流動性後得到的流動性代幣再投入 Aave 來賺取利息,以及下一節兌換虛擬貨幣的功能可以在 Pelith 的輕鬆貸 EasyDai、一站式 DeFi 組合工具 Furucombo 等場景中看到他們如何將 Uniswap 銜接上其他的 DeFi 服務。
回歸正題
在開始之前,先簡單提及一下有哪些變數、instance 需要初始化:
我們要呼叫 Uniswap 合約的 instance 來進行互動: IUniswapV2Router01
不只需要 Dai 的 instance,也需要 Dai 和 WETH 的地址;DaiAmount 和 ETHAmount 是為了稍後注入流動性所設置的,本文假設第一筆流動性我們使用 200 Dai + 1 Ether
immutable 是版本 0.6.5 加入的,用途是讓變數只能被讀取 read-only,但不同於 constant 的是能夠在 constructor() 中賦值。之所以各 instance 的地址不一起加上 immutable ,是因為若加上了,這些地址就不能在 constructor() 中被使用
p.s. 由於 gist 沒有 Solidity 的 syntax highlighting,所以隨便用了 .js 請忽略
看完了初始設定後,由於我們目前鎖定的資金池是 Dai 及 ETH,因此使用如下的 addLiquidityETH() 此函式,可以直接匯入 ETH 及 Dai。
本處我使用長度為 3 的陣列 addLiquidityResult 來記錄注入資金後的返回值:注入 Ether 的數量、Dai 的數量及返回的 Uniswap 流動性代幣的數量。實際上應該要依照不同使用者記錄的他們執行 addLiquidity() 後各自的返還值
第五行中的 approve() 是為了讓 UniswapV2Router01 的合約能夠從我們部署的合約 UniswapImplementation 取得 200 Dai 的使用權
於第六行 addLiquidityETH() 後方的大括號 {value: ETHAmount},這是 Solidity 0.6.0 後版本如果要在呼叫 function 的同時送入 Ether 的標準寫法,以前的寫法 .value() 目前也還能用但 compiler 會給提示
addLiquidityETH() 的第三、四個參數為最少要成功注入的數量。使用者能夠成功注入的數量取決於資金池中兩虛擬貨幣當下的數量,而本處直接給 0 比較方便
這邊非常重要的是上述程式碼還欠缺了一個無法被寫在合約內的步驟:使用者要同意這個被部署的合約 UniswapImplementation 可以從自己的帳戶中轉出 200 Dai。因此,將 ERC20 (Dai) 部署在 Rinkeby 上的位置,也就是0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa,接著輸入被部署合約的地址以及 200 Dai = 200000000000000000000、按下 approve() 後準備作業完成,如下圖。
終於可以呼叫 addLiquidity() 了! 如下圖,在紅框中以 1 Ether 呼叫黑框中的 addLiquidity() 後,就能成功將資金注入到 liquidity pool 了! 由於本文寫在測試後,因此沒有留下第一次 addLiquidity() 的結果 :(
此處被部署的合約位置跟上方截圖不同,因為其中測試了一些東西所以重新部署qq
接著,可以拿出 IUniswapV2Pair.sol,將其部署在 三. 創建交易對 中成功部署的位置 0x03E6c12eF405AC3F642B9184eDed8E1322de1a9e,使用黑框中的 getReserves() 就可以看到資金池中確實有匯入的資金! (本處依然沒有第一次使用後的截圖,因此截圖只是為了讓讀者看到 getReserves() 的結果)
此圖黑框中的值代表:在資金池中,Dai的數量、Ether的數量及上一次匯入資金的時間戳記
- 注意事項
使用 addLiquidity() 時需要小心的地方是:除了第一筆注入的資金可以自行決定兩虛擬貨幣的數量,第二筆開始就會依照其演算法算出兩幣可以投入的各自數量,因此使用者放入的兩幣中可能會有部分的其中一幣被 Uniswap 返回。
上方的程式碼只是為了第一筆流動性所寫,如果不是第一筆的情況就需要用成功注入流動性後的返回值(例如筆者的作法是用一陣列 addLiquidityResult 來存結果)來把沒有成功注入的資金返回給使用者。
五. 兌換虛擬貨幣
本節使用的兌換功能依舊是來自 IUniswapV2Router01.sol。
由於兌換虛擬貨幣實際上只有五行不到的程式碼,那麼就來把兌換 Ether 而得到的 Dai… 投到 Compound 來賺取放款利息吧! (雖然只是在測試網) 如果覺得這個場景似曾相識,沒錯,這就是上面提到的 輕鬆貸 EasyDai 的不專業版本!
首先將 Ether 和 Dai 互換的邏輯完成:
Ether 換 Dai : 使用 swapExactETHForTokens(),給某數量的 Ether 能換多少 Dai 是多少
Dai 換 Ether : 使用 swapExactTokensForETH(),作法只差在要把 Dai 轉到當前合約,再同意 UniswapV2Router01 可以從當前合約把 Dai 轉走
兩個做法的第二個參數都是可以自行指定兌換的路徑,此處就直接給 WETH 和 Dai 的地址即可(順序有差)。需要注意的是這個路徑要是動態陣列 dynamic array,而這就是 Vyper 所不支援的功能! 動態陣列跟靜態陣列宣告方式的差別我有註解在程式碼中
此處就先來試試 Dai 換 Ether 吧!和上方一樣,在使用時也要先 approve() 當前合約,當前合約才能轉走使用者的 Dai。
由上方的截圖可以很清楚的看到 Dai 換 Ether 這個動作牽涉到的資金轉移路徑:
Dai: 我的帳戶→當前合約→交易對所在合約
WETH: 交易對所在合約→UniswapV2Router01
Ether: WETH 合約→UniswapV2Router01→我的帳戶
以上的路徑有些人稍微思考後可能會納悶:為什麼上方沒有一筆 WETH 從 UniswapV2Router01 再轉到 WETH 合約的動作呢? 這就是在 Wrapped Ether (WETH) ? 中提到的案例。原因是:把 WETH 還回 WETH 的合約時實際上使用的函示是 withdraw() 而非 transfer(),而在 WETH 合約中發生的只是把使用者 WETH 擁有的額度歸零或減少而已。
接下來就是把 Dai 轉到 Compound 的部分。由於 Compound 不是本文重點,此處只求功能正常,因此比起真正的實作方法當然是簡化許多。
一如往常初始化 Compound 合約的 instance
ETH 換 Dai 後放入 Compound : 將用 ETH 換得的 Dai 的數量,也就是 swapExactETHForTokens() 返回的第二個值,approve() Compound 的合約後就可以用 mint() 匯入了! 要注意的是,ETH 換成 Dai 後的收款地址(第四個參數)是當前合約,才能從此合約轉 Dai 到 Compound
還款給使用者: 用 redeem() 取出 Dai,一如往常同意 UniswapV2Router01 使用 Dai 的權力
之所以說這個程式碼不能真的拿來用是因為:cDai 轉給使用者、讓使用者自己持有是比較安全的作法;即使選擇把 cDai 留在當前合約,以上程式碼檢查 cDai 數量是用當前合約 address(this) 去檢查,實際上應該要去記錄每個使用者所擁有的 cDai 數量
最後附上截圖,可以看一下資金的轉移路徑:
ETH -> WETH -> Dai -> cDai (Compound)
cDai -> Dai -> WETH -> ETH
六. 取得報價作為預言機
若使用 Uniswap v1的報價作為預言機,攻擊者可以利用其演算法造成的滑點來操控價格。為此,Uniswap v2 提供了兩個加入時間權重的合約範例:
ExampleOracleSimple.sol : 簡單版
ExampleSlidingWindowOracle.sol : 複雜版;Sliding Window 在此場景是指透過改變擷取資料(歷史價格)的片段,用該特定期間的價格來做成時間權重,讓使用上更靈活!
本處以簡單版為例。打開 ExampleOracleSimple.sol,由於一些匯入檔案的問題我將 UniswapV2OracleLibrary 也放在這份檔案中。
做法非常簡單:將 UniswapV2Factory、Dai 及 WETH 所在的地址作為部署合約 ExampleOracleSimple 時的輸入值就完成了。部署成功後會有個 24 小時的鎖 Time lock,因為這個預言機是有時間權重的,所以並不是一部署完就能立刻使用。若要體驗更新價格此功能可以使用我部署的兩個,其位置我寫在註解中。
將 WETH 或是 Dai 的地址和要查詢的數量輸入 consult() 就能查到兩虛擬貨幣的價格:
1 ETH 價格約為 97 Dai
1 Dai 價格約為 0.01 ETH
然而,在測試網上我們沒辦法拿著預言機查到的價格套入演算法來核對,因為測試網上的 Uniswap 沒有啟用收費機制,而 k 值要在收費機制啟動時才能被計算,欲知詳情者就麻煩去看官方文件了!
七. 自行兌換 WETH
上方雖然有提到 WETH 在 Uniswap 中的使用原因及場合,但或許有人想試著自己動手將 Ether 換成 WETH、把 WETH 換回 Ether。方法非常簡單,將 WETH.sol 部署到 0xc778417E063141139Fce010982780140Aa0cD5Ab 就能使用,如下圖:
按下綠框中的 At Address 後,使用下方黑框中的 deposit 搭配在中間的黑框輸入所要兌換 Ether 的量,就能成功換到 WETH。同理,圖中未顯示的 withdraw 功能就是讓人輸入 WETH 來換回等量的 Ether。
稍微提一下,如果是第一次兌換,將 WETH 所在的地址輸入 Metamask 就能在錢包中看到自己擁有的 WETH 的數量,如下兩圖:
Voila!
八. 結語
呼,雖然上述操作及程式碼的撰寫其實還蠻簡單的,但畢竟 Uniswap 的功能不少、我個人也希望能將小細節解釋清楚些,因此長度遠超過預期...有看到結尾處的讀者,辛苦了xD 希望大家現在對於 Uniswap v2 的內容跟實作方法都很清楚了!
最後,如果本文有任何錯誤,請不吝提出,我會盡快做修正;而如果我的文章有幫助到你,可以看看我的其他文章,歡迎一起交流 :)
田少谷 Shao - Medium
Uniswap v2 實作 : 從創建交易對到Ether 換 Dai 投入 Compound was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
程式註解範例 在 紀老師程式教學網 Facebook 的最佳解答
[免費教學] 千萬次播放的 Python 初學者影音課程,四個半小時馬拉松連播!
(含簡體中文字幕)
YouTube 網址: https://youtu.be/rfscVS0vtbw
------------
大家 2020 年新年快樂! :-D
今天要介紹給大家的,是我在 YouTube 上找到的一部四個半小時的影片:「學習 Python - 初學者全教程」。它一口氣把 Python 的基礎語法,在一支影片裡全部講出來!雖然沒有涵蓋到 Python 所有語法,但 80% 的情況也夠用了!希望大家會喜歡!
影片雖然是英文發音,但是已經有熱心人士,翻譯出十種語言的字幕了。其中也包含「簡體中文」。如果您對於直接聽英文沒有信心的話,可以把簡體中文字幕打開,應該能幫助您更好了解影片的內容。
附上該影片內容的時軸索引。如果您有特別想聽的內容,可以直接跳到特定時間點觀看:
0:00 簡介
1:45 環境安裝(IDLE & PyCharm)
6:40 設定&您的第一個程式
10:23 繪製幾何圖形
15:06 變數與資料型態
27:03 如何在 Python 內使用文字
38:18 如何在 Python 內使用數字
48:26 讀取使用者的輸入
52:37 範例:一個簡單的計算機
58:27 範例:填字遊戲
1:03:10 資料結構:串列(Lists)
1:10:44 串列相關函數
1:18:57 資料結構:元組(Tuples)
1:24:15 函數
1:34:11 函數傳回值
1:40:06 分支(if 指令)
1:54:07 分支與比較運算子
2:00:37 範例:改良簡單的計算機
2:07:17 資料結構:字典(Dictionaries)
2:14:13 迴圈(while 指令)
2:20:21 範例:猜字遊戲
2:32:44 迴圈(for 指令)
2:41:20 範例:製作一個指數函數
2:47:13 二維串列與巢狀迴圈
2:52:41 範例:一個簡單的翻譯器
3:00:18 註解(Comments)
3:04:17 例外處理(Try/Except 指令)
3:12:41 讀取檔案內容
3:21:26 寫資料到一個檔案裡
3:28:13 模組製作與安裝
3:43:56 類別與物件
3:57:37 範例:建立一個選擇題測驗
4:08:28 物件相關函數
4:12:37 物件導向的「繼承」
4:20:43 Python 直譯器
如果您聽完上述影片後覺得不過癮,或者想聽更完整的 Python 程式設計內容,或許可以考慮購買我在 YOTTA 這個平台製作的 Python 課程。網址是:
https://bit.ly/2k0zwCy
裡面包含:
1. 32+ 小時的精采內容!
除了 Python 語法外,還包含「計算機概論」、「Git」、「LINE 聊天機器人」等主題。
2. 26 個與課程內容緊密搭配的課後作業!
讓您學完後馬上練習,我會一題一題仔細地親自批改,徹底變身成為懂程式設計的珍貴人才!
課程目前已經全部製作完畢!600+ 位同學一致五星評價。購買後馬上可以享有完整 32 小時課程內容。
希望各位能夠喜歡今天的分享!在新的一年裡,祝福各位每天工作都順順利利、收獲滿滿!
PS: 本文歡迎轉發、按讚、留言鼓勵我一下!您的隻字片語,都是讓我繼續提供好物的動力喔!
--------
看更多的紀老師,學更多的程式語言:
● YOTTA Python 課程購買: https://bit.ly/2k0zwCy
● Facebook 粉絲頁: https://goo.gl/N1z9JB
● YouTube 頻道: https://goo.gl/pQsdCt
● Instagram 日常生活: https://goo.gl/nBHzXC
● Twitter 碎碎念: https://is.gd/xFZeub
如果您覺得這個粉絲頁不錯,請到「評論區」給我一個好評喔!
https://www.facebook.com/pg/teacherchi/reviews/
程式註解範例 在 吳老師教學部落格 Youtube 的最佳解答
基礎程式設計Excel and VBA(一)第2次
第3次
01_複習REPT與LEN並改為TEXT函數
02_開發人員與錄製巨集並產生按鈕
03_在巨集中加上註解與VBA環境
04_巨集註解與啟用巨集活頁簿存檔
完整影音
https://www.youtube.com/playlist?list=PLYDN7SApJ3PidAchpRUb7ZiqAq_S1dhk8
吳老師教學論壇
http://www.tqc.idv.tw/
課程理念:
1.以循序漸進的方式, 透過詳細的說明和實用的50個Excel VBA範例,
帶領您輕鬆進入 Excel VBA 設計的領域, 並逐步了解整個 VBA 的架構與輪廓,進而學習 VBA 變數、常數、函式及邏輯的觀念, 即使沒有任何程式設計基礎,也能自己親手撰寫 VBA 程序來提昇工作效率, 晉身職場 Excel 高手!
2.進而解說EXCEL與資料庫的結合,甚至將EXCEL當成資料庫來使用,
結合函數、VBA等更深入的功能,讓資料處理和分析的應用更上層樓。
五大類函數與自訂函數
一、文字和資料函數
二、邏輯函數
三、日期和時間函數
四、數學和三角函數
五、檢視和參照函數
上課用書:
Excel VBA一點都不難:一鍵搞定所有報表
作者: Excel Home
出版社:博碩
出版日期:2013/06/26
定價:380元
超圖解 Excel VBA 基礎講座
作者: 亮亨/譯 出版社:旗標
出版日期:2006/05/15 定價:420元
日本Amazon網站同類書籍銷售No.1
吳老師 110/9/30
函數,東吳大學,通識中心,元智大學,程式設計,線上教學excel vba教學電子書,excel vba範例,vba語法,vba教學網站,vba教學講義,vba範例教學,excel vba教學視頻
程式註解範例 在 吳老師教學部落格 Youtube 的精選貼文
基礎程式設計Excel and VBA(一)第2次
第3次
01_複習REPT與LEN並改為TEXT函數
02_開發人員與錄製巨集並產生按鈕
03_在巨集中加上註解與VBA環境
04_巨集註解與啟用巨集活頁簿存檔
完整影音
https://www.youtube.com/playlist?list=PLYDN7SApJ3PidAchpRUb7ZiqAq_S1dhk8
吳老師教學論壇
http://www.tqc.idv.tw/
課程理念:
1.以循序漸進的方式, 透過詳細的說明和實用的50個Excel VBA範例,
帶領您輕鬆進入 Excel VBA 設計的領域, 並逐步了解整個 VBA 的架構與輪廓,進而學習 VBA 變數、常數、函式及邏輯的觀念, 即使沒有任何程式設計基礎,也能自己親手撰寫 VBA 程序來提昇工作效率, 晉身職場 Excel 高手!
2.進而解說EXCEL與資料庫的結合,甚至將EXCEL當成資料庫來使用,
結合函數、VBA等更深入的功能,讓資料處理和分析的應用更上層樓。
五大類函數與自訂函數
一、文字和資料函數
二、邏輯函數
三、日期和時間函數
四、數學和三角函數
五、檢視和參照函數
上課用書:
Excel VBA一點都不難:一鍵搞定所有報表
作者: Excel Home
出版社:博碩
出版日期:2013/06/26
定價:380元
超圖解 Excel VBA 基礎講座
作者: 亮亨/譯 出版社:旗標
出版日期:2006/05/15 定價:420元
日本Amazon網站同類書籍銷售No.1
吳老師 110/9/30
函數,東吳大學,通識中心,元智大學,程式設計,線上教學excel vba教學電子書,excel vba範例,vba語法,vba教學網站,vba教學講義,vba範例教學,excel vba教學視頻
程式註解範例 在 吳老師教學部落格 Youtube 的最佳解答
基礎程式設計Excel and VBA(一)第2次
第3次
01_複習REPT與LEN並改為TEXT函數
02_開發人員與錄製巨集並產生按鈕
03_在巨集中加上註解與VBA環境
04_巨集註解與啟用巨集活頁簿存檔
完整影音
https://www.youtube.com/playlist?list=PLYDN7SApJ3PidAchpRUb7ZiqAq_S1dhk8
吳老師教學論壇
http://www.tqc.idv.tw/
課程理念:
1.以循序漸進的方式, 透過詳細的說明和實用的50個Excel VBA範例,
帶領您輕鬆進入 Excel VBA 設計的領域, 並逐步了解整個 VBA 的架構與輪廓,進而學習 VBA 變數、常數、函式及邏輯的觀念, 即使沒有任何程式設計基礎,也能自己親手撰寫 VBA 程序來提昇工作效率, 晉身職場 Excel 高手!
2.進而解說EXCEL與資料庫的結合,甚至將EXCEL當成資料庫來使用,
結合函數、VBA等更深入的功能,讓資料處理和分析的應用更上層樓。
五大類函數與自訂函數
一、文字和資料函數
二、邏輯函數
三、日期和時間函數
四、數學和三角函數
五、檢視和參照函數
上課用書:
Excel VBA一點都不難:一鍵搞定所有報表
作者: Excel Home
出版社:博碩
出版日期:2013/06/26
定價:380元
超圖解 Excel VBA 基礎講座
作者: 亮亨/譯 出版社:旗標
出版日期:2006/05/15 定價:420元
日本Amazon網站同類書籍銷售No.1
吳老師 110/9/30
函數,東吳大學,通識中心,元智大學,程式設計,線上教學excel vba教學電子書,excel vba範例,vba語法,vba教學網站,vba教學講義,vba範例教學,excel vba教學視頻
程式註解範例 在 程式註解如何寫| Jason note 的推薦與評價
程式註解 如何寫. 偶然的情況下,當我在搜尋寫作材料時,發現了這個網頁Source Code Comments 收集了十二則,來自不同 ... ... <看更多>
程式註解範例 在 PHP 通用註解寫法 - gists · GitHub 的推薦與評價
一、文件的註解通用樣例(普通程式文件,類文件,函數文件,變量定義文件). /** * XXXXX的文件 * * 功能1: xxx * 功能2: xxx ... ... <看更多>
程式註解範例 在 [翻譯] Google 建議的Python 風格指南27 - 看板Translate-CS 的推薦與評價
原文網址:https://google-styleguide.googlecode.com/svn/trunk/pyguide.html
註解
確認模組、函式、方法、行內註解的正確用法。
文件註解 (doc string)
Python 有一個獨特的文件註解格式。文件註解是寫在 package, module, class,
或 function 開頭的一段字串,這個字串可用物件的 __doc__ member method
讀取,pydoc 也是使用這段文字 (試試對你寫的模組執行 pydoc 看會如何)。
使用文件註解的慣例是用三個雙引號來包住字串。一個文件註解的開頭要有
一行摘要,摘要的結束符號應該是句號、問號,或驚嘆號。摘要的下一行是空白行
。空白行的下一行的第一個字元應對齊摘要行的第一個雙引號。下面有更多文件
註解應遵守的格式。
模組 (module)
每一個檔案都應包含固定的 license 範本。選擇一個適合專案的範本 (例如:
Apache 2.0, BSD, LGPL, GPL)
函式 (function) 與方法 (method)
本段落中所指的函式,泛指方法 (method),函式 (function),及生成器
(generator)。
除非以下的幾個狀況 *全部* 符合,否則每個函式都必須有文件註解。
1. 不會在模組外被呼叫或使用
2. 非常短
3. 很直觀
一個文件註解應該要讓使用者只看文件而不需要看程式碼就知道該如何呼叫該函
式。故文件註解應包含函式的呼叫語法及函式的用途,而非函式實現的細節。對
於比較複雜不直觀的程式,註解與程式碼放在一起要比放在文件註解中合適。
函式中的某些部份要被放在特定的段落中,以下一一列出。每個段落的段頭是一
個標頭行,標頭行以冒號結束。除了標頭行,其他的部份應使用兩個空白字元縮
排。
Args:
列出每個參數名,參數名後加上冒號,空一格,然後是該參數的敘述。若敘述太
長,一行 (80 個字元) 容納不下,下一行應縮排二或四個空白,整個文件的縮
排方式應一致。敘述應包含參數的類型 (type) 及用途。
若一個函式的參數接受 *foo (可變長度參數序列 variable length argument
list) 或 **bar(任意關鍵字參數 arbitrary keyword argument),文件註解中應
列為 *foo 及 **bar。
Returns: (若是生成函式則用 Yields:)
敘述回傳值的資料型態 (type) 及其意義與用途。若函式回傳 None,則不一定需
要有這個段落。
Raises:
列出所有此介面的例外。
def fetch_bigtable_rows(big_table, keys, other_silly_variable=None):
"""Fetches rows from a Bigtable.
Retrieves rows pertaining to the given keys from the Table instance
represented by big_table. Silly things may happen if
other_silly_variable is not None.
Args:
big_table: An open Bigtable Table instance.
keys: A sequence of strings representing the key of each table row
to fetch.
other_silly_variable: Another optional variable, that has a much
longer name than the other args, and which does nothing.
Returns:
A dict mapping keys to the corresponding table row data
fetched. Each row is represented as a tuple of strings. For
example:
{'Serak': ('Rigel VII', 'Preparer'),
'Zim': ('Irk', 'Invader'),
'Lrrr': ('Omicron Persei 8', 'Emperor')}
If a key from the keys argument is missing from the dictionary,
then that row was not found in the table.
Raises:
IOError: An error occurred accessing the bigtable.Table object.
"""
pass
類別 (class)
在類別定義底下應包含此類別的文件註解。若類別包含公開屬性 (public
attribute),則應寫在 attribute 段落中,並遵守函式中 Arg 段落中的格式。
class SampleClass(object):
"""Summary of class here.
Longer class information....
Longer class information....
Attributes:
likes_spam: A boolean indicating if we like SPAM or not.
eggs: An integer count of the eggs we have laid.
"""
def __init__(self, likes_spam=False):
"""Inits SampleClass with blah."""
self.likes_spam = likes_spam
self.eggs = 0
def public_method(self):
"""Performs operation blah."""
多行註釋及行註釋
最後一個該有註釋的地方是文件中較有技巧性的程式碼。若一段程式在下次的
code review 需要解釋,則應該要有註解。若需要多行註解來解釋較複雜的操作,
註釋應放在程式碼開始前。較不直觀的程式在行末應加上註解。
# We use a weighted dictionary search to find out where i is in
# the array. We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.
if i & (i-1) == 0: # true iff i is a power of 2
為了可讀性,註解應至少離程式碼兩個空白以上。
另一方面,絕不要敘述程式碼。假設閱讀該段程式碼的人比你更懂 Python (雖然
不一定懂你要做什麼)。
# BAD COMMENT: Now go through the b array and make sure whenever i occurs
# the next element is i+1
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 68.232.121.105
※ 編輯: sandwichC 來自: 68.232.121.105 (05/14 08:32)
... <看更多>