วิธีระบุที่อยู่ของสัญญาอัจฉริยะก่อนการใช้งาน: การใช้ CREATE2 สำหรับการแลกเปลี่ยน crypto

หัวข้อของบล็อคเชนไม่ได้หยุดเป็นแหล่งที่มาของไม่เพียงแต่การโฆษณาเกินจริงทุกประเภท แต่ยังรวมถึงแนวคิดที่มีคุณค่ามากจากมุมมองทางเทคโนโลยีอีกด้วย ดังนั้นเธอจึงไม่เลี่ยงชาวเมืองที่มีแดดจ้า ผู้คนต่างมองอย่างใกล้ชิด ศึกษา และพยายามเปลี่ยนความเชี่ยวชาญในฐานข้อมูลแบบเดิมไปสู่ระบบบล็อกเชน จนถึงตอนนี้ การพัฒนาอย่างหนึ่งของ Rostelecom-Solar คือสามารถตรวจสอบความปลอดภัยของซอฟต์แวร์ที่ใช้บล็อกเชนได้ และระหว่างทาง ก็มีความคิดบางอย่างเกิดขึ้นเกี่ยวกับการแก้ปัญหาประยุกต์ของชุมชนบล็อคเชน เคล็ดลับสำคัญอย่างหนึ่งในชีวิตเหล่านี้ - วิธีระบุที่อยู่ของสัญญาอัจฉริยะก่อนที่จะปรับใช้โดยใช้ CREATE2 - วันนี้ฉันต้องการแบ่งปันกับคุณแบบเจาะลึก

วิธีระบุที่อยู่ของสัญญาอัจฉริยะก่อนการใช้งาน: การใช้ CREATE2 สำหรับการแลกเปลี่ยน crypto
CREATE2 opcode ถูกเพิ่มเข้ามาใน Constantinople hard fork เมื่อวันที่ 28 กุมภาพันธ์ปีนี้ ตามที่ระบุไว้ใน EIP opcode นี้ถูกนำมาใช้สำหรับช่องทางของรัฐเป็นหลัก อย่างไรก็ตาม เราใช้มันเพื่อแก้ไขปัญหาอื่น

มีผู้ใช้ที่มียอดคงเหลือในการแลกเปลี่ยน เราต้องจัดเตรียมที่อยู่ Ethereum ให้กับผู้ใช้แต่ละราย ซึ่งใครๆ ก็สามารถส่งโทเค็นไปให้ได้ เพื่อเป็นการเติมเต็มบัญชีของพวกเขา เรียกที่อยู่เหล่านี้ว่า "กระเป๋าสตางค์" เมื่อโทเค็นมาถึงกระเป๋าสตางค์ เราต้องส่งโทเค็นเหล่านั้นไปยังกระเป๋าสตางค์ใบเดียว (hotwallet)

ในส่วนต่อไปนี้ ฉันวิเคราะห์ตัวเลือกสำหรับการแก้ปัญหานี้โดยไม่มี CREATE2 และอธิบายว่าทำไมเราจึงละทิ้งตัวเลือกเหล่านั้น หากคุณสนใจเฉพาะผลลัพธ์สุดท้าย คุณสามารถดูได้ในส่วนวิธีแก้ปัญหาขั้นสุดท้าย

ที่อยู่อีเธอเรียม

ทางออกที่ง่ายที่สุดคือการสร้างที่อยู่ ethereum ใหม่สำหรับผู้ใช้ใหม่ ที่อยู่เหล่านี้จะเป็นกระเป๋าเงิน หากต้องการโอนโทเค็นจากกระเป๋าเงินไปยังกระเป๋าเงินด่วน คุณจะต้องลงนามในธุรกรรมโดยการเรียกใช้ฟังก์ชัน โอนย้าย() ด้วยรหัสส่วนตัวของกระเป๋าเงินจากแบ็กเอนด์

วิธีนี้มีข้อดีดังต่อไปนี้:

  • มันง่าย
  • ค่าใช้จ่ายในการโอนโทเค็นจากกระเป๋าสตางค์ไปยัง hotwallet เท่ากับค่าใช้จ่ายในการเรียกใช้ฟังก์ชัน โอนย้าย()

อย่างไรก็ตาม เราละทิ้งแนวทางนี้เนื่องจากมีข้อเสียเปรียบที่สำคัญประการหนึ่ง นั่นคือ คุณต้องเก็บคีย์ส่วนตัวไว้ที่ใดที่หนึ่ง และไม่เพียงแต่อาจสูญหายได้เท่านั้น แต่ยังต้องจัดการการเข้าถึงคีย์เหล่านี้อย่างระมัดระวังด้วย หากอย่างน้อยหนึ่งรายการถูกบุกรุก โทเค็นของผู้ใช้บางรายจะไม่เข้าถึงกระเป๋าสตางค์ร้อน

วิธีระบุที่อยู่ของสัญญาอัจฉริยะก่อนการใช้งาน: การใช้ CREATE2 สำหรับการแลกเปลี่ยน crypto

สร้างสัญญาอัจฉริยะแยกต่างหากสำหรับผู้ใช้แต่ละราย

การปรับใช้สัญญาอัจฉริยะแยกต่างหากสำหรับผู้ใช้แต่ละรายทำให้คุณไม่สามารถจัดเก็บคีย์ส่วนตัวจากกระเป๋าเงินบนเซิร์ฟเวอร์ได้ การแลกเปลี่ยนจะเรียกสัญญาอันชาญฉลาดนี้เพื่อโอนโทเค็นไปยัง hotwallet

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

Opcode CREATE2

เพื่อแก้ไขปัญหาของวิธีการก่อนหน้านี้ เราตัดสินใจใช้ CREATE2 opcode CREATE2 ช่วยให้คุณสามารถกำหนดที่อยู่ล่วงหน้าที่จะปรับใช้สัญญาอัจฉริยะ ที่อยู่คำนวณโดยใช้สูตรต่อไปนี้:

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


, ที่ไหน:

  • ที่อยู่ — ที่อยู่ของสัญญาอัจฉริยะที่จะเรียก CREATE2
  • เกลือ - ค่าสุ่ม
  • init_code - รหัสไบต์สัญญาอัจฉริยะสำหรับการปรับใช้

เพื่อให้แน่ใจว่าที่อยู่ที่เราให้ไว้กับผู้ใช้จะมีรหัสไบต์ที่ต้องการจริงๆ นอกจากนี้ สัญญาอันชาญฉลาดนี้ยังสามารถปรับใช้ได้ทุกเมื่อที่เราต้องการ ตัวอย่างเช่น เมื่อผู้ใช้ตัดสินใจใช้กระเป๋าเงินของตนเป็นครั้งแรก
วิธีระบุที่อยู่ของสัญญาอัจฉริยะก่อนการใช้งาน: การใช้ CREATE2 สำหรับการแลกเปลี่ยน crypto
นอกจากนี้ คุณสามารถคำนวณที่อยู่สัญญาอัจฉริยะในแต่ละครั้งแทนการจัดเก็บ เนื่องจาก:

  • ที่อยู่ ในสูตรจะเป็นค่าคงที่เนื่องจากเป็นที่อยู่ของโรงงานกระเป๋าเงินของเรา
  • เกลือ - แฮช user_id
  • init_code เป็นแบบถาวรเนื่องจากเราใช้กระเป๋าสตางค์ใบเดียวกัน

การปรับปรุงเพิ่มเติม

โซลูชันก่อนหน้านี้ยังคงมีข้อเสียอยู่ประการหนึ่ง นั่นคือ คุณต้องชำระเงินสำหรับการปรับใช้สัญญาอัจฉริยะ อย่างไรก็ตามคุณสามารถกำจัดมันได้ สำหรับสิ่งนี้คุณสามารถเรียกใช้ฟังก์ชันได้ โอนย้าย()แล้ว ทำลายตนเอง() ในตัวสร้างกระเป๋าเงิน จากนั้นก๊าซสำหรับการปรับใช้สัญญาอัจฉริยะจะถูกส่งคืน

ตรงกันข้ามกับความเชื่อที่นิยม คุณสามารถปรับใช้สัญญาอัจฉริยะกับที่อยู่เดียวกันได้หลายครั้งด้วยรหัส CREATE2 เนื่องจาก CREATE2 ตรวจสอบว่า nonce ของที่อยู่เป้าหมายเป็นศูนย์ (กำหนดค่า "1" ที่จุดเริ่มต้นของตัวสร้าง) ขณะเดียวกันก็มีฟังก์ชั่น ทำลายตนเอง() รีเซ็ตที่อยู่ nonce ในแต่ละครั้ง ดังนั้น หากคุณเรียก CREATE2 อีกครั้งด้วยอาร์กิวเมนต์เดียวกัน การตรวจสอบ nonce จะผ่าน

โปรดทราบว่าโซลูชันนี้คล้ายกับโซลูชันที่อยู่ ethereum แต่ไม่จำเป็นต้องจัดเก็บคีย์ส่วนตัว ค่าใช้จ่ายในการโอนเงินจากกระเป๋าเงินไปยังกระเป๋าเงินฮอตวอลเล็ตนั้นประมาณเท่ากับค่าใช้จ่ายในการเรียกใช้ฟังก์ชัน โอนย้าย()เนื่องจากเราไม่ต้องจ่ายค่าใช้จ่ายในการปรับใช้สัญญาอัจฉริยะ

การตัดสินใจครั้งสุดท้าย

วิธีระบุที่อยู่ของสัญญาอัจฉริยะก่อนการใช้งาน: การใช้ CREATE2 สำหรับการแลกเปลี่ยน crypto

เตรียมไว้เบื้องต้น:

  • ทำหน้าที่รับเกลือด้วย user_id
  • สัญญาอัจฉริยะที่จะเรียก CREATE2 opcode พร้อมเกลือที่เหมาะสม (เช่น โรงงานกระเป๋าสตางค์)
  • wallet bytecode ที่สอดคล้องกับสัญญากับตัวสร้างต่อไปนี้:

constructor () {
    address hotWallet = 0x…;
    address token = 0x…;
    token.transfer (hotWallet, token.balanceOf (address (this)));
    selfdestruct (address (0));
}


สำหรับผู้ใช้ใหม่แต่ละราย เราจะแสดงที่อยู่กระเป๋าสตางค์ของผู้ใช้โดยการคำนวณ

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


เมื่อผู้ใช้โอนโทเค็นไปยังที่อยู่กระเป๋าเงินที่เกี่ยวข้อง แบ็กเอนด์ของเราจะมองเห็นเหตุการณ์การโอนพร้อมพารามิเตอร์ _ถึงเท่ากับที่อยู่กระเป๋าสตางค์ ณ จุดนี้ เป็นไปได้ที่จะเพิ่มยอดคงเหลือของผู้ใช้ในการแลกเปลี่ยนก่อนที่จะปรับใช้กระเป๋าเงิน

เมื่อโทเค็นสะสมเพียงพอในที่อยู่กระเป๋าสตางค์ เราสามารถโอนโทเค็นทั้งหมดไปยัง hotwallet ได้ในคราวเดียว เมื่อต้องการทำเช่นนี้ แบ็กเอนด์จะเรียกใช้ฟังก์ชันโรงงานสัญญาอัจฉริยะ ซึ่งดำเนินการต่อไปนี้:

function deployWallet (соль uint256) {
    bytes memory walletBytecode =…;
    // invoke CREATE2 with wallet bytecode and salt
}


ดังนั้นจึงมีการเรียกตัวสร้างสัญญาอัจฉริยะของ Wallet ซึ่งจะถ่ายโอนโทเค็นทั้งหมดไปยังที่อยู่ Hotwallet จากนั้นจึงทำลายตัวเอง

สามารถพบได้รหัสที่สมบูรณ์ ที่นี่. โปรดทราบว่านี่ไม่ใช่รหัสที่ใช้งานจริงของเรา เนื่องจากเราตัดสินใจเพิ่มประสิทธิภาพรหัสไบต์ของกระเป๋าเงินและเขียนเป็นรหัส opcode

ผู้เขียน Pavel Kondratenkov ผู้เชี่ยวชาญ Ethereum

ที่มา: will.com

เพิ่มความคิดเห็น