#中央社外文新聞中心FocusTaiwan徵才 Focus Taiwan
中央社外文新聞中心誠徵全職【英文編輯】和【英文改稿顧問】,歡迎對英文新聞有熱情的你,加入FocusTaiwan團隊!
履歷請寄:cnafnc2@gmail.com
薪資:4萬以上,面議
福利:比照勞基法規定
上班時段:日班/晚班/假日班,需輪班
上班地點:台北市中山區松江路209號7樓
其他:通過第一階段履歷篩選者,我們會以email通知筆試時間。
【徵才職位】
🔵英文編輯Writer
語言能力:精通中、英文,英文聽說讀寫能力近母語。
學歷要求:大學以上畢業,新聞系、外文科系尤佳。
工作經驗:具有英文新聞工作至少1年經驗者優先考慮。
工作內容:英文編輯需將中文新聞編譯成英文新聞,並撰寫圖說、替英文影音新聞過音、製作圖表,並協助管理FocusTaiwan網站後台及社群媒體平台。
工作要求:英文編輯須具備求證與求知的精神,除了編譯中文稿之外,也願意花心思查證新聞訊息,包括做電話採訪,或是上官方網站查詢數據或資料,以充實稿子內容。通訊社的發稿步調快速,英文編輯必須在短時間內掌握新聞重點,以外國讀者感興趣的角度撰寫文章。
🔵英文改稿顧問Copy Editor
語言能力:精通中、英文。以英語為母語的(外籍)人士,通曉中文,居住台灣者優先考慮。
學歷要求:大學以上畢業,新聞科系尤佳。
工作經驗:具有英文新聞工作至少3年經驗者優先考慮。
工作內容:英文改稿顧問主要負責編審英文編輯的稿件,包括檢查文法、拼字、標點符號和文章結構等。改稿顧問也需編審每日新聞頭條、圖說新聞和影音稿。
工作要求:英文改稿顧問需熟悉中央社英文新聞寫作體例和頭條寫作規則,確保文章使用正確的文法、拼字和標點符號,結構完整、內容詳實和平衡。
A. Writer Position:
Requirements:
-- Native or near native English and Chinese proficiency
-- A bachelor’s degree or higher in journalism, foreign languages or a related field
-- Experience writing English news stories
-- Willing to work night shifts and on weekends
-- Able to work in a fast-paced newsroom and meet tight deadlines.
The job:
The writer will be assigned Chinese news stories by the shift leaders and are required to rewrite the stories in English.
He/she will also be asked to write captions, do voiceovers for videos, create graphics, and manage the FocusTaiwan website’s backend and social media accounts.
The writer will specifically be expected to:
-- Ensure that all news stories have proper structure, content, clarity, accuracy and balance
-- Research and fact-check the information in the Chinese news stories by sometimes making calls, conducting interviews, or sifting through official information on government websites
B.Copy Editor Position:
Requirements:
-- A bachelor’s degree or higher in journalism or a related field
-- A background in English news writing and editing, preferably with some experience editing the work of non-native English writers.
-- Native English speaker; Chinese language proficiency a plus
-- Able to function efficiently under time and deadline pressure
-- Willing to work late night shifts and on some weekends
-- Flexible with regard to work hours and days off
-- Able to work as a team with shift leaders and other copy editors to ensure quality content
The job:
The editor will be required to edit news stories in the English language department, checking the grammar, punctuation, and structure and making other changes where necessary.
He/she will also be asked to write and edit headlines for the news stories, edit captions, and occasionally check video scripts.
The copy editor will specifically be expected to:
-- Become familiar with the style rules of CNA, as well as with the rules and restrictions associated with headline writing.
-- Ensure that all news stories have proper grammar, punctuation, structure, content, clarity, accuracy and balance.
-- Answer questions by writers and shift leaders about style, grammar and other aspects of English news writing.
#國際影音串流平台徵才 6/28更新
文化部補助、中央社承辦的國際影音串流平台誠徵以下職位專業人才,有志者請依以下徵才內容需求附上所需資料與我們聯繫。
請注意:來函應徵時,請在電郵主旨欄註明應徵類別,例如「應徵D1 社群媒體內容製作人」、「應徵E3 網路平台技術主管」或「應徵E5 數據工程師」
履歷請寄: personnel-video@mail.cna.com.tw
薪資:4萬以上,面議
福利:均比照勞基法規定
【公司介紹】
Taiwan Plus (Taiwan+) 國際影音串流平台,是台灣第一個以全球為目標族群的全英語新聞、節目平台。
本平台希望在全球舞台上呈現台灣觀點與聲音,同時在國際社會中提升台灣的能見度與影響力。我們將提供與台灣相關,以及超越一般視野的新聞與節目。無論是與台灣相關議題或是區域情勢,以及台灣高舉的普世價值:民主、人權、開放、創新等等,我們都期待在該領域的全球對話中成為最具影響力媒體。
我們以全球為範圍尋覓專業人才,希望打造一支世界級水準的團隊。如果您是專長領域的頂尖人才,同時堅信台灣所代表的多重價值,希望促成改變,您將是Taiwan Plus需要的夥伴。
【徵才職位】
🔵 B1 節目製作人
工作內容:
網路影音節目企劃規劃統籌,能產製外國受眾感興趣的網路影音內容。
1. 節目預算規劃與成本管控。
2. 節目主題發想與設定、外部資源整合洽談。
3. 影音節目行銷及文字撰寫。
4. 透過數據分析及判讀,並與社群數據相關部門緊密合作
學歷要求:大學以上畢業,不限科系,大眾傳播相關科系尤佳。
工作經驗:具網路影音相關節目製作5年以上工作經驗,熟悉新媒體作業。
工作技能:Office文書軟體,了解後製剪接、轉檔、字幕、ES、音效、配樂、調色等工作流程。
語言能力:精通中、英文。
其他條件:1、對台灣題材具熱情,可協調完成節目前製、後製工作。
2、請提供先前製作之節目連結。
🔵 B2 編導人員
工作內容:
1、網路節目發想/拍攝/製作。
2、協助主視覺及鏡面效果包裝設計。
3、短片內容拍攝。
4、其他主管交辦事項。
學歷要求:大學以上畢業,大眾傳播相關科系尤佳。
工作經驗:具節目製作3年以上工作經驗、網路影片拍攝、非線性剪輯3年以上經驗。
工作技能:Office文書軟體、After Effect、Final Cut、Premiere,會3D軟體尤佳。
語言能力:精通國台語、英語中等以上。
其他條件:
1. 對台灣題材有興趣、可以獨立完成節目前製與後製工作。
2. 請提供3∼5分鐘自製的影音作品及連結。
🔵 B3 節目企畫
工作內容:
1. 影音節目相關版權及IP洽談業務
2. 影音節目採購標案撰寫、執行與驗收
3. 重製影音節目發想、洽談與流程管控
4. 自製網路影音節目發想、規劃與執行
5. 密切與社群部門溝通,以利節目內容產生有效的國際傳播
學歷要求:大專以上畢業,不限科系。
工作經驗: 具2年以上傳播行銷、節目授權、專案開發等相關工作經驗。
工作技能:Office文書軟體
語言能力:精通中、英文。
其他條件:熟悉著作權相關法律,具備採購專業人員基本資格或進階資格者尤佳
🔵 D1 社群媒體內容製作人
工作內容:
1. 經營Facebook、YouTube、Instagram、Twitter等社群平台,以及
Line、What’s App等等通訊軟體。負責所有社群活動,包括內容排程、社群管理,以及最佳化貼文使用者互動經驗與搜尋。
2. 發想與製作能夠引起高度共鳴的社群圖文,同時密切與內容產製部門合作,達成內容傳遞最佳效益,將台灣題材透過創意社群轉譯給國際觀眾。
3. 管理全站及跨平台數位內容產品,包括主網站與手機應用程式(APP),主責新聞推播與電子報策略。
4. 監測互動與流量表現,並提出內容策略建議。
學歷要求:大學以上畢業,不限科系
工作經驗:具3年以上實際社群經營經驗(請提供相關工作經驗與成功案例)。
工作技能:具備影片、圖片製作思維與能力;社群平台數據分析、Google Analytics分析能力。
語言能力:精通中、英文。
🔵 E3 網路平台技術主管 Platform Technology Manager
工作內容:
1. 帶領並管理技術團隊,以充分掌握技術並達成產品開發或專案交付目標。
2. 依據專案需求,主導或協助專案管理。包含直接或協助專案經理帶領與管理技術團隊,能有效解決專案技術相關問題,確保專案如期如質交付。
3. 依據公司發展需求,負責建立開發技術團隊。內容包含人員面試、考核、技術帶領與管理等。
4. 針對新技術導入與知識管理需求,建立技術評估、技術分享辦法,協助團隊提升技術能力。
5. 其他主管交辦事項。
學歷要求:大學以上畢業,資訊或理工相關科系畢。
工作經驗:具備7年以上開發團隊主管經驗,5年以上C#、Python紮實技術基礎與開發經驗,具大型網路服務系統規畫建置經驗。
工作技能:熟悉C#/.net or Python/Django任一開發技術,熟悉AWS、GCP等雲端平台。具影音串流經驗尤佳。
語言能力:具備中等以上英語聽說讀寫能力。
其他條件:良好的溝通、團隊合作能力。
🔵 E4 DevOp工程師 DevOps Engineer
工作內容:
1. 負責內外部系統發佈、部署、調優、監控、日誌等系統和流程的維護和優化,確保系統的高可用性。
2. 負責雲端系統執行環境的建置與維護。
3. 負責突發問題處理並進行定位和處理。
4. 探索新的運維技術方向。
5. 其它主管交辦事項。
學歷要求:大學以上畢業,理工相關科系畢。
工作經驗:3年以上系統、應用運維經驗。
工作技能:熟悉linux系統,瞭解網路基本技術,熟悉TCP/IP協定原理,具AWS、GCP等雲端平台與服務維運經驗。熟悉網路安全者佳。
其他條件:良好的溝通、團隊合作、獨立作業的能力。
🔵 E5 數據工程師 Data Engineer
工作內容:
1. 執行資料處理、資料分析以及data lake、data mart的建立與維護。
2. 使用BI工具建立報表分析及數據探勘。
3. 因應業務需求,持續優化資料平台架構。
學歷要求:大學以上畢業,資訊或理工相關科系畢。
工作經驗:具備專案管理經驗,熟悉Agile軟體開發流程者佳。
工作技能:熟悉Python 或 Java,熟悉 Power BI或其他BI軟體工具,熟悉SQL。具數據分析與統計經驗。熟悉GCP者佳。
語言能力:具備基本英語溝通能力。
其他條件:良好的溝通協調能力。
🔵 E6 資訊安全暨系統維護主管 Information Security & System Maintenance Manager
工作內容:
1. 統籌公司內部資訊相關系統整合、部署、營運及維護 。
2. 確保資訊設備的可用性,因應公司營運發展所需改善現有資訊系統並預先規劃所需資源。
3. 機房規畫及運營。
4. 規劃辦公室網路環境。
5. 訂立資訊體制,改善資訊安全規範,落實資訊安全控管機制。
6. 定期對資訊風險進行評估以合乎公司安全策略及必要法規(包含ISO),確保系統運營的持續性與可回復。
7. 協助主管其他資訊專案推動。
學歷要求:大學以上畢業,資訊或理工相關科系畢。
工作經驗:7年以上資訊領域工作經驗,具資安經驗者佳。
工作技能:具軟體或平台開發經驗。具備資安相關證照者佳,具有導入ISO經驗者佳。
語言能力:具備中等英語聽說讀寫能力。
其他條件:良好的溝通協調能力。
🔵 E7 資訊安全主管 Information Security Lead
工作內容:
1. 帶領資安團隊、規劃與推動整體資安之目標與計畫。
2. 規劃/制定/執行整體資安治理流程管理。
3. 認證、稽核協調與管理。
4. 資安情資收集與資安事件應變處理。
5. 服務平台資安檢測、諮詢,與規範,持續強化系統資訊安全強度。
6. 辦公室資訊安全防禦建置與監控。
7. 研究與採購建置資安產品。
8. 對內對外資訊安全教育訓練規劃與推動。
學歷要求:大學以上畢業,資訊或理工相關科系畢。
工作經驗:3年以上資安工作經驗,具資安主管經驗者佳。
工作技能:具有AWS、GCP 等雲端環境經驗。具備OSCP,CEH等資安相關證照者佳。具有導入 ISO 經驗者佳。
語言能力:具備中等英語聽說讀寫能力。
其他條件:良好的溝通協調能力。
🔵 E8 資安工程師 Information Security Engineer
工作內容:
1. 協助資訊安全專案執行與維護工作。
2. 資訊安全解決方案(資安系統)專案規劃及建置、維護。
3. 週期性確認相關紀錄(Log),確認相關控制措施有效。
4. 研究資訊安全技術,如重大系統漏洞或惡意程式。
學歷要求:專科或大學以上,理工相關科系畢。
工作經驗:2年以上系統、應用開發或運營經驗。
工作技能:熟悉linux、windows系統,瞭解網路基本技術。具AWS等雲端平台與服務經驗者佳。具備OSCP,CEH等資案相關證照者佳。
其他條件:良好的溝通能力。
🔵 E9 網路暨維護主管/工程師 Network & System Maintenance Lead / Engineer
工作內容:
1. 負責公司與IDC 網路之規劃、建置、管理及維護。
2. 網路設備安裝、設定、管理及維護等。
3. 與分析網路資料傳輸與網路安全架構等特性,以設計、發展及維護網際網路系統之正常運作。
4. 網路解決方案研究與導入。
5. 網路系統進行監控與告警處理。
6. 一般告警處理流程、重大網路障礙排除。工作內容:
7. 機房監控、管理與一般障礙排除與處理。
8. 協助公司其他單位,提供相關的系統操作與技術支援。包含一般員工以及影音編輯人員的電腦故障排除,軟體安裝、設定、系統操作等。
9. 對突發狀況的緊急應變處理。
學歷要求:專科或大學以上,理工相關科系畢。
工作經驗:網管工作2年以上相關經驗。
工作技能:熟悉linux、windows系統。了解OSI架構、HTTP、TCP/IP、DNS、SMTP、CDN。具備Load-balancer/ Firewall/ Switch操作
經驗。具備CCNA優先考慮。
其他條件:能配合公司輪班制度者優先考慮。
🔵 E10 產品管理師
工作內容:
1. 負責OTT影音平台相關的產品功能設計、UI/UX設計。
2. 內部使用單位訪談及需求分析,協助提供內容部門產品端的解決方案。
3. 撰寫商業需求文件及負責產品UAT,執行產品功能上線前驗收測試。
4. 持續優化平台功能與使用者體驗。
學歷要求:大學以上畢業。
工作經驗:具備3年以上網路服務或者to-c系統運營經驗,對產品設計流程和解決問題抱有高度熱情及興趣。
工作技能:熟悉Web、App開發流程。具備專案管理方法以及流程設計的經驗。具UX思維規劃功能,改善使用者體驗。
語言能力:具備基本英語溝通能力。
其他條件:良好的溝通協調能力,個性耐心且細心者為佳。
🔵 E11 軟體開發主管 Software Development Lead
工作內容:
1. 負責影音平台網站、後台與API等相關功能開發。
2. 負責優化與維護既有網站與後台功能。
學歷要求:大學或專科以上畢業,理工相關科系畢。
工作經驗:具備5年以上C#.NET or Python開發經驗。具人員管理經驗。
工作經驗:
1. 具備5年以上C#.NET or Python開發經驗。
2. 具人員管理經驗。
工作技能:
1. http://xn--pcu439a.net/.net core 或 Django、Flask framework。
2. 熟悉JavaScript/CSS/HTML5。
3. 熟悉mySQL、PostgreSQL與mongo DB。
4. 熟悉版控軟體,如Git。
5. 熟悉CI/DC流程。
6. 熟悉Vue.js或React者佳。
其他條件:工作認真仔細,具良好的溝通、團隊合作、獨立作業的能力。
🔵 E12 軟體開發工程師 Software Development Engineer
工作內容:
1. 負責影音平台網站、後台與會員中心等相關功能開發。
2. 負責優化與維護既有網站與後台功能。
學歷要求:大學或專科以上畢業,理工相關科系畢。
工作經驗:具備3年以上C#.NET or Python開發經驗。
工作技能:
1. http://xn--pcu439a.net/.net core 或 Django、Flask framework。
2. 熟悉JavaScript/CSS/HTML5。
3. 熟悉mySQL、PostgreSQL與mongo DB。
4. 熟悉Vue.js或React者佳。
其他條件:工作認真仔細,具良好的溝通、團隊合作、獨立作業的能力。
同時也有2部Youtube影片,追蹤數超過7萬的網紅在地上滾的工程師 Nic,也在其Youtube影片中提到,硬核的知識也許不是每個工程師都能夠在職涯發展中完全運用到,但無論是本科系、轉職、自學成為工程師的朋友,都應該要知道,這些紮實的背景知識提早學習起來,在未來的日子裡,只有好沒有壞。 就透過本影片我的真實經驗分享,告訴你這些我在大學時期看似枯燥乏味的理論,其實就是程式設計內功,而日後沉睡已久的內功卻又...
「javascript function in function」的推薦目錄:
- 關於javascript function in function 在 中央社新聞粉絲團 Facebook 的最佳解答
- 關於javascript function in function 在 Taipei Ethereum Meetup Facebook 的最佳解答
- 關於javascript function in function 在 Taipei Ethereum Meetup Facebook 的精選貼文
- 關於javascript function in function 在 在地上滾的工程師 Nic Youtube 的精選貼文
- 關於javascript function in function 在 在地上滾的工程師 Nic Youtube 的最佳貼文
- 關於javascript function in function 在 JavaScript Anonymous Functions 的評價
- 關於javascript function in function 在 Calling a function inside another function in JavaScript 的評價
- 關於javascript function in function 在 程式語言教學誌FB, YouTube: PYDOING: JavaScript 入門指南 的評價
javascript function in function 在 Taipei Ethereum Meetup Facebook 的最佳解答
📜 [專欄新文章] Tornado Cash 實例解析
✍️ Johnson
📥 歡迎投稿: https://medium.com/taipei-ethereum-meetup #徵技術分享文 #使用心得 #教學文 #medium
Tornado Cash 是一個使用 zk-SNARKs 建立的 Dapp,它實現了匿名的代幣交易,這篇文章就用一些程式碼片段,來分享它是怎麼運作的。
本文為 Tornado Cash 研究系列的 Part 3,本系列以 tornado-core 為教材,學習開發 ZKP 的應用,另兩篇為:
Part 1:Merkle Tree in JavaScript
Part 2:ZKP 與智能合約的開發入門
Special thanks to C.C. Liang for review and enlightenment.
我們知道在以太坊上的交易紀錄都是公開的,你可以在 etherscan 上看到某個地址的所有歷史交易紀錄,當然地址是合約的話也是一樣。
也許創建一個新的錢包和地址就好了?假設一個情境是 Alice 想要匿名傳送 1 ETH 給 Bob,Alice 原本的錢包是 A,但她不想讓 A 地址傳給 Bob 的交易紀錄被看到,所以 Alice 創建另一個錢包 B,顯然 B 錢包是空的,Alice 必須把 A 錢包的 1 ETH 傳到 B 錢包,再用 B 錢包的地址傳給 Bob。
但問題就在於,只要追蹤 B 錢包的地址,就能看到 B 的歷史交易紀錄中 A 錢包曾經打幣給 B 錢包,於是到頭來交易還是被追蹤到了。
Tornado Cash 的解決方案,簡單來說,它是一份合約,當你要匿名傳送代幣時,就把一定數量的幣丟進合約裡 (Deposit),此時你會拿到一個 note,長得像這樣:
tornado-eth-0.1-5-0x3863c2e16abc85d72b64d78c68fca5936db2501832e26345226efdfb2bc45804977f167d86b711bb6b4095ddaa646ec93f0a93ac4884a66c1d881f4fc985
note 就是一串字串,擁有這字串的人,就能提領 (Withdraw) 剛剛傳入合約的代幣。握有 note 就代表擁有提款的權利,所以 note 一旦被別人知道,別人就可以把錢給提走。
其中,後面那段亂碼,本篇文章就以「秘密」來稱呼,這個秘密是由 secret 與 nullifier 組成,而這兩個都是在鏈下隨機產生的亂數。
因此 Tornado 的合約基本上會有兩個函式:
Deposit
Withdraw
有興趣的人可以先到 Dapp 上先玩一次看看,使用 Goerli 測試網,這裡可以領 Goerli 的代幣:https://goerli-faucet.slock.it/
Deposit
我們就從 Deposit 開始說起,簡單來說, Deposit 是將資料儲存到合約的 Merkle Tree 上。
剛剛提到的秘密,它是在鏈下產生,由 secret 跟 nullifier 組成,合在一起之後也稱作 preimage,因為我們要對這個 preimage 進行 hash,就會成為 commitment。
合約中 Deposit 如下:
deposit 除了傳送代幣到合約之外,需填入一個參數 _commitment。
我們對 preimage 使用 Pedersen 作為 hash function 加密後產生 commitment,以偽代碼表示如下:
const preimage = secret + nullifier;const commitment = pedersenHash(preimage);
這個 commitment 會成為 Merkle Tree 的葉子,所以合約中的 _insert(commitment) 來自 MerkleTreeWithHistory.sol 的合約,將我們的資料插入 Merkle Tree,然後回傳一個 index 給你,告訴你這個 commitment 在 Merkle Tree 上的位置,最後一起發布成公開的 Deposit 事件。
我們知道 MerkleTree 是將一大筆資料兩兩做雜湊後產生一個唯一值 root,這個 root 就是合約上所儲存的歷史資料。
root 的特性就是只要底下的資料一有更動,就會重新產生新的 root。
所以只要一有用戶 deposit ,就會插入新的葉子到 Merkle Tree 上,於是就會產生新的 root,所以在合約中有一個陣列是用來儲存所有的 root 的 roots:
bytes32[ROOT_HISTORY_SIZE] public roots;
roots 是用來紀錄每個 deposit 的歷史,每一次 deposit 都會創造新的 root,而所有 root 都會被儲存進 roots 裡,於是當你要提領的時候,就要證明你的 commitment 所算出的 root 曾經出現在 roots 裡,代表曾經有 deposit 的動作,因此才可以進行提領。
Withdraw
在 Deposit 之前 Tornado Cash 就會在鏈下產生秘密後交給使用者,擁有這個秘密的人等於擁有提款的權利。
提領的時候,秘密會在鏈下計算後產生 proof,proof 是 withdraw 需要的參數,所以只要確保這個 proof 能夠被驗證,那麼代幣的接收地址 (recipient) 就可以隨便我們填,只要不填上當初拿來 deposit 用的地址,基本上就做到匿名交易的效果了。
也就是說,產生這個 proof 並提交給合約,能夠證明此人知道秘密,但卻不告訴合約秘密本身是什麼。
function withdraw(bytes calldata _proof, bytes32 _root, bytes32 _nullifierHash, address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund) external payable nonReentrant;
我們可以清楚看到 withdraw 函式裡沒有接收有關秘密的任何資訊作為參數,也就是秘密不會與合約有所接觸,也不會暴露在 etherscan 上。
回顧 ZKP 所帶來的效果:
鏈下計算
隱藏秘密
在 Tornado Cash 的例子中,我們用秘密來產生證明,完成的鏈下計算包括:
將秘密 hash 成 commitment
算出 Merkle Tree 的 root。
以下是簡化後的 withdraw.circom:
template Withdraw(levels) { signal input root; signal input nullifierHash;
signal private input nullifier; signal private input secret; signal private input pathElements[levels]; signal private input pathIndices[levels];
component hasher = CommitmentHasher(); // Pedersen hasher.nullifier <== nullifier; hasher.secret <== secret; hasher.nullifierHash === nullifierHash;
component tree = MerkleTreeChecker(levels); // MiMC tree.leaf <== hasher.commitment; tree.root <== root; for (var i = 0; i < levels; i++) { tree.pathElements[i] <== pathElements[i]; tree.pathIndices[i] <== pathIndices[i]; }}
component main = Withdraw(20);
從上述代碼就可以看出這份 circuit 的 private 變數有:
secret
nullifier
pathElements
pathIndices
而 public 變數有:
root
nullifierHash
如同我們一開始說過的,秘密就是指 secret 與 nullifier。這裡進行的鏈下計算就是對 secret 與 nullifier 雜湊成 commitment。而使用的 hash function 叫做 Pedersen。
在進行 Merkle Tree 的計算之前,我們還檢查了 nullifier 雜湊後的 nullifierHash 跟 public 變數 nullifierHash 是不是一樣的。
hasher.nullifierHash === nullifierHash;
接下來,開始計算 Merkle Proof,用意是確認經過雜湊後的 commitment 有沒有出現在 Merkle Tree 上,所以我們的 private input 還有 pathElements 與 pathIndices(詳情參考 Part 1 Merkle Tree in JavaScript),讓它跑一趟 Merkle Proof 的計算,最後就能夠算出一個 root,再確認計算後的 root 與我們的 public 變數 root 是否一樣。
tree.root <== root;
於是我們就能產生一個 ZKP 的證明 — 證明 private 變數:secret, nullifier, pathElements, pathIndices 可以計算出 public 變數:root 與 nullifierHash。
把這個證明提交給合約,合約透過 Verifier 驗證 proof 是否正確,以及必須事先確認:
public 變數 root 有在合約的 roots 裡面。
public 變數 nullifierHash 在合約中是第一次出現。
以下附上完整的 withdraw 原始碼:
必須注意 ZKP 是向合約證明使用者填入的 secret 和 nullifier 可以計算出某個 root,但無法保證這個 root 曾經在合約的 roots 歷史上。
所以合約的 withdraw 中,除了 verifyProof 之外,還要事先檢查 ZKP 算出來的 root 是不是真的在歷史上發生過,所以需要 isKnownRoot 的檢查:
function isKnownRoot(bytes32 _root) public view returns(bool)
必須先檢查 isKnownRoot 後才能進行 verifyProof。
經過 verifyProof 驗證成功後,合約就開始進行提款的動作,也就會將代幣傳到 recipient 的地址,最後拋出 Withdrawal 的事件。
nullifier 與 nullifierHash
為什麼我們的秘密不是只有 secret 還要額外加一個 nullifier?
簡單來說,這是為了防止已經提領過的 note 又再提領一次,也就是所謂的 double spend。
require(!nullifierHashes[_nullifierHash], "The note has been already spent");
可以看到 withdraw 需要填入參數 nullifierHash,跟 isKnownRoot 一樣的狀況,我們需要對電路的 public 變數先經過一層檢查之後,才能帶入到 verifyProof 裡面。
nullifierHash 可以理解為這個 note 的 id,但它不會連結到 deposit,因此可以用來紀錄這個 note 是否已經被提領過。
所以當 verifyProof 驗證成功之後,我們要紀錄 nullifierHash 已完成提領:
nullifierHashes[_nullifierHash] = true;
有關為什麼需要事先檢查 public 變數後,才能帶入 verifyProof ,可以參考 Part 2:ZKP 與智能合約的開發入門 提到的 publicSignals 的部分。
附上 Tornado Cash 的架構圖:
簡化版的 tornado-core
tornado-core 的程式碼很簡潔漂亮,所以我模仿該專案自己實作一遍:
simple-tornado:https://github.com/chnejohnson/simple-tornado
這份專案只完成了 tornado-core 的核心部分,不一樣的是我的開發環境使用 hardhat 與 ethers 寫成,而 circom 與 snarkjs 使用官方當前的版本,合約用 0.7.0,測試使用 Typescript 。
比起兩年前的 tornado-core ,simple-tornado 使用的技術更新,可能更適合初學者理解這份專案,但是它有 bug…我在 issues 的地方有紀錄說明。
在開發的過程中,我的順序是先從最小單位的 MiMC hash function 開始玩,發現必須 javascript 算一次 hash、solidity 算一次、circom 再算一次,確保這三個語言對同一個值算出同樣的 hash 之後,才能放心去做更複雜的 Merkle Tree。
總結
我們可以看到 Tornado Cash 簡單的兩個函式:Deposit 與 Withdraw,透過將代幣送入合約後再提領到另一個地址的流程,應用 ZKP 達成匿名的交易。
除了斷開 Deposit 與 Withdraw 的地址關聯性之外,Tornado Cash 還有做了一層「藏樹於林」的隱私防護,這部份的解釋就請參考 ZKP 讀書會 Tornado Cash。
網路上很多關於 ZKP 的文章或專案都是在 2019 年後出產的,經過許多人對這項技術的嘗試,讓我們對 ZKP 有了更清晰的理解,如今兩年後,開發工具也變得更加成熟,期待未來在 web 隱私議題上能看到更多 ZKP 大放異彩的應用。
原始碼
tornado-core
simple-tornado
參考資料
ZKP 讀書會 Tornado Cash
Tornado Privacy Solution Cryptographic Review
Tornado Cash 實例解析 was originally published in Taipei Ethereum Meetup on Medium, where people are continuing the conversation by highlighting and responding to this story.
👏 歡迎轉載分享鼓掌
javascript function in function 在 Taipei Ethereum Meetup Facebook 的精選貼文
📜 [專欄新文章] 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.
👏 歡迎轉載分享鼓掌
javascript function in function 在 在地上滾的工程師 Nic Youtube 的精選貼文
硬核的知識也許不是每個工程師都能夠在職涯發展中完全運用到,但無論是本科系、轉職、自學成為工程師的朋友,都應該要知道,這些紮實的背景知識提早學習起來,在未來的日子裡,只有好沒有壞。
就透過本影片我的真實經驗分享,告訴你這些我在大學時期看似枯燥乏味的理論,其實就是程式設計內功,而日後沉睡已久的內功卻又恰巧的在職涯旅途中碰上用處。
章節:
00:00 學這些有用嗎
00:52 我與速成班的距離
04:45 業務增長後的影響
06:36 基本功知識科普
喜歡影片的話!可以幫忙點個喜歡以及分享、訂閱唷!😘
━━━━━━━━━━━━━━━━
⭐ 蝦皮賣場: https://shopee.tw/bboyceo
⭐ instagram (生活日常): https://www.instagram.com/niclin_tw/
⭐ Facebook (資訊分享): https://www.facebook.com/niclin.dev
⭐ Blog (技術筆記): https://blog.niclin.tw
⭐ Linkedin (個人履歷): https://www.linkedin.com/in/nic-lin
⭐ Github: https://github.com/niclin
⭐ Podcast: https://anchor.fm/niclin
━━━━━━━━━━━━━━━━
🌟 任何問題或合作邀約信箱: niclin0226@gmail.com
#資料結構 #演算法 #計算機概論 #前端 #後端 #工程師

javascript function in function 在 在地上滾的工程師 Nic Youtube 的最佳貼文
程式補習班怎麼這樣教!新手工程師到底該怎麼選擇?先學框架不好嗎?其實你應該需要更瞭解問題的核心,不管程式語言或框架它們最終只是一個解決問題的工具。
這部影片會和你分享如何先找到自己的目標,進而去選擇工具和道路。
喜歡影片的話!可以幫忙點個喜歡以及分享、訂閱唷!😘
━━━━━━━━━━━━━━━━
⭐ 蝦皮賣場: https://shopee.tw/bboyceo
⭐ instagram (生活日常): https://www.instagram.com/niclin_tw/
⭐ Facebook (資訊分享): https://www.facebook.com/niclin.dev
⭐ Blog (技術筆記): https://blog.niclin.tw
⭐ Linkedin (個人履歷): https://www.linkedin.com/in/nic-lin
⭐ Github: https://github.com/niclin
⭐ Podcast: https://anchor.fm/niclin
━━━━━━━━━━━━━━━━
🌟 任何問題或合作邀約信箱: niclin0226@gmail.com
#工程師 #框架 #程式語言

javascript function in function 在 Calling a function inside another function in JavaScript 的美食出口停車場

JavaScript Tutorial 65 - Calling a function inside another ... video: JavaScript Tutorial 64 - Functions Vs. Call ... ... <看更多>
javascript function in function 在 程式語言教學誌FB, YouTube: PYDOING: JavaScript 入門指南 的美食出口停車場
函數(function) 是一種功能性的模組,可以將程式(program) 分割成小部分,藉由呼叫函數安排執行順序 定義函數需要使用關鍵字(keyword) function ,並且指定函數名稱與 ... ... <看更多>
javascript function in function 在 JavaScript Anonymous Functions 的美食出口停車場
Summary: in this tutorial, you will learn about JavaScript anonymous functions. Introduction to JavaScript anonymous functions. An anonymous function is a ... ... <看更多>