陈寅恪《王觀堂先生挽詞 并序》
——導言:1927年6月2日,清華國學院導師王國維先生以自沉昆明湖的方式結束了自己的生命。好友陳寅恪寫下《王觀堂先生挽詞並序》,稱得上韻體文字的大著述,寫法很像王國維《頤和園詞》。《挽詞》長一百一十二句,可謂觀堂(王國維)其人學問與政治命運的哀歌。其主旨在於書寫王國維的學問歷程與高才隆遇,多述掌故,既深惋王國維之死,也藉此自抒懷抱,以清詞麗句編織結構而成絕唱。
此詩陳氏應初撰於1927年王國維自沉後兩三月間,後復撰一序及一挽聯,暢發其旨。挽詞、序言與輓挽聯乃是一個整體。陳氏曾將此詩奉贈羅振玉等師友指教,也下發清華國學研究院學生研讀,並通過《國學月刊》《學衡》等雜誌發表。
當代著名學者劉夢溪先生在《王國維、陳寅恪與吳宓》一文中認為,陳所撰《挽詞》的長序,闡述了作者的文化觀點及王之死因,不僅對王之選擇赴死給以文化意義上的正解,同時也是解開二十世紀中國文化與社會變遷謎團的一把鑰匙。「中國文化」這個概念,實際上是晚清和近代知識分子自我反省其檢討傳統的用語,對中國文化本身而言,是「他」者的概括。所以上一個百年,這個概念雖被過旋轉不停地給以討論和解說,而終無結果。以至於晚年的錢鍾書先生,與來訪的學人開玩笑,說誰再是講東西方文化,我「槍斃」他(說的時候他拿起一支筆)。
陳《輓詞》序的過人之處,是指出以綱紀之說為表徵的中國主流文化的意義,具有「抽象理想的之通性」,也就是柏拉圖的所謂理念。實際生活中是否能夠完全做到是另一回事,但它是傳統士子倫理上的人生規範。晚清以降的劇烈變動,既是社會結構的變遷,又是文化思想的變遷。簡而言之,傳統文化的核心從此崩塌了。因此為傳統文化所化之人的失落與痛苦,可想而知。王國維就是這樣的人。但失落與痛苦可以有不同的走向。由痛苦而新生,為更多的知識人士所選擇。既是未趨步新潮,也不必即死。但陳寅恪先生認為,像王國維是以文化託命之人,「此文化精神所凝聚之人,安得不與之共命而同盡」。因此,王國維之死,不是殉清,而是殉為其所化的那種文化、那種文化理想、那種文化精神。
「吾儕所學關天意」,王國維先生曾說:「國家與學術為存亡,天而未厭中國也,必不亡其學術。天不欲亡中國之學術,則於學術所寄之人,必因而篤之。」九十年後再讀斯文,我輩學人,當知王國維先生之死對於文化中國的深刻影響,陳寅恪先生和血痛書的所切所籲。——2017/06/03 來源:鳳凰網)
原文網址:https://read01.com/Ej5G54.html)
王觀堂先生挽詞序
——陳寅恪
或問觀堂先生所以死之故。應之曰:近人有東西文化之說,其區域分劃之當否,固不必論,即所謂異同優劣,亦姑不具言;然而可得一假定之義焉。其義曰:凡一種文化值衰落之時,爲此文化所化之人,必感苦痛,其表現此文化之程量愈宏,則其所受之苦痛亦愈甚;迨既達極深之度,殆非出於自殺無以求一己之心安而義盡也。吾中國文化之定義,具于白虎通三綱六紀之說,其意義爲抽象理想最高之境,猶希臘柏拉圖所謂Idea者。若以君臣之綱言之,君爲李煜亦期之以劉秀;以朋友之紀言之,友爲酈寄亦待之以鮑叔。其所殉之道,與所成之仁,均爲抽象理想之通性,而非具體之一人一事。夫綱紀本理想抽象之物,然不能不有所依託,以爲具體表現之用;其所依託以表現者,實爲有形之社會制度,而經濟制度尤其最要者。故所依託者不變易,則依託者亦得因以保存。吾國古來亦嘗有悖三綱違六紀無父無君之說,如釋迦牟尼外來之教者矣,然佛教流傳播衍盛昌於中土,而中土歷世遺留綱紀之說,曾不因之以動搖者,其說所依託之社會經濟制度未嘗根本變遷,故猶能藉之以爲寄命之地也。近數十年來,自道光之季,迄乎今日,社會經濟之制度,以外族之侵迫,致劇疾之變遷;綱紀之說,無所憑依,不待外來學說之掊擊,而已銷沈淪喪於不知覺之間;雖有人焉,強聒而力持,亦終歸於不可救療之局。蓋今日之赤縣神州值數千年未有之鉅劫奇變;劫盡變窮,則此文化精神所凝聚之人,安得不與之共命而同盡,此觀堂先生所以不得不死,遂爲天下後世所極哀而深惜者也。至於流俗恩怨榮辱委瑣齷齪之說,皆不足置辯,故亦不之及云。
漢家之厄今十世,不見中興傷老至。
一死從容殉大倫,千秋悵望悲遺志。
曾賦連昌舊苑時,興亡哀感動人思。
豈知長慶才人語,竟作靈均息壤詞。
依稀廿載憶光宣,猶是開元全盛年。
海宇承平娛旦暮,京華冠蓋萃英賢。
當日英賢誰北斗,南皮太保方迂叟。
忠順勤勞矢素衷,中西體用資循誘。
總持學部攬名流,樸學高文一例收。
圖籍藝風充館長,名詞瘉埜領編修。
校讎鞮譯憑誰助,海寧大隱潛郎署。
入洛才華正妙年,渡江流輩推清譽。
閉門人海恣冥搜,董白關王供討求。
剖別派流失品藻,宋元戲曲有陽秋。
沈酣朝野仍如故,巢燕何曾危幕懼。
君憲徒聞俟九年,廟謨已是爭孤註。
羽書一夕警江城,倉卒元戎自出征。
初意潢池嬉小盜,遽驚烽燧照神京。
養兵成賊嗟翻覆,孝定臨朝空痛哭。
再起妖腰亂領臣,遂傾寡婦孤兒族。
大都城闕滿悲笳,詞客哀時未返家。
自分琴書終寂寞,豈期舟楫伴生涯。
回望觚棱涕泗漣,波濤重泛海東船。
生逢堯舜成何世,去作夷齊各自天。
江東博古矜先覺,避地相從勤講學。
島國風光換歲時,鄉關愁思增綿邈。
大雲書庫富收藏,古器奇文日品量。
考釋殷書開盛業,鉤探商史發幽光。
當世通人數舊遊,外窮瀛渤內神州。
伯沙博士同揚搉,海日尚書互倡酬。
東國儒英誰地主,藤田狩野內藤虎。
豈便遼東老幼安,還如舜水依江戶。
高名終得徹宸聰,徵奉南齋禮數崇。
屢檢秘文升紫殿,曾聆法曲侍瑤宮。
文學承恩值近樞,鄉賢敬業事同符。
君期雲漢中興主,臣本煙波一釣徒。
是歲中元周甲子,神皋喪亂終無已。
堯城雖局小朝廷,漢室猶存舊文軌。
忽聞擐甲請房陵,奔問皇輿泣未能。
優待珠槃原有誓,宿陳芻狗遽無憑。
神武門前御河水,好報深恩酬國士。
南齋侍從欲自沈,北門學士邀同死。
魯連黃鷂績溪胡,獨為神州惜大儒。
學院遂聞傳絕業,園林差喜適幽居。
清華學院多英傑,其間新會稱耆哲。
舊是龍髯六品臣,後躋馬廠元勳列。
鯫生瓠落百無成,敢並時賢較重輕。
元祐黨家慚陸子,西京羣盜愴王先。
許我忘年為氣類,北海今知有劉備。
曾訪梅真拜地仙,更期韓偓符天意。
回思寒夜話明昌,相對南冠泣數行。
猶有宣南溫夢寐,不堪灞上共興亡。
齊州禍亂何時歇,今日吾儕皆茍活。
但就賢愚判死生,未應修短論優劣。
風義平生師友間,招魂哀憤滿人寰。
他年清史求忠蹟,一弔前朝萬壽山。
王觀堂先生挽聯
十七年家國久魂銷,猶餘賸水(昆明湖)殘山(萬壽山),留與纍臣供一死;五千卷牙籖新手觸,待檢玄文奇字,謬承遺命倍傷神。
觀堂先生靈鑒 後學陳寅恪拜挽
說明/1927年6月2日,王國維自沉於頤和園魚藻軒。其遺書云:「五十之年,只欠一死,當此事變,義無再辱。」清祚告終於宣統三年(西元1911年),距離王國維之死17年,「十七年家國久魂銷」即指此。「牙籖」指書籖,「謬承遺命」指遺書中委託陳整理書籍之事。此聯一出,時人紛紛贊之,被譽為挽聯中最佳之作,無論在思想和藝術上都有深刻價值的作品。
「定義域值域寫法」的推薦目錄:
定義域值域寫法 在 Facebook 的最佳解答
創新工場和BCG諮詢合作的「+AI改造者」系列:看看馬上贏如何在巨頭競爭下,用大數據驅動業務,實現傳統零售商和品牌商的雙贏。
改造者系列:科技巨頭下的AI企業制勝之道?-- 本文来自BCG微信公眾號,經授權轉載。
近期,創新工場聯合BCG波士頓咨詢旗下亨德森智庫,推出「AI融合產業:『改造者』如何促進AI普惠」系列研究。人工智慧在中國大陸有著明確的落地應用場景,大量的AI企業活躍於這些垂直場景中,我們定義這些企業為「改造者」。「改造者」通過傳授其AI技術和垂直行業理解,極大地打破了傳統企業應用AI的瓶頸。
作為擅於趨勢前瞻的TechVC,創新工場長期看好AI領域,深入佈局,至今已經投出了7只AI獨角獸。在系列研究中,我們采訪了數家創新系AI企業,通過這些「改造者」的視角,探究傳統企業擁抱AI的範式與路徑。
馬上贏是創新工場投資的大陸領先的快消行業大數據公司,其定位是中國快消品行業的風向標,零售監測的新標準,成為中國的「尼爾森」。通過信息化賦能小規模零售商,馬上贏打通一個個數據孤島,以大數據的方式挖掘零售數據的商業價值,為品牌商提供產品動銷數據與競品監控服務。
為了讓數據更好地服務於新品研發和上市,馬上贏引入了PDCA(Plan, Do, Check, Act)循環,通過數據說話指導快消品快速迭代,提升零售商銷售收入。
具體來說,品牌商可以在零售商的渠道內測試包括售價、外觀、營銷、陳列等要素,通過數據回饋指導新版本,實現往復循環。
在采訪中,馬上贏創始人猴哥(王傑祺)表示,垂直領域內的AI創新需要符合企業自身的需求,要在巨頭的基礎設施之上,基於更好的訓練集和更專業的垂直行業知識,不斷突破行業壁壘,優化垂直領域的AI創新。
■系列導讀
本系列由BCG亨德森智庫與創新工場董事長兼首席執行官李開復博士帶領的創新工場團隊共同推出,圍繞「AI融合產業:『改造者』1如何促進AI普惠」的課題,我們致力於探究傳統企業在應用AI過程中的關鍵要素與合作夥伴,以及傳統企業擁抱AI的範式與路徑。
在零售領域,馬上贏致力於定義中國快消品零售監測行業的新標準,成為「中國的尼爾森」,通過免費為連鎖零售商提供市場情報和「零售數字化鐵三角」2,與零售商進行數據合作,將海量的線下快消品零售數據轉換成精准的市場洞察情報。
1 「改造者」 通過傳授其AI技術和垂直行業理解,極大地打破了傳統企業應用AI的瓶頸,充當產業中傳統企業應用AI的橋樑。「改造者」包括AI企業與成功轉型AI的傳統企業。
2 「零售數位化鐵三角」指通過PDCA循環迭代的方法提升零售商銷售收入。P=Plan:52周企劃;D=Do:會員營銷;C=Check:BI看板;A=Act:改進。
■本期受訪嘉賓:猴哥(王傑祺)
馬上贏正在建設覆蓋線下門店最多的零售監測網絡,為連鎖企業免費提供BI看板、52周企劃3、會員營銷和市場情報,推進連鎖企業數字化轉型。
猴哥(王傑祺)是馬上贏的創始人兼首席執行官,清華大學學士,美國華盛頓大學碩士。他是原阿里巴巴集團資深產品專家,曾于美國UPS供應鏈部門擔任高級工業工程師。在創立馬上贏之前,他曾創業推出購物助手(如意淘),後被阿里收購。
3「52周企劃」指依托馬上贏的大數據AI技術説明零售商實現精細化管理。零售商可以瞭解一年中每周適合銷售什麼類目的產品,與陰曆節日、陽曆節日、節氣、特殊事件(如比賽活動)關聯,提升門店的銷售計劃能力。
■對談實錄
Q1 馬上贏為什麼選擇切入零售賽道?如何定義「中國的尼爾森」?
猴哥:馬上贏致力於定義快消品零售監測的新標準,做「中國的尼爾森」,為零售商和品牌商提供服務。面向零售商,馬上贏免費提供ABC服務,即AI、big data(大數據)、Cloud(雲服務),以換取訂單數據;面向品牌商,馬上贏基於零售商的脫敏數據提供大陸市場情報,賺取收入。
馬上贏發現,大陸的市場過於分散,零售的毛利又低,大量規模小的零售商缺乏足夠的IT費用以支援其獨立完成信息化應用,但他們對信息化的需求又是真實存在的。另一方面,品牌商有意願和能力為市場情報、動銷數據支付費用。馬上贏看到了零售商和品牌商的痛點以及購買力的巨大差異,嘗試通過為零售商和品牌商提供所需服務來提升整個行業的效率。
馬上贏一方面向零售商免費提供差異化的信息技術服務,按零售商的需求提供BI看板和市場情報支援,另一方面向品牌商提供產品動銷數據與競品監控服務。此外,馬上贏還在著重提升AI演算法和大數據中台數據處理能力,以便支援更多零售商和品牌商的數據服務需求。同時,這些技術優勢和服務支撐能力説明馬上贏建成大陸覆蓋範圍最大的即時零售數據監測網絡。對於馬上贏和客戶而言,這是雙贏。
在數據治理中,馬上贏需要做的是建立相對統一的內容體系,實現統一的度量衡。比如同一個條碼的商品在不同門店的名稱寫法不同,傳統方法是通過人工進行校驗和修正之後才能統一名稱入庫。馬上贏通過自己搭建的超1,600萬條碼的商品庫,使用AI演算法對零售數據做分類、清洗,並基於完善的商品知識圖譜體系標記商品屬性,再由BI看板提供數據洞察服務。馬上贏的這套全流程自動化體系,極大地提升了數據處理和情報產出的速度和效率。
Q2 相比數據咨詢商、科技巨頭等其他類別的競爭對手,馬上贏的差異化優勢是什麼?如果品牌方想自己做零售大數據,馬上贏怎麼應對?
猴哥:以往零售商想實現信息化必須高價購買專門技術公司的服務,只有少數資金充足的大零售商可以負擔得起,零售行業中數量眾多的中小型零售商往往望洋興嘆。而品牌方一般很難獲取到這些生意占比很大的中小型零售商數據,因而會尋求數據咨詢商的數據服務。但出於成本和利潤的考慮,數據咨詢商往往只服務最頭部的品牌商,在大陸可能只有幾百個品牌商能消費得起數據咨詢商的服務。相比之下,馬上贏合作的品牌商更加廣泛,從新銳品牌、區域性品牌到成熟品牌、頭部品牌,馬上贏都可以提供符合客戶需要的數據服務。
數據咨詢商從少數零售商那裏提取商品月度銷售匯總數據,再將數據整合為大盤情報,賣給少數頭部品牌商。但馬上贏從「激活生態」的角度出發,説明零售商提升數據運營能力,獲得大量一手銷售訂單數據,可以為品牌商提供更詳細的數據洞察服務。此外,馬上贏由AI賦能數據清洗和BI交付,從而可以提供即時的、更細顆粒度的看板,可以提供細到省級、地級市級、業態級、SKU級顆粒度的數據。
相比電商巨頭,馬上贏選擇線下快消品零售行業,覆蓋更多的線下零售商,涉及更豐富的業態,有大賣場、大超市、小超市、便利店、食雜店等等。在商品品類的選擇上,馬上贏暫不拓展美妝、服裝等電商渠道占比超過50%的品類,而選擇線上化率相對更低的品類,如食品、飲料、日用品。這些品類消費時效性高、頻次高、單價低,線上購物場景並不適合線下。
至於品牌方自己做零售大數據,馬上贏早前就思考過這個問題。我們和大品牌都聊過,如果建立品牌方自己的銷售追蹤網絡是否可行,得出的結論是不可行。一是單一品牌方來做大數據,做完了只能自己受用,成本攤下來很不合算,還不如投資AI企業,實現專業化分工;其次,品牌方還有一些技術壁壘解決不了,攻克下來只會對成本端造成更大的壓力,得不償失。
Q3 馬上贏在賦能零售商和品牌商的過程中遇到的最大挑戰是什麼?
猴哥:最大的挑戰來自於行業裏不透明的競爭——現在做AI的企業太多了,很多企業會虛報準確率,噪音特別大。
AI在每個垂直行業的落地需要很多行業知識,其次才是疊加AI演算法。但很多傳統企業對AI的期待特別高,導致市場上各種聲音魚龍混雜,每個企業都在講述「AI萬能」的故事。馬上贏不會激進地過度承諾,但這種冷靜和狂熱之間的衝突會帶來很多麻煩——當別的AI企業過度承諾其自動補貨的準確率高達95%的時候,馬上贏如果表示我們的準確率位於70%—85%的區間,傳統企業就會輕視我們的實力。現在,垂直行業裏缺乏行業組織或者專業機構來做客觀、公允的第三方普查。比如在圖像識別、自然語義處理領域,都有比較公認的訓練賽,大家用演算法的跑分說話,相對而言就比較客觀。落到垂直領域裡,每個企業自己報數據,很多時候就會有水分。
馬上贏曾經考慮把收集的數據脫敏之後貢獻出來,讓大家有一個公平的舞臺競技,但是很難運行起來。僅僅共享數據不足以激勵演算法團隊,需要行業組織定期舉辦競賽、活動等,或者像Netflix舉辦推薦演算法比賽,通過資本來激勵大家參與,僅僅靠社區運轉不起來。
Q4 你認為未來AI企業的發展趨勢是什麼?
猴哥:有能力的巨頭要持續加強行業的基礎設施,讓開發AI的人能有更好的工具,讓雇不起博士生的企業也能應用AI,實現技術普惠。同時,垂直領域內的AI創新需要符合企業自身的需求,AI企業要在巨頭的基礎設施之上,基於更好的訓練集和更專業的垂直行業知識,不斷突破行業壁壘,優化垂直領域的AI創新。我相信這是我們的生存之道——「科技巨頭靠算力,我們靠設計」。
同時,大陸的零售行業在洗牌,有很多更具備數據化思維的新品牌在躍躍欲試。以前是渠道經濟,在社區裏搶到點位就能有流量,未來是有技術、數據和管理能力的品牌才能從老品牌手中搶到點位。此外,隨著許多快消品牌逐步上市,出現資本外溢,更多的人會開始創業,疊加當前快消巨頭的二代交棒窗口,零售領域將有新一波浪潮湧動。我相信,未來的零售行業會更加擁抱數據,擁抱AI。
■要點回顧
1. 不只是技術層AI要有標準,應用層AI也需要標準。垂直領域應用AI需要由行業組織或龍頭企業牽頭制定公認的行業標準,從而促進AI企業公平有序發展,這也將反哺傳統企業,促使傳統企業的AI應用提質增效。
2. 「科技巨頭靠算力,AI企業靠設計」,結合巨頭提供的行業通用基礎設施和「改造者」特有的垂直領域數據集和算法,各取其長,方能最大化傳統企業應用AI的效率。
定義域值域寫法 在 Taipei Ethereum Meetup Facebook 的最佳貼文
📜 [專欄新文章] 類 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.
👏 歡迎轉載分享鼓掌
定義域值域寫法 在 要怎麼從集合論的公理構造卡氏積是很無聊的事情,有興趣可以 的推薦與評價
方法是有的,只要我們稍微修改一下定義域跟值域就好。比如說: A={有而且只有一個伴侶的人}, B={所有的人} ... 或者比較簡單的寫法就是把(a,f(a))這些點給收集起來。 ... <看更多>
定義域值域寫法 在 Re: [微積] 值域- 看板Math - 批踢踢實業坊 的推薦與評價
※ 引述《finaltry (finaltry)》之銘言:
:
: (i) y=0 <=> x=3
:
:
: (ii)y不等於0時(此時x不等於3),方程式為二次式
:
通常講定義域是誰,對應域是誰,好比f:[0,Pi]->R, f(x)=sinx
沒有人會寫說 0<=x<=Pi <=> 0<=y<=1
(因為你ii的最後就是想要證明這種東西,然後藉此說明:「噢,[0,1]就是他的值域!」
所以我才這樣跟你講)
這真的很怪。第一就符號邏輯學上來說,這樣寫很怪並且有誤。
第二就書寫上來說,因為你寫得不是很標準,會讓別人看不懂。
不過更重要的是,你這樣寫就是有錯。
舉剛才那個f為例。你想要證明它的值域是[0,1],你想要證
0<=x<=Pi <=> 0<=y<=1
先幫你修正成比較標準的寫法, 是 Forall x, 0<=x<=Pi <=> 0<=f(x)<=1
(再提醒你一次,你整個ii就是要證明這件事對吧?)
這樣也還是有問題。問題在哪?你只能說明所有的x, 只要 0<=x<=Pi, 帶入f
應變數都會介於 0,1之間。
那搞不好他們全都送到同一個值啊。看不懂我的意思嗎?
比方說令 g:[0,Pi]->R, g(x)=0.5, 注意g是常數函數
「Forall x, 0<=x<=Pi → 0<=g(x)<=1」 是對的
「Forall x, 0<=x<=Pi ← 0<=g(x)<=1」 也是對的(看不懂多想幾分鐘)
所以「Forall x, 0<=x<=Pi <=> 0<=g(x)<=1」也是對的
今天為什麼我說你錯,因為你想要證明的就是
:
: x屬於R且x不等於2且x不等於-1 (定義域)
:
: <=>y大於等於1 或y小於等於1/9 (值域) #
不是嗎?你處心積慮就是想要得到這個!
但很可惜,你得到的這個,proves nothing.
再一次幫你幫你改得正規一點,那句話也就是
Forall x, x in R\{2,-1} <=> f(x)>=1 or f(x)<=1/9
假如真的被你給證出來,上面那條是對的,我問你,你要怎麼告訴讀者
f的值域真的就是 >=1 或 <=1/9?
難道「Forall x, 0<=x<=Pi <=> 0<=g(x)<=1」,g的值域就是[0,1]?
結論:
1. 用你那種=> <=的寫法來證非常怪. 並且就像我上面點出來的,
就算你最後費了九牛二虎之力,證出了
Forall x, x in R\{2,-1} <=> f(x)>=1 or f(x)<=1/9
你也不能據此就說f的值域是 >=1 聯集 <= 1/9
2. 如果你不是很懂正規的邏輯的寫法,就別硬逼自己玩一堆=> <= <=>
我們當然知道你知道那個的來弄去脈,可是要怎麼「寫」出來,
並且邏輯正確的寫出來,顯得更重要。
今天如果你不用這些 =>, <=> 就算了,你用了,
就要按照數學界的規範走。
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.44.248.79
※ 文章網址: https://www.ptt.cc/bbs/Math/M.1408808940.A.FD5.html
※ 編輯: alfadick (114.44.248.79), 08/23/2014 23:56:54
譬如你是要送到實數呢?還是送到有理數呢?還是送到複數呢?
還是說要送到向量呢?(vector-valued function)
因為要確定一個函數的range是非常麻煩的事情,有些你根本無法人工得知range,
所以就不寫range, 寫codomain對應域就好,稍加描述一下那是怎麼樣一個函數。
沒有這種解釋法,數學就是數學,邏輯就是邏輯,
就好像寫程式一樣,有標準規範。
※ 編輯: alfadick (114.44.248.79), 08/24/2014 00:30:57
他的寫法極其之怪,我當初也是看得很痛苦....
所以我按照他的證明脈絡打的這篇文章, 完全不適合單純想要知道怎麼解這題的看 XD
你應該是在回yyc2008大XD。
---
by the way,
我覺得引進量詞來證明, 表達力就很強了
finaltry 大的解法, 該用forall時沒有用forall,
該用there exists也沒用there exists, 該用集合來書寫也沒用集合
一切只用-> <-來寫, 寫起來變得頗亂.
不只難以閱讀, 並且還出現邏輯的錯誤. (我這篇點出來的那個)
※ 編輯: alfadick (114.44.248.79), 08/25/2014 06:40:09
... <看更多>