สัญญาอัจฉริยะจะไม่เปลี่ยนรูปเมื่อใช้งานบนบล็อกเชน ซึ่งหมายความว่าไม่สามารถแก้ไขได้ ดังนั้นข้อบกพร่องหรือช่องโหว่ด้านความปลอดภัยใดๆ อาจมีผลกระทบร้ายแรง ทำให้การทดสอบเป็นขั้นตอนที่ขาดไม่ได้ในกระบวนการพัฒนา
ในบทนี้ เราจะพูดถึงสัญญา Fa1_2TestFull
ซึ่งรวมถึงชุดการทดสอบที่ออกแบบมาเพื่อตรวจสอบการทำงานของสัญญาโทเค็นของเรา
Fa1_2TestFull
สัญญา Fa1_2TestFull
เป็นคลาสที่สืบทอดฟังก์ชันทั้งหมดจากสัญญาต่างๆ เช่น Admin, Pause, Fa1_2, Mint, Burn และ ChangeMetadata ใช้เพื่อรวมฟังก์ชันการทำงานเหล่านี้ทั้งหมดและทำการทดสอบอย่างละเอียดเพื่อให้แน่ใจว่าสัญญาทำงานได้ตามที่คาดหวัง
Python
คลาส Fa1_2TestFull (ผู้ดูแลระบบ, หยุดชั่วคราว, Fa1_2, มิ้นท์, เบิร์น, ChangeMetadata):
def __init__(ตนเอง, ผู้ดูแลระบบ, ข้อมูลเมตา, บัญชีแยกประเภท, token_metadata):
ChangeMetadata __init__(ตนเอง)
เผา.__init__(ตนเอง)
สะระแหน่.__init__(ตนเอง)
ฟ้า1_2.__init__(ตนเอง ข้อมูลเมตา, บัญชีแยกประเภท, token_metadata)
หยุดชั่วคราว __init__(ตนเอง)
ผู้ดูแลระบบ __init__(ตนเอง ผู้ดูแลระบบ)
ตัวสร้างคลาส Fa1_2TestFull
เตรียมใช้งานฟังก์ชันการทำงานทั้งหมด
สำหรับสัญญาของเรา เราเริ่มต้นด้วยการตั้งค่าสถานการณ์การทดสอบด้วยบัญชีทดสอบและการเริ่มต้นสัญญา นี้จะกระทำภายในฟังก์ชั่นการทดสอบที่ตกแต่งด้วย @sp.add_test
Python
@sp.add_test(name="FA12")def test():
# เริ่มต้นสถานการณ์การทดสอบและบัญชี
sc = sp.test_scenario(m)
ผู้ดูแลระบบ = sp.test_account("ผู้ดูแลระบบ")
อลิซ = sp.test_account("อลิซ")
บ๊อบ = sp.test_account("โรเบิร์ต")
# เริ่มต้นสัญญาด้วยค่าเริ่มต้นบางค่า
token_metadata = {
"decimals": sp.utils.bytes_of_string("18"), # Mandatory by the spec"name": sp.utils.bytes_of_string("My Great Token"), # Recommended"symbol": sp.utils.bytes_of_string("MGT"), # Recommended# Extra fields"icon": sp.utils.bytes_of_string("https://smartpy.io/static/img/logo-only.svg"),
}
Contract_metadata = sp.utils.metadata_of_url("ipfs://QmaiAUj1FFNGYTu8rLBjc3eeN9cSKwaF8EGMBNDmhzPNFd")
c1 = m.Fa1_2TestFull(ผู้ดูแลระบบ=admin.address,metadata=contract_metadata,token_metadata=token_metadata,ledger={},)
สค += ค1
เรากำหนดบัญชีทดสอบ: ผู้ดูแลระบบ อลิซ และบ็อบ จากนั้นเราเริ่มต้นสัญญาของเรา Fa1_2TestFull
ด้วยค่าเริ่มต้นบางส่วน ตัวดำเนินการ +=
เพิ่มสัญญาเข้ากับสถานการณ์จำลอง
จากนี้ไป เพื่อช่วยให้คุณเข้าใจโค้ดได้ดีขึ้น โค้ดจะอยู่ด้านซ้ายและการแสดงบรรทัดโค้ดที่ไฮไลต์ไว้จะอยู่ทางด้านขวา ตัวอย่างที่นี่:
ขั้นตอนต่อไปคือการเรียกใช้การทดสอบ ซึ่งเกี่ยวข้องกับการเรียกใช้ฟังก์ชันสัญญาต่างๆ และตรวจสอบผลลัพธ์
ตัวอย่างเช่น เพื่อทดสอบฟังก์ชันการทำเหรียญ เราดำเนินการ:
Python
sc.h2("ผู้ดูแลระบบทำเหรียญไม่กี่เหรียญ")
c1.mint(address=alice.address, value=12).run(sender=admin)
บรรทัดนี้รันการทดสอบโดยที่ผู้ดูแลระบบสร้างโทเค็น 12 อันให้กับอลิซ หากฟังก์ชันสร้างโทเค็นได้สำเร็จและอัปเดตยอดคงเหลือของ Alice อย่างถูกต้อง การทดสอบนี้จะผ่านไป
SmartPy จัดเตรียมวิธี verify
เพื่อให้แน่ใจว่าเงื่อนไขเป็นจริง ถ้าไม่ตรงตามเงื่อนไข การทดสอบจะล้มเหลว ตัวอย่างเช่น:
Python
c1.update_metadata(key="", value=sp.bytes("0x00")).run(sender=admin)
sc.verify(c1.data.metadata[""] == sp.bytes("0x00"))
บรรทัดเหล่านั้นตรวจสอบว่าข้อมูลเมตาของสัญญาได้รับการอัปเดตเป็น "0x00"
อย่างถูกต้อง หากไม่ได้รับการอัพเดตอย่างถูกต้อง การทดสอบจะล้มเหลว
การทดสอบสัญญาอัจฉริยะของคุณควรครอบคลุมกรณีการใช้งานที่เป็นไปได้ทั้งหมด รวมถึงกรณี Edge และความล้มเหลวที่อาจเกิดขึ้น สิ่งเหล่านี้อาจรวมถึงการโอนที่เกินยอดคงเหลือของผู้ใช้ การเบิร์นโทเค็นเมื่อสัญญาถูกหยุดชั่วคราว ฯลฯ
ตัวอย่างเช่น การทดสอบการถ่ายโอนที่ล้มเหลวอาจมีลักษณะดังนี้:
Python
sc.h2("Bob พยายามถ่ายโอนจาก Alice แต่เขาไม่ได้รับการอนุมัติจากเธอ")
c1.transfer(from_=alice.address, ถึง_=bob.address, ค่า=4).รัน(ผู้ส่ง=บ๊อบ, ถูกต้อง=เท็จ)
ในกรณีนี้ Bob พยายามโอนโทเค็น 4 รายการจากบัญชีของ Alice โดยไม่ได้รับการอนุมัติ เนื่องจากการดำเนินการนี้ควรจะล้มเหลว เราจึงตั้ง valid=False
ในฟังก์ชัน run
หากสัญญาป้องกันการถ่ายโอนอย่างถูกต้อง การทดสอบก็จะผ่าน
การทดสอบเป็นสิ่งสำคัญในการพัฒนาสัญญาอัจฉริยะ เนื่องจากธรรมชาติของบล็อกเชนที่ไม่เปลี่ยนแปลง ข้อผิดพลาดใดๆ ในสัญญาอาจส่งผลที่ตามมาอย่างถาวรและอาจมีค่าใช้จ่ายสูง การเขียนการทดสอบที่ครอบคลุมช่วยให้แน่ใจว่าฟังก์ชันทั้งหมดทำงานตามที่คาดหวัง นำไปสู่สัญญาที่แข็งแกร่งและปลอดภัย
อย่าลืมเขียนแบบทดสอบสำหรับทั้งกรณีบวกและลบ กรณีที่เป็นค่าบวกจะตรวจสอบว่าฟังก์ชันทำงานได้อย่างถูกต้องเมื่อใช้ตามที่ตั้งใจไว้ กรณีเชิงลบทำให้สัญญาทำงานอย่างถูกต้องในการจัดการอินพุตที่ไม่ถูกต้องหรือไม่คาดคิด
สัญญาอัจฉริยะจะไม่เปลี่ยนรูปเมื่อใช้งานบนบล็อกเชน ซึ่งหมายความว่าไม่สามารถแก้ไขได้ ดังนั้นข้อบกพร่องหรือช่องโหว่ด้านความปลอดภัยใดๆ อาจมีผลกระทบร้ายแรง ทำให้การทดสอบเป็นขั้นตอนที่ขาดไม่ได้ในกระบวนการพัฒนา
ในบทนี้ เราจะพูดถึงสัญญา Fa1_2TestFull
ซึ่งรวมถึงชุดการทดสอบที่ออกแบบมาเพื่อตรวจสอบการทำงานของสัญญาโทเค็นของเรา
Fa1_2TestFull
สัญญา Fa1_2TestFull
เป็นคลาสที่สืบทอดฟังก์ชันทั้งหมดจากสัญญาต่างๆ เช่น Admin, Pause, Fa1_2, Mint, Burn และ ChangeMetadata ใช้เพื่อรวมฟังก์ชันการทำงานเหล่านี้ทั้งหมดและทำการทดสอบอย่างละเอียดเพื่อให้แน่ใจว่าสัญญาทำงานได้ตามที่คาดหวัง
Python
คลาส Fa1_2TestFull (ผู้ดูแลระบบ, หยุดชั่วคราว, Fa1_2, มิ้นท์, เบิร์น, ChangeMetadata):
def __init__(ตนเอง, ผู้ดูแลระบบ, ข้อมูลเมตา, บัญชีแยกประเภท, token_metadata):
ChangeMetadata __init__(ตนเอง)
เผา.__init__(ตนเอง)
สะระแหน่.__init__(ตนเอง)
ฟ้า1_2.__init__(ตนเอง ข้อมูลเมตา, บัญชีแยกประเภท, token_metadata)
หยุดชั่วคราว __init__(ตนเอง)
ผู้ดูแลระบบ __init__(ตนเอง ผู้ดูแลระบบ)
ตัวสร้างคลาส Fa1_2TestFull
เตรียมใช้งานฟังก์ชันการทำงานทั้งหมด
สำหรับสัญญาของเรา เราเริ่มต้นด้วยการตั้งค่าสถานการณ์การทดสอบด้วยบัญชีทดสอบและการเริ่มต้นสัญญา นี้จะกระทำภายในฟังก์ชั่นการทดสอบที่ตกแต่งด้วย @sp.add_test
Python
@sp.add_test(name="FA12")def test():
# เริ่มต้นสถานการณ์การทดสอบและบัญชี
sc = sp.test_scenario(m)
ผู้ดูแลระบบ = sp.test_account("ผู้ดูแลระบบ")
อลิซ = sp.test_account("อลิซ")
บ๊อบ = sp.test_account("โรเบิร์ต")
# เริ่มต้นสัญญาด้วยค่าเริ่มต้นบางค่า
token_metadata = {
"decimals": sp.utils.bytes_of_string("18"), # Mandatory by the spec"name": sp.utils.bytes_of_string("My Great Token"), # Recommended"symbol": sp.utils.bytes_of_string("MGT"), # Recommended# Extra fields"icon": sp.utils.bytes_of_string("https://smartpy.io/static/img/logo-only.svg"),
}
Contract_metadata = sp.utils.metadata_of_url("ipfs://QmaiAUj1FFNGYTu8rLBjc3eeN9cSKwaF8EGMBNDmhzPNFd")
c1 = m.Fa1_2TestFull(ผู้ดูแลระบบ=admin.address,metadata=contract_metadata,token_metadata=token_metadata,ledger={},)
สค += ค1
เรากำหนดบัญชีทดสอบ: ผู้ดูแลระบบ อลิซ และบ็อบ จากนั้นเราเริ่มต้นสัญญาของเรา Fa1_2TestFull
ด้วยค่าเริ่มต้นบางส่วน ตัวดำเนินการ +=
เพิ่มสัญญาเข้ากับสถานการณ์จำลอง
จากนี้ไป เพื่อช่วยให้คุณเข้าใจโค้ดได้ดีขึ้น โค้ดจะอยู่ด้านซ้ายและการแสดงบรรทัดโค้ดที่ไฮไลต์ไว้จะอยู่ทางด้านขวา ตัวอย่างที่นี่:
ขั้นตอนต่อไปคือการเรียกใช้การทดสอบ ซึ่งเกี่ยวข้องกับการเรียกใช้ฟังก์ชันสัญญาต่างๆ และตรวจสอบผลลัพธ์
ตัวอย่างเช่น เพื่อทดสอบฟังก์ชันการทำเหรียญ เราดำเนินการ:
Python
sc.h2("ผู้ดูแลระบบทำเหรียญไม่กี่เหรียญ")
c1.mint(address=alice.address, value=12).run(sender=admin)
บรรทัดนี้รันการทดสอบโดยที่ผู้ดูแลระบบสร้างโทเค็น 12 อันให้กับอลิซ หากฟังก์ชันสร้างโทเค็นได้สำเร็จและอัปเดตยอดคงเหลือของ Alice อย่างถูกต้อง การทดสอบนี้จะผ่านไป
SmartPy จัดเตรียมวิธี verify
เพื่อให้แน่ใจว่าเงื่อนไขเป็นจริง ถ้าไม่ตรงตามเงื่อนไข การทดสอบจะล้มเหลว ตัวอย่างเช่น:
Python
c1.update_metadata(key="", value=sp.bytes("0x00")).run(sender=admin)
sc.verify(c1.data.metadata[""] == sp.bytes("0x00"))
บรรทัดเหล่านั้นตรวจสอบว่าข้อมูลเมตาของสัญญาได้รับการอัปเดตเป็น "0x00"
อย่างถูกต้อง หากไม่ได้รับการอัพเดตอย่างถูกต้อง การทดสอบจะล้มเหลว
การทดสอบสัญญาอัจฉริยะของคุณควรครอบคลุมกรณีการใช้งานที่เป็นไปได้ทั้งหมด รวมถึงกรณี Edge และความล้มเหลวที่อาจเกิดขึ้น สิ่งเหล่านี้อาจรวมถึงการโอนที่เกินยอดคงเหลือของผู้ใช้ การเบิร์นโทเค็นเมื่อสัญญาถูกหยุดชั่วคราว ฯลฯ
ตัวอย่างเช่น การทดสอบการถ่ายโอนที่ล้มเหลวอาจมีลักษณะดังนี้:
Python
sc.h2("Bob พยายามถ่ายโอนจาก Alice แต่เขาไม่ได้รับการอนุมัติจากเธอ")
c1.transfer(from_=alice.address, ถึง_=bob.address, ค่า=4).รัน(ผู้ส่ง=บ๊อบ, ถูกต้อง=เท็จ)
ในกรณีนี้ Bob พยายามโอนโทเค็น 4 รายการจากบัญชีของ Alice โดยไม่ได้รับการอนุมัติ เนื่องจากการดำเนินการนี้ควรจะล้มเหลว เราจึงตั้ง valid=False
ในฟังก์ชัน run
หากสัญญาป้องกันการถ่ายโอนอย่างถูกต้อง การทดสอบก็จะผ่าน
การทดสอบเป็นสิ่งสำคัญในการพัฒนาสัญญาอัจฉริยะ เนื่องจากธรรมชาติของบล็อกเชนที่ไม่เปลี่ยนแปลง ข้อผิดพลาดใดๆ ในสัญญาอาจส่งผลที่ตามมาอย่างถาวรและอาจมีค่าใช้จ่ายสูง การเขียนการทดสอบที่ครอบคลุมช่วยให้แน่ใจว่าฟังก์ชันทั้งหมดทำงานตามที่คาดหวัง นำไปสู่สัญญาที่แข็งแกร่งและปลอดภัย
อย่าลืมเขียนแบบทดสอบสำหรับทั้งกรณีบวกและลบ กรณีที่เป็นค่าบวกจะตรวจสอบว่าฟังก์ชันทำงานได้อย่างถูกต้องเมื่อใช้ตามที่ตั้งใจไว้ กรณีเชิงลบทำให้สัญญาทำงานอย่างถูกต้องในการจัดการอินพุตที่ไม่ถูกต้องหรือไม่คาดคิด