ยินดีต้อนรับสู่คู่มือเริ่มต้นสำหรับการตรวจสอบสัญญาอัจฉริยะ! วิธีที่ดีที่สุดวิธีหนึ่งในการเริ่มต้นการตรวจสอบสัญญาอัจฉริยะคือการเข้าร่วมและดูช่องโหว่ทั่วไปสองสามประเภทในสัญญาอัจฉริยะ
มันจะเป็นประโยชน์ถ้าคุณมีความเข้าใจพื้นฐานเกี่ยวกับภาษาโปรแกรม Solidity ของ Ethereum อยู่แล้ว ในขณะที่เราจะดูรหัสบางส่วนที่เขียนโดยโปรแกรมเมอร์ Noob solidity
การโจมตีกลับเข้ามาใหม่
สถานการณ์จริงในโลกแห่งความเป็นจริง:
ลองนึกภาพคุณมีช็อคโกแลต 50 ชิ้น คุณมีน้องสาวซุกซนซึ่งคุณอนุญาตให้นำช็อคโกแลตจากคุณเพียง 2 อันเมื่อใดก็ได้ คุณไม่ต้องการให้ช็อคโกแลตมากกว่า 10 อันในหนึ่งวันเพราะกลัวว่าเธอจะเป็นฟันผุ เพื่อให้แน่ใจว่าสิ่งนี้ ทุกเย็นคุณนับจำนวนช็อคโกแลตที่เหลืออยู่กับคุณ คุณคิดว่าสิ่งนี้จะได้ผลหรือไม่? หรือคุณจะถูกแฮ็กโดยน้องสาวตัวน้อยของคุณ?
น่าเสียดาย มันจะใช้งานไม่ได้! พี่สาวของคุณคิดออกว่าคุณไม่รู้ว่าคุณมีช็อกโกแลตมากแค่ไหนจนถึงค่ำ ดังนั้นวันรุ่งขึ้น น้องสาวคนเล็กของคุณมาเยี่ยมคุณ 6 ครั้งก่อนเย็นและกินช็อกโกแลตครั้งละ 2 ช็อกโกแลต! นี่คือสิ่งที่เราเรียกว่าการโจมตีกลับเข้ามาใหม่
ที่นี่คุณกำลังอัปเดตจำนวนช็อคโกแลตที่คุณมีในตอนเย็นแทนที่จะอัปเดตการนับทุกครั้งที่พี่สาวของคุณรับช็อคโกแลต 2 อันจากคุณ นี่คือสิ่งที่จะเกิดขึ้นกับสัญญาอัจฉริยะ สัญญาอัจฉริยะใช้ความสมดุลโดยเฉพาะในขณะที่ผู้โจมตีกำลังยุ่งกับการถอน crypto จำนวนหนึ่งออกจากสัญญาหลายครั้ง
ตัวอย่างโค้ดในโลกแห่งความเป็นจริง:
รหัสนี้เป็นของสัญญาอัจฉริยะที่เรียกว่า unbanked. ทุกคนสามารถถอนอีเธอร์ออกจากสัญญา Unbanked ได้ตราบเท่าที่ยอดคงเหลือของผู้ส่ง msg.sender (เช่น ผู้โทรของ withdraw
) มากกว่าหรือเท่ากับจำนวนเงินที่ขอถอน
function withdraw(uint _amount) { require(balances[msg.sender] >= _amount); msg.sender.call.value(_amount)(); balances[msg.sender] -= _amount;
}
สังเกตว่ามีคำสำคัญที่ใช้ในการส่งจำนวนที่ต้องการของอีเธอร์ไปยัง msg.sender
. ผู้โจมตีสามารถใช้ประโยชน์จากสิ่งนี้ได้โดยการสร้างสัญญาที่เรียกว่า Thief ซึ่งเขาเรียกฟังก์ชันการถอนในa fallback()
การทำงาน. NS fallback()
ฟังก์ชันใน Solidity เป็นฟังก์ชันพิเศษที่จะดำเนินการเมื่ออีเธอร์ถูกส่งไปยังสัญญาอัจฉริยะ
ซึ่งหมายความว่าผู้โจมตีสามารถ เรียกฟังก์ชันการถอนซ้ำ. ดังนั้น ก่อนการปรับปรุงสัญญาอัจฉริยะ ยอดดุลของ msg.sender
ที่บรรทัดสุดท้ายของโค้ด ผู้โจมตีได้ถอน ether ไปแล้วหลายครั้ง สิ่งนี้สามารถหลีกเลี่ยงได้หากมีการอัปเดตยอดคงเหลือก่อนใช้คำสำคัญการโทร ดังนั้นตาม การตรวจสอบผลกระทบปฏิสัมพันธ์ ลวดลาย
ผลกระทบ:
พื้นที่ Reentrancy Attack ครั้งแรกที่เคยมีมา เกิดขึ้นในปี 2016 ใน DAO (Decentralized Autonomous Organisation) ซึ่งส่งผลให้มีการแฮ็กประมาณ 50 ล้านดอลลาร์ เพื่อย้อนกลับการแฮ็กนี้ ชุมชน Ethereum ได้แยก Ethereum blockchain ซึ่งก่อให้เกิด ETC (Ethereum Classic) และ ETH (Ethereum)
เลขคณิตล้นและอันเดอร์โฟลว์
สถานการณ์จริงในโลกแห่งความเป็นจริง:
มาเล่นเกมคิดกัน ประกอบด้วยวงล้อหมุน และผู้ชนะจะตัดสินจากจำนวนที่มากที่สุดที่เขาสามารถหมุนวงล้อได้ วงล้อถูกทำเครื่องหมายทั้งหมดจาก 256 ถึง -256
กฎของเกมคือตัวชี้สำหรับผู้เล่นทุกคนวางที่ 0 ที่จุดเริ่มต้นของการหมุนแต่ละครั้ง และอนุญาตให้ผู้เล่นหมุนในทิศทางของตัวเลขติดลบเท่านั้น คุณจะชนะเกมนี้ได้อย่างไร?
กลยุทธ์ที่ดีที่จะชนะเกมนี้ทุกครั้งคือการหมุนวงล้อด้วยพลังที่วงล้อหมุนได้มากถึง -256 แล้วเปลี่ยนเป็น 256 ในครั้งเดียว สิ่งนี้เป็นไปได้เพราะ 256 มาหลัง -256 บนพวงมาลัย นี่คือสิ่งที่เราเรียกว่าอันเดอร์โฟลว์เลขคณิต และเลขคณิตล้นก็แค่กลับกัน
ตัวอย่างโค้ดในโลกแห่งความเป็นจริง:
An ล้นหรือล้น เกิดขึ้นเมื่อการดำเนินการเลขคณิตถึงค่าต่ำสุดหรือสูงสุด
function withdraw(uint _amount) public { require(balances[msg.sender] - _amount > 0); address payable to = payable(msg.sender); to.transfer(_amount); balances[msg.sender] -= _amount;
}
พื้นที่ _amount
พารามิเตอร์ของฟังก์ชันการถอนเป็นจำนวนเต็มที่ไม่ได้ลงนาม ค่าของการแมปยอดคงเหลือ (ซึ่งเหมือนกับพจนานุกรมใน python หรือคู่คีย์-ค่าใน C++ หรือ Java) ก็เป็นจำนวนเต็มที่ไม่ได้ลงนามเช่นกัน
mapping(address => uint256) public balances
คำสั่งบังคับตรวจสอบว่ายอดดุลของ msg.sender
เป็นบวกหรือไม่ แต่ข้อความนี้จะเป็นจริงเสมอแม้ว่าจำนวนเงินจะมากกว่ายอดคงเหลือของ msg.sender
. ทั้งนี้เป็นเพราะทั้ง balances
และ _amount
ตัวแปรเป็นจำนวนเต็มที่ไม่ได้ลงนามและผลการคำนวณ (หลังจากอันเดอร์โฟลว์) จะเป็นจำนวนเต็มที่ไม่ได้ลงนามด้วย!
และอย่างที่คุณอาจจำได้ จำนวนเต็มที่ไม่ได้ลงนามจะเป็นค่าบวกเสมอ ซึ่งหมายความว่าผู้โจมตีสามารถถอน Ether ออกจากสัญญาอัจฉริยะได้ไม่จำกัดจำนวน! คุณสามารถค้นหาตัวอย่างโดยละเอียดและโค้ดการใช้งานสำหรับช่องโหว่นี้ โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
สิ่งสำคัญอีกประการหนึ่งที่ควรทราบในที่นี้คือการดำเนินการทางคณิตศาสตร์ระหว่างจำนวนเต็มที่ไม่ได้ลงนามสองจำนวนนั้นเป็นจำนวนเต็มที่ไม่ได้ลงนามเช่นกัน อาจเป็นอันตรายได้หากมองข้ามสิ่งนี้ไปในสัญญาอัจฉริยะ เนื่องจากอาจส่งผลให้เกิดการละเมิดความปลอดภัยที่ไม่พึงประสงค์ได้!
function votes(uint postId, uint upvote, uint downvotes) { if (upvote - downvote < 0) { deletePost(postId) }
}
ดังที่คุณอาจสังเกตเห็นในตัวอย่างข้างต้น คำสั่ง if นั้นค่อนข้างไร้สาระเช่น upvote - downvote
จะเป็นบวกเสมอ และโพสต์จะถูกลบแม้ว่า downvotes
มีค่ามากกว่า upvotes
. เพื่อหลีกเลี่ยงการโจมตีดังกล่าว ขอแนะนำให้ใช้เวอร์ชันคอมไพเลอร์ Solidity ที่มากกว่า 0.8.0.
ผลกระทบ:
เหรียญที่เรียกว่า เหรียญ PoWH เปิดตัวในปี 2017 แม้ว่าจะเป็นเกม Ponzi แต่ก็ถูกแฮ็กเนื่องจากข้อผิดพลาดทางคณิตศาสตร์ที่ล้นเกินซึ่งทำให้สูญเสียประมาณ 866 ETH หรือ 950,000 ดอลลาร์ในขณะนั้น คุณสามารถอ่านรายละเอียดเกี่ยวกับเรื่องนี้ได้ โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
ต้องอ่าน: บทเรียนจากการจู่โจมของ Tinyman, DEX ที่ใหญ่ที่สุดบน Algorand
การโจมตีการปฏิเสธการบริการ
สถานการณ์จริงในโลกแห่งความเป็นจริง:
ลองนึกภาพคุณอยู่ในมหาวิทยาลัยเทคโนโลยี Bitcoin ทุกอย่างดูเรียบร้อยดี ยกเว้นว่ามีโต๊ะอาหารสำหรับทุกคน และน่าเสียดายที่มีเพียงไม่กี่คนจากชั้นเรียนอื่นที่สามารถจัดโต๊ะอาหารได้ก่อนใครในชั้นเรียนของคุณเสมอ
ในสถานการณ์จริง พวกเขากำลังปฏิเสธบริการที่จำเป็นสำหรับทุกคนซึ่งส่งผลให้เสียเวลาอันมีค่าไป นี่คือสิ่งที่เราเรียกว่า 'การโจมตีแบบปฏิเสธการให้บริการ'
ตัวอย่างโค้ดในโลกแห่งความเป็นจริง:
ในเกมชื่อ ราชาแห่งอีเธอร์ทุกคนสามารถเป็นราชาได้ แต่กฎของการเป็นกษัตริย์คือบุคคลควรฝากอีเธอร์มากกว่ากษัตริย์องค์ปัจจุบัน สามารถทำได้โดยการเรียก claimThrone()
หน้าที่ของสัญญา King of Ether โดยที่บุคคลส่งอีเทอร์โดยตรงไปยังกษัตริย์องค์ก่อนและกลายเป็นกษัตริย์องค์ใหม่
function claimThrone() external payable { require(msg.value > balance, "Need to pay more to become the king"); (bool sent, ) = king.call{value: balance}(""); require(sent, "Failed to send Ether"); balance = msg.value; king = msg.sender; }
อย่างที่คุณอาจเดาได้ว่ารหัสนี้มีความเสี่ยงต่อการโจมตี DoS แต่อย่างไร สำหรับสิ่งนี้ คุณจะต้องเข้าใจว่ามีที่อยู่ใน Ethereum สองประเภท - อย่างแรกคือ ที่อยู่ภายนอก บัญชีที่เป็นเจ้าของหรือเพียงแค่ที่อยู่ของกระเป๋าเงิน และที่สองคือ ที่อยู่สัญญา. ขณะนี้ สามารถส่งอีเทอร์ได้จากที่อยู่ประเภทใดประเภทหนึ่งเหล่านี้
หากสิ่งนี้ อีเธอร์ถูกส่งโดยที่อยู่ของสัญญา สัญญาจะกลายเป็นราชา แต่สมมุติว่าสัญญาใหม่นี้ไม่มี fallback()
ฟังก์ชันที่จำเป็นหากสัญญาต้องการรับอีเทอร์ แล้วถ้ามีคนใหม่เข้ามาและพยายามเรียก claimThrone()
ฟังก์ชั่นก็จะล้มเหลวเสมอ!
สังเกตว่าสิ่งนี้เกิดขึ้นส่วนหนึ่งเพราะ claimThrone()
ฟังก์ชันจะตรวจสอบอย่างชัดเจนว่าการถ่ายโอนอีเทอร์สำเร็จหรือไม่ในคำสั่งที่สองที่จำเป็น คุณสามารถค้นหาโค้ดที่สมบูรณ์และทำการโจมตี DoS ได้ โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
นอกจากนี้ยังเป็นไปได้ที่โค้ดจะเสี่ยงต่อการโจมตี DoS หากโค้ดมีการวนซ้ำในอาร์เรย์ขนาดใหญ่ สิ่งนี้เกิดขึ้นเพราะ ขีด จำกัด ของก๊าซ เกินได้ในกรณีดังกล่าว คุณสามารถอ่านเกี่ยวกับมัน โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม.
ผลกระทบ:
เกมที่เรียกว่า รัฐบาลจิตซึ่งเห็นได้ชัดว่าเป็นโครงการ Ponzi ติดอยู่กับ 1100 อีเธอร์เพราะต้องใช้ก๊าซจำนวนมากในการประมวลผลการจ่ายเงิน
สุ่มไม่ปลอดภัย
สถานการณ์จริงในโลกแห่งความเป็นจริง:
ครั้งหนึ่งมีชายคนหนึ่งชื่อ Hesky ผู้ซึ่งมาพร้อมกับ Pesky ลิงของเขาเสมอ Hesky ดำเนินการเกมลอตเตอรีและทำกำไรได้ดี วันหนึ่งอลิซสังเกตเห็น Hesky จ้องไปที่ Pesky ลิงของเขาอย่างตั้งใจ จากนั้นเธอก็เห็นเขาเขียนอะไรบางอย่างบนกระดาษและปิดผนึกไว้ในซองจดหมาย ด้วยความอยากรู้อยากเห็น เธอจึงตัดสินใจสอบสวนเพิ่มเติม
ต่อมาในเย็นวันนั้น อลิซเห็นว่าผู้ถูกรางวัลลอตเตอรีถูกตัดสินโดยเปิดซองที่ปิดผนึกไว้อย่างเปิดเผย หลังจากเฝ้าดูเขาอยู่สองสามวัน อลิซก็พบว่า Hesky ตัดสินใจหมายเลขลอตเตอรีที่ชนะโดยดูจากท่าทางของ Pesky (เช่น ถ้าลิงเกาหัว Hesky ก็เขียนลงไป 10 อัน)! ตอนนี้อลิสมีสูตรถูกลอตเตอรีแต่ละตัวแล้วก็ต้องซื้อลอตเตอรีด้วยเลขที่ถูกต้อง!
Hesky สันนิษฐานว่าวิธีการ "สุ่ม" ในการตัดสินผู้ถูกรางวัลลอตเตอรีนั้นไม่สามารถคาดเดาได้ แต่เขาคิดผิดจริงๆ
ตัวอย่างโค้ดในโลกแห่งความเป็นจริง:
ในตัวอย่างนี้ หมายเลขสุ่มถูกสร้างขึ้นตามแฮชของการรวมกันของหมายเลขของบล็อกและการประทับเวลาของบล็อก แฮชนี้ถูกกำหนดให้กับตัวแปรคำตอบ ตอนนี้ทุกคนที่เดาหมายเลขสุ่ม (ดูเหมือน) นี้จะได้รับรางวัล 1 Ether คุณคิดว่าสิ่งนี้ไม่สามารถแฮ็คได้หรือไม่?
function guess(uint _guess) public { uint answer = uint( keccak256(abi.encodePacked(blockhash(block.number - 1), block.timestamp)) ); if (_guess == answer) { (bool sent, ) = msg.sender.call{value: 1 ether}(""); require(sent, "Failed to send Ether"); } }
ไม่! ผู้โจมตียังสามารถเดาตัวเลขสุ่มนี้ได้โดยเพียงแค่คัดลอกและวางรหัสเพื่อสร้างค่าที่กำหนดให้กับตัวแปรคำตอบ และส่งตัวแปรคำตอบเดียวกันไปยัง guess()
การทำงาน!
guessTheRandomNumber.guess(answer);
คุณสามารถค้นหารหัสที่สมบูรณ์ โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม. เพื่อหลีกเลี่ยงการโจมตีนี้ ขอแนะนำให้ใช้ฟังก์ชันสุ่มที่ตรวจสอบได้ เช่น the เชนลิงค์ VRF.
ผลกระทบ:
ประมาณ 400 ETH หายไปเนื่องจากการโจมตี on ลอตเตอรีอัจฉริยะพันล้าน สัญญา. น่าแปลกที่แม้แต่ลอตเตอรีสัญญาเองก็เป็นโครงการ Ponzi (อุ๊ย!)
การจัดการเวลา
สถานการณ์จริงในโลกแห่งความเป็นจริง:
Satoshi ชอบกินคุกกี้ เขาชอบคุกกี้ทุกประเภทที่แม่ทำ แต่แม่ของเขาเข้มงวดมากและรู้สึกว่าการกินคุกกี้มากเกินไปไม่ดีสำหรับเขา แม่เลยตั้งกฎว่าจะเอาคุกกี้ตอน 8 น. เท่านั้น
วันนั้นเอง เวลา 7:45 น. Satoshi วิ่งไปหาแม่และขอคุกกี้ แม่ถามว่า “กี่โมงแล้ว”
“แปดโมงแล้ว!” - เขาตอบกลับ
"ตกลง. จากนั้นนำคุกกี้จากตู้ของฉัน”
ดังนั้น Satoshi จึงสามารถจัดการเวลาได้สำเร็จภายใน 15 นาที เพื่อที่เขาจะได้คุกกี้ของเขา! ช่างเป็นอะไรที่หิวคุกกี้!
ตัวอย่างโค้ดในโลกแห่งความเป็นจริง:
เวลาประทับของบล็อกสามารถจัดการได้โดย about วินาที 15 โดยคนงานเหมือง ด้วยวิธีนี้ นักขุดสามารถตั้งค่าการประทับเวลาที่เหมาะสมและรวมธุรกรรมของเขาไว้ในบล็อกเดียวกันกับที่เขาทำเหมือง ฟังก์ชั่น play()
เป็นของสัญญาเกมที่เรียกว่า G-Dot
function play() public { require(now > 1640392200 && neverPlayed == true); neverPlayed = false; msg.sender.transfer(1500 ether);
}
สัญญานี้ให้รางวัล 1500 อีเธอร์แก่ผู้เล่นที่เรียกใช้ฟังก์ชันการเล่นเป็นคนแรก แต่อย่างที่คุณเห็น ฟังก์ชัน play สามารถเรียกได้ก็ต่อเมื่อ now หรือ block.timestamp ของธุรกรรมที่มีการเรียกไปยัง play()
ฟังก์ชัน มีค่ามากกว่า ยุคสมัย 1640392200.
นักขุดสามารถจัดการการประทับเวลานี้ได้อย่างง่ายดายและรวมธุรกรรมของเขาในการเรียก play()
ทำงานในบล็อกเดียวกันโดยที่ตัวเขาเองเป็นผู้เล่นคนแรก ด้วยวิธีนี้รับประกันได้ว่าผู้ขุดจะชนะเกม!
ผลกระทบ:
block.timestamp ถูกใช้เพื่อสร้างตัวเลขสุ่มใน ของรัฐบาล และเสี่ยงต่อการโจมตีที่บิดเบือนเวลา
ติดต่อ QuillAudits
QuillAudits เป็นแพลตฟอร์มการตรวจสอบสัญญาอัจฉริยะที่ปลอดภัยซึ่งออกแบบโดย ขนนกแฮช
เทคโนโลยี
เป็นแพลตฟอร์มการตรวจสอบที่วิเคราะห์และตรวจสอบสัญญาอัจฉริยะอย่างเข้มงวด เพื่อตรวจสอบช่องโหว่ด้านความปลอดภัยผ่านการตรวจสอบโดยเจ้าหน้าที่ที่มีประสิทธิภาพด้วยเครื่องมือวิเคราะห์แบบสถิตและไดนามิก เครื่องวิเคราะห์ก๊าซ และเครื่องจำลอง นอกจากนี้ กระบวนการตรวจสอบยังรวมถึงการทดสอบหน่วยอย่างละเอียดและการวิเคราะห์โครงสร้างด้วย
เราดำเนินการตรวจสอบสัญญาอัจฉริยะและการทดสอบการเจาะเพื่อค้นหาศักยภาพ
ช่องโหว่ด้านความปลอดภัยที่อาจเป็นอันตรายต่อความสมบูรณ์ของแพลตฟอร์ม
หากคุณต้องการความช่วยเหลือในการตรวจสอบสัญญาอัจฉริยะ โปรดติดต่อผู้เชี่ยวชาญของเรา ที่นี่!
เพื่อติดตามผลงานของเรา เข้าร่วมชุมชนของเรา:-
Twitter | LinkedIn | Facebook | Telegram
โพสต์ คู่มือเริ่มต้นสำหรับการตรวจสอบสัญญาอัจฉริยะ: ตอนที่ 1 ปรากฏตัวครั้งแรกเมื่อ บล็อก Quillhash.
ที่มา: https://blog.quillhash.com/2022/01/19/beginners-guide-to-smart-contract-auditing-part-1/
- "
- &
- 000
- 2016
- 7
- เกี่ยวกับเรา
- ลงชื่อเข้าใช้
- ที่อยู่
- ทั้งหมด
- แล้ว
- แม้ว่า
- การวิเคราะห์
- การตรวจสอบบัญชี
- อิสระ
- การเริ่มต้น
- ที่ดีที่สุด
- Bitcoin
- blockchain
- Bug
- ซื้อ
- โทรศัพท์
- กรณี
- การตรวจสอบ
- คลาสสิก
- รหัส
- เหรียญ
- การผสมผสาน
- ร่วมกัน
- ชุมชน
- มี
- สัญญา
- สัญญา
- คุ้กกี้
- ได้
- การสร้าง
- การเข้ารหัสลับ
- ปัจจุบัน
- DAO
- วัน
- ซึ่งกระจายอำนาจ
- Denial of Service
- รายละเอียด
- Dex
- ลง
- อย่างง่ายดาย
- กิน
- ETH
- อีเทอร์
- ethereum
- บล็อกเชน Ethereum
- Ethereum คลาสสิก
- ตัวอย่าง
- เอาเปรียบ
- ปลาย
- ชื่อจริง
- ฟรี
- ฟังก์ชัน
- เกม
- เกม
- GAS
- สร้าง
- GitHub
- ไป
- ดี
- ให้คำแนะนำ
- สับ
- แฮ็ก
- กัญชา
- หัว
- โปรดคลิกที่นี่เพื่ออ่านรายละเอียดเพิ่มเติม
- สรุป ความน่าเชื่อถือของ Olymp Trade?
- HTTPS
- สอบสวน
- IT
- ชวา
- ร่วม
- กระโดด
- พระมหากษัตริย์
- ภาษา
- ใหญ่
- Line
- นาน
- ที่ต้องการหา
- หวย
- มนุษย์
- ล้าน
- แม่
- ตัวเลข
- organizacja
- กระดาษ
- แบบแผน
- ชำระ
- คน
- ชิ้น
- เวที
- เล่น
- ผู้เล่น
- Ponzi
- โครงการ Ponzi
- อำนาจ
- กระบวนการ
- โปรแกรมเมอร์
- การเขียนโปรแกรม
- สาธารณะ
- ย้อนกลับ
- ทบทวน
- รางวัล
- กฎระเบียบ
- ซาโตชิ
- ความปลอดภัย
- ชุด
- สมาร์ท
- สัญญาสมาร์ท
- สัญญาสมาร์ท
- So
- ความแข็งแรง
- บางสิ่งบางอย่าง
- สปิน
- แยก
- ข้อความที่เริ่ม
- คำแถลง
- กลยุทธ์
- ที่ประสบความสำเร็จ
- ประสบความสำเร็จ
- เทคโนโลยี
- การทดสอบ
- ตลอด
- เวลา
- เครื่องมือ
- การทำธุกรรม
- unbanked
- มหาวิทยาลัย
- การปรับปรุง
- ความคุ้มค่า
- ช่องโหว่
- ความอ่อนแอ
- อ่อนแอ
- กระเป๋าสตางค์
- อะไร
- ล้อ
- WHO
- ชนะ
- งาน
- การเขียน