[爆卦]latex等於是什麼?優點缺點精華區懶人包

雖然這篇latex等於鄉民發文沒有被收入到精華區:在latex等於這個話題中,我們另外找到其它相關的精選爆讚文章

在 latex等於產品中有2篇Facebook貼文,粉絲數超過3,460的網紅Taipei Ethereum Meetup,也在其Facebook貼文中提到, 📜 [專欄新文章] Uniswap 解析:恆定乘積做市商模型 Constant Product Market Maker Model 的 Vyper 實作 ✍️ 田少谷 Shao 📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使...

  • latex等於 在 Taipei Ethereum Meetup Facebook 的最佳貼文

    2020-04-12 21:50:42
    有 17 人按讚

    📜 [專欄新文章] Uniswap 解析:恆定乘積做市商模型 Constant Product Market Maker Model 的 Vyper 實作
    ✍️ 田少谷 Shao
    📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium

    在 🦄 Uniswap v2 到來之前徹底了解 v1 的設計與演算法!

    Image source: https://uniswap.org/

    Outline

    一. 前言二. 恆定乘積做市商模型 Constant Product Market Maker Model 1. 計入手續費 2. 程式碼結構 3. 演算法核心與實作 4. 段落小結三. 流動性 Liquidity 1. 第一筆流動性注入、決定k值 2. 除了第一筆以外的情況四. 結語

    一. 前言

    暨上一篇開始接觸了 Vyper 後,我找了 Uniswap 的程式碼來更加熟悉 Vyper 的實作方法,順便研究了其演算法,然後就又寫了一篇 xD

    類 Python 的合約語言 Vyper 開發入門:與 Solidity 差異、用 Truffle 部署、ERC20 賣幣合約實做

    Uniswap 是以太坊上非常成功的自動做市商 Automated Market Maker (AMM)。本次我將用的 Uniswap 的程式碼搭配由 Runtime Verification 這家審計公司對 Uniswap 所做的形式化驗證結果來解釋恆定乘積做市商模型的 Vyper 實作 (2018 審計時 Uniswap 就已經是用 Vyper 而非 Solidity 了):

    智能合約程式碼:https://github.com/Uniswap/uniswap-v1/blob/master/contracts/uniswap_exchange.vy

    合約審計結果:https://github.com/runtimeverification/verified-smart-contracts/blob/master/uniswap/x-y-k.pdf

    本文將以講解實作概念及數學推導為重點,程式碼的部分只是輔助。審計結果將恆定乘積做市商模型演算法的數學推導寫得非常清楚而有趣(?),建議有興趣者可以整份看過一遍,相信得到很多收穫!

    至於更多 Uniswap 的介紹有興趣者可以參考 吳冠融 Roger Wu 所撰寫的簡介與使用流程:

    解析 DeFi 項目《Uniswap》(一)Uniswap 是什麼?

    解析 DeFi 項目《Uniswap》(二)Uniswap 如何使用?

    在開始前的最後,先預告本文頗長,所以來播個被 Youtube 推薦的歌吧:

    二. 恆定乘積做市商模型 Constant Product Market Maker Model

    交易所如果要去中心化、也不使用掛單 order book,就需要靠演算法自動算出交易標的的數量與價格,而 Uniswap 使用名為恆定乘積的演算法,其來源可追溯自 Vitalik 的這篇文章:點我。

    公式非常的簡單:x * y = k。令交易的兩虛擬貨幣為 X 和 Y,各自數量為 x 和 y,兩貨幣數量的乘積 x * y 恆等於 k,k 值是由第一筆注入的流動性所決定 (於 三. 流動性 Liquidity 解釋)。

    因此,用 ∆x 數量的 X 幣來購買 Y 幣所能得到的數量 ∆y、或是為了購買 ∆y 需要付出的 ∆x 數量,依照此公式進行計算:(x+∆x)(y-∆y) = k,而交易的價格就是兩幣量 ∆x 和 ∆y 的比。

    以下公式用 α = ∆x / x 和 β = ∆y / y 來表示 ∆x 和 ∆y 及 X Y 兩幣在交易發生後的新均衡數量:

    圖一

    1. 計入手續費

    在 Uniswap 進行的每一筆交易都會被收取 ρ = 0.003 / 0.3% 的手續費回饋給流動性提供者 liquidity provider ,因此要將手續費納入公式的考量:

    圖二

    上圖的公式或許不太直覺,我建議不要從 x’ρ 及 y’ρ 開始理解,而是從 ∆x 和 ∆y 兩值開始:手續費 ρ = 0.3% 的意思是會從付款中扣掉 0.3 %,也就是從 ∆x 扣。在有手續費的情況下 ∆x 就變成了 (1-ρ)∆x ,若令 γ = 1-ρ 則為 γ∆x。因此,將圖一中的 ∆x 換成 γ∆x,就會得到以下式子:

    source: https://www.codecogs.com/latex/eqneditor.php

    將等號左方的 γ 移到右方後就得到了圖二中的 ∆x。同理,由於 ∆y 中的 α = ∆x / x ,用 γ∆x 代換 ∆x 就會得到圖二中的 ∆y (有 α 的地方乘上 γ )。而 x’ 還有 y’ 就可以由 ∆x 和 ∆y 推出來了!

    然而,將圖二中得到的 x’ 和 y’ 相乘,會得到:

    source: https://www.codecogs.com/latex/eqneditor.php

    也就是說,當有手續費使得 γ != 1 /ρ != 0,x’ρ * y’ρ 的值其實會稍微和 xy = k 不同:在實作上 γ = 0.997 / ρ = 0.003,因此 1/γ-1 ≒ 0.003。β = ∆y / y 代表的是換得的 Y 幣佔總量的比例,即使最大值為 1,誤差也只有 1 * 0.003,故可知手續費 = 0.3% 對於 k 值的影響極小。

    2. 程式碼結構

    了解了基本的公式後,就可以開始研究程式碼是怎麼撰寫的。首先來看各個函式的功能:

    addLiquidity() 及 removeLiquidity():轉入與轉出資金,留到 三. 流動性 Liquidity 中說明

    getInputPrice() 及 getOutputPrice():最主要的函式,用以計算給 ∆x 所能換得的 ∆y 數量、以及為了得到 ∆y 所要支付 ∆x 的數量。此兩函式會被其他負責進行交易、匯幣的函式使用

    三組 (eth->Token, Token->eth, Token->Token) 的 swap() 及 transfer():swap() 的收幣人就是付款人、transfer() 的收幣人不是付款人而是指定的對象。基本上這兩函式就是呼叫 getInputPrice() 或是 getOutputPrice() 後進行匯幣的動作,因此不再多做解釋

    3. 演算法核心與實作

    在研讀程式碼前,先回顧一下 ∆x 和 ∆y 的公式:

    首先我們考慮用 ∆x 所能購買到的 ∆y 的 getInputPrice():

    什麼…就這幾行程式碼?是的。

    以上的程式碼和公式表達方式不同,因此先將 α = ∆x / x 和 β = ∆y / y 代換回來並將上下同乘 x:

    source: https://www.codecogs.com/latex/eqneditor.php

    由於 γ = 0.003,可以將上下同乘 1000 後得到:

    source: https://www.codecogs.com/latex/eqneditor.php

    接著就能來對照程式碼了:

    (109行) numerator: input_amount 是欲支付的 X 幣數量 ∆x、output_reserve 是 Y 幣數量 y,再乘上 997 後就是等式右邊的上方 (= 997∆xy)

    (110行) denominator: input_reserve 是 X 幣的數量,乘上 1000 再加上剛剛算過的 997∆x,就得到了等式右邊的下方 (= 1000x + 997∆x)

    此處要注意的是 Vyper 的除法是無條件捨去,等同於 floor() 函式。這會不會造成嚴重的影響呢?如果熟悉 ERC20 的人應該記得,在發幣時輸入的四個參數中有一個參數代表小數點的位數,如同下方程式碼中的 2 代表最後兩位在小數點後。舉例來說,當 getInputPrice() 收到 1234567 為這個幣的 input_amount 時,代表使用者擁有的幣的數目實際上是 12345.67。因此,即使將結果捨去 0.67 後的數字,影響真的不大,況且如果不捨去而選擇無條件進位,那代表交易所反而要虧損一點點啦,太佛心了吧 xD 有興趣者可以看看審計報告的內容,有更詳細地去定義這些誤差所影響的範圍!

    再來我們看若要購買 ∆y 需要付出多少 ∆x 的 getOutputPrice()。

    一樣先將 α = ∆x / x 、β = ∆y / y 和 γ = 0.003 代換並上下同乘 1000y 得到:

    source: https://www.codecogs.com/latex/eqneditor.php

    我們已經看過 getInputPrice() 一次了,所以應該能發現第 122–124 行得出的結果和上式相同。要注意的是這邊的結果反而是無條件捨去後直接 +1,因為這是在計算使用者要付多少 ∆x 才能購買到 ∆y,為了不讓交易所虧只能選擇請使用者多付一點點。

    4. 段落小結

    以上就是撇除匯幣等函示,恆定乘積做市商的 Vyper 實作,沒錯就這樣而已!Uniswap 之所以可以做到低 gas 消耗就是因為這個演算法本身就非常簡單,所需的運算也就是兩三次乘除法而已!

    不過我們還沒結束,接下來要談談如何投入資金/注入流動性,而這部分也包含了決定 k 值的精妙機制!

    三. 流動性 Liquidity

    流動性指的是交易市場中能夠交易的資金/標的物的量。使用自動做市商 (AMM) 而非掛單的最大好處就是市場一定會有流動性,而缺點就是如果交易量越大就會造成越大的滑點 Slippage,意思就是交易價格變動會越大、得到的價格越差 。

    source: https://ethresear.ch/t/improving-front-running-resistance-of-x-y-k-market-makers/1281

    我們可以用上面提到的 V 文章中的圖片來迅速帶過,畢竟有關注 Uniswap 的讀者大概都已經看過這圖很多次了。

    當要兌換的幣的數量越大/占比越重,例如:20% Y 幣的流動性,就會造成要付出比兌換少量時極為不對稱的高額 X 幣。

    接著我們要來探討注入流動性的原則,依照市場是否已經有流動性而區分為兩種情形:

    1. 第一筆流動性注入、決定 k 值

    以下程式碼是 addLiquidity() 函式中 46-48, 51, 及 64-74 行。當市場上還沒有任何流動性時,不會滿足第 51 行而是進入 64 行的 else。

    在第 65 行我們可以看到 msg.value ≥ 10¹⁰,以及在 67 行 token_amount 就是其中一個輸入值 max_tokens。這邊代表的是第一個注入流動性的使用者可以自行決定要注入多少 Ether (≥ 10¹⁰) (= x) 以及相應的幣的數量 (= y),也就是上方提到的 k 值 (= x* y),在本例的 X 幣就是 Ether。(本處先不解釋剩餘的程式碼,留到 2. 除了第一筆以外的情況)

    那麼問題來了:第一個注入流動性的人要怎麼決定提供各自多少的兩種幣呢?最好的辦法是依照當時兩幣的市價比,讓兩者的價值 (數量 * 價格) 相同,例如:當 1 Ether 的價格為 100 Dai,注入 1 Ether 以及 100 Dai 是最好的,因為兩種幣的總價值是一樣的,以下舉例說明原因。

    當 1 Ether 市價為 100 Dai 時,假設第一人決定注入 1 Ether 和 50 Dai (k = 50),總價值為 150 Dai,我們考慮兩種兌換方法:

    Ether -> Dai:用 0.1 Ether 來購買 Dai,依照上方公式 (1+0.1)(50-y) = 50 可得 y ≒ 4.55,也就是說得到的價格是 0.1 Ether = 4.55 Dai,遠低於市價 0.1 Ether = 10 Dai,相信沒有人這麼傻~

    Dai -> Ether:用 2 Dai 來購買 Ether,依照上方公式 (1-x)(50+2) = 50 可得 x ≒ 0.038,也就是說得到的價格是 2 Dai = 0.038 Ether,高於市價 2 Dai = 0.02 Ether,那麼眼尖的人就會立刻衝來套利了xD

    那麼即使如此,第一人有所損失嗎?當然有!假設路人 A 手上有 30 Dai (= 0.3 Ether),A 看到機會後就把 30 Dai 全換成 Ether:(1-x)(50+30) = 50 可得 x = 0.375,大於原本持有的 Dai 的價值 0.3 Ether。此時,第一人即使立刻抽出現存的全部資金 Ether = 0.625 及 Dai = 80,總價值也只剩下 142.5 Dai,比起原本的 150 Dai 還少。以上的計算還有手續費沒有納入考量,但也只有 30 Dai 的 0.3% = 0.09 Dai。

    由上例可知,第一位提供流動性的人為了避免自己的損失,確實得依照當時兩幣的市價比去提供相應的數量。傑克,這真是太神奇了0…0

    2. 除了第一筆以外的情況

    如果市場已經有流動性,使用 addLiquidity() 來注入流動性就會進入第 51 行的 if。

    source: https://github.com/Uniswap/uniswap-v1/blob/master/contracts/uniswap_exchange.vy

    (53行) eth_reserve: 由於使用者已經透過函式 addLiquidity() 將錢匯入了合約,因此將合約所擁有的 Ether 數量 self.balance (= x + ∆x) 減去使用者匯入的錢 msg.value (= ∆x),得到使用者匯錢之前合約內所擁有的 Ether 數量 (= x)

    (54行) token_reserve: self.token 是一個餵入幣地址的 ERC20 instance;透過呼叫 ERC20 的函式 balanceOf() 即可查出合約所擁有的 Y 幣的數量 (= y)

    (55行) token_amount: 透過將合約所擁有的 Y 幣的數量 token_reserve (= y) 乘上使用者匯入的錢 msg.value (= ∆x) 對合約原本擁有的Ether 數量 eth_reserve (= x) 的比例,代表使用者應該相應地注入多少 Y 幣 (∆y = y * ∆x / x)。除法一樣是無條件捨去

    (56行) liquidity_minted: 將原本交易所中的總流動性 total_liquidity 乘上增加的比率 msg.value / eth_reserve (= ∆x / x) ,代表增加的流動性,隨後會在第 58 行記錄下來

    (60行) transferFrom() 函式將使用者應付的 Y 幣數量 token_amount (= ∆y) 匯入當前合約,就完成了流動性的注入。小提示:智能合約中的 assert() 會確保函式內的條件如果失敗就整筆交易 transaction 直接取消,因此只要傳入的參數已經被計算好,於 60 行再進行 transferFrom() 其實與放在前面並沒有太大的差別

    以上就是注入流動性的大致實作內容。取出資金 removeLiquidity() 其實與 addLiquidity() 的做法大同小異,因此就不再贅述。

    四. 結語

    呼,真的累。恆定乘積做市商模型的概念雖然簡單,但解釋起來還是挺複雜的!其實本文並未著墨於審計報告中的主要議題:評估因為整數除法 (不使用浮點數) 而造成的誤差範圍,因為講起來非常複雜、也不是真的這麼需要知道。不過,恰巧就是這些程式碼的細節有可能讓程式產生預期之外的結果!因此,對於有興趣了解該如何去分析智能合約整數除法的讀者,可以研究一下;而 Uniswap 的程式碼因為是用 Vyper 實作,可讀性非常高、同時也不難,因此也非常值得打開來看看、甚至動手實作自己的版本!

    最後,如果本文有任何錯誤,請不吝提出,我會盡快做修正;而如果我的文章有幫助到你,可以看看我的其他文章,歡迎一起交流 :)

    田少谷 Shao - Medium

    Uniswap 解析:恆定乘積做市商模型 Constant Product Market Maker Model 的 Vyper 實作 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.

    👏 歡迎轉載分享鼓掌

  • latex等於 在 每日一冷 Facebook 的精選貼文

    2014-07-15 22:58:57
    有 46 人按讚

    #591#~本日冷知識~
    你知道嗎?【自己的論文自己審】

    「陳鎮遠事件」爆發以來,已經讓教育部長下台,媒體也喧鬧了好幾天,但是聞史迭我卻覺得沒有幾家媒體搞得清楚到底發生了什麼事情;偶爾有學術界的教授發表評論或者投書,馬上就會吸引大家的目光──但是眾家教授的說法卻又有那麼一點點不同。到底,前教育部長有沒有「抄襲」?陳鎮遠真的是手殘key錯帳號嗎?又到底,什麼是自己的論文自己審。

    首先先自我揭露,本人在電機以及物理領域都投過稿,目前著有兩篇期刊論文。以下討論的情境都僅限於所謂的理工科系,或者SCI的系統。

    首先要介紹的是為什麼會有「自己的論文自己審」這樣的故事。科學界的論文發表方式大致分為會議論文以及期刊論文兩種,其中大部分具有聲望的論文都是採用所謂同儕審查,也就是 peer-review的方式。在你的論文完成之後,會到期刊的網站做投稿的動作。現今大部分的科學期刊都是採用非常進步的電子投稿系統,甚至如果是用 LaTex 排版的話,投稿的速度更近是如閃電般迅速。

    除了文章的標題與摘要之外,最重要的資訊,莫過於作者名單了。 Authorship 是期刊論文最敏感的地方,也是兵家必爭之地,因為一旦被列名掛入「共同作者」,就可以把這篇文章列入著作清單,為自己的學術生涯又增添光亮的一顆星星。然而作者清單之中,卻又還有高下之分,其中最重要的就是所謂的 first author 第一作者,通常這位就是實際上的撰稿者,也是實際完成實驗或者研究的人;除了第一作者之外,同樣具有地位的還有所謂的 corresponding author,也就是俗稱的通訊作者,慣例上通常排在最後,但是卻是 last but not least。關於通訊作者的意義眾說紛紜,有人說是通常是指導教授、有人說是主導者,也有人說是出錢的人;但是我認為這些說法都是離題太遠了,實際上通訊作者的意義,就是某人讀了這篇文章之後如果有問題,要寫信問誰。這也是為什麼通常通訊作者會是實驗領導者或者指導教授的原因,因為第一作者可能來來去去,但是指導教授才是一直持續在做研究的人。

    人文領域的朋友可能不太習慣科學界這樣的掛名模式,但是實際上完成一個科學研究,實在已經很難由一個人就能獨立完成了。一個科學研究的完成,大家都有貢獻,大家一起分享作者的榮耀,這就是共同作者的概念。

    但是,說了這麼多,到底什麼是「自己的論文自己審」呢?剛才介紹到了作者清單,接著也是相當重要的就是推薦 reviewer 審閱者了。常見的情況有「白名單」與「黑名單」,有的期刊兩個都有,有的只有其中一個,當然也有可能有的期刊兩者皆無。列出黑名單,是為了避免自己的論文被同樣領域的競爭者所審到。被競爭者審到有兩不好:第一,在論文正式被刊出以前,都是屬於機密的狀態,但是被競爭者看到了,等於洩漏自己的機密;更慘的是萬一競爭者就差臨門一腳,那看了你投的內容之後偷學,連夜也發一篇一樣的,那可就慘兮兮了。第二,通常被競爭者審到,常常會得到非常敵意的審查意見,輕則大肆批評,重則直接打槍──不過這些都還不是最慘的──最慘的狀況是刻意富奸,壓著你的投稿不審,拖你的時間,又自己偷學,慘到不行。只要理由合理,絕大多數的期刊編輯都會尊重投稿者的意見。

    另一方面,有些期刊也開放投稿者推薦「白名單」,但是這並非是為投稿者建立有利的條件,而是幫助編輯找到適當的審核者。科學領域百百種,光是物理可能就有上千種學門,即使編輯本身是物理大師,也不見得了解每一種領域,或者認識該領域的專家;如果給了錯誤的人審閱,審閱者完全看不懂,要不是直接給過,要不然就整篇錯誤解讀,給了完全莫名其妙的打槍結論──這對期刊的聲譽或者投稿者都不好。因此,正確的「白名單」應該是推薦該領域具有相當份量者,但是盡量迴避自己熟悉或者本國的學者,尤其自己的研究夥伴以及親人是絕對應該迴避的。

    通常審閱者可能一到三人,給的評語通常有三種: minor revision、 major revision或者 reject,而經過多次修改之後沒有意外就有機會拿到 accept了。至於是不是只要有一個 reject 就會被打槍呢?這就要看編輯的態度了。編輯又是何許人也?科學期刊裡面除了負責行政事務的人員之外,通常也會有具有博士學位的主編,有的是真的全職在期刊內工作,也有的是學術單位裡面的研究人員或者教授。與其說 reviewer 權力很大,說主編主掌生殺大權可能更為貼切。

    現在你知道了 peer-review的機制與原理,接著我想「如何為自己創造有利的審核優勢」大家應該已經都知道了吧!陳鎮遠「不小心」創造了許多假的人頭帳號,再加上如果精心營造一個屬於自己的「專門領域」,那就很有可能讓自己投出的論文又讓自己審到,因此被認為是令人震驚的詐騙行為。

    那麼編輯有何責任?編輯直接負責指定審閱者,並做出最後判斷;在這個事件中,編輯未能正確判斷審閱者真偽,因此相當失職。在學術界裡面,email帳號其實是一個地位的象徵,例如同樣是 @ntu.edu.tw 的帳號,學生只有學位的帳號,但是教職人員卻能有自己自訂的帳號;又或者如果你有幸進入 mit,拿到了一個 @mit.edu 的電子郵件帳號,這些都可以說是地位的象徵。因為 .edu 的帳號具有珍貴性,我想陳鎮遠創造的人頭,大概是用免費的信箱創的;該期刊的編輯未能查明這點,我個人認為的確是有疏忽之處。

    本期附圖是陳鎮遠其中一篇JVC文章 "The development of autonomous low-cost biped mobile surveillance robot by intelligent bricks"的引用圖。左邊的是反向引用,也就是該篇文章所引用的參考文獻;右邊則是正向引用,也就是引用了這篇文章的人,也就是「被引用」的紀錄。各位讀者可以看到,這篇文章引用了17篇文獻,卻被引用了38次,可以說是相當具有引響力的文章啊!不過如果仔細一看,會發現引用的人之中,有相當的數量是陳鎮遠自己;不是陳鎮遠的人之中,又有將近一半是其胞弟陳鎮武。「自我引用」其實並不罕見,畢竟一般研究者的研究都有延續性,適當引用自己的文章,當然有助於讀者往回查詢其研究的脈絡;但是如果是故意引用自己的文獻以達到洗引用次數的目的,那就非常引人非議了。

    受限於篇幅,無法詳盡地介紹每一個環節,歡迎各位讀者留言討論。明天,我會再繼續跟各位聊聊關於期刊引用以及 "impact factor"的大小事。

    #聞史迭 代班

你可能也想看看

搜尋相關網站