[爆卦]對照變數例子是什麼?優點缺點精華區懶人包

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

在 對照變數例子產品中有13篇Facebook貼文,粉絲數超過9萬的網紅我是賀禎禎 - 攝影教學 & 自助旅行 & 數位生活,也在其Facebook貼文中提到, [想攝影141] 細說分鏡 Vol.18 🎥 影片時間連結:https://youtu.be/3XpWY8Xbe5U?t=252 🖍我認為,在欣賞任何一幅作品之前 🖍別被其表象,框住了你的思考 從何時開始拍照? 如果從拿相機開始亂拍,那到現在也有20 多年,但真正開始學習攝影基礎? 大概是 200...

  • 對照變數例子 在 我是賀禎禎 - 攝影教學 & 自助旅行 & 數位生活 Facebook 的最讚貼文

    2021-09-26 20:52:45
    有 51 人按讚

    [想攝影141] 細說分鏡 Vol.18
    🎥 影片時間連結:https://youtu.be/3XpWY8Xbe5U?t=252
    🖍我認為,在欣賞任何一幅作品之前
    🖍別被其表象,框住了你的思考

    從何時開始拍照? 如果從拿相機開始亂拍,那到現在也有20 多年,但真正開始學習攝影基礎? 大概是 2003 年那時開始;那又何時開始從事攝影寫作? 從 2010 年 10 月第一篇文章起,也有 10 年了;那又何時開始教攝影? 再晚一點,2012 年 07 月開始至今,也有 9 年了,回想這過去這些重要時間點,照片對我的意義也好、用途也好,也會不斷的改變。

    🟥接觸更多不同人
    我曾經在資訊展、商場賣過相機,待在台北光華商場某個小角落一段時間,喜好是攝影,接觸到的自然是對「拍照、攝影」有需求、有興趣的消費者,而前來櫃位的消費者,從對攝影一無所知,開口就直問「我需要一台如何如何功能的相機」,到以攝影為攝業的「攝影師」,二者之間需求落差很大,消費金額從一台3-4 千元的相機,到一顆 5-6 萬元的鏡頭,直到一台將近 20 萬元的相機。

    不同需求的客人,聊起攝影有完全不同的故事,完全不懂的客人,讓我了解他們對拍照的想法,為何會這麼簡單的也不懂? 口中說的、需要的、花錢買下去的完全不一樣,有些客人會接受我的意見,選擇我所推薦的,有些則是很確定的是「我就是要這台」,即使我心中覺得這台並不完全適合你,但有花錢、有消費,你就是客人。

    另一種是以攝影為職業的攝影師,像是「婚禮攝影、新聞記者、攝影工作室」等等都有,談起攝影又是另一片天地,印象最深刻的是其中一位前輩問我「你覺得,職業與專業,哪裡不一樣」? 一時間我也分不清楚這界限如何區分。

    🔹「職業是拍出客戶滿意的作品讓他下單,專業是客戶買你拍得滿意的作品讓他下單」,二句話聽起來很像,卻完全不一樣的層級與境界,雖然我還不曾體會後者的心情是什麼,但前者的心情我卻很能體會。🔹

    談起「器材」的看法,一般消費者與職業工作者則是不同的見解,特別是職業工作者如何訴說「高級相機、鏡頭」那規格表看不到的的實際體驗,那真的沒有實際用上是真的比較不出差別,由於這裡是「光華商場」不是「攝影研究社」,也無法具體的更深入的討論,但從這些職業攝影師心得交流分享,讓我能稍稍接觸更高攝影領域的境界。

    🟥天哪,你能教嗎?
    一開始寫攝影教學從沒想過「我可以開課」「我能教」,甚至直到今天是我每天工作內容之一,而一通陌生電話響起,聊了一下「你是誰?」,再聊聊「你能來教我們攝影嗎?」,一開始是拒絕的,連個課程大綱、講義都沒有,一點經驗也沒有,哪敢答應一個陌生電話另一頭的邀約,但對方熱情與堅持,於是帶著一點心虛的說「既然如此,我們就來試看看吧」,於是開啟了第一堂課。

    一開始設計 6 門課,慢慢變成 8 堂、10 堂、12 堂,連同進階 18 堂課,講義也從 V1.0 到 V16 版不斷的改變,也能針對不同需求、上課形態設計不同的課程組合,再設計新課程,新的內容等等。

    一開始會認真的去數開了幾個班,默默為這個班的學生做點記錄,比如說有多少人啦、第一堂何時開課啦,但經過數年下來,已經數不清開過少課、有多少學生上過我的課,東西南北跑過多少地方,如果當初那個記錄的習慣有維持下來的話,我想想這幾年開過的班,教過的學生,應該是非常可觀。

    🔹我總是不斷的接觸「初學者」,課程也是為他們不斷的設計、改版,背後動機當然是希望自己越教越好,能讓他們接受到更簡單易懂的內容,「教學相長」這好段時間,我從初學者身上學到非常多、非常多,了解為何他們想學、困難在哪裡、需求在哪裡,雖然不同班的新生,彼此間對拍照的想法需求都大同小異,但每一次課程都能讓「再一次的重新學習、體會」,如果我是一位初學者,我會如何期待攝影能帶給我什麼收獲,攝影又可能是什麼樣子。🔹

    「是得,我能教,我很會教」至少到了今天我總算能大聲說出這句話,但這背後無心插柳柳成陰的故事,少數讀者、朋友才知道的事情。

    🟥旅行、攝影
    除了身為他人眼中的老師,其實老師也該不斷進步,除了不斷追求更好的教學內容與方法,也試著在別的領域相結合,看看從「不同領域看攝影」,能否有想出新的見解。

    我開始出國旅行,在有機會與能力下,多出去看看,2013、2014 年,我各別去歐洲自助旅行,這二次都各去一個月,當時的心情走馬看花 (現在想想哪一次不是),眼裡看到的盡是「新鮮貨」,連個路邊的垃圾桶都長的不一樣,順手拍個幾張。

    在陌生的環境能產生一種「與環境陌生的隔閡」,除了眼裡看到的新鮮貨之外,心境也跟著看開了 – 原來世界好大,自己這麼渺小,應該在有心有餘且力充足下,多出去看看,雖稱不上打開什麼我們說的「攝影眼」,但至少讓我能期待自己能抱著相機,多看看更多地方,挑戰自己能走到多遠、多久。

    當自己看得多了、玩得多了,就產生了另一個新的念頭「想讓我的學生、讀者看看我所看見的世界」,該如何最安全、有效率的達成這一點? 是的,我考上了外語領隊,跟著旅行社合作帶讀者、學生出國,這是最具體的方法。

    🔹這讓我又用不同的心態來看待「攝影」,自己用相機、鏡頭體會這世界不足以讓我滿足,帶著其它人感動我曾經有過的感動,這是我另外的目標,我想這比多年前「入門攝影課程」相比,這更像是「進階的攝影課程」,只是這是屬於我自己的課程、我的團員反而是我的老師,從他們身上學習到,如何透過其它人的視野,來增見我所見到的世界。🔹

    🟥攝影與錄影
    確切的說是「靜態攝影與動態錄影」,除了在「完全不同的工作領域」外,我也在「不同的表達呈現」上嚐試,也就是「動態錄影」,雖然很多人會說,若你攝影基礎有了,那麼動態錄影入門也不會太難,我也這麼認為,但就「基礎入門」上確是如此,但實際上跳進來學習,才發現學會「從無到有製作出一隻影片」,跟「拍出一系列攝影作品」,這兩個根本就是「二件事」,共通點大概就是…,手上的相機既能攝影,也能錄影,少了器材進入的成本 (一部分啦)。

    從 2018 年中,我開始自習「動態錄影」,從剪輯軟體的學習、到如何拍出一隻教學影片、VLOG 影片,嚐試不同器材,在這個領域,我也是初學者,每件事就像從頭來過,中間有些辛苦,但也十分新鮮,我偶爾會跟學生說:

    🔹「好好體會你是初學者的身份,因你對任何事都感到好奇,而當你一切都熟練了,很容易將任何事情視為理所當然,你也就會慢慢麻痺,失去觀察力與好奇心」🔹

    當我開始學習動態錄影過程,我也這樣子告訴自己,慢慢學習、不急,享受初學者的過程,來看看動態錄影裡頭的世界,逐漸找到與「靜態攝影」有哪些異同、彼此可以互相接替的部分,直到撰文的今天,我依舊還是個「初學者」,很多東西還是一知半解、仍然好奇。

    🟥跳脫領域思考
    🔹「通常在一個問題卡住,原地打轉不得其解,你在原有的領域想不出答案,而透過站在其它領域來看這待這個問題,通常都能獲得解答,或是不同的想法」🔹

    我們都知道「要站在別人的立場來想自己的事情」,但這何其困難? 如果你不是「真的站在別人的立場過」,你是無法用不同的角度、思維方法來看自己問題,但一但你有過類似的經驗,也許你也能認同上面我所說的 – 跳脫領域思考,能發現原有領域所想不出的答案,也或許答案依舊想不出來,但相信能產生更多新的想法,重回既有的領域再試圖尋找答案。

    每每在教攝影過程,在課堂上講解任何觀念,教得好不好,學生有無吸收,從學生的眼中可以得到答案,對我來說難的不只是「教」這件事,難的是如何知道他們哪裡不懂? 為何不懂? 不懂為何不舉手? 還是連自己懂不懂都不清楚? 他們的眼神流露的,除了疲憊以外就是「呆滯」,這該怎麼解? 我除了試著換更多不同的例子,講講不同的比喻,笑話也一講再講,想辦法打通他們的關卡,雖有些進步改善,但我覺得問題依舊存在,不是今天,而是明天。

    而直到我「真的跳脫了既有的領域」,再思考上面這些問題,部分問題我得到了答案,當我接觸到「旅行」,讓我對攝影有著更大的夢想之外,也讓我思考「為何我那麼辛苦拿著相機原因是什麼」,用這角度去想想學生辛苦下班,接著來教室上課,他們心情與期待是什麼?

    當我接觸到「動態錄影」,從動態錄影過程,我思考這問題「照片真的勝過千言萬語嗎?」一張照片帶給我們除了「視覺的記憶外」,好像留下來的東西也不多,那前面那問題「照片有無勝於有聲」這觀念是值得深思好一會。

    🔹當把「動態錄影」帶到課上,才發現學生為何部分觀念依舊死記,是因為他們不在「現場」缺乏對於照片判斷的線索,他們看到照片只是「結果」,也只能參考,甚至死記,若能在一張照片之前帶點影片,較能讓他們「如臨現場」感受一些氛圍,要他們學習新的觀念,好像這問題似乎解決了。🔹

    也同時能解決另一個我好奇的問題「為何一到外拍練習,學生就把課堂上學到的內容全還給我一樣」,因為外拍過程中,整個世界都是充滿線索的「大教室」,該如何依現場教他們如何判斷眼前的東西,結合所學,因為「氣氛環境」擁有太多變數需要講解,這些東西帶不進教室裡,這才是我們需要「外拍」的原因。

    🟥持續重看「攝影」
    教學、寫作十年的經驗,我也不斷的在改變我所擅長的領域之外,同時我也跨足不同的媒體、不同的專業,帶著初學者的心情去看看我所不懂的,這份好奇心讓我在其它領域事物上,學到了很多新點子,在「攝影」及「攝影教學」上,我有很多的改變。

    🔹最重要的改變,是改變我對「照片、攝影」的看法,我不再堅持那套「照片無聲勝於有聲」「一張照片勝過千言萬語」這些過去我埾持的念頭,而是更加「超越、溶合」不同領域的專業、觀點來看待這些事情,讓我能確實的跳脫單純的靜態攝影的想法,有著更進一步的成功與成果。🔹

    別誤會,我依舊喜歡「攝影」,而我仍舊在不同領域持續的學習,並且帶著這些學習接觸後的感想「帶回我所熱愛的攝影」,照片對我來說,已不再只是記錄、回憶、創作、證明等等念頭,更不只是視為自己獨享的小小世界,許許多多觀念仍在我心中發芽、成長,希望我能更加堅持下去,持續的進步,也更加認識自己「為何如此對攝影的熱情,仍持續不停」,我想這問題,也是許多人心中最大的疑問,對吧?

    📷📷📷📷
    7 堂攝影入門課 🙆‍♂️終生看 ⏱隨時看 🎞線上看
    #報名連結:https://go.hojenjen.com/3p2g6n
    👉9/30 前早鳥價~~ $4990

  • 對照變數例子 在 Taipei Ethereum Meetup Facebook 的最讚貼文

    2021-06-21 17:57:12
    有 1 人按讚

    📜 [專欄新文章] ZKP 與智能合約的開發入門

    ✍️ Johnson

    📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium

    這篇文章將以程式碼範例,說明 Zero Knowledge Proofs 與智能合約的結合,能夠為以太坊的生態系帶來什麼創新的應用。

    本文為 Tornado Cash 研究系列的 Part 2,本系列以 tornado-core 為教材,學習開發 ZKP 的應用,另兩篇為:

    Part 1:Merkle Tree in JavaScript

    Part 3:Tornado Cash 實例解析

    Special thanks to C.C. Liang for review and enlightenment.

    近十年來最強大的密碼學科技可能就是零知識證明,或稱 zk-SNARKs (zero knowledge succinct arguments of knowledge)。

    zk-SNARKs 可以將某個能得出特定結果 (output) 的計算過程 (computation),產出一個證明,而儘管計算過程可能非常耗時,這個證明卻可以快速的被驗證。

    此外,零知識證明的額外特色是:你可以在不告訴對方輸入值 (input) 的情況下,證明你確實經過了某個計算過程並得到了結果。

    上述來自 Vitalik’s An approximate introduction to how zk-SNARKs are possible 文章的首段,該文說是給具有 “medium level” 數學程度的人解釋 zk-SNARKs 的運作原理。(可惜我還是看不懂 QQ)

    本文則是從零知識證明 (ZKP) 應用開發的角度,結合電路 (circuit) 與智能合約的程式碼來說明 ZKP 可以為既有的以太坊智能合約帶來什麼創新的突破。

    基本上可以謹記兩點 ZKP 帶來的效果:

    1. 擴容:鏈下計算的功能。
    2. 隱私:隱藏秘密的功能。

    WithoutZK.sol

    首先,讓我們先來看一段沒有任何 ZKP 的智能合約:

    這份合約的主軸在 process(),我們向它輸入一個秘密值 secret,經過一段計算過程後會與 answer 比對,如果驗證成功就會改寫變數 greeting 為 “answer to the ultimate question of life, the universe, and everything”。

    Computation

    而計算過程是一個簡單的函式:f(x) = x**2 + 6。

    我們可以輕易推出秘密就是 42。

    這個計算過程有很多可能的輸入值 (input) 與輸出值 (output):
    f(2) = 10
    f(3) = 15
    f(4) = 22


    但是能通過驗證的只有當輸出值和我們存放在合約的資料 answer 一樣時,才會驗證成功,並執行 process 的動作。

    可以看到有一個 calculate 函式,說明這份合約在鏈上進行的計算,以及 process 需要輸入參數 _secret,而我們知道合約上所有交易都是公開的,所以這個 _secret 可以輕易在 etherscan 上被看到。

    從這個簡單的合約中我們看到 ZKP 可以解決的兩個痛點:鏈下計算與隱藏秘密。

    Circuits

    接下來我們就改寫這份合約,加入 ZKP 的電路語言 circom,使用者就能用他的 secret 在鏈下進行計算後產生一個 proof,這 proof 就不會揭露有關 secret 的資訊,同時證明了當 secret 丟入 f(x) = x**2 + 6 的計算過程後會得出 1770 的結果 (output),把這個 proof 丟入 process 的參數中,經過 Verifier 的驗證即可執行 process 的內容。

    有關電路 circuits 的環境配置,可以參考 ZKP Hello World,這裡我們就先跳過去,直接來看 circom 的程式碼:

    template Square() { signal input in; signal output out; out <== in * in;}template Add() { signal input in; signal output out; out <== in + 6;}template Calculator() { signal private input secret; signal output out; component square = Square(); component add = Add(); square.in <== secret; add.in <== square.out; out <== add.out;}component main = Calculator();

    這段就是 f(x) = x**2 + 6 在 circom 上的寫法,可能需要時間去感受一下。

    ZK.sol

    circom 寫好後,可以產生一個 Verifier.sol 的合約,這個合約會有一個函式 verifyProof,於是我們把上方的合約改寫成使用 ZKP 的樣子:

    我們可以發現 ZK 合約少了 calculate 函式,顯然 f(x) = x**2 + 6 已經被我們寫到電路上了。

    snarkjs

    產生證明的程式碼以 javascript 寫成如下:

    let { proof, publicSignals } = await groth16.fullProve(input, wasmPath, zkeyPath);

    於是提交 proof 給合約,完成驗證,達到所謂鏈下計算的功能。

    最後讓我們完整看一段 javascript 的單元測試,使用 snarkjs 來產生證明,對合約的 process 進行測試:

    對合約來說, secret = 42 是完全不知情的,因此隱藏了秘密。

    publicSignals

    之前不太清楚 publicSignals 的用意,因此在這裡特別說明一下。

    基本上在產生證明的同時,也會隨帶產生這個 circom 所有的 public 值,也就是 publicSignals,如下:

    let { proof, publicSignals } = await groth16.fullProve(input, wasmPath, zkeyPath);

    在我們的例子中 publicSignals 只有一個,就是 1770。

    而 verifyProof 要輸入的參數除了 proof 之外,也要填入 public 值,簡單來說會是:

    const isValid = verifyProof(proof, publicSignals);

    問題來了,我們在設計應用邏輯時,當使用者要提交參數進行驗證的時候,publicSignals 會是由「使用者」填入嗎?或者是說,儘管是使用者填入,那它需不需要先經過檢查,才可以填入 verifyProof?

    關鍵在於我們的合約上存有一筆資料:answer = 1770

    回頭看合約上的 process 在進行 verifyProof 之前,必須要檢查 isAnswer(publicSignals[0]):

    想想要是沒有檢查 isAnswer,這份合約會發生什麼事情?

    我們的應用邏輯就會變得毫無意義,因為少了要驗證的答案,就只是完成計算 f(42) = 1770,那麼不論是 f(1) = 7 或 f(2) = 10,使用者都可以自己產生證明與結果,自己把 proof 和 publicSignals 填入 verifyProof 的參數中,都會通過驗證。

    至此可以看出,ZKP 只有把「計算過程」抽離到鏈下的電路,計算後的結果仍需要與鏈上既有的資料進行比對與確認後,才能算是有效的應用 ZKP。

    應用邏輯的開發

    本文主要談到的是 zk-SNARKs 上層應用邏輯的開發,關於 ZKP 的底層邏輯如上述使用的 groth16 或其他如 plonk 是本文打算忽略掉的部分。

    從上述的例子可以看到,即使我們努力用 circom 實作藏住 secret,但由於計算過程太過簡單,只有 f(x) = x**2+6,輕易就能從 answer 反推出我們的 secret 是 42,因此在應用邏輯的開發上,也必須注意 circom 的設計可能出了問題,導致私密訊息容易外洩,那儘管使用再強的 ZKP 底層邏輯,在應用邏輯上有漏洞,也沒辦法達到隱藏秘密的效果。

    此外,在看 circom 的程式碼時,可以關注最後一個 template 的 private 與 public 值分別是什麼。以本文的 Calculator 為例,private 值有 secret,public 值有 out。

    另外補充:

    如果有個 signal input 但它不是 private input,就會被歸類為 public。

    一個 circuit 至少會有一個 public,因為計算過程一定會有一個結果。

    最後,在開發的過程中我會用 javascript 先實作計算過程,也可以順便產出 input.json,然後再用 circom 語言把計算過程實現,產生 proof 和 public 後,再去對照所有 public 值和 private 值,確認是不是符合電路計算後所要的結果,也就是比較 javascript 算出來的和 circom 算出來的一不一樣,如果不一樣就能確定程式碼是有 bug 的。

    參考範例:https://github.com/chnejohnson/circom-playground

    總結

    本文的程式碼展現 ZKP 可以做到鏈下計算與隱藏秘密的功能,在真實專案中,可想而知電路的計算過程不會這麼單純。

    會出現在真實專案中的計算像是 hash function,複雜一點會加入 Merkle Tree,或是電子簽章 EdDSA,於是就能產生更完整的應用如 Layer 2 擴容方案之一的 ZK Rollup,或是做到匿名交易的 Tornado Cash。

    本文原始碼:https://github.com/chnejohnson/mini-zkp

    下篇文章就來分享 Tornado Cash 是如何利用 ZKP 達成匿名交易的!

    參考資料

    概念介紹

    Cryptography Playground

    zk-SNARKs-Explainer

    神奇的零知識證明!既能保守秘密,又讓別人信你!

    認識零知識證明 — COSCUP 2019 | Youtube

    應用零知識證明 — COSCUP 2020 | Youtube

    ZK Rollup

    動手實做零知識 — circom — Kimi

    ZK-Rollup 开发经验分享 Part I — Fluidex

    ZkRollup Tutorial

    ZK Rollup & Optimistic Rollup — Kimi Wu | Medium

    Circom

    circom/TUTORIAL.md at master · iden3/circom · GitHub

    ZKP Hello World

    其他

    深入瞭解 zk-SNARKs

    瞭解神秘的 ZK-STARKs

    zk-SNARKs和zk-STARKs解釋 | Binance Academy

    [ZKP 讀書會] MACI

    Semaphore

    Zero-knowledge Virtual Machines, the Polaris License, and Vendor Lock-in | by Koh Wei Jie

    Introduction & Evolution of ZK Ecosystem — YouTube

    The Limitations of Privacy — Barry Whitehat — YouTube

    Introduction to Zero Knowledge Proofs — Elena Nadolinski

    ZKP 與智能合約的開發入門 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.

    👏 歡迎轉載分享鼓掌

  • 對照變數例子 在 Taipei Ethereum Meetup Facebook 的精選貼文

    2020-03-24 23:33:18
    有 8 人按讚

    📜 [專欄新文章] 類 Python 的合約語言 Vyper 開發入門:與 Solidity 差異、用 Truffle 部署、ERC20 賣幣合約實做
    ✍️ 田少谷 Shao
    📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium

    有鑒於個人近期關注的 Uniswap 及 Curve 皆用 Vyper 實作,索性瀏覽了官方文件並嘗試一些開發工具,希望此文能減少一些讀者初嘗 Vyper 會遇到的麻煩!

    Vyper and Solidity

    Outline

    一. Vyper 極簡介二. 與 Solidity 語法差異三. 開發、開發環境設置 1. 語法高亮 2. 本地 Vyper compiler 安裝 3. 使用 Truffle 操作 ERC20 - 安裝 Truffle - 發幣 - 寫個簡易賣幣合約四. 已知 Remix 問題 五. 結語

    一. Vyper 極簡介

    Vyper 是除 Solidity 外,以太坊上的另一智能合約 (Smart contract) 語言。其語法和 Python 相近,但畢竟也是寫合約的語言,邏輯差異不大,所以若熟悉 Solidity 應該不難理解用 Vyper 寫出的合約!

    Vyper 主要被設計和 Solidity 的區別是安全性及可讀性,這部分會在下一段落及後方的實作中舉例說明。

    二. 與 Solidity 語法差異

    Vyper 與 Solidity 的差異有許多,在本段只就個人認為感受較深的三點進行說明,其他差異只進行翻譯,有興趣的讀者可以到官方文件詳細了解:https://vyper.readthedocs.io/en/latest/index.html

    1. 沒有 modifier

    Solidity 常見的 onlyOwner() modifier; 由於 gist 沒有 Solidity 的語法高亮,故截圖

    在 Vyper 中單純用 assert 及 assert_modifiable 來進行條件檢查,兩者差別為若要檢查函數執行後的返還值,要用後者,如下圖:

    Vyper 寫法

    2. 沒有 Class inheritance 繼承

    繼承是物件導向程式設計 (OOP) 的核心概念,但各種繼承關係有時候確實很複雜。Vyper 沒有繼承,這無疑大幅地增加了程式可讀性及安全性,以及降低審計程式碼的難度。在此提供一個例子供不熟悉 OOP 複雜之處的讀者有個概念:

    source: https://consensys.github.io/smart-contract-best-practices/recommendations/#multiple-inheritance-caution

    在上例中,contract A 的 fee 值 (因繼承自 contract B 和 C,故有 fee 一值) 是 5、a 值也是 5 (因繼承自 contract Final,故有 a 一值)。原因是 A 先繼承 B 再繼承 C,因此 contract A 中的 setFee() 是使用了 contract C 的 setFee(),而 a 值是由於 C(5),這代表 contract C 的 constructor (舊版本中即 function C(),函式名稱同 contract 名稱) 被傳入的值為 5。

    稍微延伸一下以上概念,將 contract A 改成:contract A is C, B。如此一來,a 值還有 fee 值都會是 3,因為這次 A 先繼承 C 再繼承 B,因此最終吃到的值是 contract B 的。

    以上就是 OOP 繼承的複雜之處的簡單範例說明,應該能稍微感受到爲什麼除去繼承後會大幅提高可讀性及安全性,畢竟即使是熟悉 OOP 的人有時頭腦一混亂也會開始懷疑自己寫的程式碼繼承結構是否正確 …

    3. 沒有 dynamic array 動態陣列

    這應該是目前 Vyper 設計中爭議最大的部分。沒有動態陣列代表在宣告陣列時需要宣告其長度,也就是說 Solidity 中的寫法 uint[], bool[] 等等,這些是不會出現在 Vyper 的。在 Vyper 中只能出現諸如:

    # Vyper 的變數宣告方式為 變數名稱: 存取範圍(變數型態(若為陣列給長度))

    values: uint256[10]participants: public(address[20])

    可以看到上方的 uint256 及 address 兩陣列皆需要宣告長度,不能不宣告而使其動態地配置空間。

    沒有動態陣列固然可以確保執行運算的範圍、次數,但一來動態陣列真的很方便、二來在 Solidity 有此功能而 Vyper 卻沒有的情況下可能會造成麻煩,詳見此一討論串:點我。

    4. 沒有 inline assembly,程式碼中不會有組合語言

    5. 沒有 function overloading,函式不會因傳入的參數數目不同而結果不同

    6. 沒有 operator overloading,運算符號不會有不同於預設的自定義功能

    7. 沒有無限迴圈,可免於 gas limit attack

    8. 十進位定點數 decimal fixed point 而非二進位 (binary) 定點數,詳見:點我

    三. 開發、開發環境設置

    結論先講

    開發 Vyper 的最佳姿勢目前個人認為是在本地裝上 Vyper compiler、用 Truffle 部署,並在撰寫時將檔名後加上 .py 就能有 Python 的語法高亮👌

    1. 語法高亮 (syntax highlighting)

    有語法高亮絕對是舒服地寫程式的第一步。

    Remix 有 Vyper 的語法高亮,但一來個人目前不推薦使用 Remix 來撰寫 Vyper,原因詳見下方 4. 已知 Remix 問題;二來 Remix 的語法高亮其實也沒有很清楚,因此個人推薦:在本地開發,將檔名後加上 .py 就會有 Python 的語法高亮。

    2. 本地 Vyper compiler 安裝

    照官方說明使用 Python 的虛擬環境 virtualenv:

    source: https://vyper.readthedocs.io/en/latest/installing-vyper.html#installing-vyper

    簡單兩點提醒:

    如果中間那行報錯但確實已經有 Python,則可能是版本問題。依照自己電腦上的版本改成相應的即可,ex: python3.6 改成 python3

    進入虛擬環境後(檔案路徑前方應有 vyper-venv 的提示),使用此指令: vyper {檔案名稱}.vy,即可編譯 .vy 檔;使用完畢後輸入 deactivate 即可退出

    3. 使用 Truffle 操作 ERC20

    安裝 Truffle

    Truffle 雖有冗餘的 migration 但也別無他法,畢竟 Remix 目前仍不完善 :(

    下載流程可以照官方文件,使用 vyper-example:

    source: https://github.com/truffle-box/vyper-example-box

    由於我們會接上測試網 Ropsten,因此還要下載 truffle-hdwallet-provider:

    source: https://github.com/trufflesuite/truffle-hdwallet-provider

    接者就可以開始使用 Vyper 寫合約了!

    發幣

    由於 Vyper 的官方文件中已經有許多優質範例,因此本文希望來點不一樣但大家卻又很熟悉的…以 ERC20 為例(這千篇一律的主題xD):

    用 Curve 的 ERC20 程式碼為範本,發一個幣(又要發…)

    寫一個簡易賣幣合約

    選擇這個主題一方面畢竟 ERC20 是以太坊的最大宗應用之一,二來有興趣的讀者可以透過讀 ERC20 的程式碼來熟悉 Vyper,並在看過本文的流程後對於用 Vyper+Truffle 來操作 ERC20 有完整的概念!

    好的,首先複製一份 Curve 的 ERC20 程式碼(看到就順手拿來用),並複製到 Truffle 所在路徑的 contracts 資料夾中:https://github.com/curvefi/curve-contract/blob/pool_compound/vyper/ERC20.vy

    由於第一點希望著重在跑一次流程,因此不改動合約的程式碼。

    ERC20.vy 複製到 contracts 資料夾中後,到 migrations 資料夾開啟 2_deploy_contracts.js,首先將 require() 中的參數改為 ERC20.vy 的檔名 ERC20,再來依照自己喜好決定幣的名稱、代號、小數點位數及發行總量,輸入於 deployer.deploy() 中。

    接著,為了和測試網 Ropsten 互動,需要將以下程式碼寫入 truffle-config.js。

    第二行的 privateKeys 是帳號的私鑰。以下實作需要兩個帳號來操作,因此請從錢包匯入兩組私鑰(並非助憶詞)。

    在第 13 行中 HDWalletProvider 此函式的第三個參數代表要用第幾個帳號最為預設帳號(部署合約等),第四個函數代表總共匯入幾組帳號。而第二個參數則是需要至 Infura 申請一個 project 來得到串接 Ropsten 的連結。這兩步驟並非本文重點,因此不詳細解說步驟,Google 搜尋關鍵字應該就會找到方法!

    接著,就可以輸入以下指令來將代幣發佈到 Ropsten:

    truffle deploy --network ropsten

    有進入虛擬環境才可以編譯 .vy 檔,若忘記就會收到如下的錯誤訊息:

    記得打開虛擬環境才能編譯 .vy 檔

    成功後就可以在 contract address 中看到代幣發佈的位置,加入到 Metamask 中就可以看到。本文的例子是維尼代幣 Winnie the Coin, WTC ;)

    contract address 便是 ERC20 的所在

    Winnie the Coin, WTC

    好了,到此測試網上又多了一個測試用的垃圾廢幣。

    寫個簡易賣幣合約

    賣幣合約中我想要簡單有兩個功能就好:付錢買幣 、結束銷售,以下就是程式碼。買幣的部分就不寫太詳細,固定價格為 0.01 Ether 可以買 500 代幣。

    簡單說明幾點:

    Solidity 的 constructor() 在 Vyper 中為 Python 風的 __init__():

    函式的屬性(public, private, payable 等等)放在函式上方,與 Python 的修飾器位置相同

    總之寫法跟 Python 很像,次方也一樣是用兩次乘法代表:**

    變數前加上 self 代表是當前合約的變數/全域變數,因此非常容易與函式中的變數/區域變數做區隔

    由於已經在第一行匯入了 ERC20 那份合約,因此透過將地址傳入合約當參數,就可以呼叫在該地址的合約:ERC20(self.tokenAddress) 。並且,可以將部署的合約存成一個變數 erc20 較方便

    寫完合約後一樣要更改 migrations 資料夾中的 2_deploy_contracts.js 如下,將代幣所在的地址作為參數輸入。

    由於先前已經部署過一次了,因此要重置才能再部署第二次,輸入以下指令:

    truffle deploy --reset --network ropsten

    部署成功之後就要來試著買幣啦!輸入以下來進入 console:

    truffle console --network ropsten

    成功進入後應該會看到 truffle(ropsten)> 的字樣。接著,首先取得部署的兩合約,並查看是否有返回合約資訊:

    # ERC20 及 SellToken 是先前在 2_deploy_contracts.js 中的變數名稱,代表被部署的合約

    let instance1 = await ERC20.deployed()instance1 # 印出 instance1 的資訊

    let instance2 = await SellToken.deployed()instance2 # 印出 instance2 的資訊

    再來,為了讓 SellToken 可以賣幣,要先用 ERC20 的合約匯幣到 SellToken 的合約。因此,輸入以下指令:

    instance1.transfer(instance2.address, 10000)

    # 這裡數字只要設為 > 500 就可以

    接著,我們要利用第二個帳號去買幣(第一個帳號為預設帳號,因此就是代幣擁有者)。將帳號的資訊存入變數 accounts 中,再指定送出交易的帳號是第二個帳號。由於我個人匯入私鑰的順序是將第一個帳號存在 truffle-config.js 的 privateKeys[0]、第二個帳號存在 privateKeys[1],因此第二個帳號的地址就會在 accounts[1] 的位置:

    let accounts = await web3.eth.getAccounts()

    instance2.buyToken({from: accounts[1], value: 10000000000000000})

    # value 為 10^16 是因為在 SellToken 的 buyToken 函式中買一次要 0.01 Ether, 即為 10^16 wei

    然後應該就會在自己的第二個帳號中看到匯入的幣了~

    最後,由於合約中結束銷售就是一個自殺 selfdestruct 函式,因此可以呼叫看看,第一個帳戶錢包中的錢應該會增加,因為第二個帳戶有付款買幣;並且,可以到 Ropsten 上瀏覽,應該能看到相關提示:

    中間 contract 的右上角有 Self Destruct 的樣式

    四. 已知 Remix 問題

    Remix 目前有兩個版本,只有新版有 Vyper 的編譯器。在此整理目前遇到的問題,如果有人也遇到可以對照一下本處,可以省去很多自我懷疑xD

    不會報錯

    Remix 的編譯結果有時會是錯的、和本地端編譯出來的結果不同

    舉上方的 SellToken 合約為例,將其複製到 Remix 中使用左邊的 Remote Compiler 有錯,但又不報錯 q_q (ERC20 的合約有在同檔案目錄)

    左方有紅色三角形,代表編譯失敗,但沒有報錯訊息可以看…

    getter function 竟然要花錢

    用 Solidity 寫的合約,查詢 public 變數的值應該是不用消耗 gas 的,但不知何故查詢 Vyper 寫的合約的 public 變數卻要消耗 gas,如下圖…

    可以看到中下方有 22026 gas 的消耗

    Local compiler 無法使用

    圖中的 Local Compiler 此選項,個人雖照官方文件執行 vyper-serve 但卻失敗,因此若有讀者成功希望能留個言不吝分享!

    五. 結語

    Vyper 作為一個比 Solidity 更新的合約語言,在寫程式碼的方面沒什麼問題,但相關的開發工具、學習資源等都遠不及 Solidity。

    Vyper 主打的兩個特色:可讀性的部分相信看完上面的讀者應該已經有些感覺;安全性…小白如作者我倒是沒有感受到顯著的不同。況且 Solidity 已經發展許久,很多錯誤的寫法、知名的安全漏洞大家應該也很熟悉了,還有 Openzeppelin 提供安全合約寫法的範本,因此有待以後高人解說安全性是否真的是 Vyper 較好。

    有興趣者可以查看 Vyper 的安全報告:點我,大意是目前 Vyper 的編譯器仍有許多問題待改進! (感謝 Chih-Cheng Liang 的提供)

    本文對 Vyper 的介紹及其與 Solidity 的差異只講了個大概,欲知更詳細的介紹還是要麻煩讀者前往官方文件了:https://vyper.readthedocs.io/en/latest/index.html

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

    田少谷 Shao - Medium

    類 Python 的合約語言 Vyper 開發入門:與 Solidity 差異、用 Truffle 部署、ERC20 賣幣合約實做 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.

    👏 歡迎轉載分享鼓掌

你可能也想看看

搜尋相關網站