เข้าร่วมชุมชน PolkaWorld และสร้าง Web 3.0 ด้วยกัน!
เมื่อ Polkadot 1.0 เวอร์ชันสุดท้ายและพาราเชนใกล้เข้ามา รูปแบบข้อความข้ามความเห็นพ้องต้องกัน หรือเรียกสั้นๆ ว่า XCM กำลังจะเปิดตัวเวอร์ชันแรกที่พร้อมสำหรับการผลิตจริง นี่คือการแนะนำรูปแบบ เป้าหมาย วิธีการทำงาน และสามารถนำไปใช้งานข้ามสายโซ่ทั่วไปได้
เมื่อ Polkadot 1.0 เวอร์ชันสุดท้ายและพาราเชนใกล้เข้ามา รูปแบบข้อความข้ามความเห็นพ้องต้องกัน หรือเรียกสั้นๆ ว่า XCM กำลังจะเปิดตัวเวอร์ชันแรกที่พร้อมสำหรับการผลิตจริง นี่คือการแนะนำรูปแบบ เป้าหมาย วิธีการทำงาน และสามารถนำไปใช้งานข้ามสายโซ่ทั่วไปได้
เริ่มจากข้อเท็จจริงที่น่าสนใจกันก่อน XCM เป็นรูปแบบข้อความ "ข้ามฉันทามติ" ไม่ใช่แค่ "ข้ามสายโซ่" ความแตกต่างนี้เป็นสัญญาณของสิ่งที่รูปแบบบรรลุในท้ายที่สุด รูปแบบที่ไม่เพียงแต่สื่อสารระหว่างเชนเท่านั้น แต่ยังรวมถึงระหว่างสัญญาอัจฉริยะและโมดูล ตลอดจนผ่านสะพานและชิ้นส่วน (เช่น Polkadot's Spree) เพื่อส่งแนวคิดต่างๆ
บรรณาธิการ mdnice
🤟 รูปแบบ ไม่ใช่โปรโตคอล
หากไม่รวมบริดจ์และโมดูลสัญญา Polkadot มาพร้อมกับระบบที่แตกต่างกันสามระบบสำหรับการสื่อสารข้อความ XCM ระหว่างเชนที่เป็นส่วนประกอบ: UMP, DMP และ XCMP UMP (Up Message Passing) ช่วยให้พาราเชนสามารถส่งข้อความไปยังรีเลย์เชนได้ DMP (Downward Messaging) ช่วยให้รีเลย์เชนส่งข้อความลงไปยังพาราเชน XCMP น่าจะมีชื่อเสียงที่สุดในบรรดาสิ่งเหล่านี้ ซึ่งช่วยให้สามารถส่งข้อความระหว่างพาราเชนได้ สามารถใช้ XCM เพื่อแสดงความหมายของข้อความผ่านช่องทางการสื่อสารทั้งสามช่องทางนี้
นอกจากการส่งข้อความระหว่างเชนแล้ว XCM ยังมีประโยชน์ในบริบทอื่นๆ เช่น สามารถใช้ทำธุรกรรมบนเชนซึ่งคุณไม่รู้จักรูปแบบธุรกรรมเป็นอย่างดีมาก่อน สำหรับเชนที่ตรรกะทางธุรกิจเปลี่ยนแปลงน้อยมาก (เช่น Bitcoin) รูปแบบการทำธุรกรรม—หรือรูปแบบกระเป๋าเงินที่ใช้เพื่อส่งคำสั่งไปยังเชน—มักจะยังคงเหมือนเดิมทุกประการ หรืออย่างน้อยก็เข้ากันได้อย่างไม่มีกำหนด การใช้เชนที่ใช้เมตาโปรโตคอลที่พัฒนาได้สูง เช่น Polkadot และพาราเชนที่เป็นส่วนประกอบ ตรรกะทางธุรกิจสามารถอัปเกรดได้ทั่วทั้งเครือข่ายด้วยธุรกรรมเดียว การดำเนินการนี้สามารถเปลี่ยนแปลงอะไรก็ได้ รวมถึงรูปแบบการทำธุรกรรม ซึ่งก่อให้เกิดปัญหาที่อาจเกิดขึ้นกับผู้ดูแลกระเป๋าเงิน โดยเฉพาะอย่างยิ่งสำหรับกระเป๋าเงินที่ต้องเก็บไว้ออฟไลน์ (เช่น Parity Signer) เนื่องจาก XCM เป็นเวอร์ชันที่ดี เป็นนามธรรม และเป็นแบบทั่วไป จึงสามารถใช้เป็นวิธีการจัดหากระเป๋าเงินที่มีรูปแบบการทำธุรกรรมแบบถาวรสำหรับการสร้างธุรกรรมทั่วไปจำนวนมาก
บรรณาธิการ mdnice
🥅เป้าหมาย
เช่นเดียวกับทุกภาษา บางคนมีแนวโน้มที่จะใช้องค์ประกอบบางอย่างมากกว่าองค์ประกอบอื่นๆ XCM ไม่ได้ออกแบบมาให้ทุกระบบที่รองรับ XCM สามารถตีความข้อความ XCM ที่เป็นไปได้ทั้งหมด บางข้อความจะไม่มีการตีความที่สมเหตุสมผลภายใต้บางระบบ อื่นๆ อาจมีเหตุผล แต่ยังคงไม่ได้รับการสนับสนุนจากล่ามโดยจงใจเนื่องจากข้อจำกัดด้านทรัพยากร หรือเนื่องจากเนื้อหาเดียวกันสามารถแสดงออกได้ชัดเจนกว่าและเป็นแบบบัญญัติมากกว่า ระบบจะสนับสนุนเฉพาะข้อความที่เป็นไปได้บางส่วนเท่านั้น ระบบที่มีข้อจำกัดด้านทรัพยากรอย่างมาก (เช่น สัญญาอัจฉริยะ) อาจรองรับเฉพาะ "ภาษาถิ่น" ที่จำกัดมากเท่านั้น
ความแพร่หลายนี้ขยายไปถึงแนวคิดต่างๆ เช่น การจ่ายเงินสำหรับการดำเนินการข้อความ XCM เนื่องจากเราทราบดีว่า XCM สามารถใช้ได้ในระบบที่หลากหลาย ตั้งแต่แพลตฟอร์มสัญญาอัจฉริยะแบบตรวจวัดก๊าซและร่มชูชีพชุมชน ไปจนถึงการโต้ตอบที่เชื่อถือได้ระหว่างร่มชูชีพระบบและโซ่รีเลย์ เราจึงไม่ต้องการอบองค์ประกอบต่างๆ เช่น การชำระค่าธรรมเนียม ลึกเกินไปและเปลี่ยนแปลงไม่ได้ในข้อตกลง
บรรณาธิการ mdnice
😬 ทำไมไม่ใช้แค่รูปแบบข้อความเนทีฟ
ประการที่สอง กรณีการใช้งานทั่วไปบนเครือข่ายไม่เหมาะกับธุรกรรมเดียวโดยง่าย อาจต้องใช้เทคนิคพิเศษในการถอนเงิน แลกเปลี่ยนเงิน แล้วฝากผลลัพธ์ทั้งหมดไว้ในธุรกรรมเดียว การแจ้งเตือนการโอนในภายหลังที่จำเป็นสำหรับเฟรมเวิร์กสินทรัพย์สำรองที่สอดคล้องกันไม่มีอยู่ในสายโซ่ที่ผู้อื่นไม่รู้จัก
ประการที่สาม การดำเนินการ เช่น การจ่ายค่าธรรมเนียมไม่เหมาะกับรูปแบบที่ถือว่าการชำระเงินค่าธรรมเนียมได้รับการเจรจาอย่างเช่นข้อความสัญญาอัจฉริยะ ในทางตรงกันข้าม ซองธุรกรรมมีระบบบางอย่างสำหรับการประมวลผลการชำระเงิน แต่โดยทั่วไปยังได้รับการออกแบบให้มีลายเซ็น ซึ่งไม่มีความหมายเมื่อสื่อสารระหว่างระบบที่สอดคล้องกัน
บรรณาธิการ mdnice
🎬 กรณีการใช้งานเบื้องต้นบางส่วน
แม้ว่า XCM มีเป้าหมายที่จะเป็นแบบทั่วไป ยืดหยุ่น และรองรับอนาคต แต่แน่นอนว่าต้องตอบสนองความต้องการในทางปฏิบัติ โดยเฉพาะอย่างยิ่งสำหรับการโอนโทเค็นระหว่างเชน การชำระค่าธรรมเนียมเพิ่มเติม (อาจใช้โทเค็นเหล่านี้) เป็นอีกวิธีหนึ่ง เช่นเดียวกับอินเทอร์เฟซทั่วไปสำหรับบริการแลกเปลี่ยน ซึ่งพบได้ทั่วไปทั่วโลกของ DeFi สุดท้าย ควรดำเนินการเฉพาะแพลตฟอร์มโดยใช้ภาษา XCM ตัวอย่างเช่น ใน Substrate chain อาจจำเป็นต้องส่งการโทรระยะไกลไปยังโมดูลใดโมดูลหนึ่งเพื่อเข้าถึงฟังก์ชันพิเศษ
ยิ่งไปกว่านั้น มีรูปแบบการโอนโทเค็นมากมายที่เราต้องการสนับสนุน: เราอาจต้องการควบคุมบัญชีบนเครือข่ายระยะไกล อนุญาตให้เครือข่ายท้องถิ่นมีที่อยู่บนเครือข่ายระยะไกลเพื่อรับเงิน และในที่สุดก็โอนเงินได้ ควบคุมไปยังบัญชีอื่น ๆ บนห่วงโซ่ระยะไกล
เราอาจมีระบบฉันทามติสองระบบ ซึ่งทั้งสองระบบเป็น "บ้านพื้นเมือง" สำหรับโทเค็นหนึ่งๆ ลองนึกภาพโทเค็นเช่น USDT หรือ USDC ที่มีอินสแตนซ์ในหลายเครือข่ายที่แตกต่างกันและสามารถใช้แทนกันได้อย่างเต็มที่ ควรเป็นไปได้ที่จะเบิร์นโทเค็นดังกล่าวบนเชนหนึ่งและสร้างโทเค็นที่สอดคล้องกันบนเชนอื่นที่รองรับ ในภาษา XCM เราเรียกมันว่าเทเลพอร์ต เพราะจริงๆ แล้วการถ่ายโอนสินทรัพย์ทำได้โดยการทำลายมันด้านหนึ่งและสร้างร่างโคลนในอีกด้านหนึ่ง
สุดท้าย อาจมีสองเชนที่ต้องการเสนอชื่อเชนที่สาม และสินทรัพย์ในหนึ่งในเชนเหล่านั้นอาจได้รับการพิจารณาว่าเป็นสินทรัพย์ดั้งเดิมเพื่อใช้เป็นทุนสำรองสำหรับสินทรัพย์นั้น รูปแบบตราสารอนุพันธ์ของสินทรัพย์บนเครือข่ายแต่ละรายการจะได้รับการสนับสนุนอย่างเต็มที่ ทำให้สามารถแลกเปลี่ยนสินทรัพย์อนุพันธ์กับสินทรัพย์อ้างอิงบนห่วงโซ่สำรองที่สำรองไว้ กรณีนี้อาจเป็นกรณีที่เครือข่าย 2 แห่งไม่จำเป็นต้องไว้วางใจซึ่งกันและกัน แต่ (อย่างน้อยเท่าที่เกี่ยวกับสินทรัพย์ที่เกี่ยวข้อง) เต็มใจที่จะไว้วางใจเครือข่ายท้องถิ่นของสินทรัพย์นั้น ตัวอย่างที่นี่คือเรามีร่มชูชีพหลายชุมชนที่ต้องการส่ง DOT ระหว่างกัน แต่ละตัวมีรูปแบบดั้งเดิมของ DOT ซึ่งได้รับการสนับสนุนอย่างเต็มที่โดย DOT ที่ควบคุมด้วยพาราเชนบนห่วงโซ่ Statemint (ศูนย์กลางท้องถิ่นของ DOT) ในขณะที่รูปแบบดั้งเดิมของ DOT ถูกส่งไปมาระหว่างเชน แต่เบื้องหลังนั้น DOT "จริง" จะย้ายระหว่างบัญชีพาราเชนบน Statemint
แม้ว่าระดับฟังก์ชันการทำงานที่ดูเรียบง่ายนี้จะมีการกำหนดค่าค่อนข้างมาก การใช้งานอาจเป็นที่ต้องการ และต้องมีการออกแบบที่น่าสนใจเพื่อหลีกเลี่ยงการใช้งานมากเกินไป
กายวิภาคของ XCM
หัวใจสำคัญของรูปแบบ XCM คือ XCVM ตรงกันข้ามกับสิ่งที่บางคนอาจเชื่อ นี่ไม่ใช่เลขโรมัน (ที่ถูกต้อง) (แม้ว่าจะมีก็ตาม อาจหมายถึง 905) อันที่จริงแล้ว สิ่งนี้ย่อมาจาก Cross Consensus Virtual Machine มันเป็นคอมพิวเตอร์ระดับสูงที่ไม่ใช่ทัวริงที่สมบูรณ์พร้อมคำสั่งที่ออกแบบมาให้อยู่ในระดับเดียวกับการทำธุรกรรม
"ข้อความ" ใน XCM เป็นเพียงโปรแกรมที่ทำงานบน XCVM เป็นคำสั่ง XCM อย่างน้อยหนึ่งคำสั่ง โปรแกรมดำเนินการจนกว่าจะทำงานจนจบหรือพบข้อผิดพลาด ซึ่งจุดนั้นจะสิ้นสุด (ฉันไม่ได้ตั้งใจอธิบายในตอนนี้) และหยุดทำงาน
enum Instruction {
TransferAsset {
assets: MultiAssets,
beneficiary: MultiLocation,
}
/* snip */
}
XCVM มีการลงทะเบียนจำนวนหนึ่ง เช่นเดียวกับการเข้าถึงสถานะโดยรวมของระบบฉันทามติที่โฮสต์ คำแนะนำอาจเปลี่ยนการลงทะเบียน อาจเปลี่ยนสถานะของระบบฉันทามติ หรือทั้งสองอย่าง
อย่างที่คุณคาดเดาได้ สินทรัพย์คือพารามิเตอร์ที่ระบุว่าสินทรัพย์ใดที่จะโอน ในขณะที่ผู้รับผลประโยชน์ระบุว่าใคร/ที่ไหนที่จะมอบสินทรัพย์เหล่านั้น แน่นอน เรายังขาดข้อมูลอีกชิ้นหนึ่งว่าใคร/จะรับเนื้อหาจากที่ใด สิ่งนี้อนุมานโดยอัตโนมัติจาก Register ดั้งเดิม ในช่วงเริ่มต้นของโปรแกรม โดยทั่วไป Register นี้จะถูกตั้งค่าตามระบบการส่งสัญญาณ (Network, XCMP หรืออื่นๆ) เพื่อสะท้อนว่าข้อความนั้นมาจากไหนจริง ๆ และผู้รับเป็นข้อมูลประเภทเดียวกัน Origin Register ทำงานเป็น Register ที่ได้รับการป้องกัน -- โปรแกรมไม่สามารถตั้งค่าได้ตามอำเภอใจ แม้ว่าจะมีสองคำแนะนำที่สามารถใช้เพื่อเปลี่ยนแปลงได้ในทางใดทางหนึ่ง
ประเภทที่ใช้เป็นแนวคิดพื้นฐานใน XCM: สินทรัพย์ ซึ่งแสดงโดย MultiAsset ตำแหน่งภายในฉันทามติ ซึ่งแสดงโดย MultiLocation Origin Register เป็น MultiLocation ที่เป็นทางเลือก (ไม่บังคับ เนื่องจากสามารถล้างข้อมูลทั้งหมดได้หากจำเป็น)
บรรณาธิการ mdnice
📍 ณ ที่ตั้งของ XCM
ประเภท MultiLocation ระบุตำแหน่งเดียวใดๆ ที่มีอยู่ในโลกที่เป็นเอกฉันท์ นี่เป็นแนวคิดที่ค่อนข้างเป็นนามธรรมที่สามารถแสดงทุกอย่างตั้งแต่บล็อกเชนแบบมัลติชาร์ดที่ปรับขนาดได้ (เช่น Polkadot) ไปจนถึงบัญชีสินทรัพย์ ERC-20 ระดับต่ำบนพาราเชนที่มีฉันทามติ ในแง่วิทยาการคอมพิวเตอร์ จริงๆ แล้วเป็นเพียงโครงสร้างข้อมูลซิงเกิลตันทั่วโลก โดยไม่คำนึงถึงขนาดหรือความซับซ้อน
MultiLocation จะแสดงตำแหน่งที่สัมพันธ์กับตำแหน่งปัจจุบันเสมอ คุณสามารถคิดว่ามันเหมือนเส้นทางของระบบไฟล์ แต่ไม่มีวิธีใดที่จะแสดง "รูท" ของโครงสร้างระบบไฟล์โดยตรง มีเหตุผลง่ายๆ สำหรับสิ่งนี้: ในโลกของ Polkadot บล็อกเชนสามารถรวมเข้ากับบล็อกเชนอื่น หรือแยกออกจากบล็อกเชนอื่น บล็อกเชนสามารถเริ่มต้นชีวิตได้อย่างอิสระและในที่สุดก็ได้รับการเลื่อนขั้นเป็นพาราเชนในฉันทามติที่ใหญ่ขึ้น หากคุณทำเช่นนั้น ความหมายของ "รูท" จะเปลี่ยนไปในชั่วข้ามคืน ซึ่งอาจทำให้ข้อความ XCM สับสนและสิ่งอื่นๆ ที่ใช้ MultiLocation เพื่อความง่าย เราได้ตัดความเป็นไปได้นี้ออกไปโดยสิ้นเชิง
ตำแหน่งใน XCM เป็นแบบลำดับชั้น โดยตำแหน่งบางส่วนในฉันทามติจะถูกรวมไว้อย่างสมบูรณ์ในที่อื่นในฉันทามติ ร่มชูชีพของ Polkadot มีอยู่ทั้งหมดภายในฉันทามติของ Polkadot โดยรวม ซึ่งเราเรียกว่าตำแหน่งภายใน เราสามารถพูดให้เคร่งครัดยิ่งขึ้นได้ว่า เมื่อใดก็ตามที่การเปลี่ยนแปลงใด ๆ ในระบบฉันทามติหนึ่งเป็นนัยถึงการเปลี่ยนแปลงในระบบฉันทามติอีกระบบหนึ่ง ระบบเดิมจะอยู่ภายในระบบหลัง ตัวอย่างเช่น สัญญาอัจฉริยะของ Canvas อยู่ภายในโมดูลสัญญาที่โฮสต์ UTXO ใน Bitcoin นั้นอยู่ภายใน Bitcoin blockchain
ซึ่งหมายความว่า XCM ไม่แยกแยะระหว่างคำถาม "ใคร" และ "ที่ไหน" จากมุมมองของสิ่งที่ค่อนข้างเป็นนามธรรมอย่าง XCM ความแตกต่างนั้นไม่สำคัญ ทั้งสองจะเบลอและกลายเป็นสิ่งเดียวกันโดยพื้นฐานแล้ว
MultiLocations ใช้เพื่อระบุว่าข้อความ XCM ถูกส่งไปที่ใด สามารถรับเนื้อหาได้จากที่ใด และยังช่วยอธิบายประเภทของเนื้อหาด้วย ดังที่เราจะเห็น สิ่งที่มีประโยชน์มาก
เมื่อเขียนลงในข้อความเช่นนี้ พวกเขาจะแสดงเป็นส่วนประกอบ .. (หรือ "พาเรนต์" ซึ่งครอบคลุมถึงระบบฉันทามติ) ตามด้วยจุดรวมบางจุด ทั้งหมดคั่นด้วย / (สิ่งนี้มักจะไม่เกิดขึ้นเมื่อเราแสดงในภาษาอย่างเช่น Rust แต่มันสมเหตุสมผลบนกระดาษเพราะมันคล้ายกับพาธไดเร็กทอรีที่คุ้นเคยในการใช้งานอย่างแพร่หลาย) การเชื่อมต่อในฉันทามติที่ห่อหุ้มไว้ ระบุระบบตำแหน่งภายใน หากไม่มีโหนดแม่/จุดเชื่อมต่อเลย เราก็แค่บอกว่าตำแหน่งนั้นอยู่ที่นี่
ตัวอย่างเช่น:
../Parachain(1000): ประเมินใน parachain ซึ่งจะระบุ parachain พี่น้องของเราด้วยดัชนี 1,000 (ใน Rust เราจะเขียน ParentThen(Parachain(1,000)).into())
Parachain(42)/AccountKey20(0x1234...abcd): ประเมินบนรีเลย์เชน สิ่งนี้จะระบุบัญชี 20 ไบต์ 0x1234...abcd บน parachain หมายเลข 42 (น่าจะคล้ายกับ Moonbeam ที่โฮสต์บัญชีที่รองรับ Ethereum)
มีจุดรวมหลายประเภทที่ใช้เพื่อระบุตำแหน่งที่คุณอาจพบในเชนด้วยวิธีต่างๆ เช่น คีย์ ดัชนี binary blobs และคำอธิบายพหูพจน์
บรรณาธิการ mdnice
💰 สินทรัพย์ใน XCM
เมื่อทำงานใน XCM มักจำเป็นต้องอ้างอิงสินทรัพย์บางประเภท นี่เป็นเพราะบล็อกเชนสาธารณะที่มีอยู่เกือบทั้งหมดพึ่งพาสินทรัพย์ดิจิทัลดั้งเดิมบางส่วนเพื่อเป็นแกนหลักของกลไกเศรษฐกิจและความปลอดภัยภายใน สำหรับบล็อกเชนที่พิสูจน์การทำงานได้ เช่น Bitcoin สินทรัพย์ดั้งเดิม (BTC) จะถูกใช้เพื่อตอบแทนนักขุดที่พัฒนาบล็อกเชนและป้องกันการใช้จ่ายซ้ำซ้อน สำหรับบล็อกเชนแบบ Proof-of-stake เช่น Polkadot จะใช้เนทีฟแอสเซ็ท (DOT) เป็นรูปแบบหลักประกันที่ผู้ดูแลระบบเครือข่าย (เรียกว่า stakers) ต้องแบกรับเพื่อสร้างบล็อกที่ถูกต้องและรับรางวัลจริง
struct MultiAsset {
id: AssetId,
fun: Fungibility,
}
บล็อกเชนบางตัวจัดการสินทรัพย์หลายรายการ เช่น กรอบ ERC-20 ของ Ethereum อนุญาตให้จัดการสินทรัพย์ต่างๆ มากมายบนเชน สินทรัพย์บางอย่างที่จัดการสิ่งที่ไม่สามารถเปลี่ยนได้ เช่น ETH ของ Ethereum นั้นใช้งานร่วมกันไม่ได้ — เป็นกรณีเฉพาะ Crypto-kitties เป็นตัวอย่างแรก ๆ ของโทเค็นหรือ NFT ที่ไม่สามารถใช้ร่วมกันได้
plain
enum AssetId {
Concrete(MultiLocation),
Abstract(BinaryBlob),
}
XCM ได้รับการออกแบบมาเพื่อจัดการกับสินทรัพย์ดังกล่าวทั้งหมดได้อย่างง่ายดาย เพื่อจุดประสงค์นี้มีประเภทข้อมูล MultiAsset และประเภทที่เกี่ยวข้อง MultiAssets, WildMultiAsset และ MultiAssetFilter ลองดูที่ MultiAsset ใน Rust:
enum Fungibility {
Fungible(NonZeroAmount),
NonFungible(AssetInstance),
}
จึงมีฟิลด์สองฟิลด์ที่กำหนดเนื้อหาของเรา: id และ fun ซึ่งเป็นตัวบ่งชี้ที่ดีว่า XCM จัดการกับเนื้อหาอย่างไร ขั้นแรก ต้องระบุตัวตนของเนื้อหาโดยรวม สำหรับสินทรัพย์ที่เปลี่ยนได้ นี่จะเป็นการระบุสินทรัพย์ สำหรับ NFT สิ่งนี้จะระบุ "คลาส" ของเนื้อหาทั้งหมด - อินสแตนซ์ของเนื้อหาที่แตกต่างกันอาจอยู่ในคลาสนี้
ข้อมูลประจำตัวของสินทรัพย์แสดงด้วยวิธีใดวิธีหนึ่งจากสองวิธี ได้แก่ รูปธรรมหรือนามธรรม บทคัดย่อไม่ได้ใช้จริง แต่อนุญาตให้ระบุ ID เนื้อหาตามชื่อ วิธีนี้สะดวก แต่ต้องอาศัยผู้รับในการตีความชื่อในแบบที่ผู้ส่งคาดหวัง ซึ่งอาจไม่ง่ายเสมอไป การใช้อย่างเป็นรูปธรรมและใช้สถานที่โดยทั่วไปเพื่อระบุทรัพย์สินอย่างชัดเจน สำหรับสินทรัพย์ดั้งเดิม (เช่น DOT) สินทรัพย์มักจะถูกระบุว่าเป็นเชนที่สร้างสินทรัพย์ (ในกรณีนี้คือโซ่รีเลย์ Polkadot ซึ่งจะเป็นจุดที่พาราเชนอยู่ .. ) สินทรัพย์ที่จัดการภายในโมดูลลูกโซ่เป็นหลักสามารถระบุได้โดยการรวมตำแหน่งที่จัดทำดัชนีไว้ภายในโมดูลนั้น ตัวอย่างเช่น Karura parachain อาจอ้างอิงถึงสินทรัพย์บน Statemine parachain ที่ ../Parachain(1000)/PalletInstance(50)/GeneralIndex(42)
ประการที่สอง พวกมันจะต้องเป็นเชื้อราหรือไม่ใช่เชื้อรา หากเป็นเชื้อรา ควรมีปริมาณที่ไม่เป็นศูนย์ที่เกี่ยวข้อง หากไม่สามารถเปลี่ยนได้ ควรระบุว่าเป็นอินสแตนซ์ใดมากกว่าปริมาณ (โดยปกติจะแสดงด้วยดัชนี แต่ XCM ยังอนุญาตประเภทข้อมูลอื่นๆ เช่น อาร์เรย์และไบนารีบล็อบ) ซึ่งครอบคลุมถึง MultiAsset แต่บางครั้งเราใช้ประเภทอื่นที่เกี่ยวข้องกันสามประเภท MultiAssets เป็นหนึ่งในนั้น และหมายถึงชุดของรายการ MultiAsset จริงๆ จากนั้นเราก็มี WildMultiAsset ซึ่งเป็นไวด์การ์ดที่สามารถใช้จับคู่รายการ MultiAsset ตั้งแต่หนึ่งรายการขึ้นไป รองรับไวด์การ์ดเพียงสองตัวเท่านั้น: ทั้งหมด (ตรงกับสินทรัพย์ทั้งหมด) และ AllOf จับคู่สินทรัพย์ทั้งหมดด้วยข้อมูลประจำตัวเฉพาะ (AssetId) และความสามารถในการใช้งานร่วมกัน โดยเฉพาะอย่างยิ่ง สำหรับกรณีหลัง ไม่จำเป็นต้องระบุปริมาณ (ในกรณีของสิ่งทดแทนได้) หรือตัวอย่าง (สำหรับสิ่งทดแทนไม่ได้) และตรงกันทั้งหมด
👉 Holding Register
ในที่สุดก็มี MultiAssetFilter นี่เป็นวิธีที่ใช้บ่อยที่สุดและเป็นเพียงการรวมกันของ MultiAssets และ WildMultiAsset ทำให้สามารถระบุรายการสินทรัพย์ที่เป็นสัญลักษณ์แทนหรือชัดเจน (เช่นไม่ใช่สัญลักษณ์แทน)
WithdrawAsset(MultiAssets),
ใน Rust XCM API เรามีการแปลงจำนวนหนึ่งเพื่อให้การทำงานกับประเภทข้อมูลเหล่านี้ง่ายที่สุดเท่าที่จะเป็นไปได้ ตัวอย่างเช่น เมื่อเราอยู่ในห่วงโซ่การถ่ายทอด Polkadot เพื่อระบุ MultiAsset ที่ใช้งานได้ (Planck สำหรับผู้ที่ทราบ) เท่ากับ 100 หน่วยสินทรัพย์ DOT ที่แบ่งแยกไม่ได้ เราจะใช้ (ที่นี่ 100)ลงใน ()
ลองดูคำสั่ง XCM อื่น: WithdrawAsset ดูเผินๆ ก็เหมือนช่วงครึ่งแรกของ TransferAsset คือถอนสินทรัพย์บางส่วนออกจากบัญชีต้นทาง แต่มันสำคัญอะไรกับพวกเขา? หากพวกเขาไม่ฝากมันไว้ที่ใด มันก็จะต้องเป็นการดำเนินการที่ไร้ประโยชน์ทีเดียว หากเราดูการประกาศของ Rust เราจะพบเบาะแสเพิ่มเติมเกี่ยวกับการใช้งาน:
enum Instruction {
DepositAsset {
assets: MultiAssetFilter,
max_assets: u32,
beneficiary: MultiLocation,
},
/* snip */
}
ดังนั้น ในครั้งนี้จึงมีเพียงพารามิเตอร์เดียว (ประเภท MultiAssets ซึ่งระบุว่าต้องถอนสินทรัพย์ใดออกจากความเป็นเจ้าของของ Origin Register) แต่ไม่ได้ระบุว่าจะวางทรัพย์สินไว้ที่ไหน
สินทรัพย์ที่ไม่ได้ใช้ซึ่งถูกถือครองชั่วคราวเหล่านี้เรียกว่าโฮลดิ้งรีจิสเตอร์ ("การระงับ" เนื่องจากอยู่ในตำแหน่งชั่วคราวที่ไม่มีกำหนด และ "ลงทะเบียน" เนื่องจากคล้ายกับการลงทะเบียน CPU ซึ่งเป็นที่สำหรับเก็บข้อมูลการทำงาน) มีคำแนะนำมากมายที่ดำเนินการกับการลงทะเบียนการระงับ คำสั่งง่ายๆ คือคำสั่ง DepositAsset ลองมาดูกัน:
อ่า! ผู้อ่านที่ชาญฉลาดจะสังเกตเห็นว่าสิ่งนี้ดูเหมือนกับคำสั่ง TransferAsset ที่ขาดหายไปครึ่งหนึ่ง เรามีพารามิเตอร์สินทรัพย์ ซึ่งระบุว่าสินทรัพย์ใดควรถูกลบออกจากทะเบียนการถือครองเพื่อฝากบนเครือข่าย max_assets ช่วยให้ผู้เขียน XCM แจ้งผู้รับว่าต้องการฝากสินทรัพย์เฉพาะจำนวนเท่าใด (สิ่งนี้มีประโยชน์เมื่อคำนวณค่าธรรมเนียมก่อนที่จะทราบเนื้อหาของทะเบียนโฮลดิ้ง เนื่องจากการฝากสินทรัพย์อาจเป็นการดำเนินการที่มีราคาแพง) สุดท้ายคือผู้รับผลประโยชน์ ซึ่งเป็นพารามิเตอร์เดียวกับที่เราพบก่อนหน้านี้ในการดำเนินการโอนสินทรัพย์ มีคำสั่งมากมายที่แสดงถึงการดำเนินการที่ต้องดำเนินการใน Holding Register และ DepositAsset เป็นหนึ่งในคำสั่งที่ง่ายที่สุด อื่น ๆ มีความซับซ้อนมากขึ้น
🤑 ชำระค่าธรรมเนียมเป็น XCM
การชำระค่าธรรมเนียมใน XCM เป็นกรณีการใช้งานที่สำคัญพอสมควร ร่มชูชีพส่วนใหญ่ในชุมชน Polkadot จะกำหนดให้คู่สนทนาของพวกเขาจ่ายสำหรับการดำเนินการใด ๆ ที่พวกเขาต้องการ เพื่อไม่ให้เปิดประตูสู่ "สแปมธุรกรรม" และการโจมตีแบบปฏิเสธการให้บริการ ข้อยกเว้นยังมีอยู่เมื่อเครือข่ายมีเหตุผลที่ดีที่จะเชื่อว่าคู่สนทนาของพวกเขาจะทำงานได้ดี - นี่คือกรณีที่เครือข่ายส่งต่อ Polkadot สื่อสารกับเครือข่ายผลประโยชน์สาธารณะของ Polkadot Statemint อย่างไรก็ตาม ในกรณีทั่วไป ค่าธรรมเนียมเป็นวิธีที่ดีในการรับรองว่าข้อความ XCM และโปรโตคอลการขนส่งจะไม่ถูกใช้งานมากเกินไป มาดูกันว่าค่าธรรมเนียมจะจ่ายอย่างไรเมื่อข้อความ XCM ไปถึง Polkadot
ตามที่กล่าวไว้ก่อนหน้านี้ XCM ไม่รวมค่าธรรมเนียมและการชำระค่าธรรมเนียมในฐานะพลเมืองชั้นหนึ่ง ซึ่งแตกต่างจากรูปแบบการทำธุรกรรม Ethereum สำหรับการชำระค่าธรรมเนียมเป็นสิ่งที่ไม่จำเป็นในโปรโตคอล จะต้องหลีกเลี่ยง เช่นเดียวกับนามธรรมที่ไม่มีต้นทุนของ Rust การจ่ายค่าธรรมเนียมไม่มีค่าใช้จ่ายในการออกแบบที่สำคัญใน XCM
สำหรับระบบที่ต้องชำระเงิน XCM ให้ความสามารถในการใช้สินทรัพย์เพื่อซื้อทรัพยากรการดำเนินการ พูดอย่างกว้าง ๆ นี้ประกอบด้วยสามส่วน:
ขั้นแรก จำเป็นต้องจัดเตรียมทรัพย์สินบางอย่าง
ประการที่สอง สินทรัพย์ต้องแลกเปลี่ยนกับเวลาคำนวณ (น้ำหนักในภาษา Substrate)
สุดท้าย การดำเนินการ XCM จะดำเนินการตามคำสั่ง
WithdrawAsset((Here, 10_000_000_000).into()),
ส่วนแรกได้รับการจัดการโดยหนึ่งในหลาย ๆ คำสั่ง XCM ที่ให้สินทรัพย์ เรารู้หนึ่งในคำสั่งเหล่านี้แล้ว ( WithdrawAsset ) แต่ยังมีอีกหลายคำสั่งที่เราจะดูในภายหลัง แน่นอนว่าทรัพย์สินที่เกิดขึ้นในทะเบียนการถือครองจะถูกใช้เพื่อชำระค่าใช้จ่ายที่เกี่ยวข้องกับการดำเนินการของ XCM สินทรัพย์ใด ๆ ที่ไม่ได้ใช้ชำระค่าธรรมเนียมจะถูกฝากเข้าบัญชีปลายทาง ในตัวอย่างของเรา เราถือว่า XCM เกิดขึ้นบนรีเลย์เชนของ Polkadot และมีการแลกเปลี่ยน 1 DOT (เช่น 10,000,000,000 หน่วยที่แบ่งแยกไม่ได้)
enum Instruction {
/* snip */
BuyExecution {
fees: MultiAsset,
weight: u64,
},
}
ขณะนี้คำสั่ง XCM ของเรามีลักษณะดังนี้:
สิ่งนี้นำเราไปสู่ส่วนที่สอง การแลกเปลี่ยน (ส่วนหนึ่งของ) สินทรัพย์เหล่านี้เพื่อแลกกับเวลาในการคำนวณเพื่อจ่ายให้เราเป็น XCM สำหรับสิ่งนี้ เรามีคำสั่ง XCM BuyExecution มาดูกันว่าหน้าตาเป็นอย่างไร:
ค่าธรรมเนียมรายการแรกคือจำนวนเงินที่ควรถอนออกจากทะเบียนโฮลดิ้งและใช้เพื่อชำระค่าธรรมเนียม ในทางเทคนิคแล้ว นี่เป็นเพียงค่าสูงสุดเท่านั้น เนื่องจากยอดคงเหลือที่ไม่ได้ใช้จะได้รับการคืนทันที
WithdrawAsset((Here, 10_000_000_000).into()),
BuyExecution {
fees: (Here, 10_000_000_000).into(),
weight: 3_000_000,
},
จำนวนเงินสุดท้ายที่ใช้ไปขึ้นอยู่กับระบบการแปล - ค่าธรรมเนียมเป็นเพียงการจำกัด และหากระบบการแปลจำเป็นต้องจ่ายมากขึ้นสำหรับการดำเนินการที่ต้องการ คำสั่ง BuyExecution จะทำให้เกิดข้อผิดพลาด รายการที่สองระบุระยะเวลาการดำเนินการที่จะซื้อ โดยทั่วไปไม่ควรน้อยกว่าน้ำหนักรวมของโปรแกรม XCM
ในตัวอย่างของเรา เราสมมติน้ำหนัก 1 ล้านสำหรับคำสั่ง XCM ทั้งหมด จนถึงขณะนี้เรามีสองโครงการ (WithdrawAsset และ BuyExecution) ที่ 2 ล้าน และอีกหนึ่งโครงการที่จะตามมา เราจะใช้ DOT ทั้งหมดที่เราต้องจ่ายค่าธรรมเนียมเหล่านั้น (ซึ่งจะสมเหตุสมผลก็ต่อเมื่อเราไว้วางใจให้เชนปลายทางไม่มีค่าธรรมเนียมบ้าๆ บอๆ สมมติว่าเป็นเช่นนั้น) ณ จุดนี้ มาดู XCM ของเรา:
WithdrawAsset((Here, 10_000_000_000).into()),
BuyExecution {
fees: (Here, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parachain(1000).into(),
},ส่วนที่ 3 ของ XCM ของเราคือการฝากเงินที่เหลืออยู่ในทะเบียนโฮลดิ้ง สำหรับสิ่งนี้ เราจะใช้คำสั่ง DepositAsset เราไม่รู้จริง ๆ ว่าเหลืออยู่ในทะเบียนโฮลดิ้งเท่าไร แต่นั่นไม่สำคัญเนื่องจากเราสามารถระบุสัญลักษณ์ตัวแทนสำหรับสินทรัพย์ที่ควรฝากได้ เราใส่ไว้ในบัญชีอธิปไตยใน Statemint (ระบุว่าเป็น Parachain(1000))
ดังนั้นคำสั่ง XCM สุดท้ายของเราจึงมีลักษณะดังนี้:
การส่งเนื้อหาไปยังเครือข่ายอื่นน่าจะเป็นกรณีการใช้งานทั่วไปสำหรับการส่งข้อความระหว่างเครือข่าย การอนุญาตให้เชนหนึ่งจัดการสินทรัพย์ที่มาจากอีกเชนหนึ่งจะอนุญาตให้มีกรณีการใช้งานอนุพันธ์ที่หลากหลาย (ไม่ได้ตั้งใจเล่นสำนวน) การแลกเปลี่ยนที่ง่ายที่สุดคือการแลกเปลี่ยนแบบกระจายอำนาจ แต่มักจะถูกรวมอยู่ภายใต้การกระจายอำนาจทางการเงินหรือ De-Fi
โดยทั่วไป มีสองวิธีสำหรับสินทรัพย์ที่จะย้ายระหว่างเชน ขึ้นอยู่กับว่าเชนนั้นเชื่อถือความปลอดภัยและตรรกะของกันและกันหรือไม่
บรรณาธิการ mdnice
✨เทเลพอร์ต
WithdrawAsset((Here, 10_000_000_000).into()),
InitiateTeleport {
assets: All.into(),
dest: Parachain(1000).into(),
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parent.into(),
},
]),
}
สำหรับห่วงโซ่ที่ไว้วางใจซึ่งกันและกัน (เช่น ชิ้นส่วนที่เป็นเนื้อเดียวกันภายใต้ความเห็นพ้องต้องกันโดยรวมและร่มความปลอดภัยเดียวกัน) เราสามารถใช้เฟรมเวิร์กของ Polkadot ที่เรียกว่าการเคลื่อนย้ายทางไกล ซึ่งโดยทั่วไปหมายถึงการทำลายทรัพย์สินในฝั่งส่งและสร้างมันในฝั่งรับ วิธีการป้องกันนี้ทั้งง่ายและมีประสิทธิภาพ - ต้องการเพียงการประสานกันของโซ่สองเส้นและเกี่ยวข้องกับการกระทำเพียงครั้งเดียวในแต่ละด้าน น่าเสียดาย หากเชนรับไม่สามารถไว้วางใจได้ 100% ว่าเชนส่งทำลายสินทรัพย์ที่กำลังสร้าง (และไม่ได้สร้างสินทรัพย์นอกกฎที่ตกลงไว้ของสินทรัพย์) ดังนั้นเชนส่งก็ไม่มีเหตุผลที่จะสร้างสินทรัพย์ตาม ข้อความ.
มาดูกันว่า XCM จะโอน (ส่วนใหญ่) 1 DOT จาก Polkadot รีเลย์เชนไปยังบัญชีอธิปไตยบน Statemint อย่างไร เราถือว่า Polkadot ได้ชำระค่าธรรมเนียมแล้ว
อย่างที่คุณเห็น มันคล้ายกับโมเดลการถอน-ซื้อ-การฝากโดยตรงที่เราเห็นเมื่อครั้งที่แล้ว ข้อแตกต่างคือคำสั่ง InitiateTeleport ซึ่งแทรกอยู่รอบๆ สองคำสั่งสุดท้าย (BuyExecution และ DepositAsset) เบื้องหลัง ห่วงโซ่การส่ง (ห่วงโซ่การส่งต่อ Polkadot) กำลังสร้างข้อความใหม่ล่าสุดเมื่อดำเนินการตามคำสั่ง InitiateTeleport จะใช้ฟิลด์ xcm และใส่ลงใน XCMReceiveTeleportedAsset ใหม่ จากนั้นส่ง XCM นี้ไปยังห่วงโซ่การรับ (Statemint) Statemint เชื่อว่าโซ่รีเลย์ Polkadot ได้ทำลาย 1 DOT ที่ด้านข้างก่อนที่จะส่งข้อความ (และมันก็เป็น!)
ReceiveTeleportedAsset((Parent, 10_000_000_000).into()),
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: Parent.into(),
},
ผู้รับผลประโยชน์ได้รับการประกาศเป็น Parent.into() ผู้อ่านที่ชาญฉลาดอาจสงสัยว่าสิ่งนี้หมายถึงอะไรในบริบทของห่วงโซ่การส่งต่อ Polkadot คำตอบคือ "ไม่มีอะไร" แต่ไม่มีอะไรผิดปกติที่นี่ ทุกอย่างในพารามิเตอร์ xcm ถูกเขียนขึ้นจากมุมมองของผู้รับ ดังนั้นในขณะที่นี่เป็นส่วนหนึ่งของ XCM โดยรวมที่ป้อนเข้าสู่ Polkadot รีเลย์เชน จริง ๆ แล้วมันถูกดำเนินการบน Statemint เท่านั้น ดังนั้นบริบทจึงตามด้วย Statemint หายไป
ดังที่คุณอาจสังเกตเห็นว่าสิ่งนี้ดูคล้ายกับ WithdrawAsset XCM ก่อนหน้านี้มาก ข้อแตกต่างที่สำคัญประการเดียวคือ แทนที่จะเสียค่าธรรมเนียมการระดมทุนและการฝากเงินโดยการถอนออกจากบัญชีท้องถิ่น ระบบจะใช้ข้อความ เป็นที่น่าสังเกตว่าตัวระบุสินทรัพย์ของ 1 DOT ที่เราส่งไปบนรีเลย์เชนของ Polkadot (ในที่นี้หมายถึงรีเลย์เชนเองคือสภาพแวดล้อมดั้งเดิมของ DOT) ได้รับการกลายพันธุ์โดยอัตโนมัติเพื่อเป็นตัวแทนของมันใน Statemint: Parent. into() ตำแหน่งของรีเลย์เชนในบริบทของ Statemint
ผู้รับผลประโยชน์ยังถูกกำหนดให้เป็นห่วงโซ่การส่งต่อของ Polkadot ดังนั้นบัญชีอธิปไตย (บน Statemint) จะได้รับเครดิตด้วย 1 DOT ลบค่าธรรมเนียมที่เพิ่งสร้างใหม่ XCM อาจระบุบัญชีสำหรับผู้รับผลประโยชน์หรืออย่างอื่นได้อย่างง่ายดาย ในความเป็นจริง 1 DOT นี้สามารถย้ายได้โดยใช้ TransferAsset ที่ตามมาซึ่งส่งมาจากรีเลย์เชน
บรรณาธิการ mdnice
🏦สำรอง
อีกวิธีในการโอนสินทรัพย์ข้ามเครือข่ายนั้นซับซ้อนกว่าเล็กน้อย ใช้บุคคลที่สามที่เรียกว่ากองหนุน ชื่อนี้มาจากระบบการสำรองของธนาคาร ซึ่งสินทรัพย์จะถูก "สงวนไว้" เพื่อให้ความน่าเชื่อถือแก่คำมั่นสัญญาเกี่ยวกับมูลค่าที่ตีพิมพ์ ตัวอย่างเช่น หากเรามีเหตุผลที่จะเชื่อได้ว่า DOT "ที่ได้มา" แต่ละรายการที่ออกบนพาราเชนอิสระสามารถแลกเปลี่ยนเป็น DOT "จริง" ได้ 1 DOT (เช่น Statemint หรือ DOT บนรีเลย์เชน) เราก็สามารถทำให้ DOT ของพาราเชนเป็น ถือว่าประหยัดเทียบเท่ากับ DOT จริง (ธนาคารส่วนใหญ่ทำธนาคารสำรองแบบเศษส่วน ซึ่งหมายความว่าพวกเขาเก็บเงินสำรองไว้น้อยกว่ามูลค่าที่ตราไว้ ซึ่งปกติแล้วจะใช้ได้ แต่อาจผิดพลาดได้อย่างรวดเร็วเมื่อมีคนจำนวนมากเกินไปต้องการไถ่ถอน) ดังนั้น เงินสำรองเป็นสถานที่สำหรับเก็บ "ของจริง" สินทรัพย์เพื่อวัตถุประสงค์ในการส่งซึ่งตรรกะและความปลอดภัยได้รับความไว้วางใจจากทั้งผู้ส่งและผู้รับ สินทรัพย์ที่เกี่ยวข้องใดๆ ของผู้ส่งและผู้รับจะเป็นอนุพันธ์ แต่จะได้รับการสนับสนุน 100% โดยสินทรัพย์สำรอง "ของจริง" สมมติว่าพาราเชนมีพฤติกรรมที่ดี (กล่าวคือ ไม่มีข้อบกพร่องและการกำกับดูแลไม่ได้ตัดสินใจขโมยของสำรองและหลบหนีไป) สิ่งนี้จะทำให้ DOT อนุพันธ์มีค่าใกล้เคียงกันโดยประมาณกับ DOT สำรองพื้นฐาน สินทรัพย์สำรองถูกเก็บไว้ในบัญชีผู้ส่ง/ผู้รับ (เช่น บัญชีที่ควบคุมโดยผู้ส่งหรือผู้รับ) บนห่วงโซ่สำรอง ดังนั้น เว้นแต่จะมีปัญหากับ parachain มีเหตุผลที่ดีที่จะเชื่อได้ว่าสินทรัพย์เหล่านี้จะได้รับการคุ้มครองอย่างดี ของ.
WithdrawAsset((Parent, 10_000_000_000).into()),
InitiateReserveWithdraw {
assets: All.into(),
dest: ParentThen(Parachain(1000)).into(),
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositReserveAsset {
assets: All.into(),
max_assets: 1,
dest: ParentThen(Parachain(2001)).into(),
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: ParentThen(Parachain(2000)).into(),
},
]),
},
]),
},
ย้อนกลับไปที่กลไกการโอน ผู้ส่งจะสั่งให้เงินสำรองโอนสินทรัพย์ที่เป็นของผู้ส่ง (และใช้เป็นเงินสำรองสำหรับสินทรัพย์รุ่นเดียวกัน) ไปยังบัญชีอธิปไตยของผู้รับ และเงินสำรอง (แทนที่จะเป็น ฝ่ายผู้ส่ง!) เพื่อแจ้งให้ผู้รับทราบถึงทรัพย์สินใหม่ของพวกเขา ซึ่งหมายความว่าผู้ส่งและผู้รับไม่จำเป็นต้องเชื่อถือตรรกะหรือความปลอดภัยของกันและกัน แต่จะเชื่อในตรรกะหรือความปลอดภัยของห่วงโซ่ที่ใช้เป็นข้อมูลสำรองเท่านั้น อย่างไรก็ตาม หมายความว่าทั้งสามฝ่ายจำเป็นต้องประสานงานกัน ซึ่งจะเพิ่มต้นทุน เวลา และความซับซ้อนโดยรวม
WithdrawAsset((Parent, 10_000_000_000).into()),
InitiateReserveWithdraw {
assets: All.into(),
dest: ParentThen(Parachain(1000)).into(),
xcm: /* snip */
}
มาดู XCM ที่จำเป็นกัน ครั้งนี้เราจะส่ง 1 DOT จาก parachain 2000 ไปยัง parachain 2001 ซึ่งใช้ DOT สำรองสำรองบน parachain 1000 อีกครั้ง เราถือว่าค่าธรรมเนียมได้ชำระให้กับผู้ส่งแล้ว
/*snip*/
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositReserveAsset {
assets: All.into(),
max_assets: 1,
dest: ParentThen(Parachain(2001)).into(),
xcm: /* snip */
},
]),
/*snip*/
อย่างที่ฉันพูดไปก่อนหน้านี้ มันจะซับซ้อนเล็กน้อย มาดูขั้นตอนกัน ส่วนภายนอกมีหน้าที่รับผิดชอบในการถอน 1 DOT บนผู้ส่ง (parachain 2000) และถอน 1 DOT ที่สอดคล้องกันบน Statemint (parachain 1000) - สำหรับสิ่งนี้ จะใช้ InitiateReserveWithdraw ซึ่งทำหน้าที่ตามที่กล่าวไว้
/*snip*/
xcm: Xcm(vec![
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: ParentThen(Parachain(2000)).into(),
},
]),
/*snip*/
ตอนนี้เรามี 1 DOT ในทะเบียนโฮลดิ้งของ Statemint ก่อนที่เราจะทำสิ่งอื่น เราต้องซื้อเวลาในการดำเนินการบน Statemint กระบวนการนี้ดูคุ้นเคยเช่นกัน:
ReserveAssetDeposited((Parent, 10_000_000_000).into()),
BuyExecution {
fees: (Parent, 10_000_000_000).into(),
weight: 3_000_000,
},
DepositAsset {
assets: All.into(),
max_assets: 1,
beneficiary: ParentThen(Parachain(2000)).into(),
},
เราใช้ 1 DOT ของเราเองเพื่อชำระค่าธรรมเนียม และเราถือว่า 1 ล้านต่อการดำเนินการ XCM หลังจากชำระเงินสำหรับการดำเนินการนี้แล้ว เราฝาก 1 DOT (ลบค่าธรรมเนียม และเราขี้เกียจ เราจึงใช้ All.into()) เข้าในบัญชีอธิปไตยของ Parachain 2001 แต่จะทำในลักษณะสินทรัพย์สำรอง ซึ่งหมายความว่า เรายังขอให้ Statemint ส่งการแจ้งเตือน XCM ไปยังห่วงโซ่การรับนี้ เพื่อแจ้งให้ทราบถึงการโอนและคำแนะนำบางอย่างที่จะดำเนินการกับสินทรัพย์อนุพันธ์ที่เป็นผลลัพธ์ คำสั่ง DepositReserveAsset ไม่ได้ผลเสมอไป เพื่อให้ทำงานได้ ปลายทางจะต้องเป็นตำแหน่งที่กองทุนสามารถถือครองได้อย่างสมเหตุสมผลในห่วงโซ่สำรอง และตำแหน่งที่ห่วงโซ่สำรองสามารถส่ง XCM ไป บราเดอร์ Parachains พอดีกับใบเสร็จ
ส่วนสุดท้ายกำหนดส่วนของข้อความที่มาถึง parachain 2001 เช่นเดียวกับการเริ่มดำเนินการถ่ายโอน DepositReserveAsset เขียนและส่งข้อความใหม่ ในกรณีนี้คือ ReserveAssetDeposited ข้อความนี้แม้ว่าจะมีโปรแกรม XCM ที่เรากำหนดไว้ ซึ่งส่งถึงพาราเชนที่ได้รับ ดูเหมือนว่า:
(ซึ่งถือว่า Statemint ไม่ได้เรียกเก็บค่าธรรมเนียมใดๆ และผ่าน 1 DOT ทั้งหมด ซึ่งไม่เป็นไปตามความเป็นจริงอย่างยิ่ง ดังนั้นตัวเลขสำหรับรายการสินทรัพย์อาจต่ำกว่านี้) ข้อความนี้ส่วนใหญ่ควรดูคุ้นเคย ; ข้อแตกต่างที่โดดเด่นเพียงอย่างเดียวจากข้อความ GetTeleportedAsset ที่เราเห็นในส่วนก่อนหน้านี้คือคำสั่งระดับบนสุด ReserveAssetDeposited ซึ่งบรรลุวัตถุประสงค์ที่คล้ายกัน ยกเว้นว่า "ห่วงโซ่การส่งทำลายสินทรัพย์ ดังนั้นคุณจึงสร้างสินทรัพย์ที่เทียบเท่าได้" ซึ่งหมายความว่า คือ "ห่วงโซ่การส่งได้รับสินทรัพย์และเก็บไว้ให้คุณ ดังนั้นคุณจึงสามารถสร้างตราสารอนุพันธ์ที่สนับสนุนโดยสินทรัพย์ทั้งหมด" ไม่ว่าจะด้วยวิธีใด เชนปลายทางจะส่งมันไปยังโฮลดิ้งรีเสิร์ฟ และเราจะฝากมันไว้ในบัญชีอธิปไตยของผู้ส่งในเชนรับ 🎉
“
🏁 สรุป
