การวิเคราะห์เชิงลึกเกี่ยวกับการพัฒนาสัญญาอัจฉริยะ: การศึกษาเปรียบเทียบของ Move and Rust
ชื่อเรื่องเดิม: "Smart Contract Development—Move vs.Rust》
รวบรวมข้อความต้นฉบับ: Guo Qianwen, Chain Catcher
รวบรวมข้อความต้นฉบับ: Guo Qianwen, Chain Catcher
ชื่อระดับแรก
1. บทนำ
เมื่อเร็ว ๆ นี้ การอภิปรายเกี่ยวกับ Aptos และ Sui ดำเนินไปอย่างเต็มรูปแบบ ทั้งสองเป็นเครือข่ายสาธารณะ L1 ที่มีประสิทธิภาพสูงที่เกิดขึ้นใหม่ ภาษาโปรแกรม Move smart contract เป็นส่วนสำคัญที่ขาดไม่ได้ของเครือข่ายใหม่เหล่านี้ นักพัฒนาบางรายหันมาใช้ Move โดยประกาศว่าเป็นอนาคตของการพัฒนาสัญญาอัจฉริยะ คนอื่น ๆ ระมัดระวังมากขึ้นโดยโต้แย้งว่า Move ไม่สามารถนำเสนอสิ่งที่ใหม่เกินไปเมื่อเทียบกับภาษาโปรแกรมที่มีอยู่
นักลงทุนด้านการเข้ารหัสยังสงสัยว่าเครือข่ายสาธารณะ L1 ที่ไม่ซ้ำใครสามารถแข่งขันกับ Solana ซึ่งปัจจุบันเป็นผู้เล่นหลักใน L1 ประสิทธิภาพสูงและเป็นที่รู้จักกันดีในการใช้ Rust เป็นโปรแกรมสัญญาอัจฉริยะ
แต่การอภิปรายที่เราได้เห็นจนถึงขณะนี้ยังไม่ถึงระดับที่แน่นอน และเราสามารถเข้าใจได้อย่างแท้จริงถึงผลกระทบของเทคโนโลยีใหม่เหล่านี้ที่มีต่อเรา สิ่งนี้ใช้ได้กับทั้งสองขั้วของการสนทนา - ผู้ที่มีความคลางแคลงใจ Move ไม่สนใจ Move ว่าไม่มีอะไรและไม่ได้ชื่นชมด้านที่ละเอียดกว่า (แต่สำคัญ) แต่ผู้เสนอ Move ที่ตื่นเต้นกับ Move มากเกินไปกลับมองไม่เห็นว่าอะไรคือสิ่งที่ทำให้มันยอดเยี่ยม สิ่งนี้นำมาซึ่งความเป็นกลางและความคลุมเครืออย่างมาก ทำให้ผู้ชมภายนอก ผู้พัฒนาการเข้ารหัส และนักลงทุนให้ความสนใจกับหัวข้อนี้ แต่พวกเขาไม่แน่ใจในมุมมองของตนเอง
ในโพสต์นี้ ฉันจะเจาะลึกทางเทคนิคเกี่ยวกับ Move โมเดลการเขียนโปรแกรมแบบใหม่ Sui blockchain และวิธีใช้ประโยชน์จากพลังของ Move และวิธีเปรียบเทียบกับ Solana และรูปแบบการเขียนโปรแกรมของมัน เพื่อเน้นคุณลักษณะของ Move ฉันจะเปรียบเทียบ Solana/Rust กับ Sui/Move เพราะการทำความเข้าใจจะง่ายขึ้นเมื่อคุณเปรียบเทียบสิ่งหนึ่งกับอีกสิ่งหนึ่งที่คุณคุ้นเคยมี Move ในรูปแบบอื่นๆ เช่น Aptos Move ซึ่งจะแตกต่างกันเล็กน้อยในบางประการ ประเด็นของบทความนี้ไม่ใช่เพื่อหารือเกี่ยวกับความแตกต่างเล็กน้อยระหว่างรุ่นต่างๆ ของ Move แต่เพื่อแสดงข้อดีทั่วไปของ Move และวิธีเปรียบเทียบกับรูปแบบการเขียนโปรแกรม Solana ดังนั้นเพื่อความง่าย ฉันใช้ตัวแปรเดียว (Sui Move) ในบทความนี้ ดังนั้นฉันเป็นแต่ถึงกระนั้น ประโยชน์หลักๆ ทั้งหมดของ Move ที่กล่าวถึงในบทความนี้ก็นำไปใช้กับการรวม Move ทั้งหมด (ซึ่งสนับสนุน Move bytecode แบบเนทีฟ) รวมถึง Aptos ฉันเลือกซุยเพราะฉันคุ้นเคยกับมันมากกว่า และฉันคิดว่าการนำเสนอในรูปแบบของบทความนั้นเป็นธรรมชาติและง่ายกว่า
ชื่อระดับแรก
2. แบบจำลองการเขียนโปรแกรม Solana
บน Solana โปรแกรม (สัญญาอัจฉริยะ) จะไม่มีสถานะและไม่สามารถเข้าถึง (อ่านหรือเขียน) สถานะใด ๆ ที่ยังคงอยู่ในการทำธุรกรรม ในการเข้าถึงหรือรักษาสถานะ โปรแกรมจำเป็นต้องใช้บัญชี แต่ละบัญชีมีที่อยู่เฉพาะ (คีย์สาธารณะของคู่คีย์ Ed25519) ซึ่งสามารถจัดเก็บข้อมูลโดยพลการ
เราสามารถนึกถึงพื้นที่บัญชีของ Solana เป็นที่เก็บคีย์-ค่าส่วนกลาง โดยที่คีย์คือที่อยู่บัญชี (pubkey) และค่าคือข้อมูลบัญชี โปรแกรมทำงานในที่เก็บคีย์-ค่านี้โดยการอ่านและแก้ไขค่า
บัญชีมีความคิดของความเป็นเจ้าของ แต่ละบัญชีเป็นเจ้าของโดยโปรแกรมหนึ่งโปรแกรม (และโปรแกรมเดียวเท่านั้น) เมื่อบัญชีเป็นของโปรแกรม โปรแกรมนั้นจะได้รับอนุญาตให้แก้ไขข้อมูลได้ โปรแกรมไม่สามารถแก้ไขบัญชีที่ไม่ได้เป็นเจ้าของ (แต่ได้รับอนุญาตให้อ่านได้) ระหว่างการดำเนินการ การตรวจสอบแบบไดนามิกประเภทนี้สามารถทำได้โดยการเปรียบเทียบสถานะบัญชีก่อนและหลังการดำเนินการของโปรแกรม หากมีการดัดแปลงที่ผิดกฎหมาย การทำธุรกรรมจะล้มเหลว
แต่ละบัญชียังมีคีย์ส่วนตัวที่เชื่อมโยงอยู่ด้วย (คีย์สาธารณะที่เกี่ยวข้องคือที่อยู่ของบัญชี) และผู้ใช้ที่มีสิทธิ์เข้าถึงคีย์ส่วนตัวนี้จะสามารถใช้คีย์ดังกล่าวเพื่อลงนามธุรกรรมได้ การใช้กลไกนี้ เราใช้สิทธิ์และฟังก์ชันความเป็นเจ้าของในสัญญาอัจฉริยะของ Solana ตัวอย่างเช่น เพื่อให้ได้เงินทุนบางอย่าง สัญญาอัจฉริยะอาจกำหนดให้ผู้ใช้ระบุลายเซ็นที่จำเป็น
เมื่อเรียกใช้โปรแกรมอื่น ลูกค้าจำเป็นต้องระบุว่าบัญชีใดที่โปรแกรมจะเข้าถึงเมื่อโทร ด้วยวิธีนี้ รันไทม์การประมวลผลธุรกรรมสามารถกำหนดเวลาธุรกรรมที่ไม่ทับซ้อนกันเพื่อดำเนินการแบบคู่ขนานในขณะเดียวกันก็รับประกันความสอดคล้องของข้อมูล นี่เป็นหนึ่งในคุณสมบัติการออกแบบของ Solana ที่ทำให้มีปริมาณงานสูง
โปรแกรมสามารถเรียกโปรแกรมอื่นผ่านการเรียก CPI การโทรเหล่านี้ทำงานโดยทั่วไปเหมือนกับการโทรจากลูกค้า - โปรแกรมผู้โทรจำเป็นต้องระบุบัญชีที่โปรแกรมผู้โทรจะเข้าถึง และโปรแกรม callee จะทำการตรวจสอบอินพุต เช่นเดียวกับการโทรจากลูกค้า (เนื่องจากไม่ไว้วางใจ โปรแกรมโทรออก)
สิ่งเหล่านี้เป็นองค์ประกอบพื้นฐานของการเขียนโปรแกรมสัญญาอัจฉริยะที่ปลอดภัยบน Solana ในระดับหนึ่ง คุณอาจคิดว่าโปรแกรม Solana เป็นโปรแกรมในระบบปฏิบัติการและบัญชีเป็นไฟล์ ใครๆ ก็สามารถเรียกใช้โปรแกรมได้อย่างอิสระและแม้แต่ปรับใช้โปรแกรมของตนเอง เมื่อโปรแกรม (สัญญาอัจฉริยะ) ทำงาน โปรแกรมจะอ่านและเขียนไฟล์ (บัญชี) ไฟล์ทั้งหมดสามารถอ่านได้โดยทุกโปรแกรม แต่เฉพาะโปรแกรมที่มีสิทธิ์เป็นเจ้าของไฟล์เท่านั้นที่สามารถเขียนได้ โปรแกรมยังสามารถเรียกใช้โปรแกรมอื่นๆ ได้ แต่โปรแกรมเหล่านี้ไม่มีความเชื่อใจซึ่งกันและกัน -- ใครก็ตามที่เรียกใช้โปรแกรมต้องถือว่าอินพุตนั้นอาจเป็นอันตราย เนื่องจากระบบปฏิบัติการนี้สามารถเข้าถึงได้โดยทุกคนทั่วโลก การสนับสนุนการตรวจสอบลายเซ็นแบบเนทีฟจึงถูกสร้างขึ้นในโปรแกรมเพื่อใช้การอนุญาตและฟังก์ชันความเป็นเจ้าของสำหรับผู้ใช้... ไม่ใช่การเปรียบเทียบที่สมบูรณ์แบบ แต่ก็น่าสนใจ
ชื่อระดับแรก
3. รูปแบบการเขียนโปรแกรมของ Move
ใน Solana สิ่งนี้เทียบเท่ากับการเผยแพร่สัญญาอัจฉริยะทั้งหมดเป็นโมดูลในโปรแกรม ซึ่งหมายความว่าสัญญาอัจฉริยะ (โมดูล) ทั้งหมดรวมอยู่ในระบบคลาสเดียวกันและสามารถโทรหากันได้โดยตรงโดยไม่ต้องผ่าน API หรืออินเทอร์เฟซระดับกลาง สิ่งนี้สำคัญมากและจะมีการกล่าวถึงความหมายของมันอย่างละเอียดในบทความนี้
ชื่อเรื่องรอง
3.1 วัตถุ
โปรดทราบว่าแนวคิดของอ็อบเจกต์ด้านล่างนั้นเฉพาะกับตัวแปร Sui ของ Move ในการผสานรวมอื่นๆ ของ Move (เช่น Aptos หรือ Diem/core Move) สถานการณ์อาจแตกต่างออกไปเล็กน้อย อย่างไรก็ตาม มีโซลูชันที่คล้ายกันในรุ่น Move อื่นๆ ที่บรรลุสิ่งเดียวกัน (การคงอยู่ของสถานะ) ซึ่งไม่แตกต่างกันมากนัก
เหตุผลหลักในการแนะนำตัวแปร Sui ที่นี่คือตัวอย่างโค้ดในบทความต่อไปล้วนอิงตามตัวแปร Sui ของ Move และออบเจกต์เช่นกลไกการจัดเก็บข้อมูลส่วนกลางใน Core Move นั้นใช้งานง่ายและเข้าใจง่ายกว่า ที่สำคัญ ประโยชน์หลักทั้งหมดของ Move ที่กล่าวถึงในบทความนี้นำไปใช้กับการรวม Move ทั้งหมด (ซึ่งรองรับ Move bytecode แบบเนทีฟ) รวมถึง Aptos
อ็อบเจกต์คืออินสแตนซ์โครงสร้างที่จัดเก็บโดยรันไทม์และคงอยู่ในสถานะตลอดธุรกรรม
มีวัตถุสามประเภทที่แตกต่างกัน (ในซุย):
วัตถุที่เป็นเจ้าของ
วัตถุที่ใช้ร่วมกัน
วัตถุที่ไม่เปลี่ยนรูป
วัตถุที่เป็นเจ้าของคือวัตถุที่เป็นของผู้ใช้ เฉพาะผู้ใช้ที่เป็นเจ้าของวัตถุเท่านั้นที่สามารถใช้ในการทำธุรกรรมได้ ข้อมูลเมตาของการเป็นเจ้าของมีความโปร่งใสอย่างสมบูรณ์และได้รับการจัดการโดยรันไทม์ มีการนำไปใช้โดยใช้การเข้ารหัสคีย์สาธารณะ - แต่ละอ็อบเจ็กต์ของตัวเองเชื่อมโยงกับคีย์สาธารณะ (เก็บไว้ในข้อมูลเมตาของออบเจกต์ขณะรันไทม์) และเมื่อใดก็ตามที่คุณต้องการใช้อ็อบเจกต์ในธุรกรรม คุณต้องระบุลายเซ็นที่เกี่ยวข้อง (ตอนนี้รองรับ Ed25519 ซึ่งจะรองรับ ECDSA และ K-of-N แบบหลายลายเซ็นในเร็วๆ นี้)
วัตถุที่ใช้ร่วมกันนั้นคล้ายกับวัตถุที่เป็นเจ้าของ แต่ไม่มีเจ้าของที่เชื่อมโยงกับวัตถุนั้น ดังนั้นคุณไม่จำเป็นต้องเป็นเจ้าของคีย์ส่วนตัวเพื่อใช้ในการทำธุรกรรม (ทุกคนสามารถใช้คีย์เหล่านี้ได้) วัตถุใดๆ ของตัวเองสามารถแบ่งปันได้ (โดยเจ้าของวัตถุนั้น) และเมื่อวัตถุถูกแบ่งปันแล้ว วัตถุนั้นจะยังคงแบ่งปันตลอดไป - วัตถุนั้นจะไม่สามารถถ่ายโอนหรือกลายเป็นวัตถุของตัวเองได้อีก
โมเดลการเขียนโปรแกรม Move นั้นใช้งานง่ายและเรียบง่ายมาก สัญญาอัจฉริยะแต่ละรายการเป็นโมดูลที่ประกอบด้วยคำจำกัดความของฟังก์ชันและโครงสร้าง โครงสร้างถูกสร้างอินสแตนซ์ในฟังก์ชันและสามารถส่งผ่านไปยังโมดูลอื่นๆ ผ่านการเรียกใช้ฟังก์ชัน ในการทำให้โครงสร้างคงอยู่ตลอดการทำธุรกรรม เราทำให้เป็นออบเจกต์ที่สามารถเป็นเจ้าของ แบ่งปัน หรือเปลี่ยนแปลงไม่ได้ (เฉพาะ Sui เท่านั้น แตกต่างเล็กน้อยในรุ่น Move อื่นๆ)
ชื่อระดับแรก
4. ความปลอดภัยของการย้าย
เราได้เห็นสิ่งนั้นใน Move:
คุณสามารถส่งวัตถุใดๆ ที่คุณเป็นเจ้าของ (หรือแชร์) ไปยังฟังก์ชันใดก็ได้ในโมดูลใดก็ได้
ทุกคนสามารถเผยแพร่โมดูล (อาจเป็นศัตรู) ได้
ไม่มีแนวคิดเกี่ยวกับโครงสร้างที่เป็นเจ้าของโมดูล ซึ่งจะให้อำนาจแก่เจ้าของโมดูลแต่เพียงผู้เดียวในการเปลี่ยนแปลงโครงสร้าง เช่นเดียวกับในกรณีของบัญชี Solana - โครงสร้างสามารถไหลเข้าสู่โมดูลอื่นหรือฝังอยู่ในโครงสร้างอื่น
คำถามคือเหตุใดการปฏิบัตินี้จึงปลอดภัย อะไรที่ทำให้ผู้คนไม่สามารถโพสต์โมดูลที่เป็นอันตราย นำวัตถุที่ใช้ร่วมกัน (เช่น พูล AMM) ส่งไปยังโมดูลที่เป็นอันตราย และดำเนินการระบายเงินของพวกเขาต่อไป
นั่นคือความแปลกใหม่ของ Move... เรามาพูดถึงทรัพยากรกัน
ชื่อเรื่องรอง
4.1 โครงสร้าง

การกำหนดประเภทโครงสร้างเป็นสิ่งที่คุณคาดหวัง:
ดีมาก - เป็นวิธีที่คุณกำหนดโครงสร้างใน Rust แต่ใน Move โครงสร้างจะไม่ซ้ำกันเมื่อเทียบกับภาษาการเขียนโปรแกรมแบบดั้งเดิม โมดูล Move มีพื้นที่มากกว่าในการใช้ประเภทต่างๆ โครงสร้างที่กำหนดไว้ในข้อมูลโค้ดด้านบนจะอยู่ภายใต้ข้อจำกัดต่อไปนี้:
สามารถสร้างอินสแตนซ์ ("แพ็ค") และทำลาย ("คลายแพ็ก") ได้ภายในโมดูลที่กำหนดโครงสร้าง นั่นคือ คุณไม่สามารถสร้างอินสแตนซ์หรือทำลายอินสแตนซ์ของโครงสร้างจากฟังก์ชันใดๆ ในโมดูลอื่นได้
ฟิลด์ของอินสแตนซ์ struct สามารถเข้าถึงได้ (และสามารถเปลี่ยนแปลงได้) ภายในโมดูลเท่านั้น
ไม่สามารถโคลนหรือคัดลอกอินสแตนซ์ struct ภายนอกโมดูลได้
ไม่สามารถจัดเก็บอินสแตนซ์ struct ในฟิลด์ของอินสแตนซ์ struct อื่นได้
ซึ่งหมายความว่าหากเราจัดการกับอินสแตนซ์ของโครงสร้างนี้ในฟังก์ชันของโมดูลอื่น เราจะไม่สามารถเปลี่ยนแปลงฟิลด์ของมัน โคลนมัน เก็บไว้ในฟิลด์ของโครงสร้างอื่น หรือทิ้งมัน (จะต้องผ่านการเรียกฟังก์ชันไปยังโมดูลอื่น สถานที่). นี่คือสิ่งที่: โมดูลของโครงสร้างใช้ฟังก์ชันที่สามารถเรียกใช้จากโมดูลของเราเพื่อทำสิ่งเหล่านี้ แต่นอกเหนือจากนั้นเราไม่สามารถทำสิ่งเหล่านี้กับประเภทภายนอกได้โดยตรง สิ่งนี้ทำให้โมดูลสามารถควบคุมวิธีการใช้และไม่ใช้ประเภทของโมดูลได้อย่างสมบูรณ์
ดูเหมือนว่าเราจะสูญเสียความยืดหยุ่นไปมากเนื่องจากข้อจำกัดเหล่านี้ นี่เป็นเรื่องจริงเช่นกัน - ในการเขียนโปรแกรมแบบดั้งเดิม การจัดการกับโครงสร้างดังกล่าวจะยุ่งยากมาก แต่อันที่จริงแล้ว นี่คือสิ่งที่เราต้องการในสัญญาอัจฉริยะ ท้ายที่สุดแล้วการพัฒนาสัญญาอัจฉริยะนั้นเกี่ยวกับการเขียนโปรแกรมสินทรัพย์ดิจิทัล (ทรัพยากร) หากคุณดูโครงสร้างที่อธิบายไว้ข้างต้น นั่นคือสิ่งที่เป็นอยู่ นั่นคือทรัพยากร ไม่สามารถสร้างขึ้นจากอากาศได้ตามต้องการ ไม่สามารถลอกเลียนแบบได้ และไม่สามารถทำลายโดยไม่ได้ตั้งใจได้ ดังนั้นเราจึงสูญเสียความยืดหยุ่นบางส่วนไป แต่ความยืดหยุ่นที่เราสูญเสียไปคือสิ่งที่เราต้องการอย่างแท้จริง เนื่องจากสิ่งนี้ทำให้การจัดการทรัพยากรทำได้ง่ายและปลอดภัย

นอกจากนี้ Move ยังช่วยให้เราสามารถผ่อนคลายข้อจำกัดเหล่านี้ได้ด้วยการเพิ่มความสามารถให้กับโครงสร้าง มีความสามารถสี่ประการ: คีย์ จัดเก็บ คัดลอก และลบ คุณสามารถเพิ่มการผสมผสานของความสามารถเหล่านี้เข้ากับโครงสร้างได้
นี่คือสิ่งที่พวกเขาทำ:
คีย์ - อนุญาตให้โครงสร้างเป็นวัตถุ (เฉพาะสำหรับ Sui, กรณีการย้ายหลักจะแตกต่างกันเล็กน้อย) ดังที่ได้กล่าวไว้ก่อนหน้านี้ อ็อบเจ็กต์จะคงอยู่ และหากเป็นอ็อบเจ็กต์ที่เป็นเจ้าของเอง ผู้ใช้จำเป็นต้องเซ็นชื่อออบเจ็กต์ก่อนจึงจะสามารถใช้ในการเรียกสัญญาอัจฉริยะได้ เมื่อใช้ความสามารถของคีย์ ฟิลด์แรกของโครงสร้างต้องเป็น ID อ็อบเจ็กต์ที่มีประเภท UID สิ่งนี้จะให้รหัสเฉพาะทั่วโลกที่สามารถอ้างอิงได้
ที่เก็บข้อมูล - อนุญาตให้ฝังโครงสร้างเป็นฟิลด์ในโครงสร้างอื่น
คัดลอก - อนุญาตให้คัดลอก / โคลนโครงสร้างโดยพลการจากทุกที่
โดยพื้นฐานแล้ว ทุกโครงสร้างใน Move เป็นทรัพยากรเริ่มต้น ความสามารถทำให้เรามีอำนาจในการผ่อนคลายข้อจำกัดเหล่านี้อย่างประณีตเพื่อให้มีลักษณะเหมือนโครงสร้างแบบดั้งเดิมมากขึ้น
ชื่อเรื่องรอง
4.2 เหรียญ

คุณสามารถค้นหาการใช้งานโมดูลที่สมบูรณ์ได้ในที่เก็บรหัส Sui (ลิงค์)。
ลิงค์
ประเภทเหรียญมีฟังก์ชั่นกุญแจและการจัดเก็บ คีย์หมายความว่าพร้อมใช้งานเป็นวัตถุ สิ่งนี้ทำให้ผู้ใช้สามารถเป็นเจ้าของเหรียญได้โดยตรง (เป็นวัตถุระดับบนสุด) เมื่อคุณเป็นเจ้าของเหรียญ จะไม่มีใครสามารถอ้างอิงในการทำธุรกรรมได้ (นับประสาอะไรกับการใช้จ่าย) ยกเว้นคุณ ที่เก็บข้อมูลหมายความว่าสามารถฝังเหรียญเป็นฟิลด์ในโครงสร้างอื่นได้ ซึ่งมีประโยชน์สำหรับความสามารถในการจัดองค์ประกอบ
เนื่องจากไม่มีฟังก์ชันการทิ้งเหรียญ จึงไม่สามารถทิ้ง (ทำลาย) เหรียญโดยไม่ตั้งใจภายในฟังก์ชันได้ นี่เป็นคุณลักษณะที่ดีมาก หมายความว่าคุณจะไม่ทำเหรียญหายโดยไม่ตั้งใจ หากคุณกำลังใช้งานฟังก์ชันที่รับเหรียญเป็นพารามิเตอร์ ในตอนท้ายของฟังก์ชัน คุณต้องทำบางอย่างกับมันอย่างชัดเจน - ถ่ายโอนไปยังผู้ใช้ ฝังไว้ในวัตถุอื่น หรือส่งไปยังวัตถุอื่นโดยเรียก ฟังก์ชั่น (ซึ่งต้องทำอะไรกับมันอีกครั้ง) แน่นอน มันเป็นไปได้ที่จะเบิร์นเหรียญโดยการเรียกฟังก์ชั่น coin::burn ในโมดูลเหรียญ แต่คุณต้องทำอย่างตั้งใจ (คุณไม่สามารถทำได้โดยไม่ได้ตั้งใจ)
ไม่มีความสามารถในการโคลนหมายความว่าไม่มีใครสามารถทำซ้ำเหรียญได้ สร้างอุปทานใหม่ขึ้นมาจากอากาศที่เบาบาง การสร้างอุปทานใหม่สามารถทำได้ด้วยฟังก์ชัน coin::mint และสามารถเรียกได้โดยเจ้าของออบเจกต์คลังของเหรียญเท่านั้น
ในการย้าย ความปลอดภัยของทรัพยากรถูกกำหนดโดยประเภทของทรัพยากรนั้น เนื่องจาก Move มีระบบประเภทส่วนกลาง สิ่งนี้ทำให้รูปแบบการเขียนโปรแกรมเป็นธรรมชาติและปลอดภัยยิ่งขึ้น ซึ่งทรัพยากรสามารถส่งเข้าและออกจากรหัสที่ไม่น่าเชื่อถือได้โดยตรง
ชื่อเรื่องรอง
4.3 การตรวจสอบ Bytecode
ดังที่ได้กล่าวไว้ก่อนหน้านี้ สัญญาอัจฉริยะสำหรับอุปกรณ์เคลื่อนที่ได้รับการเผยแพร่เป็นโมดูล ทุกคนได้รับอนุญาตให้สร้างและอัปโหลดโมดูลใด ๆ ตามอำเภอใจไปยัง blockchain เพื่อดำเนินการโดยใครก็ได้ เรายังเห็นว่า Move มีกฎสำหรับการใช้โครงสร้าง
ดังนั้น อะไรรับประกันว่าโมดูลใด ๆ ปฏิบัติตามกฎเหล่านี้ อะไรที่ทำให้ผู้คนไม่สามารถอัปโหลดโมดูลด้วย bytecode ที่สร้างขึ้นมาเป็นพิเศษ เช่น การรับวัตถุที่เป็นเหรียญ แล้วแปลงฟิลด์ภายในโดยตรงเพื่อข้ามกฎเหล่านี้ การทำเช่นนี้สามารถเพิ่มจำนวนเหรียญทั้งหมดได้อย่างผิดกฎหมาย ไวยากรณ์ของ bytecode เพียงอย่างเดียวอนุญาตอย่างแน่นอน
การตรวจสอบ Bytecode สามารถช่วยป้องกันการละเมิดประเภทนี้ได้ Move Verifier เป็นเครื่องมือวิเคราะห์แบบสแตติกที่วิเคราะห์ Move bytecode และพิจารณาว่าเป็นไปตามประเภทที่จำเป็น หน่วยความจำ และกฎความปลอดภัยของทรัพยากรหรือไม่ โค้ดทั้งหมดที่อัปโหลดไปยังเชนจำเป็นต้องผ่านตัวตรวจสอบความถูกต้อง เมื่อคุณพยายามอัปโหลดโมดูล Move ไปยังเชน โหนดและตัวตรวจสอบความถูกต้องจะทำงานผ่านตัวตรวจสอบความถูกต้องก่อนจึงจะอนุญาตให้ส่งได้ หากโมดูลใดพยายามข้ามกฎความปลอดภัยของ Move โมดูลนั้นจะถูกปฏิเสธโดยโปรแกรมตรวจสอบและจะไม่เผยแพร่
Move bytecode และตัวตรวจสอบคือนวัตกรรมหลักของ Move มันใช้รูปแบบการเขียนโปรแกรมที่เน้นทรัพยากรที่ใช้งานง่ายซึ่งไม่สามารถทำได้ในที่อื่น สิ่งสำคัญที่สุดคือช่วยให้ประเภทที่มีโครงสร้างสามารถข้ามขอบเขตความน่าเชื่อถือได้โดยไม่สูญเสียความสมบูรณ์
ในการย้าย ประเภทมีอยู่ทั่วทั้งโมดูล - ระบบประเภทเป็นส่วนกลาง ซึ่งหมายความว่าไม่มีการเรียกใช้ CPI, การเข้ารหัส/ถอดรหัสบัญชี, การตรวจสอบความเป็นเจ้าของบัญชี ฯลฯ คุณเพียงแค่เรียกฟังก์ชันและอาร์กิวเมนต์โดยตรงจากโมดูลอื่น ประเภทและความปลอดภัยของทรัพยากรของสัญญาอัจฉริยะทั้งหมดรับประกันโดยการตรวจสอบ bytecode ณ เวลาคอมไพล์/เผยแพร่ และไม่จำเป็นต้องดำเนินการที่ระดับสัญญาอัจฉริยะเช่น Solana แล้วจึงตรวจสอบที่รันไทม์
ชื่อระดับแรก
ตอนนี้เราได้เห็นแล้วว่าการเขียนโปรแกรม Move ทำงานอย่างไร และเหตุใดจึงปลอดภัยโดยพื้นฐาน ดังนั้น มาดูกันให้ลึกยิ่งขึ้นว่าสิ่งนี้ส่งผลกระทบต่อการตั้งโปรแกรมสัญญาอัจฉริยะอย่างไรจากความสามารถในการจัดองค์ประกอบ การยศาสตร์ และจุดยืนด้านความปลอดภัย ในที่นี้ ฉันจะเปรียบเทียบการพัฒนาของ Move/Sui กับ EVM และ Rust/Solana/Anchor เพื่อช่วยให้เข้าใจถึงประโยชน์ที่ได้รับจากโมเดลการเขียนโปรแกรมของ Move
ชื่อเรื่องรอง
5.1 สินเชื่อแฟลช
สินเชื่อแฟลชเป็นเงินกู้ประเภทหนึ่งใน DeFi ซึ่งจะต้องชำระคืนจำนวนเงินกู้ในการทำธุรกรรมเดียวกันกับการยืม ประโยชน์หลักของสิ่งนี้คือเงินกู้สามารถไม่มีหลักประกันได้อย่างสมบูรณ์เนื่องจากธุรกรรมเป็นแบบปรมาณู สามารถใช้เพื่อเก็งกำไรระหว่างสินทรัพย์โดยไม่ต้องมีตัวการ
ปัญหาหลักในการบรรลุเป้าหมายนี้คือ - คุณรับประกันจากสัญญาสมาร์ทของสินเชื่อแฟลชได้อย่างไรว่าจะมีการชำระคืนเงินกู้ในการทำธุรกรรมเดียวกัน? เพื่อให้เงินกู้ไม่มีหลักประกัน ธุรกรรมจำเป็นต้องเป็นแบบ atomic นั่นคือ หากไม่ได้ชำระจำนวนเงินกู้ในธุรกรรมเดียวกัน ธุรกรรมทั้งหมดจะต้องล้มเหลว
EVM มีการตั้งเวลาแบบไดนามิก ดังนั้นจึงสามารถใช้การกลับเข้ามาใหม่เพื่อให้บรรลุตามนี้:
ผู้ใช้ Lightning Loan สร้างและอัปโหลดสัญญาอัจฉริยะแบบกำหนดเอง และเมื่อเรียกใช้สัญญา การควบคุมจะถูกส่งผ่านไปยังสัญญาอัจฉริยะ Lightning Loan โดยการโทร
จากนั้นสัญญาสมาร์ทของสินเชื่อแฟลชจะส่งจำนวนเงินกู้ที่ร้องขอไปยังสัญญาสมาร์ทที่กำหนดเองและเรียกฟังก์ชันการโทรกลับ executeOperation() ในสัญญาสมาร์ทที่กำหนดเอง
จากนั้นสมาร์ทคอนแทรคแบบกำหนดเองจะใช้จำนวนเงินกู้ที่ได้รับเพื่อดำเนินการที่จำเป็น (เช่น การเก็งกำไร)
หลังจากที่สัญญาสมาร์ทแบบกำหนดเองเสร็จสิ้นการดำเนินการ จำเป็นต้องคืนเงินที่ยืมไปยังสัญญาอัจฉริยะของสินเชื่อแฟลช
ด้วยวิธีนี้ การดำเนินการ () ของสัญญาอัจฉริยะแบบกำหนดเองจะเสร็จสมบูรณ์ และการควบคุมจะถูกส่งกลับไปยังสัญญาอัจฉริยะของสินเชื่อแฟลช ซึ่งจะตรวจสอบว่ามีการส่งคืนจำนวนเงินกู้อย่างถูกต้องหรือไม่
หากสมาร์ทคอนแทรคแบบกำหนดเองไม่คืนจำนวนเงินกู้อย่างถูกต้อง ธุรกรรมทั้งหมดจะล้มเหลว
สิ่งนี้บรรลุฟังก์ชันการทำงานที่ต้องการอย่างสวยงาม แต่ปัญหาคือต้องพึ่งพาการกลับเข้าใช้ใหม่ ซึ่งเราไม่ต้องการให้มีในการเขียนโปรแกรมสัญญาอัจฉริยะ เนื่องจากการกลับเข้ามาใหม่นั้นอันตรายโดยเนื้อแท้และเป็นต้นเหตุของช่องโหว่มากมาย รวมถึงการแฮ็ก DAO ที่น่าอับอาย
Solana ทำสิ่งนี้ได้ดีกว่าเพราะมันไม่อนุญาตให้กลับเข้ามาใหม่ แต่ถ้าไม่มีการกลับเข้ามาใหม่ สินเชื่อแฟลชจะถูกนำมาใช้กับ Solana ได้อย่างไร หากสัญญาสมาร์ทสินเชื่อแฟลชไม่สามารถโทรกลับไปยังสัญญาสมาร์ทที่กำหนดเองได้ ขอบคุณคำแนะนำวิปัสสนา บน Solana ธุรกรรมแต่ละรายการประกอบด้วยหลายคำสั่ง (การเรียกสัญญาอัจฉริยะ) และจากคำสั่งใดๆ คุณสามารถตรวจสอบคำสั่งอื่นๆ (รหัสโปรแกรม ข้อมูลคำสั่ง และบัญชี) ที่มีอยู่ในธุรกรรมเดียวกัน สิ่งนี้ทำให้สามารถใช้สินเชื่อแฟลชได้ดังต่อไปนี้:
สัญญาสมาร์ทสินเชื่อฟ้าผ่าใช้คำแนะนำในการยืมและชำระคืน
ผู้ใช้สร้างธุรกรรมการยืมแฟลชโดยซ้อนการเรียกเพื่อยืมและชำระคืนคำสั่งในธุรกรรมเดียวกัน เมื่อคำสั่งยืมถูกดำเนินการ มันจะใช้การทบทวนคำสั่งเพื่อตรวจสอบว่าคำสั่งการชำระคืนมีกำหนดในขั้นตอนต่อมาของธุรกรรมเดียวกันหรือไม่ หากไม่มีคำสั่งร้องขอการแลกรางวัลหรือไม่ถูกต้อง การทำธุรกรรมจะล้มเหลวในขั้นตอนนี้
ระหว่างการโทรเพื่อยืมและชำระคืน เงินที่ยืมมานั้นสามารถใช้ได้ฟรีโดยคำแนะนำอื่น ๆ ในระหว่างนั้น
ในตอนท้ายของการทำธุรกรรม การโทรคำสั่งชำระคืนจะคืนเงินไปยังสัญญาอัจฉริยะ Lightning Lender (การมีอยู่ของคำสั่งนี้จะถูกตรวจสอบในการสะท้อนคำสั่งยืม)
วิธีนี้ดีพอ แต่ก็ยังไม่เหมาะ Instruction Introspection ค่อนข้างเป็นกรณีพิเศษ ซึ่งไม่ได้ใช้กันทั่วไปใน Solana และการใช้งานนั้นต้องการให้นักพัฒนาเชี่ยวชาญในแนวคิดจำนวนมาก และการนำไปใช้เองก็เป็นเรื่องทางเทคนิคมากเช่นกัน เนื่องจากมีความแตกต่างบางประการที่ต้องได้รับการพิจารณาอย่างเหมาะสม นอกจากนี้ยังมีข้อจำกัดทางเทคนิค - คำสั่งการชำระคืนจำเป็นต้องมีแบบคงที่ในการทำธุรกรรม ดังนั้นจึงเป็นไปไม่ได้ที่จะเรียกการชำระคืนแบบไดนามิกผ่านการเรียก CPI ในระหว่างการดำเนินการธุรกรรม นี่ไม่ใช่เรื่องใหญ่ แต่ค่อนข้างจะจำกัดความยืดหยุ่นของโค้ดเมื่อรวมเข้ากับสัญญาอัจฉริยะอื่นๆ และยังเพิ่มความซับซ้อนให้กับไคลเอ็นต์อีกด้วย
Move ยังห้ามการตั้งเวลาแบบไดนามิกและการกลับเข้ามาใหม่ แต่แตกต่างจาก Solana คือมีวิธีแก้ปัญหาการยืมแฟลชที่เรียบง่ายและเป็นธรรมชาติ ระบบประเภทเชิงเส้นของ Move ช่วยให้สามารถสร้างโครงสร้างที่รับประกันว่าจะถูกใช้งานเพียงครั้งเดียวในระหว่างการดำเนินการธุรกรรม นี่คือรูปแบบที่เรียกว่า "Hot Potato" ซึ่งเป็นโครงสร้างที่ไม่มีฟังก์ชันคีย์ จัดเก็บ ลบ หรือโคลน โมดูลที่ใช้รูปแบบนี้มักจะมีฟังก์ชันที่ยกตัวอย่างโครงสร้างและฟังก์ชันที่ทำลายโครงสร้าง เนื่องจากโครงสร้าง "มันฝรั่งร้อน" ไม่มีฟังก์ชันการทิ้ง คีย์ หรือการจัดเก็บ ฟังก์ชันการทำลายจึงรับประกันได้ว่าจะถูกเรียกใช้เพื่อใช้งาน แม้ว่าเราจะส่งต่อไปยังฟังก์ชันอื่นในโมดูลใดก็ได้ แต่ท้ายที่สุดก็ต้องจบลงที่ฟังก์ชันการทำลายล้าง เนื่องจากไม่มีวิธีอื่นในการกำจัด และตัวตรวจสอบความถูกต้องต้องการให้กำจัดทิ้งเมื่อสิ้นสุดการทำธุรกรรม (ไม่สามารถทิ้งโดยพลการได้ เนื่องจากไม่มีฟังก์ชันละทิ้ง)
มาดูกันว่าเราจะใช้สิ่งนี้เพื่อดำเนินการสินเชื่อแฟลชได้อย่างไร
สัญญาอัจฉริยะ Lightning Loan ใช้โครงสร้างใบเสร็จ (ใบเสร็จรับเงิน) "มันฝรั่งร้อน"
เมื่อทำการกู้ยืมโดยเรียกฟังก์ชันเงินกู้ ผู้เรียกจะส่งวัตถุสองอย่าง - เงินที่ร้องขอ (หนึ่งเหรียญ) และใบเสร็จ ซึ่งเป็นบันทึกจำนวนเงินกู้ที่ต้องชำระคืน
จากนั้นผู้กู้สามารถใช้เงินที่ได้รับสำหรับการดำเนินการที่ต้องการ (เช่น การเก็งกำไร)
หลังจากที่ผู้กู้ดำเนินการตามที่ตั้งใจไว้เสร็จแล้ว จะต้องเรียกใช้ฟังก์ชันการชำระคืน ซึ่งจะรับเงินที่ยืมและใบเสร็จรับเงินเป็นพารามิเตอร์ ฟังก์ชันนี้รับประกันว่าจะถูกเรียกใช้ภายในธุรกรรมเดียวกัน เนื่องจากผู้เรียกไม่มีวิธีอื่นในการกำจัดอินสแตนซ์การรับ (ไม่อนุญาตให้ทิ้งหรือฝังในวัตถุอื่น ซึ่งจำเป็นโดยตัวตรวจสอบความถูกต้อง)
ฟังก์ชันการชำระคืนจะตรวจสอบว่ามีการส่งคืนจำนวนเงินที่ถูกต้องโดยการอ่านข้อมูลเงินกู้ที่ฝังอยู่ในใบเสร็จรับเงิน
คุณลักษณะด้านความปลอดภัยของทรัพยากรของ Move เปิดใช้งานการยืมแฟลชใน Move โดยไม่ต้องใช้การกลับเข้าที่ใหม่หรือการทบทวน พวกเขารับประกันว่าใบเสร็จรับเงินไม่สามารถแก้ไขได้ด้วยรหัสที่ไม่น่าเชื่อถือ และจะต้องส่งคืนไปยังฟังก์ชันการชำระคืนเมื่อสิ้นสุดการทำธุรกรรม ด้วยวิธีนี้ เราสามารถรับประกันได้ว่าจำนวนเงินที่ถูกต้องจะถูกส่งคืนในการทำธุรกรรมเดียวกัน
Flash Loan เป็นตัวอย่างที่ดีของวิธีที่ระบบประเภทเชิงเส้นของ Move และการรับประกันความปลอดภัยของทรัพยากรช่วยให้เราสามารถแสดงฟังก์ชันการทำงานในแบบที่ภาษาโปรแกรมอื่นไม่สามารถทำได้
ชื่อเรื่องรอง
5.2 โรงกษาปณ์ล็อคผู้มีอำนาจ
สัญญาอัจฉริยะ "การล็อกอำนาจการขุดเหรียญ" ขยายการทำงานของการสร้างเหรียญโทเค็น ทำให้หลายฝ่ายที่อนุญาตพิเศษ (หน่วยงาน) สามารถดำเนินการเหรียญกษาปณ์ได้ ฟังก์ชันที่ต้องการของสัญญาอัจฉริยะนี้มีดังต่อไปนี้ (สำหรับทั้งการใช้งาน Solana และ Sui):
ผู้มีอำนาจสร้างเหรียญโทเค็นดั้งเดิมสร้าง "การล็อคเหรียญกษาปณ์" ซึ่งจะช่วยให้สัญญาอัจฉริยะของเราดูแลการสร้างเหรียญกษาปณ์ ผู้โทรจะกลายเป็นผู้ดูแลระบบของ mintlock
ผู้ดูแลระบบสามารถสร้างการอนุญาตการสร้างเหรียญเพิ่มเติมสำหรับล็อคนี้ ซึ่งสามารถมอบให้กับบุคคลอื่นและอนุญาตให้เขาใช้ล็อคนี้เพื่อสร้างเหรียญโทเค็นได้ตลอดเวลา
การอนุญาตให้สร้างเหรียญแต่ละครั้งมีการจำกัดจำนวนโทเค็นต่อวันที่สามารถสร้างเหรียญได้
ผู้ดูแลระบบสามารถแบน (และปลดบล็อก) หน่วยงานโรงกษาปณ์ใดๆ ได้ตลอดเวลา
ความสามารถของผู้ดูแลระบบสามารถถ่ายโอนไปยังบุคคลอื่นได้
ตัวอย่างเช่น สามารถใช้สัญญาอัจฉริยะนี้เพื่อถ่ายโอนพลังการสร้างเหรียญของโทเค็นไปยังผู้ใช้รายอื่นหรือสัญญาอัจฉริยะ ในขณะที่ผู้มีอำนาจสร้างเหรียญดั้งเดิม (ผู้ดูแลระบบ) ยังคงควบคุมการสร้างเหรียญ มิฉะนั้น เราจะต้องมอบการควบคุมโรงกษาปณ์ให้กับอีกฝ่ายหนึ่งอย่างสมบูรณ์ ซึ่งไม่เหมาะเนื่องจากเราจะต้องเชื่อใจไม่ให้ใช้อำนาจนั้นในทางที่ผิด และไม่สามารถอนุญาตหลายฝ่ายได้
การใช้งานสัญญาอัจฉริยะทั้งหมดสามารถพบได้ที่นี่ (Solana) และที่นี่ (Sui)
หมายเหตุ: โปรดอย่าใช้รหัสนี้ในการผลิต นี่เป็นตัวอย่างรหัสเพื่อการศึกษาเท่านั้น ในขณะที่ฉันได้ทดสอบการทำงานของมัน ฉันยังไม่ได้ทำการตรวจสอบอย่างละเอียดหรือทดสอบความปลอดภัย

ทีนี้มาดูที่โค้ดและดูว่าการใช้งานนั้นแตกต่างกันอย่างไร ด้านล่างนี้คือภาพหน้าจอโค้ดแบบเคียงข้างกันของการนำ Solana และ Sui ไปใช้สัญญาอัจฉริยะนี้อย่างเต็มรูปแบบ
สังเกตได้ว่าสำหรับฟังก์ชันเดียวกัน การใช้งานของ Solana มีขนาดใหญ่กว่า Sui มากกว่าสองเท่า (230 LOC เทียบกับ 104) นี่เป็นเรื่องใหญ่เพราะโค้ดที่น้อยลงมักจะหมายถึงบั๊กที่น้อยลงและเวลาในการพัฒนาที่น้อยลง
แล้ว Solana เอาแถวพิเศษเหล่านี้มาจากไหน? หากเราดูโค้ดของ Solana อย่างละเอียด เราสามารถแบ่งโค้ดออกเป็นสองส่วน - การนำคำสั่งไปใช้ (ตรรกะของสัญญาอัจฉริยะ) และการตรวจสอบบัญชี การดำเนินการตามคำสั่งค่อนข้างใกล้เคียงกับสิ่งที่เรามีใน Sui --- Solana มี 136 บรรทัด และ Sui มี 104 บรรทัด จำนวนบรรทัดพิเศษเกิดจากการอ้างอิงของการเรียก CPI สองครั้ง (ประมาณ 10 LOC ต่อครั้ง) ความแตกต่างที่สำคัญที่สุดคือการตรวจสอบบัญชี (ทำเครื่องหมายด้วยสีแดงในภาพหน้าจอด้านบน) ซึ่งจำเป็น (อันที่จริงสำคัญอย่างยิ่ง) ใน Solana แต่ไม่ใช่ใน Move การตรวจสอบบัญชีคิดเป็นประมาณ 40% (91 LOC) ของสัญญาอัจฉริยะนี้
ย้ายไม่ต้องตรวจสอบบัญชี การลด LOC สามารถก่อให้เกิดประโยชน์ แต่ก็จำเป็นต้องกำจัดการตรวจสอบบัญชีด้วย เนื่องจากปรากฎว่าการดำเนินการตรวจสอบเหล่านี้อย่างถูกต้องนั้นยุ่งยากมาก และหากคุณทำพลาดแม้แต่ครั้งเดียว ก็มักจะนำไปสู่การละเมิดครั้งใหญ่และการสูญเสียเงินของผู้ใช้ ในความเป็นจริงช่องโหว่ที่ใหญ่ที่สุด (ในแง่ของการสูญเสียเงินทุนของผู้ใช้) Solana smart contract คือการโจมตีเพื่อแทนที่บัญชีซึ่งเกิดจากการตรวจสอบบัญชีที่ไม่เหมาะสม
-Wormhole ($336 ล้าน) - https://rekt.news/wormhole-rekt/
-Cashio (48 ล้านเหรียญสหรัฐ) - https://rekt.news/cashio-rekt/
- Crema Finance ($8.8 ล้าน) - https://rekt.news/crema-finance-rekt/

แล้ว Move จะปลอดภัยได้อย่างไรหากไม่มีการตรวจสอบเหล่านี้ มาดูกันดีกว่าว่าการตรวจสอบเหล่านี้ทำอะไรได้บ้าง นี่คือการตรวจสอบบัญชีที่จำเป็นโดยคำสั่ง mint_to (ผู้ถือสิทธิ์โทเค็น mint โดยเรียกคำสั่งนี้):
มี 6 เช็ค (ทำเครื่องหมายด้วยสีแดง):
1. ตรวจสอบว่าบัญชีล็อคที่ให้ไว้นั้นเป็นของสัญญาอัจฉริยะและเป็นประเภท MintLock หรือไม่ จำเป็นต้องล็อกขาเข้าเนื่องจากใช้สำหรับการเรียก CPI ไปยังโปรแกรมโทเค็นสำหรับการสร้างเหรียญ (ซึ่งเก็บสิทธิ์)
2. ตรวจสอบว่าบัญชีอนุญาตการสร้างเหรียญที่ให้มานั้นเป็นของล็อคที่ให้ไว้หรือไม่ บัญชีผู้ออกโรงกษาปณ์มีสถานะการอนุญาต (คีย์สาธารณะ ไม่ว่าจะถูกแบนหรือไม่ เป็นต้น)
3. ตรวจสอบว่าผู้เรียกคำสั่งมีรหัสที่จำเป็นสำหรับการอนุญาต (ผู้มีอำนาจลงนามในการทำธุรกรรมที่จำเป็น)
4. ต้องผ่านบัญชีเป้าหมายโทเค็นเนื่องจากโปรแกรมโทเค็นจะเปลี่ยน (เพิ่มยอดคงเหลือ) ในการเรียก CPI การตรวจสอบเหรียญกษาปณ์ไม่จำเป็นอย่างยิ่งที่นี่ เนื่องจากการเรียก CPI จะล้มเหลวหากมีการส่งผ่านบัญชีที่ไม่ถูกต้อง แต่ก็ยังเป็นแนวทางปฏิบัติที่ดี
5. คล้ายกับ 4.
6. ตรวจสอบว่ามีการส่งผ่านบัญชีโปรแกรมโทเค็นอย่างถูกต้องหรือไม่
เราจะเห็นว่าการตรวจสอบบัญชี (ในตัวอย่างนี้) อยู่ในห้าหมวดหมู่เหล่านี้:
การตรวจสอบความเป็นเจ้าของบัญชี (1, 2, 4, 5)
ตรวจสอบประเภทบัญชี (1, 2, 4, 5)
การตรวจสอบอินสแตนซ์ของบัญชี (ว่ามีการส่งผ่านอินสแตนซ์ของประเภทบัญชีที่ถูกต้องหรือไม่) (2, 5)
การตรวจสอบลายเซ็นบัญชี(3)
ตรวจสอบที่อยู่บัญชีโปรแกรม(6)

แต่ใน Move ไม่มีการตรวจสอบบัญชีหรืออะไรทำนองนั้น มีเพียงลายเซ็นของฟังก์ชันเท่านั้น:
ฟังก์ชัน mint_balance ต้องการพารามิเตอร์เพียงสี่ตัว ในบรรดาพารามิเตอร์ทั้งสี่นี้ มีเพียงตัวล็อคและตัวพิมพ์ใหญ่เท่านั้นที่แสดงถึงวัตถุ (ค่อนข้างคล้ายกับบัญชี)
ใน Solana เราจำเป็นต้องประกาศ 6 บัญชีและใช้การตรวจสอบต่างๆ กับพวกเขาด้วยตนเอง ในขณะที่ใน Move เราจำเป็นต้องส่งเพียง 2 อ็อบเจ็กต์ และไม่จำเป็นต้องมีการตรวจสอบที่ชัดเจน สำเร็จได้อย่างไร
ใน Move การตรวจสอบเหล่านี้บางส่วนทำอย่างโปร่งใสโดยรันไทม์ บางส่วนทำแบบคงที่โดยตัวตรวจสอบ ณ เวลาคอมไพล์ และบางส่วนไม่จำเป็นเลยในการก่อสร้าง
การตรวจสอบความเป็นเจ้าของบัญชี - Move มีระบบประเภท ดังนั้นการออกแบบนี้จึงไม่จำเป็น โครงสร้างการย้ายสามารถเปลี่ยนแปลงได้โดยฟังก์ชันที่กำหนดในโมดูลเท่านั้น ไม่ใช่โดยตรง การตรวจสอบ Bytecode ช่วยให้มั่นใจได้ว่าอินสแตนซ์ struct สามารถไหลเข้าสู่โค้ดที่ไม่น่าเชื่อถือ (โมดูลอื่นๆ) ได้อย่างอิสระโดยไม่ถูกดัดแปลงอย่างผิดกฎหมาย
การตรวจสอบประเภทบัญชี - ไม่จำเป็น เนื่องจากมีประเภทการย้ายอยู่ในสัญญาอัจฉริยะ คำจำกัดความของประเภทถูกฝังอยู่ในโมดูลไบนารี (เผยแพร่บนบล็อกเชนและดำเนินการโดยเครื่องเสมือน) ตัวตรวจสอบความถูกต้องจะตรวจสอบว่า ระหว่างการคอมไพล์/เผยแพร่ เมื่อฟังก์ชันของเราถูกเรียกใช้ ประเภทที่ถูกต้องจะถูกส่งผ่าน
การตรวจสอบอินสแตนซ์ของบัญชี - ใน Move (และบางครั้งใน Solana ด้วย) คุณทำสิ่งนี้ในเนื้อหาของฟังก์ชัน ในกรณีเฉพาะนี้ สิ่งนี้ไม่จำเป็นเนื่องจากพารามิเตอร์ประเภททั่วไป T ของประเภทพารามิเตอร์ล็อคและแคปบังคับว่าอ็อบเจกต์แคปที่เข้ามา
การตรวจสอบลายเซ็นบัญชี - เราไม่จัดการการลงนามโดยตรงใน Sui ผู้ใช้สามารถเป็นเจ้าของวัตถุได้ สิทธิ์การสร้างเหรียญได้รับจากการเป็นเจ้าของออบเจกต์ความสามารถของ Minting Authority (สร้างโดยผู้ดูแลระบบ) การส่งการอ้างอิงไปยังวัตถุนี้ในฟังก์ชัน mint_balance จะทำให้เราสามารถสร้างเหรียญกษาปณ์ได้ วัตถุที่เป็นเจ้าของสามารถใช้ในการทำธุรกรรมโดยเจ้าของเท่านั้น กล่าวอีกนัยหนึ่ง การตรวจสอบลายเซ็นของออบเจกต์นั้นดำเนินการอย่างโปร่งใสโดยรันไทม์
โดยพื้นฐานแล้ว Move ใช้ประโยชน์จากการตรวจสอบ bytecode เพื่อทำให้โมเดลการเขียนโปรแกรมสำหรับสินทรัพย์ดิจิทัลเป็นธรรมชาติมากขึ้น โมเดลของ Solana เกี่ยวข้องกับการเป็นเจ้าของบัญชี ลายเซ็น การเรียก CPI PDA เป็นต้น แต่เมื่อเราย้อนกลับไปคิดดู เราตระหนักว่าเราไม่ต้องการจัดการกับปัญหาเหล่านี้ พวกเขาไม่มีความเกี่ยวข้องใดๆ กับสินทรัพย์ดิจิทัล แต่เราต้องใช้มันเพราะสิ่งนี้ทำให้เราสามารถใช้ฟังก์ชันที่ต้องการในแบบจำลองการเขียนโปรแกรมของ Solana
บน Solana ไม่มีการยืนยันด้วยรหัสไบต์เพื่อให้แน่ใจว่ามีประเภทที่ละเอียดยิ่งขึ้นหรือความปลอดภัยของทรัพยากร และคุณไม่สามารถอนุญาตให้โปรแกรมใดๆ เปลี่ยนแปลงบัญชีใดๆ ได้ ดังนั้นจึงจำเป็นต้องแนะนำแนวคิดของการเป็นเจ้าของบัญชี ด้วยเหตุผลที่คล้ายกัน (ไม่มีความปลอดภัยของประเภท/ทรัพยากรในการเรียกใช้โปรแกรม) ไม่มีความคิดเกี่ยวกับวัตถุที่ผู้ใช้เป็นเจ้าของที่สามารถเข้าและออกจากโปรแกรมได้ แต่เราจะใช้ลายเซ็นบัญชีเพื่อพิสูจน์การอนุญาตแทน เนื่องจากบางครั้งโปรแกรมจำเป็นต้องสามารถให้ลายเซ็นบัญชีได้ เราจึงมี PDA...
การแยกทรัพยากรแบบเนทีฟของ Move ช่วยให้เราสามารถจัดการทรัพยากรได้โดยตรงโดยไม่ต้องแนะนำแบบเอกสารสำเร็จรูประดับต่ำ เช่น PDA การรับประกันความปลอดภัยของประเภทและทรัพยากรทั่วทั้งขอบเขตของสัญญาอัจฉริยะนั้นได้รับการรับรองโดยตัวตรวจสอบความถูกต้องและไม่จำเป็นต้องดำเนินการด้วยตนเอง
ชื่อเรื่องรอง
5.3 ข้อจำกัดขององค์ประกอบ Solana
ผมขอยกตัวอย่างอีกหนึ่งตัวอย่างเพื่อเน้นประเด็นปัญหาบางประการของความสามารถในการจัดองค์ประกอบสัญญาอัจฉริยะบน Solana
เราเห็นในตัวอย่างการล็อกการอนุญาตมิ้นต์ที่เราจำเป็นต้องประกาศอินพุตเพิ่มเติมบน Solana เมื่อเทียบกับ Sui (mint_to เรียก 6 บัญชีบน Solana เทียบกับ 2 อ็อบเจ็กต์บน Sui) เห็นได้ชัดว่าการจัดการกับ 6 บัญชีนั้นลำบากกว่าการจัดการกับ 2 วัตถุ โดยเฉพาะอย่างยิ่งหากคุณพิจารณาว่าคุณจำเป็นต้องดำเนินการตรวจสอบบัญชีสำหรับบัญชีด้วย ตามทฤษฎีแล้วส่วนนี้จัดการได้ แต่จะเกิดอะไรขึ้นเมื่อเราเริ่มสร้างสัญญาอัจฉริยะที่แตกต่างกันหลายรายการพร้อมกันในการโทรครั้งเดียว
สมมติว่าเราต้องการสร้างสัญญาอัจฉริยะที่สามารถดำเนินการต่อไปนี้:
มีสิทธิ์ในการสร้างโทเค็นบางอย่างจากโปรแกรมล็อคสิทธิ์การสร้างเหรียญและสามารถสร้างเหรียญได้
เมื่อมีการเรียกใช้ จะใช้สิทธิ์ในการสร้างโทเค็นตามจำนวนที่ผู้ใช้กำหนด สลับเป็นโทเค็นอื่นโดยใช้ AMM และส่งไปยังผู้ใช้ด้วยคำสั่งเดียวกัน

จุดเน้นของตัวอย่างนี้คือเพื่อแสดงให้เห็นว่าหน่วยงานโรงพิมพ์ล็อกสัญญาอัจฉริยะและสัญญาอัจฉริยะ AMM จะถูกรวมเข้าด้วยกันอย่างไร การตรวจสอบบัญชีที่เรียกใช้โดยคำสั่งอาจมีลักษณะดังนี้:
17 บัญชี 5-6 โปรแกรมต่อการโทร CPI (การขุดและการแลกเปลี่ยน) รวมถึงบัญชีโปรแกรม

ใน Sui ลายเซ็นของฟังก์ชันที่เทียบเท่าจะมีลักษณะดังนี้:
มีเพียง 3 องค์เท่านั้น
เหตุใดเราจึงส่งวัตถุน้อยลงมากบน Sui เมื่อเทียบกับบัญชีบน Solana (3 เทียบกับ 17) โดยพื้นฐานแล้ว เนื่องจากใน Move เราสามารถฝัง (ห่อ) พวกมันได้ การรับประกันความปลอดภัยของระบบประเภททำให้เราทำเช่นนี้ได้

ด้านล่างนี้คือการเปรียบเทียบระหว่างบัญชี Solana และอ็อบเจ็กต์ Sui ซึ่งมีสถานะของพูล AMM
เราจะเห็นว่าใน Solana เราจัดเก็บที่อยู่ (Pubkeys) ของบัญชีอื่น ซึ่งเปรียบเสมือนพอยน์เตอร์และไม่ได้จัดเก็บข้อมูลจริง ในการเข้าถึงบัญชีเหล่านี้ จำเป็นต้องส่งต่อบัญชีทีละบัญชี และเราต้องตรวจสอบด้วยตนเองด้วยว่าบัญชีที่ถูกต้องถูกส่งเข้ามา ใน Move เราสามารถฝังโครงสร้างภายในกันและกันและเข้าถึงค่าของมันได้โดยตรง เราสามารถผสมและจับคู่ประเภทจากโมดูลใดก็ได้ในขณะที่ยังคงรักษาทรัพยากรและการรับประกันความปลอดภัยของประเภทไว้ ทั้งสองต้องขอบคุณระบบประเภททั่วโลกของ Move และความปลอดภัยของทรัพยากร ซึ่งขับเคลื่อนโดยการตรวจสอบ bytecode
อย่างไรก็ตาม เมื่อสร้างสัญญาอัจฉริยะหลายรายการ จะต้องผ่านหลายบัญชี (และตรวจสอบด้วยวิธีนี้) ซึ่งสร้างความซับซ้อนในการใช้งานอย่างมากและมีผลกระทบด้านความปลอดภัย ความสัมพันธ์ระหว่างบัญชีเหล่านี้อาจค่อนข้างซับซ้อน จนยากที่จะติดตามการตรวจสอบบัญชีที่จำเป็นทั้งหมด และดูว่ามีการใช้งานอย่างถูกต้องหรือไม่
อันที่จริง นั่นคือสิ่งที่ฉันคิดว่าเกิดขึ้นใน Cashio breach ($48 ล้าน) ด้านล่างนี้คือรายละเอียดของการตรวจสอบบัญชี (ไม่เพียงพอ) ที่นำไปสู่ช่องโหว่ อย่างที่คุณเห็น การตรวจสอบบัญชีเหล่านี้จะซับซ้อนขึ้นเล็กน้อย นักพัฒนามีความตั้งใจดีที่จะตรวจสอบให้ถูกต้อง แต่เมื่อถึงจุดหนึ่ง ความกดดันทางจิตใจจะมากเกินไปและเกิดข้อผิดพลาดได้ง่าย ยิ่งคุณมีบัญชีมากเท่าไหร่ คุณก็ยิ่งมีโอกาสเกิดข้อผิดพลาดมากขึ้นเท่านั้น
ระบบประเภทสากลของ Move และรูปแบบการเขียนโปรแกรมที่เป็นธรรมชาติมากขึ้น หมายความว่าเราสามารถขับเคลื่อนองค์ประกอบสัญญาอัจฉริยะด้วยความปลอดภัยที่มากขึ้นก่อนที่จะถึงขีดจำกัดของความเครียดทางจิตใจ
Move ได้รับการออกแบบโดยคำนึงถึงการลด TCB - Move ได้ตัดสินใจหลายครั้งเพื่อลด TCB ให้ได้มากที่สุด ตัวตรวจสอบรหัสไบต์จะลบการตรวจสอบจำนวนมากที่ดำเนินการโดยคอมไพเลอร์ Move ออกจาก TCB ในขณะที่ใน Rust/Anchor มีส่วนประกอบอีกมากมายที่ต้องเชื่อถือได้ ดังนั้นพื้นที่ผิวสำหรับจุดบกพร่องด้านความปลอดภัยที่ร้ายแรงจึงมีขนาดใหญ่กว่า
ชื่อระดับแรก
เราสามารถมี Move on Solana ได้หรือไม่ และอย่างไร?
ชื่อเรื่องรอง
6.1 มี Anchor ที่ปลอดภัยสำหรับประเภททั่วโลกหรือไม่?

ก่อนที่เราจะเริ่มต้น ลองมาดู Anchor และทำการทดลองทางความคิดกันสักเล็กน้อยก่อน บางทีเราอาจจะอัพเกรด Anchor เพื่อให้ได้รับประโยชน์บางอย่างที่เราได้รับจาก Move? บางทีเราอาจจะได้รับการสนับสนุนแบบพื้นเมืองที่ปลอดภัยสำหรับการโทรข้ามขั้นตอน? ท้ายที่สุดแล้ว คำสั่ง Anchor นั้นคล้ายกับฟังก์ชันรายการของ Move อยู่แล้ว:

บางทีเราสามารถขยาย Anchor เพื่อให้สามารถส่งผ่านบัญชีไปยังพารามิเตอร์คำสั่งได้โดยตรง
เราสามารถหลีกเลี่ยงการตรวจสอบบัญชีได้หรือไม่?
ในกรณีนี้ เราต้องการให้การตรวจสอบประเภทดำเนินการโดยการเรียกใช้มากกว่าโปรแกรม - การรันจะอ่านตัวแยกประเภทบัญชี Anchor (หรือเทียบเท่า) และสามารถตรวจสอบได้ว่าบัญชีที่ส่งผ่านนั้นสอดคล้องกับตัวแยกประเภทที่ต้องการ (Anchor 8 ไบต์แรกของบัญชี)
Solana ไม่แยกความแตกต่างระหว่างการเรียกใช้คำสั่งต่างๆ ของโปรแกรมเดียวกัน โปรแกรมนี้ดำเนินการด้วยตนเอง (ในกรณีนี้ Anchor จะยกของหนัก) ดังนั้น ในการทำเช่นนี้ รันไทม์จะต้องรู้เกี่ยวกับคำสั่งต่างๆ ลายเซ็น ข้อมูลประเภทต่างๆ
โปรแกรม Solana ถูกคอมไพล์เป็น SBF (Solana Bytecode Format ซึ่งแตกต่างจาก eBPF) และอัปโหลดไปยังเชน (และดำเนินการ) ด้วยวิธีนี้ SBF เองไม่ได้ฝังข้อมูลประเภทหรือฟังก์ชันใดๆ ที่จะช่วยเรา แต่บางทีเราอาจแก้ไข SBF เพื่อให้คำสั่งและข้อมูลประเภทฝังอยู่ในไบนารี่ได้? วิธีนี้สามารถอ่านคำแนะนำที่จำเป็นและข้อมูลลายเซ็นจากไบนารีโดยรันไทม์
เราสามารถทำได้จริง สิ่งนี้จะต้องใช้วิศวกรรมจำนวนมาก โดยเฉพาะอย่างยิ่งเมื่อเราจำเป็นต้องรักษาความเข้ากันได้แบบย้อนหลังกับโปรแกรมรุ่นเก่า แต่สิ่งที่เราได้รับมีดังนี้:
- การตรวจสอบความเป็นเจ้าของบัญชีและประเภททำได้โดยการรันแทนโปรแกรม
- สำหรับบัญชีที่ทราบที่อยู่ ณ เวลาคอมไพล์ (เช่น บัญชีโปรแกรม) เราสามารถหลีกเลี่ยงการส่งผ่านจากไคลเอนต์ได้ ตอนนี้สามารถส่งผ่านโดยการเรียกใช้
- หากเราจัดการฝังข้อจำกัดของบัญชีลงในไบนารีได้ เราสามารถลดจำนวนบัญชีที่ลูกค้าต้องส่งผ่านเข้ามาเพิ่มเติมได้ โดยโหลดซ้ำแบบไดนามิกด้วยรันไทม์ (ตามข้อมูลข้อจำกัดที่ฝังอยู่)
เรายังไม่ได้รับ:
- บัญชีฝังตัว เรายังต้องใช้ Pubkey เพื่ออ้างถึงบัญชีอื่นและไม่สามารถฝังได้โดยตรง ซึ่งหมายความว่าเราไม่ได้กำจัดปัญหาการขยายตัวของบัญชีที่อธิบายไว้ในข้อ 5.3
-เมื่อทำการเรียกข้ามโปรแกรม การตรวจสอบประเภทบัญชียังคงต้องทำแบบไดนามิกที่รันไทม์ แทนที่จะทำแบบคงที่ในเวลาคอมไพล์เหมือนใน Move
หมายเหตุ: นี่เป็นเพียงการทดลองทางความคิดเท่านั้น ไม่ได้หมายความว่าจะเสร็จสมบูรณ์ได้อย่างปลอดภัย และไม่ได้หมายความว่าจะทำได้ยาก และไม่ได้โฆษณาว่าประโยชน์เหล่านี้คุ้มค่ากับความพยายามของวิศวกรรม
ผลประโยชน์เหล่านี้เป็นสิ่งที่ดีอย่างแน่นอน แต่ก็ไม่ได้เปลี่ยนแปลงอะไรโดยพื้นฐานจากมุมมองของการพัฒนาสัญญาอัจฉริยะ การตรวจสอบประเภทในขณะรันไทม์แทนที่จะเป็นในโปรแกรมอาจให้ประโยชน์ด้านประสิทธิภาพ และไม่จำเป็นต้องส่งบัญชีที่อยู่จากลูกค้าด้วยตนเองในเวลาคอมไพล์ ปรับปรุงการยศาสตร์ในระดับหนึ่ง (สิ่งนี้สามารถบรรเทาได้ด้วยการใช้เครื่องมือ) แต่ท้ายที่สุดแล้ว เรายังคงต้องจัดการกับโมเดลการเขียนโปรแกรมของ Solana ซึ่งให้ความช่วยเหลือในการจัดการสินทรัพย์ดิจิทัลมากขึ้น เรายังไม่มีความปลอดภัยของทรัพยากรดั้งเดิม เราไม่สามารถฝังบัญชีได้ ดังนั้นจึงยังคงมีการขยายบัญชี เรายังจัดการอยู่ พร้อมเซ็นชื่อบัญชีและพีดีเอ...
เราต้องการมีรูปแบบการเขียนโปรแกรมที่เป็นธรรมชาติ แต่ในขณะเดียวกันเราก็จัดการกับโค้ดที่ไม่น่าเชื่อถือ แม้ว่าเราจะสามารถจัดการกับโค้ดที่ไม่น่าเชื่อถือบน Solana ได้อย่างปลอดภัย แต่ก็มีการประนีประนอมในโมเดลการเขียนโปรแกรม การตรวจสอบ Bytecode ทำให้เรามีทั้งสองอย่าง หากไม่มีสิ่งนี้ ดูเหมือนว่าเราจะไม่สามารถปรับปรุงโมเดลการเขียนโปรแกรมได้จริงๆ
ชื่อเรื่องรอง
6.2 รูปแบบ Solana Bytecode
ดังที่ได้กล่าวไว้ก่อนหน้านี้ SBF (Solana Bytecode Format) ซึ่งเป็นรูปแบบการคอมไพล์และการจัดเก็บแบบออนเชนของสัญญาอัจฉริยะของ Solana อิงจาก eBPF การใช้ eBPF บน Solana แทนรูปแบบ bytecode อื่นๆ (เช่น WASM) ส่วนใหญ่เป็นเพราะข้อกำหนดของ Solana สำหรับการดำเนินการตามสัญญาอัจฉริยะที่ปลอดภัยและมีประสิทธิภาพสูงนั้นสอดคล้องกับข้อกำหนดการดำเนินการโปรแกรมเคอร์เนลแซนด์บ็อกซ์ของการออกแบบ eBPF (นอกจากนี้ยังต้องการความปลอดภัยและประสิทธิภาพสูง)
เมื่อพิจารณาแล้ว eBPF เป็นตัวเลือกที่ดี ประสิทธิภาพสูง ออกแบบโดยคำนึงถึงความปลอดภัย ขนาดโปรแกรมและจำนวนคำสั่งจำกัด มีตัวตรวจสอบ bytecode... ดูดี
แต่เรามาดูกันว่าสิ่งนี้หมายความว่าอย่างไรในทางปฏิบัติ บางทีเราอาจจะใช้ประโยชน์จากตัวตรวจสอบความถูกต้องของ eBPF เพื่อปรับปรุงความปลอดภัยของสัญญาอัจฉริยะของเรา ต่อไปนี้คือสิ่งที่ผู้ตรวจสอบความถูกต้องของ eBPF ทำ:
- ไม่อนุญาตให้วนซ้ำไม่สิ้นสุด
- ตรวจสอบว่าโปรแกรมเป็น DAG (Directed Acyclic Graph) หรือไม่
- ไม่อนุญาตให้กระโดดนอกขอบเขต
- ตรวจสอบประเภทพารามิเตอร์เมื่อเรียกใช้ฟังก์ชันตัวช่วยต่างๆ (ฟังก์ชันตัวช่วยถูกกำหนดไว้ในเคอร์เนล เช่น สำหรับการแก้ไขแพ็กเก็ตเครือข่าย)
การไม่อนุญาตให้กระโดดออกนอกขอบเขตดูเหมือนจะมีประโยชน์ แต่ก็จำกัด ในความเป็นจริง การกำหนดให้โปรแกรมต้องเป็น DAG และไม่มีการวนซ้ำแบบไม่มีที่สิ้นสุดนั้นเป็นปัญหา เนื่องจากโปรแกรมดังกล่าวจะจำกัดความสามารถในการทำงานของโปรแกรมอย่างมาก (เราไม่มีความครบถ้วนสมบูรณ์ของทัวริง) เหตุผลที่จำเป็นในโปรแกรม eBPF คือผู้ตรวจสอบต้องแน่ใจว่าโปรแกรมสิ้นสุดภายในจำนวนคำสั่งที่กำหนด (เพื่อที่โปรแกรมจะไม่ทำให้เคอร์เนลยุติ นี่เป็นปัญหาการหยุดทำงานที่มีชื่อเสียง) และก๊าซ การวัดแสงไม่ใช่ตัวเลือกเนื่องจากจะส่งผลต่อประสิทธิภาพมากเกินไป
แม้ว่าการแลกเปลี่ยนนี้จะดีสำหรับการติดตั้งไฟร์วอลล์ประสิทธิภาพสูง แต่ก็ไม่เหมาะสำหรับการพัฒนาสัญญาอัจฉริยะ ตัวตรวจสอบ eBPF ส่วนใหญ่ไม่สามารถใช้ซ้ำกับโปรแกรม Solana ได้ ในความเป็นจริง Solana ไม่ได้ใช้ตัวตรวจสอบความถูกต้องของ eBPF ดั้งเดิมเลย แต่ใช้ตัวตรวจสอบความถูกต้องแบบกำหนดเอง (พื้นฐานกว่า) ที่โดยทั่วไปจะตรวจสอบคำแนะนำที่ถูกต้องและการกระโดดนอกขอบเขต
ในขณะเดียวกัน eBPF ได้รับการออกแบบให้สามารถส่งผ่านพารามิเตอร์ได้สูงสุด 5 พารามิเตอร์ไปยังฟังก์ชันสำหรับการโทร ซึ่งหมายความว่าไม่สามารถรวบรวมไลบรารี่มาตรฐาน Rust กับ eBPF ได้โดยตรง หรือขนาดสแต็กถูกจำกัดไว้ที่ 512 ไบต์ ซึ่งลดขนาดของอาร์กิวเมนต์ที่เราสามารถส่งไปยังฟังก์ชันโดยไม่ต้องมีการจัดสรรฮีป
ดังนั้น แม้ว่า Rust จะคอมไพล์เป็น LLVM มีแบ็กเอนด์ eBPF สำหรับ LLVM และแม้แต่รองรับคอมไพเลอร์ Rust สำหรับ eBPF คุณก็ยังไม่สามารถรับสัญญาอัจฉริยะของ Solana เพื่อคอมไพล์เป็น eBPF ได้เท่าที่ควร นี่คือเหตุผลที่ทีม Solana ต้องทำการแก้ไขหลายอย่างกับฐานข้อมูลรหัส Rust และแบ็กเอนด์ eBPF LLVM (เช่น การส่งผ่านอาร์กิวเมนต์ผ่านสแต็ก)
เนื่องจากการเปลี่ยนแปลงเหล่านี้บางส่วนเป็นการสนับสนุนต้นทางแบบเนทีฟ (ไม่ว่าจะเป็น Rust หรือ LLVM) ทีมงานของ Solana จึงยังคงแยกทั้ง Rust และ LLVM ไว้ เมื่อคุณดำเนินการ Cargo build-bpf (คำสั่งทั่วไปในการสร้าง Solana smart contract) Cargo จะดึง rustc เวอร์ชันเฉพาะของ Solana นี้ (คอมไพเลอร์สำหรับภาษาโปรแกรม Rust) เพื่อคอมไพล์สัญญาอัจฉริยะ (rustc ดั้งเดิมจะไม่ทำงาน ) .
นี่คือที่มาของ SBF - Solana ต้องการข้อกำหนดบางอย่างที่ไม่รองรับกับ eBPF ขณะนี้ทีม Solana กำลังทำงานในการอัพสตรีม SBF เป็นแบ็กเอนด์ LLVM แยกต่างหาก และเพิ่มเป็นเป้าหมายของ Rust เพื่อหลีกเลี่ยงการรักษา Fork แยกต่างหาก
ดังนั้น แม้ว่า eBPF สามารถใช้เป็นรูปแบบสำหรับสัญญาอัจฉริยะได้ แต่ก็ไม่เหมาะอย่างที่คิดบนพื้นผิว จำเป็นต้องมีการปรับเปลี่ยนบางอย่าง และตัวตรวจสอบเดิมไม่มีประโยชน์มากนัก
ในการอภิปรายเกี่ยวกับ Move และ Solana/SBF ความเข้าใจผิดคือบางคนคิดว่าแนวคิดหลักของ Move ควรใช้ได้กับ SBF เนื่องจากอิงจาก eBPF และอาจใช้ตัวตรวจสอบความถูกต้องเพื่อทำการตรวจสอบการเปลี่ยนแปลงบัญชีแบบคงที่แทน ในทำการตรวจสอบแบบไดนามิกที่รันไทม์
ในความเห็นของฉัน นี่เป็นการกล่าวอ้างที่น่าสงสัย แม้ว่าจะสามารถพิสูจน์ได้ว่าโปรแกรมไม่ได้เปลี่ยนแปลงบัญชีใน eBPF ที่พวกเขาไม่ได้เป็นเจ้าของ ซึ่งเป็นสิ่งที่ Move กำลังทำอยู่ แต่ก็ไม่ใช่แนวคิดหลักของ Move อย่างแน่นอน
แนวคิดหลักของ Move คือการสร้างโมเดลการเขียนโปรแกรมที่เน้นทรัพยากรซึ่งสามารถโต้ตอบกับโค้ดที่ไม่น่าเชื่อถือได้อย่างเป็นธรรมชาติ
ในทางปฏิบัติหมายความว่า:
ความปลอดภัยระดับโลก
ความปลอดภัยของทรัพยากร (คีย์ โคลน ซ่อน ทิ้ง)
ทรัพยากรที่ฝังได้
...
ทรัพยากรไหลเข้าและออกจากโค้ดที่ไม่น่าเชื่อถืออย่างปลอดภัย
เป็นเรื่องยากมากที่จะแนะนำแนวคิด Move หลักใน eBPF/SBF การบังคับใช้คุณสมบัติเช่น "รหัสที่ไม่น่าเชื่อถือนี้ไม่สามารถทิ้ง T" เป็นไปไม่ได้หากไม่มีการเปลี่ยนแปลงที่สำคัญกับ eBPF การดำเนินการนี้ต้องการการปรับเปลี่ยนอย่างมากเพื่อให้คุณลงเอยด้วยรหัสไบต์ใหม่ที่ดูเหมือน Move มากกว่า eBPF
ในความเป็นจริงแล้ว แนวคิดที่คล้ายกันคือสิ่งที่นำไปสู่การกำเนิดของ Move ในตอนแรก ในตอนแรกทีม Move (จากนั้นอยู่ที่ Diem) พิจารณาเริ่มต้นด้วยรูปแบบอื่นๆ เช่น WASM, JVM หรือ CLR แต่การเพิ่มสิ่งนี้ภายหลังความจริงนั้นยากเกินไป - ความเป็นเชิงเส้น/ความจุนั้นไม่เป็นทางการ ดังนั้น Move จึงได้รับการออกแบบใหม่ทั้งหมดโดยมีแนวคิดในการดำเนินการตรวจสอบเหล่านี้อย่างมีประสิทธิภาพผ่านช่องตรวจสอบความถูกต้องที่มีน้ำหนักเบา
ถ้าลองคิดดู ก็ไม่น่าแปลกใจเท่าไหร่ ท้ายที่สุดแล้ว การเขียนโปรแกรมสัญญาอัจฉริยะไม่ใช่การเขียนโปรแกรมระบบ การเขียนโปรแกรมแบ็กเอนด์ หรือการเขียนโปรแกรมแบบดั้งเดิมอื่นๆ แต่เป็นการเขียนโปรแกรมประเภทอื่นโดยสิ้นเชิง ดังนั้นจึงไม่น่าแปลกใจที่ความสามารถของ bytecode และรูปแบบคำสั่งที่มีอยู่จะไม่สามารถนำมาใช้ประโยชน์ได้ เนื่องจากได้รับการออกแบบโดยคำนึงถึงกรณีการใช้งานที่แตกต่างกันอย่างสิ้นเชิง
ฉันไม่ได้วิจารณ์ Solana สำหรับการใช้ eBPF อันที่จริง ฉันคิดว่ามันเป็นตัวเลือกที่ค่อนข้างมั่นคงและทีมงานใช้วิจารณญาณที่ดีเมื่อพิจารณาจากบริบท เมื่อมองย้อนกลับไป ทีมงานอาจเลือก WASM มากกว่า eBPF ซึ่งจะหลีกเลี่ยงปัญหาที่กล่าวมาข้างต้นในการรวบรวมสัญญาอัจฉริยะเป็น eBPF เนื่องจาก WASM มีการสนับสนุนชั้นหนึ่งใน Rust (แม้ว่า WASM อาจมีปัญหาอื่นๆ) แต่จะเห็นได้ว่า ทีมอาจรู้สึกว่า eBPF เป็นทางเลือกที่ปลอดภัยกว่าเนื่องจากเน้นที่ประสิทธิภาพ นอกจากนี้ ในขณะที่มีการเลือกการออกแบบเหล่านี้ Move ยังไม่มีการประกาศด้วยซ้ำ และการสร้างภาษาใหม่ตั้งแต่ต้นก็ไม่ใช่ทางเลือกที่เหมาะสมสำหรับการเริ่มต้นอย่างแน่นอน ในที่สุด Solana ก็สามารถส่งมอบ L1 ที่มีประสิทธิภาพสูงได้สำเร็จ และนั่นคือสิ่งที่สำคัญ
มีสามวิธีในการรับ Move on Solana:
เพิ่ม Move vm เป็นตัวโหลดในเครื่อง (ควบคู่ไปกับ SBF vm)
เรียกใช้เครื่องเสมือน Move เป็นโปรแกรม (เช่น Neon)
รวบรวมย้ายไปที่ SBF (เช่น Solang)
เรามาพูดถึง (3) ก่อน แนวคิดนี้คือการมีส่วนหน้า LLVM สำหรับ Move เพื่อให้คอมไพล์เป็น SBF Move smart contract ที่คอมไพล์ไปยัง SBF นั้นดำเนินการอย่างโปร่งใส เช่นเดียวกับ smart contract ที่สร้างขึ้นใน Rust (หรือภาษาอื่น ๆ ที่สามารถคอมไพล์เป็น SBF ได้) และไม่ต้องการความแตกต่างหรือความรู้ใด ๆ เกี่ยวกับ Move ณ รันไทม์ จากมุมมองด้านการปฏิบัติงาน นี่จะเป็นโซลูชันที่สวยงามมาก เนื่องจากไม่จำเป็นต้องทำการเปลี่ยนแปลงหรือสมมติฐานด้านความปลอดภัย
แต่ฉันคิดว่าการพัฒนาสัญญาอัจฉริยะด้วยวิธีนี้จะแย่กว่าการใช้ Anchor โดยตรง สิ่งที่คุณได้รับจาก (3) คือไวยากรณ์ของ Move ในรูปแบบการเขียนโปรแกรม Solana ซึ่งหมายความว่าข้อดีที่สำคัญทั้งหมดของ Move ที่กล่าวถึงในบทที่ 5 (ความปลอดภัยประเภทส่วนกลาง ความปลอดภัยของทรัพยากรส่วนกลาง ออบเจกต์ที่ฝังได้...) จะไม่มีอยู่อีกต่อไป แต่เรายังคงต้องจัดการกับการตรวจสอบบัญชี การเรียก CPI พีดีเอ ฯลฯ เช่นเดียวกับใน Rust และเนื่องจาก Move ไม่รองรับมาโคร จึงเป็นไปไม่ได้ที่จะใช้เฟรมเวิร์กอย่าง Anchor โดยใช้ eDSL เพื่อลดความซับซ้อนของงานนี้ ดังนั้นโค้ดจะคล้ายกัน (แต่อาจแย่กว่านั้น) กับ vanilla Rust ไลบรารี่มาตรฐานและระบบนิเวศของ Rust ก็ไม่พร้อมใช้งานเช่นกัน ดังนั้น จึงต้องดำเนินการต่างๆ เช่น การจัดลำดับบัญชีและการแยกซีเรียลไลเซชันใหม่ใน Move
Move ไม่เหมาะสำหรับการใช้กับโมเดลการเขียนโปรแกรมอื่นๆ เนื่องจากได้รับการออกแบบมาโดยเฉพาะเพื่อคอมไพล์เป็น Move bytecode และผ่านตัวตรวจสอบความถูกต้อง นี่เป็นสิ่งจำเป็นเนื่องจากกฎที่กำหนดเองเกี่ยวกับความสามารถและยืมตัวตรวจสอบ การตรวจสอบ bytecode มีความเฉพาะเจาะจงมากจนภาษาอื่น ๆ มีโอกาสน้อยที่จะรวบรวมเพื่อ Move bytecode และผ่านตัวตรวจสอบ เนื่องจาก Move สร้างขึ้นจากการตรวจสอบ bytecode ที่เฉพาะเจาะจงมากนี้ จึงไม่ยืดหยุ่นเท่ากับภาษาอย่างเช่น Rust
การถอด bytecode ทำให้ข้อดีหลักๆ ทั้งหมดของ Move หมดไป แม้ว่าคุณสมบัติประเภท ทรัพยากร และความปลอดภัยของหน่วยความจำของ Move จะถูกรักษาไว้ที่ระดับโปรแกรม แต่จะไม่ถูกรักษาไว้ทั้งหมด และความปลอดภัยระดับโปรแกรมไม่ได้นำมาซึ่งผลลัพธ์ใหม่ๆ มากนัก เราบรรลุผลสำเร็จแล้วด้วย Rust
ระบบนิเวศสัญญาอัจฉริยะของ Move ยังใช้ไม่ได้กับ Solana - โมเดลการเขียนโปรแกรมแตกต่างกันมากจนต้องเขียนส่วนสำคัญของสัญญาอัจฉริยะใหม่ เมื่อพิจารณาทั้งหมดนี้ ฉันคาดการณ์ว่าการใช้ Move ด้วย (3) จะไม่ได้รับการยอมรับ
สำหรับ (1) แนวคิดที่นี่คือ (ร่วมกับตัวโหลด SBF) เพื่อเพิ่มการรองรับสำหรับตัวโหลด Move ที่รันไทม์ สัญญาอัจฉริยะของ Move จะถูกจัดเก็บเป็น Move bytecode on-chain และดำเนินการโดย Move VM (เช่นเดียวกับใน Sui) ซึ่งหมายความว่าเราจะมีระบบนิเวศของสัญญาอัจฉริยะของ SBF และระบบนิเวศของสัญญาอัจฉริยะของ Move ซึ่งก่อนหน้านี้ทำงานบนโมเดลการเขียนโปรแกรมของ Solana ปัจจุบัน และรุ่นหลังจะทำงานบนโมเดล Move (ขั้นสูงกว่า)
ด้วยวิธีการนี้ เป็นไปได้ที่จะรักษาผลประโยชน์ทั้งหมดของการโต้ตอบระหว่างสัญญาอัจฉริยะของ Move แต่ความท้าทายประการหนึ่งในที่นี้คือการเปิดใช้งานสัญญาอัจฉริยะของ Move เพื่อโต้ตอบกับสัญญาอัจฉริยะของ SBF และในทางกลับกัน คุณต้องใช้ Move คู่หนึ่ง และสำหรับผู้ที่ มีความเข้าใจอย่างลึกซึ้งเกี่ยวกับ Solana ผู้ตรวจสอบก็ต้องได้รับการปรับเช่นกัน
นอกจากนี้ยังมีข้อเสียที่ต้องบำรุงรักษารถตักที่แตกต่างกันสองตัวในขณะรันไทม์ การดำเนินการนี้มีผลกระทบด้านความปลอดภัย เนื่องจากหมายถึงพื้นผิวการโจมตีจะเพิ่มเป็นสองเท่า ข้อผิดพลาดของตัวโหลดเพียงครั้งเดียวอาจหมายถึงห่วงโซ่ทั้งหมดถูกโจมตี การสนับสนุนก่อนหน้านี้สำหรับ MoveVM นั้นถูกเพิ่มเข้ามาใน Solana ในปี 2019 (#5150) แต่ถูกลบออกในภายหลังเนื่องจากปัญหาด้านความปลอดภัย (#11184)
สำหรับ (2) แนวคิดคือการเรียกใช้ Move VM ทั้งหมดเป็นโปรแกรม Solana เดียว (สัญญาอัจฉริยะ) Move VM ใช้งานใน Rust ดังนั้นมันอาจจะคอมไพล์เป็น SBF (เว้นแต่จะใช้เธรดหรือ API อื่นๆ ที่ไม่รองรับ) แม้ว่าสิ่งนี้จะฟังดูบ้า แต่ Neon ก็ได้ใช้แนวทางที่คล้ายกัน โดยรัน EVM เป็นโปรแกรม Solana ประโยชน์ของแนวทางนี้คือไม่จำเป็นต้องมีการปรับเปลี่ยนการรันและสามารถรักษาสมมติฐานด้านความปลอดภัยเดียวกันได้
ไม่มีวิธีโดยตรงที่จะนำฟังก์ชันหลักของ Move to Solana แม้ว่าจะสามารถสร้างส่วนหน้าของ LLVM และคอมไพล์ Move to SBF ได้ แต่การดำเนินการนี้ก็ไม่ได้ช่วยอะไรมากนักเนื่องจากรูปแบบการเขียนโปรแกรมจะยังคงเหมือนเดิม ดังที่การทดลองทางความคิดในส่วนที่ 6.1 แสดงให้เห็น โมเดลการเขียนโปรแกรมไม่สามารถปรับปรุงได้หากไม่มีการตรวจสอบความถูกต้องของรหัสไบต์ การเปลี่ยน eBPF/SBF เพื่อรองรับการตรวจสอบ bytecode จะเป็นเรื่องยากมาก ดูเหมือนว่าตัวเลือกเดียวที่สมเหตุสมผลคือการทำให้ MoveVM ทำงาน แต่นั่นหมายความว่าจะมีระบบนิเวศสองแห่งที่ทำงานบนโมเดลการเขียนโปรแกรมที่แตกต่างกัน และการทำให้พวกมันทำงานร่วมกันอย่างเหมาะสมนั้นเป็นสิ่งที่ท้าทายอย่างยิ่ง
ชื่อเรื่องรอง
6.4 ประสิทธิภาพของการย้าย
bytecode ของ Move ไม่ใช่ภาษา bytecode สำหรับใช้งานทั่วไป มีระบบประเภทที่ "แน่วแน่" มาก ซึ่งค่อนข้างก้าวหน้าเพื่อให้มีการตรวจสอบที่จำเป็นทั้งหมด ซึ่งหมายถึงประสิทธิภาพที่ต่ำกว่าเมื่อเทียบกับรูปแบบไบต์โค้ดอื่นๆ เช่น eBPF/SBF ซึ่งใกล้เคียงกับโค้ดเนทีฟ ซึ่งอาจถือว่าเป็นปัญหาสำหรับการใช้งานใน L1 ประสิทธิภาพสูง
อย่างไรก็ตาม จนถึงตอนนี้ การดำเนินการตามสัญญาอัจฉริยะไม่ได้เป็นปัญหาคอขวดสำหรับทั้ง Solana (ค่าเฉลี่ย 3k TPS ณ เวลาที่เขียน) หรือ Sui (อิงตามเกณฑ์มาตรฐาน e2e เริ่มต้นที่ทีมทำ) วิธีหลักในการปรับปรุงประสิทธิภาพการประมวลผลธุรกรรมคือการดำเนินการแบบขนาน ทั้ง Solana และ Sui ใช้สิ่งนี้โดยกำหนดให้มีการประกาศการพึ่งพาล่วงหน้าและการตั้งเวลาคู่ขนานของการดำเนินการธุรกรรมที่ขึ้นอยู่กับชุดของวัตถุ/บัญชีที่แตกต่างกัน
เมื่อคำนึงถึงทั้งหมดนี้แล้ว ฉันหวังว่าประสิทธิภาพของ Move จะไม่เป็นอุปสรรคสำคัญสำหรับอนาคตอันใกล้นี้
7. ฟังก์ชั่นอื่น ๆ ของ Move
ชื่อเรื่องรอง
7.1 ตัวตรวจสอบความถูกต้อง
Move มีเครื่องมือยืนยันอย่างเป็นทางการสำหรับสัญญาอัจฉริยะที่เรียกว่า Move Prover ด้วยเครื่องมือนี้ คุณสามารถตัดสินได้ว่าค่าคงที่ที่แตกต่างกันมีไว้สำหรับสัญญาอัจฉริยะของคุณหรือไม่ เบื้องหลัง เงื่อนไขการตรวจสอบจะถูกแปลเป็นสูตร SMT ซึ่งจะตรวจสอบโดยใช้ตัวแก้ SMT สิ่งนี้แตกต่างอย่างมากจากการฟัซซิ่ง ซึ่งเป็นการลองผิดลองถูกโดยการเดินในพื้นที่ป้อนข้อมูล เป็นต้น ตัวอย่างเช่น การทดสอบ fuzzing และ unit/integration ยังสามารถให้ผลบวกลวงได้หากไม่สามารถทดสอบอินพุตเฉพาะหรืออินพุตรวมกัน ซึ่งบ่งชี้ถึงจุดบกพร่องในโปรแกรม ในทางกลับกัน ผู้ตรวจสอบจะให้หลักฐานที่เป็นทางการว่าค่าคงที่ที่ระบุมีไว้สำหรับโปรแกรมที่จัดเตรียมไว้ มันเหมือนกับการตรวจสอบโปรแกรมกับอินพุตที่เป็นไปได้ทั้งหมด แต่ก็ไม่จำเป็น
ด้านล่างนี้คือตัวอย่างเครื่องมือตรวจสอบความถูกต้อง (นำมาจากเอกสารไวท์เปเปอร์ "การตรวจสอบสัญญาอัจฉริยะที่รวดเร็วและเชื่อถือได้อย่างเป็นทางการด้วย Move Prover")

ชื่อเรื่องรอง
7.2 ความปลอดภัยของกระเป๋าเงิน
เนื่องจาก Sui ต้องการให้ออบเจกต์ทั้งหมดที่ธุรกรรมจะเข้าถึงถูกส่งผ่านในอาร์กิวเมนต์ของฟังก์ชัน (ไม่ได้โหลดแบบไดนามิกจากสถานะส่วนกลาง) และลายเซ็นของฟังก์ชันการย้ายจะถูกเก็บไว้ใน bytecode เองพร้อมกับข้อมูลประเภท เราจึงสามารถให้กระเป๋าเงินส่งได้ ผู้ใช้ให้ ข้อมูลที่มีความหมายมากขึ้น อธิบายเนื้อหาของธุรกรรม

ตัวอย่างเช่น ถ้าเรามีฟังก์ชันที่มีลายเซ็นดังต่อไปนี้:
เราสามารถเห็นได้จากลายเซ็นของฟังก์ชันที่ธุรกรรมนี้จะเข้าถึงสินทรัพย์ 3 ประเภทของผู้ใช้ (ประเภทสินทรัพย์) ไม่เพียงแค่นั้น ตามคำหลัก & และ &mut (หรือไม่มีคำหลัก) เรายังสามารถรู้ได้ว่าเนื้อหา 1 สามารถอ่านได้ เนื้อหา 2 สามารถเปลี่ยนแปลงได้ (แต่ไม่สามารถถ่ายโอนหรือทำลายได้) และเนื้อหา 3 อาจเปลี่ยนแปลง ถ่ายโอน หรือทำลายได้ . ทำลาย
กระเป๋าเงินสามารถแสดงข้อมูลนี้แก่ผู้ใช้ ซึ่งจะสามารถรับรู้มากขึ้นว่าธุรกรรมอาจมีการดำเนินการอย่างไรกับสินทรัพย์ หากมีสิ่งผิดปกติ เช่น การเรียกใช้ธุรกรรมจากแอปพลิเคชัน Web3 แตะสินทรัพย์หรือเหรียญบางอย่างที่ไม่ควร ผู้ใช้สามารถสังเกตสิ่งนี้และตัดสินใจว่าจะไม่ดำเนินการธุรกรรมต่อ
สิ่งนี้ไม่สามารถทำได้บน Solana เนื่องจากบัญชีมีข้อมูลตามอำเภอใจจากมุมมองการดำเนินงาน คุณต้องมีคำอธิบายภายนอกของบัญชี (เฉพาะสำหรับแอปพลิเคชัน) เพื่อตีความ ซึ่งไม่จำเป็นต้องระบุโดยผู้ออกสัญญาอัจฉริยะ นอกจากนี้ แนวคิดของการเป็นเจ้าของเนื้อหาไม่มีอยู่ในรันไทม์ของ Solana และสัญญาอัจฉริยะแต่ละรายการจำเป็นต้องนำความหมายนี้ไปใช้ด้วยตนเอง (โดยปกติจะใช้ลายเซ็นบัญชีและ PDA) ซึ่งหมายความว่าไม่มีวิธีทั่วไปในการติดตามสิ่งนี้
ชื่อเรื่องรอง
7.3 การทำธุรกรรมที่ง่ายและซับซ้อน
โดยเฉพาะอย่างยิ่งสำหรับ Sui มีการเพิ่มประสิทธิภาพที่น่าสนใจในระดับฉันทามติที่อนุญาตให้ธุรกรรมบางประเภทละทิ้งฉันทามติทั้งหมดเพื่อสนับสนุนอัลกอริทึมที่ง่ายกว่าซึ่งอิงตามการออกอากาศที่สอดคล้องกันของไบแซนไทน์ ข้อดีของสิ่งนี้คือการทำธุรกรรมเหล่านี้สามารถดำเนินการแบบคู่ขนานกันในระดับฉันทามติ ขจัดการบล็อกของหัวหน้าสายงาน และบรรลุผลสำเร็จที่เกือบจะในทันที—โดยหลักแล้วตระหนักถึงความสามารถในการปรับขนาดของ web2
นี่เป็นเพราะความแตกต่างของ Sui ระหว่างวัตถุที่มีเจ้าของและสิ่งของที่ใช้ร่วมกัน (ดูหัวข้อ 3.1) การทำธุรกรรมที่เกี่ยวข้องกับวัตถุของตัวเองเท่านั้น (เรียกว่าการทำธุรกรรมอย่างง่าย) ไม่จำเป็นต้องมีฉันทามติอย่างเต็มที่ในซุย เนื่องจากอ็อบเจกต์ของตัวเองไม่สามารถใช้ในธุรกรรมอื่นนอกเหนือจากผู้ส่ง และผู้ส่งสามารถส่งธุรกรรมได้ครั้งละหนึ่งรายการเท่านั้น ในตัวมันเองหมายความว่าธุรกรรมเหล่านี้ไม่จำเป็นต้องสั่งซื้อโดยอ้างอิงถึงธุรกรรมอื่น (การสั่งซื้อทั้งหมดและการสั่งซื้อเชิงสาเหตุ) - เราทราบดีว่าทรานแซกชันอ็อบเจกต์ที่อ้างอิงในทรานแซกชันอื่นไม่สามารถรับผลกระทบได้ และทรานแซกชันไม่สามารถกระทบกับอ็อบเจกต์อื่นได้ ดังนั้นเราจึงไม่สนใจเกี่ยวกับลำดับของการทำธุรกรรมนั้นเมื่อเทียบกับธุรกรรมอื่น ๆ ที่เกิดขึ้นพร้อมกันในห่วงโซ่ - มันไม่เกี่ยวข้องกัน Sui สามารถใช้ประโยชน์จากข้อเท็จจริงนี้เพื่อเพิ่มประสิทธิภาพการประมวลผลธุรกรรมอย่างง่ายได้อย่างมาก โดยบรรลุผลสำเร็จในเวลาไม่กี่ร้อยมิลลิวินาที แต่ข้อเสียคือผู้ส่งสามารถส่งได้ครั้งละหนึ่งธุรกรรมเท่านั้น ในทางกลับกัน ธุรกรรมที่เกี่ยวข้องกับอ็อบเจกต์ที่ใช้ร่วมกันจำนวนเท่าใดก็ได้ ซึ่งเรียกว่าธุรกรรมที่ซับซ้อน จำเป็นต้องได้รับความเห็นพ้องต้องกันอย่างเต็มที่เสมอ
แอปพลิเคชันบางประเภทสามารถใช้ประโยชน์จากธุรกรรมง่ายๆ ได้ดี เนื่องจากการสร้าง ถ่ายโอน และแก้ไขออบเจกต์ของตัวเองสามารถทำได้ทั้งหมดผ่านธุรกรรมง่ายๆ ตัวอย่างที่ดีคือ NFT (รวมถึงการสร้างจำนวนมาก) และเกมบนเว็บ 3 กรณีการใช้งานเหล่านี้ได้รับประโยชน์อย่างมากจากการสิ้นสุดเวลาแฝงต่ำและการกำจัดการบล็อกเพียร์ ทำให้ผู้ใช้ได้รับประสบการณ์ที่ดีขึ้นและสามารถปรับขยายได้
แต่การใช้งานประเภทอื่น ๆ ต้องอาศัยการทำธุรกรรมที่ซับซ้อน ซึ่งรวมถึงแอปพลิเคชัน DeFi ส่วนใหญ่ ตัวอย่างเช่น แหล่งรวมสภาพคล่องของ AMM จะต้องเป็นออบเจกต์ที่ใช้ร่วมกัน เนื่องจากการดำเนินการคำสั่งแลกเปลี่ยนใดๆ ก็ตามต้องการความเห็นพ้องต้องกันทั้งหมดและการสั่งซื้อทั้งหมด เนื่องจากโดยพื้นฐานแล้ว หากหลายคำสั่งมาจากผู้ใช้หลายคนในเวลาเดียวกัน เราจำเป็นต้องตกลงว่าคำสั่งของใครจะถูกดำเนินการก่อน ซึ่งเป็นตัวกำหนดราคาดำเนินการที่ผู้ใช้แต่ละคนจะได้รับ
เอกสารประกอบของ Sui มีรายละเอียดเพิ่มเติมเกี่ยวกับธุรกรรมที่ง่ายและซับซ้อน
https://docs.sui.io/devnet/learn/sui-compared
https://docs.sui.io/devnet/learn/how-sui-works#system-overview
ชื่อระดับแรก
8. บทสรุป
บทความนี้สำรวจและเปรียบเทียบโมเดลการเขียนโปรแกรมของ Solana และ Sui ในเชิงลึก และยังกล่าวถึงภาษาโปรแกรม Move
บทที่สองเป็นบทสรุปของโมเดลการเขียนโปรแกรม Solana ในขณะที่บทที่สามแนะนำ Sui Move และโมเดลการเขียนโปรแกรม บทที่ 4 อธิบายต่อไปว่าประเภทและความปลอดภัยของทรัพยากรในการทำงานของ Move เป็นอย่างไร ความหมายโดยนัยของฟังก์ชัน Move สำหรับการพัฒนาสัญญาอัจฉริยะนั้นไม่ชัดเจนในทันที ดังนั้นในบทที่ 5 ฉันจะให้การเปรียบเทียบอย่างละเอียดยิ่งขึ้นของ Solana และ SuiMove โดยใช้ตัวอย่างในชีวิตจริง บทที่ 6 กล่าวถึง eBPF/SBF ซึ่งแสดงให้เห็นว่ามันไม่ง่ายเลยที่จะรับฟังก์ชันการย้ายหรือย้ายตัวเองเพื่อทำงานบน Solana บทที่ 7 กล่าวถึงคุณสมบัติที่เกี่ยวข้องกับการย้ายของซุย
การเขียนโปรแกรมสัญญาอัจฉริยะเป็นเรื่องเกี่ยวกับการเขียนโปรแกรมสินทรัพย์ดิจิทัล อาจกล่าวได้ว่าเป็นการเขียนโปรแกรมประเภทใหม่ซึ่งแตกต่างจากการเขียนโปรแกรมประเภทอื่น (เช่น ระบบ แบ็กเอนด์...) ที่เราเคยเห็นมามาก ด้วยเหตุนี้ ภาษาการเขียนโปรแกรมและโมเดลการเขียนโปรแกรมที่มีอยู่จึงไม่เหมาะกับกรณีการใช้งานนี้
สาระสำคัญของเรื่องคือเราต้องการรูปแบบการเขียนโปรแกรมที่ทำงานตามธรรมชาติกับทรัพยากร แต่ในขณะเดียวกันก็โต้ตอบกับรหัสที่ไม่น่าเชื่อถือ Solana ประนีประนอมที่นี่ ช่วยให้ smart contract มีความสามารถในการตั้งโปรแกรมที่จำเป็นในสภาพแวดล้อมที่ไม่ไว้วางใจ แต่รูปแบบการเขียนโปรแกรมนั้นไม่เป็นธรรมชาติสำหรับการเขียนโปรแกรมด้วยทรัพยากร การตรวจสอบ Bytecode ทำให้สามารถมีคุณสมบัติทั้งสองได้ มันเปลี่ยนรหัสที่ไม่น่าเชื่อถือให้เป็นรหัสที่เชื่อถือได้
Move เป็นภาษาโปรแกรมใหม่สำหรับการพัฒนาสัญญาอัจฉริยะ นวัตกรรมหลักของมันคือ bytecode ซึ่งออกแบบมาเพื่อให้สามารถตรวจสอบได้ แม้ว่าการตรวจสอบ bytecode จะไม่ใช่แนวคิดใหม่ แต่การยืนยันที่ Move ทำถือเป็นนวัตกรรมอย่างแท้จริง ด้วยรหัสไบต์และการตรวจสอบ Move ใช้รูปแบบการเขียนโปรแกรมสัญญาอัจฉริยะพร้อมการสนับสนุนชั้นหนึ่งสำหรับทรัพยากรและรับประกันการเขียนโปรแกรมที่ปลอดภัยในสภาพแวดล้อมที่ไม่น่าเชื่อถือ
ฉันคิดว่า Move คือการพัฒนาสัญญาอัจฉริยะ ส่วน React คือการพัฒนาส่วนหน้า การพูดว่า "สิ่งที่สามารถทำได้ใน Move สามารถทำได้ใน Rust" เหมือนกับการพูดว่า "สิ่งที่สามารถทำได้ใน React สามารถทำได้ใน jQuery" แน่นอนว่าเป็นไปได้ที่จะใช้แอปพลิเคชันที่ใช้ jQuery ซึ่งเทียบได้กับแอปพลิเคชัน React แต่ก็ไม่สามารถใช้ได้จริง React แนะนำแนวคิดของ DOM เสมือน ซึ่งนักพัฒนาสามารถเข้าใจได้อย่างสมบูรณ์ แต่ทำให้การพัฒนาส่วนหน้าเร็วขึ้น ปรับขนาดได้ และง่ายขึ้น ในทำนองเดียวกัน การตรวจสอบ bytecode ของ Move เป็นเทคโนโลยีระดับต่ำที่นักพัฒนาสามารถเข้าใจได้ง่าย แต่ก็ให้การพัฒนาสัญญาอัจฉริยะที่ถูกหลักสรีรศาสตร์ ประกอบได้ และปลอดภัยยิ่งขึ้น Move ยังลดอุปสรรคในการเข้าสู่ตลาดสำหรับผู้พัฒนาสัญญาอัจฉริยะได้อย่างมาก เนื่องจากความปลอดภัยและรูปแบบการเขียนโปรแกรมที่ใช้งานง่ายกว่า
หาก Move สามารถรับแรงดึงได้ (และมีข้อบ่งชี้ตั้งแต่เนิ่นๆ ว่าทำได้) มันอาจเป็นภัยคุกคามร้ายแรงต่อ Solana มีสองเหตุผล
ประการแรก เวลาในการพัฒนาของ Move smart contract นั้นเร็วกว่ามาก การพัฒนาสัญญาอัจฉริยะตั้งแต่เริ่มต้นใน Move สามารถทำได้เร็วกว่าใน Rust 2-5 เท่า ดังนั้นการพัฒนาระบบนิเวศของ Move จึงเหนือกว่าของ Solana เนื่องจากลักษณะที่เปิดกว้างและไม่ได้รับอนุญาตของบล็อคเชน จึงไม่มีผลล็อคอินอย่างรุนแรงและสภาพคล่องสามารถเคลื่อนย้ายได้ง่าย นักพัฒนา Solana อาจถูกบังคับให้ใช้ Move เพียงเพราะการพิจารณาทางเศรษฐกิจ - เปลี่ยนไปใช้ Move หรือถูกแซงหน้าโดยนักพัฒนา Move เพราะพวกเขาสามารถพัฒนาสัญญาอัจฉริยะที่ปลอดภัยมากขึ้นได้เร็วกว่า หากคุณต้องการจ้างนักพัฒนา Smart Contract คุณสามารถจ้างนักพัฒนา Rust ที่สามารถสร้าง Smart Contract หนึ่งรายการ หรือจ้างนักพัฒนา Move ที่สามารถสร้าง Smart Contract ที่ปลอดภัยมากกว่าสองรายการในระยะเวลาที่เท่ากัน สิ่งนี้คล้ายกับที่ React ทำกับการพัฒนาส่วนหน้า
ประการที่สอง Move มีอุปสรรคในการเข้าที่ต่ำกว่า Rust หรือ Solidity มาก เนื่องจากไวยากรณ์ของ Move นั้นง่ายกว่าและโมเดลการเขียนโปรแกรมนั้นใช้งานง่ายกว่า นักพัฒนาบางรายไม่สามารถพัฒนาสัญญาอัจฉริยะใน Rust หรือ Solidity ได้ แต่อาจทำได้ใน Move เนื่องจากมีแนวคิดที่ต้องเรียนรู้น้อยกว่า นักพัฒนาที่ไม่ใช่สมาร์ทคอนแทรคสามารถเข้าสู่ Move ได้มากกว่าการเข้าสู่ Rust (Rust เป็นภาษาที่ซับซ้อน ประกอบกับแนวคิดของ Solana เช่น PDA จะทำให้เกิดความสับสนอย่างมากสำหรับผู้เริ่มต้น) หรือ Solidity (คุณ จำเป็นต้องคุ้นเคยกับรายละเอียดปลีกย่อยของภาษา เช่น การกลับเข้ามาใหม่ เพื่อให้สามารถพัฒนาสัญญาอัจฉริยะที่ปลอดภัยได้) นั้นง่ายกว่ามาก แม้ว่านักพัฒนา Solana และ Solidity ที่มีอยู่จะไม่เปลี่ยนไปใช้ Move แต่ตลาดของนักพัฒนาที่ยังไม่ได้เข้าสู่พื้นที่นั้นมีขนาดใหญ่กว่าจำนวนนักพัฒนาที่มีอยู่ในพื้นที่ เนื่องจากอุปสรรคในการเข้าสู่ตลาดที่ต่ำกว่าของ Move และการพัฒนาที่เร็วกว่า จึงทำให้มีผลิตภัณฑ์ที่เหมาะสมกับตลาดมากกว่า Rust หรือ Solidity และสามารถแย่งชิงส่วนแบ่งที่ใหญ่กว่าได้ หากนักพัฒนารายใหม่เริ่มหลั่งไหลเข้ามา ฉันอยากให้พวกเขาเริ่มที่ Move ไม่ใช่ Rust หรือ Solidity สิ่งนี้ก็คล้ายกับ React ในอุตสาหกรรมเว็บ
ด้วยเหตุนี้ ฉันคาดหวังอย่างเต็มที่ว่า Solana จะเพิ่มการสนับสนุนระดับเฟิร์สคลาสสำหรับ Move ในระยะกลางถึงระยะยาว แต่มันไม่ง่ายเลย เพื่อให้ได้รับประโยชน์หลักของ Move จำเป็นต้องรองรับ Move bytecode ซึ่งหมายความว่าไม่สามารถรวบรวม Move เป็น eBPF/SBF ได้ (ดูหัวข้อ 6.3) เพื่อรักษาระบบนิเวศที่มีอยู่ การดำเนินการทั้งสองจำเป็นต้องได้รับการสนับสนุน ความท้าทายทางเทคนิคหลักคือทำอย่างไรจึงจะสามารถทำงานร่วมกันระหว่างการปฏิบัติงานได้อย่างเหมาะสม สิ่งนี้ต้องการความเข้าใจอย่างลึกซึ้งเกี่ยวกับ Move และ Solana ดังนั้นฉันหวังว่าทีม Solana จะผลักดันเรื่องนี้โดยตรงด้วยการสนับสนุนจากทีม Move
การย้ายเกิดขึ้นจากโครงการ Diem ของ Meta (née Facebook) ทีม Move ซึ่งนำโดย Sam Blackshear ได้รับมอบหมายให้หาวิธีจัดการกับสัญญาอัจฉริยะ หลังจากเจาะลึกปัญหา พวกเขาพบว่าการเขียนโปรแกรมสัญญาอัจฉริยะนั้นเกี่ยวกับสินทรัพย์ดิจิทัล (ทรัพยากร) แต่ไม่มีภาษาใดที่มีอยู่รองรับกรณีการใช้งานนี้ และตัดสินใจสร้างภาษาโปรแกรมใหม่ตั้งแต่เริ่มต้น


