วิธีสร้าง Node.js API สำหรับ Ethereum Blockchain
เผยแพร่แล้ว: 2022-03-10เทคโนโลยีบล็อคเชนเพิ่มขึ้นอย่างมากในช่วงสิบปีที่ผ่านมา และได้นำผลิตภัณฑ์และแพลตฟอร์มจำนวนมากมาสู่ชีวิต เช่น Chainalysis (เทคโนโลยีการเงิน), Burstiq (เทคโนโลยีด้านสุขภาพ), Filament (IoT), Opus (การสตรีมเพลง) และจักษุ (ความปลอดภัยทางไซเบอร์)
จากตัวอย่างเหล่านี้ เราจะเห็นได้ว่าบล็อคเชนสามารถตัดผลิตภัณฑ์และกรณีการใช้งานจำนวนมากออกไปได้ ทำให้มีความจำเป็นและมีประโยชน์มาก ในฟินเทค (finance tech) มันถูกใช้เป็น Decentralized Ledger เพื่อความปลอดภัยและความโปร่งใสในสถานที่ต่างๆ เช่น Chain, Chainalysis และยังมีประโยชน์ในเทคโนโลยีด้านสุขภาพสำหรับการรักษาความปลอดภัยของข้อมูลด้านสุขภาพที่มีความละเอียดอ่อนใน Burstiq และ Robomed — อย่าลืมเทคโนโลยีสื่อเช่น Opus และ Audius ที่ใช้ blockchain เพื่อความโปร่งใสของค่าลิขสิทธิ์ และได้รับค่าลิขสิทธิ์เต็มจำนวน
Ocular ใช้การรักษาความปลอดภัยที่มาพร้อมกับ blockchain สำหรับการจัดการข้อมูลประจำตัวสำหรับระบบไบโอเมตริกซ์ ในขณะที่ Filament ใช้บัญชีแยกประเภท blockchain สำหรับการสื่อสารที่เข้ารหัสแบบเรียลไทม์ สิ่งนี้แสดงให้เห็นว่าบล็อคเชนมีความสำคัญต่อเราอย่างไรโดยการทำให้ชีวิตของเราดีขึ้น แต่บล็อคเชนคืออะไร กันแน่ ?
บล็อกเชนเป็น ฐานข้อมูล ที่แชร์ผ่านเครือข่ายคอมพิวเตอร์ เมื่อเพิ่มบันทึกลงในห่วงโซ่แล้ว การเปลี่ยนแปลงค่อนข้างยาก เพื่อให้แน่ใจว่าสำเนาทั้งหมดของฐานข้อมูลเหมือนกัน เครือข่ายจะทำการตรวจสอบอย่างต่อเนื่อง
ทำไมเราถึง ต้องการ บล็อคเชน? Blockchain เป็น วิธีที่ปลอดภัยในการบันทึกกิจกรรม และเก็บข้อมูลให้สดใหม่ในขณะที่ยังคงบันทึกประวัติเมื่อเทียบกับบันทึกหรือฐานข้อมูลแบบเดิมที่การแฮ็ก ข้อผิดพลาด และเวลาหยุดทำงานเป็นไปได้อย่างมาก ข้อมูลไม่สามารถเสียหายได้โดยใครก็ตามหรือถูกลบโดยไม่ได้ตั้งใจ และคุณจะได้ประโยชน์จากทั้งร่องรอยของข้อมูลในอดีตและบันทึกที่เป็นปัจจุบันทันทีที่ไม่สามารถลบหรือไม่สามารถเข้าถึงได้เนื่องจากการหยุดทำงานของเซิร์ฟเวอร์
เนื่องจากบล็อคเชนทั้งหมดถูกทำซ้ำในคอมพิวเตอร์หลายเครื่อง ผู้ใช้ทุกคนสามารถดูบล็อคเชนทั้งหมดได้ ธุรกรรมหรือบันทึกไม่ได้รับการประมวลผลโดยผู้ดูแลระบบส่วนกลางเพียงคนเดียว แต่ดำเนินการโดยเครือข่ายผู้ใช้ที่ทำงานเพื่อยืนยันข้อมูลและบรรลุข้อตกลงร่วมกัน
แอปพลิเคชันที่ใช้บล็อคเชนเรียกว่า dApps (แอปพลิเคชันแบบกระจายอำนาจ) เมื่อมองไปรอบๆ วันนี้ เราจะพบแอปกระจายอำนาจในฟินเทคเป็นส่วนใหญ่ แต่บล็อกเชนเป็นมากกว่าการเงินแบบกระจายอำนาจ เรามีแพลตฟอร์มด้านสุขภาพ แพลตฟอร์มสตรีม/แชร์เพลง แพลตฟอร์มอีคอมเมิร์ซ แพลตฟอร์มความปลอดภัยทางไซเบอร์ และ IOT ที่มุ่งสู่แอปพลิเคชันแบบกระจายศูนย์ (dApps) ตามที่กล่าวไว้ข้างต้น
ดังนั้นเมื่อใดที่ควรพิจารณาใช้บล็อคเชนสำหรับแอปพลิเคชันของเรา แทนที่จะเป็นฐานข้อมูลมาตรฐานหรือบันทึก
แอปพลิเคชั่นทั่วไปของ Blockchain
- การจัดการและการรักษาความปลอดภัยความสัมพันธ์ทางดิจิทัล
เมื่อใดก็ตามที่คุณต้องการเก็บบันทึกระยะยาวและโปร่งใสของทรัพย์สิน (เช่น เพื่อบันทึกสิทธิ์ในทรัพย์สินหรืออพาร์ตเมนต์) blockchain อาจเป็นทางออกที่ดี โดยเฉพาะอย่างยิ่ง 'สัญญาอัจฉริยะ' ของ Ethereum นั้นยอดเยี่ยมสำหรับการอำนวยความสะดวกในความสัมพันธ์ทางดิจิทัล ด้วยสัญญาอัจฉริยะ การชำระเงินอัตโนมัติสามารถออกได้เมื่อคู่สัญญาในธุรกรรมตกลงว่าตรงตามเงื่อนไขของพวกเขา - กำจัดคนกลาง/คนเฝ้าประตู
ตัวอย่างเช่น ผู้ให้บริการส่วนใหญ่ในปัจจุบันต้องโต้ตอบกับแขกผ่านแพลตฟอร์มรวมศูนย์ เช่น Airbnb หรือ Uber (ซึ่งจะลดการทำธุรกรรมแต่ละครั้ง) Blockchain สามารถเปลี่ยนแปลงทุกสิ่งได้
ตัวอย่างเช่น TUI เชื่อมั่นในพลังของบล็อคเชนว่าเป็นวิธีบุกเบิกในการเชื่อมโยงเจ้าของโรงแรมและลูกค้าโดยตรง ด้วยวิธีนี้ พวกเขาสามารถทำธุรกรรมผ่านบล็อคเชนในวิธีที่ง่าย ปลอดภัย และสม่ำเสมอ มากกว่าผ่านแพลตฟอร์มการจองส่วนกลาง - บันทึกธุรกรรมที่ปลอดภัยระหว่างคู่ค้าเพื่อให้เกิดความไว้วางใจ
ฐานข้อมูลแบบดั้งเดิมอาจดีสำหรับการบันทึกธุรกรรมง่ายๆ ระหว่างสองฝ่าย แต่เมื่อสิ่งต่าง ๆ มีความซับซ้อนมากขึ้น blockchain สามารถช่วยลดปัญหาคอขวดและทำให้ความสัมพันธ์ง่ายขึ้น ยิ่งไปกว่านั้น การรักษาความปลอดภัยที่เพิ่มขึ้นของระบบกระจายอำนาจทำให้บล็อคเชนเหมาะอย่างยิ่งสำหรับการทำธุรกรรมโดยทั่วไป
ตัวอย่างคือมหาวิทยาลัยเมลเบิร์นที่เริ่มจัดเก็บบันทึกในบล็อคเชน กรณีการใช้งานที่มีแนวโน้มมากที่สุดสำหรับ blockchain ในการศึกษาระดับอุดมศึกษาคือการเปลี่ยน "การเก็บบันทึก" ขององศา ประกาศนียบัตร และอนุปริญญา ซึ่งช่วยประหยัดค่าใช้จ่ายได้มากจากเซิร์ฟเวอร์เฉพาะสำหรับการจัดเก็บหรือบันทึก - การเก็บบันทึกการกระทำในอดีตสำหรับแอปพลิเคชันที่มีข้อมูลอยู่ในฟลักซ์คงที่
Blockchain เป็นวิธีที่ดีกว่าและปลอดภัยกว่าในการบันทึกกิจกรรมและเก็บข้อมูลให้สดใหม่ในขณะที่ยังคงบันทึกประวัติไว้ ข้อมูลไม่สามารถเสียหายโดยใครก็ตามหรือถูกลบโดยไม่ได้ตั้งใจ และคุณจะได้ประโยชน์จากทั้งร่องรอยของข้อมูลในอดีต บวกกับบันทึกที่เป็นปัจจุบันทันที ตัวอย่างของกรณีการใช้งานที่ดีคือบล็อคเชนในอีคอมเมิร์ซ ทั้งบล็อคเชนและอีคอมเมิร์ซเกี่ยวข้องกับธุรกรรม
Blockchain ทำให้ธุรกรรมเหล่านี้ปลอดภัยและเร็วขึ้นในขณะที่กิจกรรมอีคอมเมิร์ซพึ่งพาพวกเขา เทคโนโลยีบล็อคเชนทำให้ผู้ใช้สามารถแบ่งปันและจัดเก็บสินทรัพย์ดิจิทัลได้อย่างปลอดภัยทั้งแบบอัตโนมัติและด้วยตนเอง เทคโนโลยีนี้มีความสามารถในการจัดการกับกิจกรรมของผู้ใช้ เช่น การประมวลผลการชำระเงิน การค้นหาผลิตภัณฑ์ การซื้อผลิตภัณฑ์ และการดูแลลูกค้า นอกจากนี้ยังช่วยลดค่าใช้จ่ายในการจัดการสินค้าคงคลังและการประมวลผลการชำระเงิน - การกระจายอำนาจทำให้สามารถใช้งานได้ทุกที่
ต่างจากเมื่อก่อนที่เราจะต้องจำกัดตัวเองให้อยู่เฉพาะภูมิภาคใดภูมิภาคหนึ่งเนื่องจากเหตุผลต่างๆ เช่น นโยบายการแลกเปลี่ยนสกุลเงิน ข้อจำกัดของเกตเวย์การชำระเงินทำให้การเข้าถึงทรัพยากรทางการเงินของหลายประเทศไม่ได้ยากลำบากในภูมิภาคหรือทวีปของคุณ ด้วยการเติบโตและพลังของการกระจายอำนาจของบล็อกเชนหรือระบบเพียร์ทูเพียร์ ทำให้ทำงานร่วมกับประเทศอื่นๆ ได้ง่ายขึ้น
ตัวอย่างเช่น ร้านค้าอีคอมเมิร์ซในยุโรปสามารถมีผู้บริโภคในแอฟริกาได้ และไม่ต้องการให้คนกลางดำเนินการตามคำขอชำระเงิน นอกจากนี้ เทคโนโลยีเหล่านี้กำลังเปิดประตูสำหรับผู้ค้าปลีกออนไลน์เพื่อใช้ประโยชน์จากตลาดผู้บริโภคในประเทศที่ห่างไกลด้วย bitcoin นั่นคือสกุลเงินดิจิตอล - Blockhain เป็นเทคโนโลยีที่เป็นกลาง
Blockchain ทำงานได้กับทุกเทคโนโลยีที่นักพัฒนาใช้ คุณไม่จำเป็นต้องเรียนรู้ Node ในฐานะนักพัฒนา Python เพื่อใช้ blockchain หรือเรียนรู้ Golang ทำให้บล็อกเชนใช้งานง่ายมาก
เราสามารถใช้มันได้โดยตรงกับแอปส่วนหน้าของเราใน Vue/React โดยบล็อกเชนทำหน้าที่เป็นฐานข้อมูลเดียวของเราสำหรับงานที่ไม่ซับซ้อนและกรณีการใช้งาน เช่น การอัปโหลดข้อมูลหรือการรับแฮชเพื่อแสดงบันทึกสำหรับผู้ใช้ของเรา หรือสร้างเกมส่วนหน้า เช่น คาสิโน เกมและเกมเดิมพัน (ซึ่งต้องการความไว้วางใจสูง) นอกจากนี้ ด้วยพลังของ web3 เราสามารถจัดเก็บข้อมูลในสายโซ่ได้โดยตรง
ตอนนี้เราได้เห็นข้อดีมากมายของการใช้บล็อคเชนแล้ว แต่เมื่อไรที่เราไม่ควรใส่ใจกับการใช้บล็อคเชนเลย?
ข้อเสียของบล็อคเชน
- ลดความเร็วสำหรับธุรกรรมดิจิทัล
บล็อคเชนต้องการพลังประมวลผลจำนวนมาก ซึ่งมีแนวโน้มที่จะลดความเร็วของธุรกรรมดิจิทัล แม้ว่าจะมีวิธีแก้ไขปัญหาชั่วคราว ขอแนะนำให้ใช้ฐานข้อมูลแบบรวมศูนย์เมื่อต้องการธุรกรรมความเร็วสูงในหน่วยมิลลิวินาที - ข้อมูลไม่เปลี่ยนรูป
ความไม่เปลี่ยนรูปของข้อมูลเป็นข้อเสียที่ใหญ่ที่สุดอย่างหนึ่งของบล็อกเชนเสมอมา เป็นที่ชัดเจนว่าหลายระบบได้รับประโยชน์จากมัน รวมถึงห่วงโซ่อุปทาน ระบบการเงิน และอื่นๆ อย่างไรก็ตาม มันได้รับผลกระทบจากข้อเท็จจริงที่ว่าเมื่อเขียนข้อมูลแล้ว จะไม่สามารถลบออกได้ ทุกคนบนโลกมีสิทธิในความเป็นส่วนตัว อย่างไรก็ตาม หากคนๆ เดียวกันใช้แพลตฟอร์มดิจิทัลที่ทำงานบนเทคโนโลยีบล็อกเชน เขาจะไม่สามารถลบร่องรอยออกจากระบบได้เมื่อเขาไม่ต้องการให้มีที่นั่น พูดง่ายๆ ก็คือ ไม่มีทางที่เขาจะสามารถลบร่องรอยของเขาได้ — ปล่อยให้สิทธิ์ความเป็นส่วนตัวเป็นชิ้นๆ - ต้องใช้ความรู้ความชำนาญ
การดำเนินการและจัดการโครงการบล็อคเชนนั้นยาก ต้องใช้ความรู้อย่างละเอียดในการดำเนินการทั้งหมด ด้วยเหตุนี้จึงเป็นเรื่องยากที่จะหาผู้เชี่ยวชาญหรือผู้เชี่ยวชาญเกี่ยวกับบล็อกเชน เนื่องจากต้องใช้เวลาและความพยายามอย่างมากในการฝึกอบรมผู้เชี่ยวชาญบล็อคเชน ดังนั้นบทความนี้จึงเป็นจุดเริ่มต้นที่ดีและเป็นแนวทางที่ดีหากคุณได้เริ่มต้นไปแล้ว - การทำงานร่วมกัน
เครือข่ายบล็อคเชนหลายแห่งทำงานอย่างหนักเพื่อแก้ปัญหาบัญชีแยกประเภทแบบกระจาย ทำให้ยากต่อการเชื่อมโยงหรือรวมเข้าด้วยกัน ทำให้การสื่อสารระหว่างเครือข่ายต่างๆ เป็นไปอย่างยากลำบาก - การรวมแอปพลิเคชันดั้งเดิม
ธุรกิจและแอปพลิเคชันจำนวนมากยังคงใช้ระบบและสถาปัตยกรรมแบบเดิม การนำเทคโนโลยีบล็อคเชนมาใช้จำเป็นต้องมีการยกเครื่องระบบเหล่านี้ใหม่ทั้งหมด ซึ่งต้องบอกว่าไม่สามารถทำได้สำหรับหลาย ๆ คน
Blockchain ยังคงพัฒนาและเติบโตตลอดเวลา ดังนั้นอย่าแปลกใจถ้าข้อเสียเหล่านี้ที่กล่าวถึงในวันนี้กลายเป็นมืออาชีพในภายหลัง Bitcoin ซึ่งเป็นสกุลเงินดิจิทัลเป็นตัวอย่างหนึ่งที่ได้รับความนิยมของบล็อคเชน บล็อคเชนที่ได้รับความนิยมที่เพิ่มขึ้นนอกเหนือจากสกุลเงินดิจิตอลบิทคอยน์คือ Ethereum blockchain Bitcoin มุ่งเน้นไปที่ cryptocurrencies ในขณะที่ Ethereum เน้นที่สัญญาอัจฉริยะซึ่งเป็นแรงผลักดันที่สำคัญสำหรับแพลตฟอร์มเทคโนโลยีใหม่
การอ่านที่แนะนำ : Bitcoin กับ Ethereum: อะไรคือความแตกต่าง?
มาเริ่มสร้าง API ของเรากันเถอะ
ด้วยความเข้าใจอย่างถ่องแท้เกี่ยวกับบล็อคเชน ตอนนี้เรามาดูวิธีสร้างบล็อคเชน Ethereum และรวมเข้ากับ API มาตรฐานใน Node.js กัน เป้าหมายสูงสุดคือการได้รับความเข้าใจที่ดีเกี่ยวกับวิธีการสร้างแพลตฟอร์ม dApps และ Blockchain
dApps ส่วนใหญ่มีสถาปัตยกรรมและโครงสร้างที่คล้ายคลึงกัน โดยพื้นฐานแล้ว เรามีผู้ใช้ที่โต้ตอบกับส่วนหน้าของ dApp ไม่ว่าจะเป็นเว็บหรือมือถือ ซึ่งจะโต้ตอบกับ API แบ็กเอนด์ จากนั้น แบ็กเอนด์จะโต้ตอบกับสัญญาอัจฉริยะหรือบล็อกเชนผ่านโหนดสาธารณะตามคำขอ เหล่านี้เรียกใช้แอปพลิเคชัน Node.js หรือแบ็กเอนด์ใช้ blockchain โดยเรียกใช้ซอฟต์แวร์ Node.js โดยตรง ยังมีอีกหลายสิ่งหลายอย่างระหว่างกระบวนการเหล่านี้ ตั้งแต่การเลือกสร้างแอปพลิเคชันที่กระจายอำนาจอย่างสมบูรณ์หรือแอปพลิเคชันกึ่งกระจายอำนาจ ไปจนถึงการเลือกสิ่งที่ควรกระจายอำนาจและวิธีจัดเก็บคีย์ส่วนตัวอย่างปลอดภัย
การอ่านที่แนะนำ : Decentralized Applications Architecture: Back End, Security และ Design Patterns
สิ่งที่เราควรรู้ก่อน
สำหรับบทช่วยสอนนี้ เราจะพยายามสร้างแบ็กเอนด์ของ แอพคลังเพลงแบบกระจายอำนาจ ที่ใช้พลังของ Ethereum blockchain สำหรับจัดเก็บเพลงและแชร์เพื่อดาวน์โหลดหรือสตรีม
โครงสร้างพื้นฐานของแอปพลิเคชันที่เรากำลังพยายามสร้างมีสามส่วน:
- การ รับรองความถูกต้อง ซึ่งทำโดยอีเมล แน่นอนว่าเราต้องเพิ่มรหัสผ่านที่เข้ารหัสลงในแอป
- การจัดเก็บข้อมูล โดยที่ข้อมูลเพลงจะถูกจัดเก็บใน ipfs ก่อน และที่อยู่ที่จัดเก็บจะถูกจัดเก็บไว้ใน blockchain เพื่อเรียกค้น
- การ ดึงข้อมูล โดยที่ผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์จะสามารถเข้าถึงข้อมูลที่จัดเก็บไว้บนแพลตฟอร์มของเราและใช้งานได้
เราจะสร้างสิ่งนี้ด้วย Node.js แต่คุณสามารถสร้างด้วย Python หรือภาษาการเขียนโปรแกรมอื่นๆ ได้ เราจะดูวิธีจัดเก็บข้อมูลสื่อใน IPFS รับที่อยู่และเขียนฟังก์ชันเพื่อจัดเก็บที่อยู่นี้ และดึงที่อยู่นี้จากบล็อกเชนด้วยภาษาโปรแกรม Solidity
ต่อไปนี้คือเครื่องมือบางส่วนที่เราควรมีไว้ใช้เพื่อสร้างหรือทำงานกับ Ethereum และ Node.js
- Node.js
ข้อกำหนดแรกคือแอปพลิเคชันโหนด เรากำลังพยายามสร้างแอป Node.js ดังนั้นเราจึงต้องมีคอมไพเลอร์ โปรดตรวจสอบให้แน่ใจว่าคุณได้ติดตั้ง Node.js แล้ว และโปรดดาวน์โหลดไบนารีการสนับสนุนระยะยาวล่าสุด ( LTS ) - ทรัฟเฟิลสวีท
Truffle คือสภาพแวดล้อมสำหรับการพัฒนาและทดสอบสัญญา เช่นเดียวกับท่อส่งทรัพย์สินสำหรับ Ethereum blockchain จัดเตรียมสภาพแวดล้อมสำหรับการคอมไพล์ ไพพ์ไลน์ และรันสคริปต์ เมื่อคุณกำลังพูดถึงการพัฒนาบล็อคเชน ทรัฟเฟิลเป็นสถานที่ยอดนิยมที่ต้องไป ตรวจสอบ Truffle Suite ใน Truffle Suite: Sweet Tools สำหรับ Smart Contracts - Ganache CLI
เครื่องมืออื่นที่ทำงานได้ดีกับ Truffle คือ Ganache-CLI สร้างและดูแลโดยทีมงาน Truffle Suite หลังจากสร้างและคอมไพล์แล้ว คุณต้องมีโปรแกรมจำลองเพื่อพัฒนาและเรียกใช้แอพบล็อคเชน จากนั้นจึงปรับใช้สัญญาอัจฉริยะเพื่อใช้งาน Ganache ช่วยให้คุณปรับใช้สัญญาในโปรแกรมจำลองได้ง่ายขึ้นโดยไม่ต้องใช้เงินจริงสำหรับต้นทุนการทำธุรกรรม บัญชีรีไซเคิล และอื่นๆ อีกมากมาย อ่านเพิ่มเติมเกี่ยวกับ Ganache CLI ที่ Ganache CLI และ Ganache - รีมิกซ์
Remix เป็นเหมือนทางเลือกแทน Ganache แต่ยังมาพร้อมกับ GUI เพื่อช่วยนำทางในการปรับใช้และทดสอบ Ethereum smart contract คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับมันได้ใน Remix — Ethereum IDE & ชุมชน สิ่งที่คุณต้องทำคือเข้าไปที่ https://remix.ethereum.org และใช้ GUI เพื่อเขียนและปรับใช้สัญญาอัจฉริยะ - Web3
Web3 คือชุดของไลบรารีที่ให้คุณโต้ตอบกับโหนด Ethereum สิ่งเหล่านี้อาจเป็นโหนดภายในหรือระยะไกลของสัญญาผ่าน HTTP, IPC หรือ Web Sockets Intro to Web3.js · Ethereum Blockchain Developer Crash Course เป็นสถานที่ที่ดีในการเรียนรู้เล็กน้อยเกี่ยวกับ Web3 - IPFS
โปรโตคอลหลักที่ใช้ในการสร้าง dApps InterPlanetary File System (IPFS) เป็นโปรโตคอลและเครือข่ายเพียร์ทูเพียร์สำหรับการจัดเก็บและแบ่งปันข้อมูลในระบบไฟล์แบบกระจาย IPFS Powers the Distributed Web อธิบายเพิ่มเติมเกี่ยวกับ IPFS และวิธีใช้งานโดยทั่วไป
การสร้าง Backend API ตั้งแต่เริ่มต้น
ก่อนอื่นเราต้องสร้างแบ็กเอนด์เพื่อใช้งาน และเรากำลังใช้ Node.js เมื่อเราต้องการสร้าง Node.js API ใหม่ สิ่งแรกที่เราจะทำคือเริ่มต้นแพ็คเกจ npm อย่างที่คุณอาจทราบ npm ย่อมาจาก Node Package Manager และมาพร้อมกับไบนารี Node.js ดังนั้นเราจึงสร้างโฟลเดอร์ใหม่และเรียกมันว่า “blockchain-music” . เราเปิดเทอร์มินัลในไดเร็กทอรีโฟลเดอร์นั้น จากนั้นรันคำสั่งต่อไปนี้:
$ npm init -y && touch server.js routes.js
สิ่งนี้จะเริ่มต้นโครงการด้วยไฟล์ package.json และตอบ ใช่ สำหรับข้อความแจ้งทั้งหมด จากนั้น เรายังสร้างไฟล์ server.js และไฟล์ routes.js สำหรับเขียนฟังก์ชัน routes
ใน API
หลังจากทั้งหมดนี้ คุณจะต้องติดตั้งแพ็คเกจที่เราจำเป็นต้องทำให้งานสร้างของเราง่ายและตรงไปตรงมา กระบวนการนี้เป็นกระบวนการที่ต่อเนื่อง กล่าวคือ คุณสามารถติดตั้งแพ็คเกจเมื่อใดก็ได้ในระหว่างการพัฒนาโครงการของคุณ
มาติดตั้งสิ่งที่สำคัญที่สุดที่เราต้องการตอนนี้:
- Express.js
- @ทรัฟเฟิล/สัญญา
- เห็ดทรัฟเฟิล.js
- web3.js
- dotenv
-
short-id
- MongoDB
- โนเดมอน
คุณจะต้องติดตั้ง Truffle.js ทั่วโลก เพื่อให้คุณสามารถใช้งานได้ทุกที่ในสภาพแวดล้อมท้องถิ่นของคุณ หากคุณต้องการติดตั้งทั้งหมดพร้อมกัน ให้รันโค้ดต่อไปนี้ใน Terminal ของคุณ:
$ npm install nodemon truffle-contract dotenv mongodb shortid express web3 --save && npm install truffle -g
แฟ --save
คือการบันทึกชื่อแพ็กเกจในไฟล์ package.json แฟล็ก -g
คือการจัดเก็บแพ็กเกจนี้โดยเฉพาะทั่วโลก เพื่อให้เราสามารถนำไปใช้ในโปรเจ็กต์ใดๆ ที่เรากำลังดำเนินการอยู่
จากนั้นเราสร้างไฟล์ .env ซึ่งเราสามารถจัดเก็บ URI ลับฐานข้อมูล MongoDB ไว้ใช้งาน ทำได้โดยเรียกใช้ touch.env ในเทอร์มินัล หากคุณยังไม่มีบัญชีฐานข้อมูลกับ MongoDB ให้เริ่มที่หน้า MongoDB ก่อน
แพ็คเกจ dotenv ส่งออกตัวแปรที่เก็บไว้ของเราไปยังสภาพแวดล้อมกระบวนการ Node.js โปรดตรวจสอบให้แน่ใจว่าคุณไม่ได้ส่งไฟล์ .env เมื่อกดไปยังที่เก็บข้อมูลสาธารณะ เพื่อหลีกเลี่ยงไม่ให้รหัสผ่านและข้อมูลส่วนตัวของคุณรั่วไหล
ต่อไป เราต้องเพิ่มสคริปต์สำหรับขั้นตอนการสร้างและการพัฒนาของโครงการของเราในไฟล์ package.json ปัจจุบัน package.json ของเรามีลักษณะดังนี้:
{ "name": "test", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "socket.io": "^2.3.0", "truffle-contract": "^4.0.31", "web3": "^1.3.0" } }
จากนั้นเราจะเพิ่มสคริปต์เริ่มต้นลงในไฟล์ package.json เพื่อใช้เซิร์ฟเวอร์ nodemon เพื่อให้ทุกครั้งที่เราทำการเปลี่ยนแปลง เซิร์ฟเวอร์จะรีสตาร์ทเอง และสคริปต์สำหรับสร้างที่ใช้เซิร์ฟเวอร์โหนดโดยตรง อาจมีลักษณะดังนี้:
{ "name": "test", "version": "1.0.0", "description": "", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon server.js", "build": "node server.js" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.17.1", "socket.io": "^2.3.0", "truffle-contract": "^4.0.31", "web3": "^1.3.0" } }
ต่อไป เราต้องเริ่มต้นทรัฟเฟิลเพื่อใช้ในสัญญาอัจฉริยะของเราโดยใช้แพ็คเกจทรัฟเฟิลที่เราติดตั้งทั่วโลกก่อนหน้านี้ ในโฟลเดอร์เดียวกันของโปรเจ็กต์ของเรา เราเรียกใช้คำสั่งต่อไปนี้ด้านล่างในเทอร์มินัลของเรา:
$ truffle init
จากนั้นเราสามารถเริ่มเขียนโค้ดของเราในไฟล์ server.js ของเรา อีกครั้ง เรากำลังพยายามสร้างแอปร้านเพลงแบบกระจายศูนย์อย่างง่าย ซึ่งลูกค้าสามารถอัปโหลดเพลงเพื่อให้ผู้ใช้รายอื่นเข้าถึงและฟังได้
server.js ของเราควรจะสะอาดเพื่อให้สามารถเชื่อมต่อและแยกส่วนประกอบได้ง่าย ดังนั้นเราต์และฟังก์ชันอื่นๆ จะถูกใส่ไว้ในไฟล์อื่นๆ เช่น routes.js ตัวอย่าง server.js ของเราอาจเป็น:
require('dotenv').config(); const express= require('express') const app =express() const routes = require('./routes') const Web3 = require('web3'); const mongodb = require('mongodb').MongoClient const contract = require('truffle-contract'); app.use(express.json()) mongodb.connect(process.env.DB,{ useUnifiedTopology: true },(err,client)=>{ const db =client.db('Cluster0') //home routes(app,db) app.listen(process.env.PORT || 8082, () => { console.log('listening on port 8082'); }) })
โดยพื้นฐานแล้ว ด้านบนเรานำเข้าไลบรารีที่เราต้องการด้วย require
จากนั้นเพิ่มมิดเดิลแวร์ที่อนุญาตให้ใช้ JSON ใน API ของเราโดยใช้ app.use
จากนั้นเชื่อมต่อกับฐานข้อมูล MongoDB ของเราและรับการเข้าถึงฐานข้อมูล จากนั้นเราระบุว่าคลัสเตอร์ฐานข้อมูลใด เรากำลังพยายามเข้าถึง (สำหรับบทช่วยสอนนี้คือ “Cluster0” ) หลังจากนี้ เราเรียกใช้ฟังก์ชันและนำเข้าจาก ไฟล์ routes สุดท้าย เรารับฟังความพยายามในการเชื่อมต่อพอร์ต 8082
ไฟล์ server.js นี้เป็นเพียงแบร์โบนในการเริ่มต้นแอปพลิเคชัน สังเกตว่าเรานำเข้า routes.js ไฟล์นี้จะเก็บปลายทางของเส้นทางสำหรับ API ของเรา นอกจากนี้เรายังนำเข้าแพ็คเกจที่เราจำเป็นต้องใช้ในไฟล์ server.js และเริ่มต้นใช้งาน
เราจะสร้าง ปลายทางห้าจุด สำหรับการบริโภคของผู้ใช้:
- จุดสิ้นสุดการลงทะเบียนสำหรับการลงทะเบียนผู้ใช้ผ่านอีเมล ตามหลักการแล้ว เราจะใช้อีเมลและรหัสผ่าน แต่เนื่องจากเราเพียงต้องการระบุผู้ใช้แต่ละราย เราจะไม่เสี่ยงกับการรักษาความปลอดภัยรหัสผ่านและการแฮชเพื่อความกระชับของบทช่วยสอนนี้
POST /register Requirements: email
- เข้าสู่ระบบปลายทางสำหรับผู้ใช้ทางอีเมล
POST /login Requirements: email
- อัพโหลดปลายทางสำหรับผู้ใช้ — API ที่ได้รับข้อมูลของไฟล์เพลง ส่วนหน้าจะแปลงไฟล์ MP3/WAV เป็นบัฟเฟอร์เสียง และส่งบัฟเฟอร์นั้นไปยัง API
POST /upload Requirements: name, title of music, music file buffer or URL stored
- ปลายทางการเข้าถึงที่จะให้ข้อมูลบัฟเฟอร์เพลงแก่ผู้ใช้ที่ลงทะเบียนที่ร้องขอ และบันทึกว่าใครเข้าถึงมัน
GET /access/{email}/{id} Requirements: email, id
- เรายังต้องการให้สิทธิ์เข้าถึงคลังเพลงทั้งหมดและส่งคืนผลลัพธ์ไปยังผู้ใช้ที่ลงทะเบียน
GET /access/{email} Requirements: email
จากนั้นเราเขียนฟังก์ชันเส้นทางของเราในไฟล์ routes.js เราใช้คุณสมบัติการจัดเก็บฐานข้อมูลและการดึงข้อมูล จากนั้นตรวจสอบให้แน่ใจว่าเราส่งออกฟังก์ชันเส้นทางที่ส่วนท้ายของไฟล์เพื่อให้สามารถนำเข้าในไฟล์หรือโฟลเดอร์อื่นได้
const shortid = require('short-id') function routes(app, db){ app.post('/register', (req,res)=>{ let email = req.body.email let idd = shortid.generate() if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.status(400).json({"status":"Failed", "reason":"Already registered"}) }else{ db.insertOne({email}) res.json({"status":"success","id":idd}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/login', (req,res)=>{ let email = req.body.email if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.json({"status":"success","id":doc.id}) }else{ res.status(400).json({"status":"Failed", "reason":"Not recognised"}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/upload', (req,res)=>{ let buffer = req.body.buffer let name = req.body.name let title = req.body.title if(buffer && title){ }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.get('/access/:email/:id', (req,res)=>{ if(req.params.id && req.params.email){ }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) } module.exports = routes
ภายในฟังก์ชัน route
นี้ เรามีฟังก์ชันอื่นๆ มากมายที่เรียกว่าภายในพารามิเตอร์ app
และ db
นี่คือฟังก์ชันจุดปลาย API ที่ช่วยให้ผู้ใช้สามารถระบุปลายทางใน URL ในที่สุด เราเลือกหนึ่งในฟังก์ชันเหล่านี้เพื่อดำเนินการและให้ผลลัพธ์เป็นการตอบสนองต่อคำขอที่เข้ามา
เรามีฟังก์ชันปลายทางหลักสี่ฟังก์ชัน:
-
get
: สำหรับการอ่านบันทึกการดำเนินงาน -
post
: สำหรับสร้างบันทึกการทำงาน -
put
: สำหรับการอัพเดทการดำเนินการบันทึก -
delete
: สำหรับการลบการดำเนินการบันทึก
ในฟังก์ชัน routes
นี้ เราใช้การดำเนินการ get
และ post
เราใช้ post
สำหรับการลงทะเบียน เข้าสู่ระบบ และอัปโหลด และ get
การดำเนินการข้อมูล สำหรับคำอธิบายเพิ่มเติมเล็กน้อยเกี่ยวกับเรื่องนั้น คุณสามารถดูบทความของ Jamie Corkhill เรื่อง “How To Get Started With Node: An Introduction To APIs, HTTP And ES6+ JavaScript”
ในโค้ดด้านบน เราสามารถเห็นการทำงานของฐานข้อมูลบางอย่างเช่นในเส้นทางการ ลงทะเบียน เราเก็บอีเมลของผู้ใช้ใหม่ด้วย db.createa
และตรวจสอบอีเมลในฟังก์ชันการเข้าสู่ระบบด้วย db.findOne
ก่อนที่เราจะทำทุกอย่างได้ เราจำเป็นต้องตั้งชื่อคอลเลกชันหรือตารางด้วยเมธอด db.collection
นั่นคือสิ่งที่เราจะพูดถึงต่อไป
หมายเหตุ : หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการทำงานของฐานข้อมูลใน MongoDB ให้ตรวจสอบเอกสารประกอบ mongo Shell Methods
การสร้างสัญญาอัจฉริยะบล็อคเชนอย่างง่ายด้วยความแข็งแกร่ง
ตอนนี้เรากำลังจะเขียนสัญญาบล็อคเชนใน Solidity (นั่นคือภาษาที่เขียนสัญญาอัจฉริยะ) เพื่อจัดเก็บข้อมูลของเราและดึงข้อมูลเมื่อเราต้องการ ข้อมูลที่เราต้องการจัดเก็บคือข้อมูลไฟล์เพลง หมายความว่าเราต้องอัปโหลดเพลงไปยัง IPFS จากนั้นจึงเก็บที่อยู่ของบัฟเฟอร์ในบล็อกเชน
ขั้นแรก เราสร้างไฟล์ใหม่ในโฟลเดอร์สัญญาและตั้งชื่อเป็น Inbox.sol ในการเขียน smart contract การมีความเข้าใจ Solidity นั้นมีประโยชน์ แต่ก็ไม่ได้ยากเพราะคล้ายกับ JavaScript
หมายเหตุ : หากคุณสนใจที่จะเรียนรู้เพิ่มเติมเกี่ยวกับ Solidity ฉันได้เพิ่มแหล่งข้อมูลที่ด้านล่างของบทความเพื่อให้คุณเริ่มต้นได้
pragma solidity ^0.5.0; contract Inbox{ //Structure mapping (string=>string) public ipfsInbox; //Events event ipfsSent(string _ipfsHash, string _address); event inboxResponse(string response); //Modifiers modifier notFull (string memory _string) { bytes memory stringTest = bytes(_string); require(stringTest.length==0); _; } // An empty constructor that creates an instance of the conteact constructor() public{} //takes in receiver's address and IPFS hash. Places the IPFSadress in the receiver's inbox function sendIPFS(string memory _address, string memory _ipfsHash) notFull(ipfsInbox[_address]) public{ ipfsInbox[_address] = _ipfsHash; emit ipfsSent(_ipfsHash, _address); } //retrieves hash function getHash(string memory _address) public view returns(string memory) { string memory ipfs_hash=ipfsInbox[_address]; //emit inboxResponse(ipfs_hash); return ipfs_hash; } }
ในสัญญาของเรา เรามีฟังก์ชันหลักสองอย่าง: sendIPFS
และฟังก์ชัน getHash
ก่อนที่เราจะพูดถึงฟังก์ชัน เราจะเห็นได้ว่าเราต้องกำหนดสัญญาก่อนเรียกว่า Inbox
ภายในคลาสนี้ เรามีโครงสร้างที่ใช้ในอ็อบเจ็กต์ ipfsInbox
(เหตุการณ์แรก จากนั้นตัวแก้ไข)
หลังจากกำหนดโครงสร้างและเหตุการณ์แล้ว เราต้องเริ่มต้นสัญญาโดยเรียกใช้ฟังก์ชันตัว constructor
จากนั้นเรากำหนดสามฟังก์ชัน (ฟังก์ชัน checkInbox
ใช้ในการทดสอบผลการทดสอบ)
sendIPFS
เป็นที่ที่ผู้ใช้ป้อนตัวระบุและที่อยู่แฮชหลังจากนั้นจะถูกเก็บไว้ในบล็อกเชน ฟังก์ชัน getHash
จะดึงที่อยู่แฮชเมื่อได้รับตัวระบุ อีกครั้ง เหตุผลเบื้องหลังนี้คือเราต้องการจัดเก็บเพลงใน IPFS ในท้ายที่สุด ในการทดสอบว่ามันทำงานอย่างไร คุณสามารถเข้าสู่ Remix IDE คัดลอก วาง และทดสอบสัญญาของคุณ ตลอดจนแก้ไขข้อผิดพลาดและเรียกใช้อีกครั้ง (หวังว่าจะไม่จำเป็น!)
หลังจากทดสอบว่าโค้ดของเราทำงานอย่างถูกต้องในรีมิกซ์แล้ว เรามาทำการคอมไพล์ภายในเครื่องด้วยชุดทรัฟเฟิลกัน แต่ก่อนอื่น เราต้องทำการเปลี่ยนแปลงบางอย่างกับไฟล์ของเราและตั้งค่าโปรแกรมจำลองของเราโดยใช้ ganache-cli
:
ขั้นแรกให้ติดตั้ง ganache-cli
ในไดเร็กทอรีเดียวกัน ให้รันคำสั่งต่อไปนี้ในเทอร์มินัลของคุณ:
$ npm install ganache-cli -g
จากนั้นให้เปิด Terminal อื่นและเรียกใช้คำสั่งอื่นในโฟลเดอร์เดียวกัน:
$ ganache-cli
สิ่งนี้จะเริ่มต้นโปรแกรมจำลองสำหรับสัญญาบล็อคเชนของเราเพื่อเชื่อมต่อและทำงาน ย่อขนาด Terminal และดำเนินการต่อด้วย Terminal อื่นที่คุณใช้อยู่
ไปที่ไฟล์ truffle.js หากคุณใช้ Linux/Mac OS หรือ truffle-config.js ใน Windows และแก้ไขไฟล์นี้ให้มีลักษณะดังนี้:
const path = require("path"); module.exports = { // to customize your Truffle configuration! contracts_build_directory: path.join(__dirname, "/build"), networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*" //Match any network id } } };
โดยพื้นฐานแล้ว สิ่งที่เราทำคือการเพิ่มเส้นทางของโฟลเดอร์บิลด์ที่สัญญาอัจฉริยะถูกแปลงเป็นไฟล์ JSON จากนั้น เรายังระบุเครือข่ายที่ทรัฟเฟิลควรใช้สำหรับการย้ายข้อมูล
จากนั้นในโฟลเดอร์การ โยกย้าย ให้สร้างไฟล์ใหม่ชื่อ 2_migrate_inbox.js และเพิ่มรหัสต่อไปนี้ภายในไฟล์:
var IPFSInbox = artifacts.require("./Inbox.sol"); module.exports = function(deployer) { deployer.deploy(IPFSInbox); };
เราทำเช่นนั้นเพื่อรับไฟล์สัญญาและปรับใช้กับ deployer
โดยอัตโนมัติ โดยใช้ฟังก์ชันปรับใช้ระหว่างการย้าย Truffle
หลังจากการเปลี่ยนแปลงข้างต้น เราดำเนินการ:
$ truffle compile
เราควรจะเห็นข้อความบางส่วนแสดงการคอมไพล์สำเร็จ เช่น:
> Compiled successfully using: - solc: 0.5.16+commit.9c3226ce.Emscripten.clang
ต่อไป เราย้ายสัญญาของเราโดยดำเนินการ:
$ truffle migrate
เมื่อเราย้ายสัญญาของเราสำเร็จแล้ว เราควรมีสิ่งต่อไปนี้ในตอนท้าย:
Summary ======= > Total deployments: 1 > Final cost: 0.00973432 ETH
และเราใกล้จะเสร็จแล้ว! เราได้สร้าง API ของเราด้วย Node.js และยังตั้งค่าและสร้างสัญญาอัจฉริยะของเราอีกด้วย
เราควรเขียนการทดสอบสำหรับสัญญาของเราเพื่อทดสอบพฤติกรรมของสัญญาของเราและให้แน่ใจว่าเป็นพฤติกรรมที่ต้องการ การทดสอบมักจะเขียนและวางไว้ในโฟลเดอร์ test
ตัวอย่างการทดสอบที่เขียนในไฟล์ชื่อ InboxTest.js ที่ สร้างขึ้นในโฟลเดอร์ทดสอบคือ:
const IPFSInbox = artifacts.require("./Inbox.sol") contract("IPFSInbox", accounts =>{ it("emit event when you send a ipfs address", async()=>{ //ait for the contract const ipfsInbox = await IPFSInbox.deployed() //set a variable to false and get event listener eventEmitted = false //var event = () await ipfsInbox.ipfsSent((err,res)=>{ eventEmitted=true }) //call the contract function which sends the ipfs address await ipfsInbox.sendIPFS(accounts[1], "sampleAddress", {from: accounts[0]}) assert.equal(eventEmitted, true, "sending an IPFS request does not emit an event") }) })
ดังนั้นเราจึงทำการทดสอบโดยดำเนินการดังต่อไปนี้:
$ truffle test
มันทดสอบสัญญาของเรากับไฟล์ในโฟลเดอร์ ทดสอบ และแสดงจำนวนการทดสอบที่ผ่านและล้มเหลว สำหรับบทช่วยสอนนี้ เราควรจะได้รับ:
$ truffle test Using network 'development'. Compiling your contracts... =========================== > Compiling .\contracts\Inbox.sol > Artifacts written to C:\Users\Ademola\AppData\Local\Temp\test--2508-n0vZ513BXz4N > Compiled successfully using: — solc: 0.5.16+commit.9c3226ce.Emscripten.clang Contract: IPFSInbox √ emit event when you send an ipfs address (373ms) 1 passing (612ms)
การรวม Smart Contract เข้ากับ Backend API โดยใช้ Web3
ส่วนใหญ่เมื่อคุณดูบทช่วยสอน คุณจะเห็นแอปกระจายอำนาจที่สร้างขึ้นเพื่อรวมส่วนหน้าเข้ากับบล็อกเชนโดยตรง แต่มีบางครั้งที่จำเป็นต้องมีการรวมเข้ากับแบ็กเอนด์ เช่น เมื่อใช้แบ็คเอนด์ API และบริการของบุคคลที่สาม หรือเมื่อใช้บล็อคเชนเพื่อสร้าง CMS
การใช้ Web3 มีความสำคัญมากสำหรับสาเหตุนี้ เนื่องจากช่วยให้เราเข้าถึงโหนด Ethereum ระยะไกลหรือในพื้นที่และใช้ในแอปพลิเคชันของเรา ก่อนที่เราจะไปต่อ เราจะพูดถึงโหนด Ethereum ในพื้นที่และระยะไกล โหนดในเครื่องคือโหนดที่ปรับใช้บนระบบของเราด้วยโปรแกรมจำลอง เช่น ganache-cli
แต่โหนดระยะไกลเป็นโหนดที่ติดตั้งบน faucets/แพลตฟอร์มออนไลน์ เช่น ropsten หรือ rinkeby หากต้องการเจาะลึกลงไป คุณสามารถทำตามบทช่วยสอนเกี่ยวกับวิธีการปรับใช้ตามคำแนะนำ 5 นาที ในการปรับใช้สัญญาอัจฉริยะกับทรัฟเฟิลและรอปสเทน หรือคุณสามารถใช้ผู้ให้บริการกระเป๋าเงินทรัฟเฟิลและปรับใช้ผ่านวิธีที่ง่ายกว่าในการปรับใช้สัญญาอัจฉริยะของคุณ
เรากำลังใช้ ganache-cli
ในบทช่วยสอนนี้ แต่ถ้าเราปรับใช้บน ropsten เราควรคัดลอกหรือจัดเก็บที่อยู่สัญญาของเราไว้ที่ใดที่หนึ่งในไฟล์ .env ของเรา จากนั้นไปที่อัปเดตไฟล์ server.js , นำเข้า web3, นำเข้า สัญญาที่ย้ายมาและตั้งค่าอินสแตนซ์ Web3
require('dotenv').config(); const express= require('express') const app =express() const routes = require('./routes') const Web3 = require('web3'); const mongodb = require('mongodb').MongoClient const contract = require('truffle-contract'); const artifacts = require('./build/Inbox.json'); app.use(express.json()) if (typeof web3 !== 'undefined') { var web3 = new Web3(web3.currentProvider) } else { var web3 = new Web3(new Web3.providers.HttpProvider('https://localhost:8545')) } const LMS = contract(artifacts) LMS.setProvider(web3.currentProvider) mongodb.connect(process.env.DB,{ useUnifiedTopology: true }, async(err,client)=>{ const db =client.db('Cluster0') const accounts = await web3.eth.getAccounts(); const lms = await LMS.deployed(); //const lms = LMS.at(contract_address) for remote nodes deployed on ropsten or rinkeby routes(app,db, lms, accounts) app.listen(process.env.PORT || 8082, () => { console.log('listening on port '+ (process.env.PORT || 8082)); }) })
ในไฟล์ server.js เราตรวจสอบว่าอินสแตนซ์ web3 ได้รับการเตรียมใช้งานแล้วหรือไม่ หากไม่เป็นเช่นนั้น เราจะเริ่มต้นบนพอร์ตเครือข่ายที่เรากำหนดไว้ก่อนหน้านี้ ( 8545
) จากนั้น เราสร้างสัญญาตามไฟล์ JSON ที่ย้ายข้อมูลและแพ็คเกจ truffle-contract
และตั้งค่าผู้ให้บริการสัญญาเป็นผู้ให้บริการอินสแตนซ์ Web3 ซึ่งต้องได้รับการเริ่มต้นแล้วในตอนนี้
จากนั้นเรารับบัญชีโดย web3.eth.getAccounts
สำหรับขั้นตอนการพัฒนา เราเรียกฟังก์ชันที่ปรับใช้แล้วในคลาสสัญญาของเราที่ถาม ganache-cli
ซึ่งยังคงทำงานอยู่ เพื่อให้ที่อยู่ของสัญญาแก่เราใช้งานได้ แต่ถ้าเราปรับใช้สัญญาของเรากับโหนดระยะไกลแล้ว เราจะเรียกใช้ฟังก์ชันที่ป้อนที่อยู่เป็นอาร์กิวเมนต์ ฟังก์ชันตัวอย่างมีความคิดเห็นด้านล่างตัวแปร lms
ที่กำหนดไว้ในโค้ดด้านบนของเรา จากนั้นเราเรียกฟังก์ชัน routes
ที่ป้อนอินสแตนซ์ของแอป อินสแตนซ์ฐานข้อมูล อินสแตนซ์สัญญา ( lms
) และข้อมูลบัญชีเป็นอาร์กิวเมนต์ สุดท้าย เรารับฟังคำขอที่พอร์ต 8082
ในตอนนี้ เราควรติดตั้งแพ็คเกจ MongoDB แล้ว เพราะเรากำลังใช้ใน API ของเราเป็นฐานข้อมูล เมื่อทราบแล้ว เราจะไปยังหน้าเส้นทางซึ่งเราใช้วิธีการที่กำหนดไว้ในสัญญาเพื่อทำงานให้สำเร็จ เช่น การบันทึกและเรียกข้อมูลเพลง
ในท้ายที่สุด routes.js ของเราควรมีลักษณะดังนี้:
const shortid = require('short-id') const IPFS =require('ipfs-api'); const ipfs = IPFS({ host: 'ipfs.infura.io', port: 5001,protocol: 'https' }); function routes(app, dbe, lms, accounts){ let db= dbe.collection('music-users') let music = dbe.collection('music-store') app.post('/register', (req,res)=>{ let email = req.body.email let idd = shortid.generate() if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.status(400).json({"status":"Failed", "reason":"Already registered"}) }else{ db.insertOne({email}) res.json({"status":"success","id":idd}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/login', (req,res)=>{ let email = req.body.email if(email){ db.findOne({email}, (err, doc)=>{ if(doc){ res.json({"status":"success","id":doc.id}) }else{ res.status(400).json({"status":"Failed", "reason":"Not recognised"}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.post('/upload', async (req,res)=>{ let buffer = req.body.buffer let name = req.body.name let title = req.body.title let id = shortid.generate() + shortid.generate() if(buffer && title){ let ipfsHash = await ipfs.add(buffer) let hash = ipfsHash[0].hash lms.sendIPFS(id, hash, {from: accounts[0]}) .then((_hash, _address)=>{ music.insertOne({id,hash, title,name}) res.json({"status":"success", id}) }) .catch(err=>{ res.status(500).json({"status":"Failed", "reason":"Upload error occured"}) }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.get('/access/:email', (req,res)=>{ if(req.params.email){ db.findOne({email: req.body.email}, (err,doc)=>{ if(doc){ let data = music.find().toArray() res.json({"status":"success", data}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) app.get('/access/:email/:id', (req,res)=>{ let id = req.params.id if(req.params.id && req.params.email){ db.findOne({email:req.body.email},(err,doc)=>{ if(doc){ lms.getHash(id, {from: accounts[0]}) .then(async(hash)=>{ let data = await ipfs.files.get(hash) res.json({"status":"success", data: data.content}) }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) }else{ res.status(400).json({"status":"Failed", "reason":"wrong input"}) } }) } module.exports = routes
At the beginning of the routes file, we imported the short-id
package and ipfs-http-client
and then initialized IPFS with the HTTP client using the backend URL ipfs.infura.io
and port 5001
. This allowed us to use the IPFS methods to upload and retrieve data from IPFS (check out more here).
In the upload route, we save the audio buffer to IPFS which is better compared to just storing it on the blockchain for anyone registered or unregistered to use. Then we saved the address of the buffer in the blockchain by generating an ID and using it as an identifier in the sendIFPS
function. Finally, then we save all the other data associated with the music file to our database. We should not forget to update our argument in the routes function since we changed it in the server.js file.
In the access route using id
, we then retrieve our data by getting the id
from the request, using the id
to access the IPFS hash address, and then access the audio buffer using the address. But this requires authentication of a user by email which is done before anything else.
Phew, we're done ! Right now we have an API that can receive requests from users, access a database, and communicate to a node that has the software running on them. We shouldn't forget that we have to export our function with module.exports
though!
As we have noticed, our app is a decentralized app . However, it's not fully decentralized as we only stored our address data on the blockchain and every other piece of data was stored securely in a centralized database which is the basis for semi-dApps . So the consumption of data can be done directly via request or using a frontend application in JavaScript to send fetch requests.
Our music store backend app can now safely store music data and provide access to anyone who needs to access it, provided it is a registered user. Using blockchain for music sharing makes it cheaper to store music data while focusing on connecting artists directly with users, and perhaps it could help them generate revenue that way. This wouldn't require a middleman that uses royalty; instead, all of the revenue would go to the artist as users request their music to either download or stream. A good example of a music streaming application that uses blockchain just like this is Opus OPUS: Decentralized music sharing platform. However, there are also a few others like Musicoin, Audius, and Resonate.
อะไรต่อไป?
The final thing after coding is to start our server by running npm run start
or npm run build
and test our backend endpoints on either the browser or with Postman. After running and testing our API we could add more features to our backend and blockchain smart contract. If you'd like to get more guidance on that, please check the further reading section for more articles.
It's worth mentioning that it is critical to write unit and integration tests for our API to ensure correct and desirable behaviors. Once we have all of that done, we can deploy our application on the cloud for public use. This can be done on its own with or without adding a frontend (microservices) on Heroku, GCP, or AWS for public use. Happy coding!
Note : You can always check my repo for reference. Also, please note that the .env file containing the MongoDB database URI is included for security reasons.
Further Reading And Related Resources
- “How to Build Ethereum Dapp with React.js: Complete Step-By-Step Guide,” Gregory McCubbin
- “Ethereum + IPFS + React DApp Tutorial Pt. 1,” Alexander Ma
- “Ethereum Development with Go,” Miguel Mota
- “Create your first Ethereum dAPP with Web3 and Vue.JS (Part 1),” Nico Vergauwen
- “Deploy a Smart Contract on Ethereum with Python, Truffle and web3py,” Gabriel Saldanha
- “Why Use Blockchain Technology?,” Bernard Marr
- “How To Build Your Own Blockchain Using Node.js,” DevTeam.Space
- “How To Build A Blockchain App With Ethereum, Web3.js & Solidity Smart Contracts,” Gregory McCubbin
- “How To Build A Simple Cryptocurrency Blockchain In Node.js,” Alfrick Opidi
- “How Blockchain Technology Is Going To Revolutionize Ecommerce,” Sergii Shanin
- “4 Ways Blockchain Will Transform Higher Education — Smarter With Gartner,” Susan Moore
- “How To Learn Solidity: The Ultimate Ethereum Coding Tutorial,” Ryan Molecke
- “Developing Ethereum Smart Contracts For Beginners,” Coursetro
- “Learn about Ethereum,” Ethereum official site