Nghiên cứu này sẽ bao gồm những nội dung xoay quanh các van dé về an toàn toànbảo mật trên hợp đồng thông minh Ethereum, cụ thé như sau: Dựa vào những tài liệu đã có về những lỗ hồng tồ
CƠ SỞ NGHIÊN CỨU -:::++cccc2 22tr 7
Cơ sở lý thuYẾt .-2c:-222222 222222 2222111122221112221111122111 2121111211111 ccrrxer 7
3.1.1 Khái niệm hợp đồng thông minh
Thuật ngữ hợp đồng thông minh đã được sử dụng trong nhiều năm dé mô tả nhiều thứ khác nhau Vào những năm 1990, nhà mật mã học Nick Szabo đã đặt ra thuật ngữ này và định nghĩa nó là “một tập hợp các lời hứa, được chỉ định ở dạng kỹ thuật số, bao gồm các giao thức mà trong đó các bên thực hiện các lời hứa khác” (“a set of promises, specified in digital form, including protocols within which the parties perform on the other promises”) Kể từ đó, khái niệm hợp đồng thông minh đã phát triển, đặc biệt là sau sự ra đời của các nên tảng blockchain phi tập trung với sự phát minh ra Bitcoin vào năm 2009.
Trong bối cảnh của Ethereum, thuật ngữ “hợp đồng thông minh” để chỉ các chương trình máy tinh bat biến chạy một cách xác định trong bối cảnh của Máy ảo Ethereum như một phần của giao thức mạng Ethereum Nói cách khác, nó là các đoạn mã được lưu trữ trên Blockchain, có khả năng tự thực thi khi các điều khoản hay điều kiện xác định trước được đáp ứng.
Matching of buyer and seller
Bob wants to sell John wants to buy his house — the house
Automation of clearing and settlement
Land Deed is (†) Undisputed digitised ownership
Hình 3.1: Cơ chế hoạt động của hợp đồng thông minh
Có thé phân tách khái niệm về hợp đồng thông minh thành những thành phần như sau:
Chương trình máy tính: Hợp đồng thông minh chỉ đơn giản là các chương trình máy tính Từ hợp đồng không có ý nghĩa pháp lý trong ngữ cảnh này.
Bắt biến: Sau khi được triển khai, mã của hợp đồng thông minh không thé thay đổi.Không giống như phần mềm truyền thống, cách duy nhất dé sửa đổi hợp đồng thông minh là triển khai một phiên bản mới.
Tinh xác định: Kết quả của việc thực hiện hợp đồng thông minh là giống nhau đối với tất cả những người chạy nó, dựa trên bối cảnh của giao dịch bắt đầu thực hiện và trạng thái của chuỗi khối Ethereum tại thời điểm thực thi.
Máy tính thế giới phi tập trung: EVM chạy như một phiên bản cục bộ trên mọi nút Ethereum, nhưng vì tất cả các phiên bản EVM hoạt động trên cùng một trạng thái ban đầu và tạo ra cùng một trạng thái cuối cùng, nên toàn bộ hệ thống hoạt động như một
Có thể hình dung hợp đồng thông minh dưới góc nhìn trạng thái như sau.
Transaction of message call input data
World state of World state g H1
Hình 3.2: Hop đồng thông minh dưới góc nhìn trang thái
Hình dung hệ thống Blockchain là một chuỗi các trạng thái Mỗi trang thái bao gồm một địa chỉ Ethereum liên kết với một trạng thái tài khoản Có hai loại tài khoản trongEthereum là tài khoản EOA và tài khoản hợp đồng Tài khoản đang được đề cập trong trường hợp này là tài khoản hợp đồng Điểm khác biệt của loại tài khoản này so với tài khoản EOA đó chỉnh là có chứa mã hợp đồng và một không gian lưu trữ trạng thái hợp đồng Khi có một giao dịch được thực hiện với đích đến là địa chỉ hợp đồng, dữ liệu đầu vào cùng với mã hợp đồng và trạng thái hợp đồng được truyền vào EVM củaNode đang thực thi giao dịch Các điều khoản sẽ được thực thi tại EVM và trạng thái mới của hợp đồng sau khi giao dịch được thực thi sẽ được cập nhật vào trạng thái toàn cục của toàn mạng.
Có thé thấy rằng, với một mô hình như vậy, lỗ hồng hợp đồng thông minh có thể xuất hiện ở môi trường thực thi, mạng, cơ chế đồng thuận, mã hợp đồng, Nghiên cứu nay sẽ tập trung vào các lỗ héng xuất phát từ mã hợp đồng Một đầu vào độc hại có thể khiến một mã hợp đồng không tốt ghi lên hệ thống Blockchain một đầu ra không mong muôn.
3.1.2 Ngôn ngữ cấp cao trong lập trình hợp đồng thông minh
Mặc dù có thê lập trình các hợp đồng thông minh trực tiếp bằng bytecode, nhưng EVM bytecode khá khó sử dụng và rất khó cho các lập trình viên đọc và hiểu Thay vào đó, hầu hết các nhà phát triển Ethereum sử dụng một ngôn ngữ cấp cao đề viết chương trình và một trình biên dịch đề chuyển đổi chúng thành bytecode.
Mặc dù bất kỳ ngôn ngữ cấp cao nào cũng có thể được điều chỉnh đề viết các hợp đồng thông minh, nhưng việc điều chỉnh một ngôn ngữ tùy ý dé có thé biên dịch được với EVM bytecode là một bài toán khá phức tạp Ngoài ra, cần phải có một bộ biến và hàm đặc biệt của hệ thống EVM cụ thể Do đó, việc xây dựng một ngôn ngữ hợp đồng thông minh từ đầu sẽ dễ dàng hơn so với việc tạo ra một ngôn ngữ có mục đích chung phù hợp dé viết các hợp đồng thông minh Kết quả là, một số ngôn ngữ có mục dich đặc biệt đã xuất hiện dé lập trình các hợp đồng thông minh Ethereum có một số ngôn ngữ như vậy, cùng với các trình biên dịch cần thiết để tạo ra mã bytecode thực thi EVM.
Solidity là một ngôn ngữ như vậy, nó được tạo ra như một ngôn ngữ dành riêng cho việc viết các hợp đồng thông minh với các tính năng hỗ trợ trực tiếp việc thực thi trong môi trường phi tập trung của máy tính thế giới Ethereum Nó được phát triển bởi Christian Reitiwessner và sau đó là Alex Beregszaszi, Liana Husikyan, Yoichi
Hirai và một số cựu cộng tác viên cốt lõi của Ethereum Solidity hiện được phát triển và duy trì như một dự án độc lập trên GitHub: https://github.com/ethereum/solidity
3.1.3 Khái niệm ứng dụng phi tập trung Ứng dụng phi tập trung hay Dapps (Decentralized Application) là các ứng dụng chạy trên một hệ thống máy tính phân tán và các máy có quyền hạn như nhau thay vì có một Server tập trung như các ứng dụng truyền thống.
& 4 4 4 ee 6 | e-e@- @ -|* vs ry ISP Isp ISP 4
Hình 3.3: Sự khác nhau giữa Ung dụng truyền thống và Ung dụng phi tap trung
Một ứng dụng được gọi là Dapps phải thé hiện được 4 đặc điểm sau: o_ Mã nguồn mở: Bắt kỳ ai cũng có thể xem được mã nguồn của ứng dụng. o Tính phân tán: Lưu trữ mọi thứ trên một hệ thống phân tán như Blockchain. o_ Khuyến khích / Phần thưởng: Những người có tham gia vào việc kiểm tra và xác thực sẽ được trả một phần thưởng tương ứng. o_ Thuật toán: Sử dụng cơ chế đồng thuận.
Trong các ứng dụng truyền thống, chẳng hạn như Facebook, khi người ding truy cập vào giao diện (Front End), ứng dụng sẽ gọi các API đề lấy dữ liệu người dùng từ Cơ sở dữ liệu sau đó hiển thị ra màn hình (theo kiến trúc Front End — API — Database). Trong khi đó, Ứng dụng phi tập trung cơ bản cũng giống như một ứng dụng truyền thống, nhưng điểm khác biệt rõ rệt là thay vì sử dụng các API để kết nói đến Cơ sở dữ liệu thì Dapps sử dụng Smart Contract dé kết nối đến Blockchain (theo kiến trúc
Front End — Smart Contract — Blockchain).
3.1.4 Các danh sách lỗ hồng phố biến
SWC (The Smart Contract Weakness Classification) (hitps://swcregistry.io/) là một danh sách phân loại lỗ héng hợp đồng thông minh dành cho các nhà phát triển, nhà cung cấp công cụ và các chuyên gia bảo mật SWC có liên kết với các thuật ngữ và cấu trúc được sử dung CWE (https://cwe.mitre.org/) nhưng được chồng lên một loạt các biến thê điểm yếu cụ thẻ cho hợp đồng thông minh.
Mục tiêu của dự án này là:
(i) Cung cấp phân loại đơn giản các vấn dé bảo mật trong hệ thống hợp đồng thông minh.
(ii) Xác định ngôn ngữ chung dé mô tả các van dé bảo mật trong kiến trúc, thiết kế hoặc mã của hệ thống hợp đồng thông minh.
(iii) Phục vụ như một cách dé đào tạo và tăng hiệu suất cho các công cụ phân tích bảo mật hợp đồng thông minh.
Phương pháp nghiên cứu -¿- ¿+ 5: St tt 11 23 CHƯƠNG 4: KET QUA NGHIÊN CỨU -2¿¿©22+¿+2222+++222++zrsrvxseee 25
Phương pháp nghiên cứu quan sát: Quan sát kết quả nghiên cứu của các hướng nghiên cứu liên quan hiện có Quan sát các tài liệu mô tả được tìm thấy trong quá trình nghiên cứu Thu thập thông tin từ những đối tượng quan sát được, kiểm chứng các giả thuyết đã có và so sánh, đối chiếu các kết quả với tình hình thực tiễn.
Phương pháp nghiên cứu thực nghiệm: Triển khai giả lập và thực tế các ý tưởng, kịch bản về những van đề nghiên cứu Điều chỉnh thông tin triển khai dé thu được kết quả mong muốn Ghi nhận và kiểm chứng các kết quả.
Phương pháp phân tích tổng kết: Tổng hợp, xem xét và phân tích những thành quả về cả lý thuyết và thực tiễn của các nghiên cứu đã có cũng như nghiên cứu này để đưa ra những đề xuất, kết luận.
CHƯƠNG 4: KÉT QUÁ NGHIÊN CỨU
4.1 Phân loại lỗ hồng hợp đồng thông minh
'Việc phân loại các lỗ hồng thành từng nhóm có những đặc điểm tương đồng với nhau sẽ mang lại một cái nhìn bao quát hơn, có hệ thống hơn về các 16 hồng Điều này sẽ giúp các nhà phát triển dé dàng trong việc kiểm soát có hay không lỗ hồng dang tồn tại trên hợp đồng của mình. Đồng thời danh sách phân loại đưới đây cũng có thể được sử dụng để phục vụ trong công tác kiểm thử hợp đồng, trong một quy trình đánh giá hợp đồng nào đó, hoặc quy trình đánh giá được đề xuất trong phan 4.3.
Danh sách này phân chia các lỗ hong hợp đồng thông minh thành 5 nhóm dựa trên nguyên nhân cốt lõi dẫn đến lỗ hồng, như sau:
Bang 4.1: Danh sách phân loại lỗ hong
STT Nguyên nhân Tên gọi
Phụ thuộc vào hợp đồng bên ngoài
4 Kiém tra dau vao va gid tri tra vé
5 Đặc thù của Solidity Type casts
4.1.1 Nhóm lỗ héng do phụ thuộc vào hợp đồng bên ngoài
Khi nói về các lỗ hồng của hợp đồng thông minh, đầu tiên phải nói đến Reentrancy. Lần đầu tiên xuất hiện trong cuộc tấn công The DAO [2], gây thiệt hại hàng chục triệu USD.
Reentrancy có liên quan tới một tiện ích trong hợp đồng thông minh Ethereum là khả năng gọi đến hợp đồng bên ngoài Điểm nguy hiểm của tiện ích này đó là khi thực hiện một lệnh gọi đến hợp đồng bên ngoài, hợp đồng đó sẽ có khả năng kiểm soát luồng xử lý Do đó, có thể thay đổi đổi dữ liệu hoặc thực hiện các chức năng không mong muốn trên hợp đồng gọi.
Có nhiều dạng để thực hiện một cuộc tấn công Reentrancy Trong bai viết này sẽ trình bày hai dạng đã dẫn đến sự sụp đô của The DAO.
Trong dang nay, hop đồng Callee có thể thực hiện một cuộc gọi ngược trở lại hợp đồng Caller trước khi lệnh gọi ban đầu của hợp đồng Caller hoàn thành Attacker đã dựa vào Fallback Function để làm được điều này. mapping(address => uint256) balanceOf;
//deposit fund function deposit() public payable{ balanceOf[msg.sender] += msg.value;
//withdraw function (insecure) function withdrawBalance() public{ require(balanceOf[msg.sender] > 8);
(bool s, ) = msg.sender.call{value: balanceOf[msg.sender]}(""); require(s); balanceOf[msg.sender] = 9;
Hinh 4.1: Minh hoa "Reentrancy on a Single Function"
Gọi hợp đồng trên là (A) Khi thực hiện hàm withdrawBalance(), hop đồng (A) sẽ kiểm tra điều kiện, gửi toàn bộ số dư khả dụng đến dia chỉ người dung, sau đó đặt số dư lại bằng 0 Rắc rối xảy ra nếu địa chỉ người dùng là một hợp đồng (B) Khi thực hiện chuyển số dư đến (B), có thể (A) sẽ phải thực hiện các dòng lệnh nằm trong Fallback Function của (B) Tại đây (B) có thể gọi lại withdrawBalanceQ Lệnh gọi này được thực hiện trước khi đặt lại số dư, do đó vẫn thỏa điều kiện ban đầu.
Có một biến thé khác dé thực hiện Reentrancy Tương tự như dang đầu tiên, nhưng thay vì thực hiện trên một hàm, dạng này gọi lại một hàm khác nhưng có cùng trạng thái. mapping(address => uint256) balanceOf;
//deposit fund function deposit() public payable{ balanceOf[msg.sender] += msg.value;
//transfer to other address function transferTo(address to, uint256 amount) public{ if (balanceOf[msg.sender] >= _amount){ balanceOf[_to] += _amount; balanceOf[msg.sender] -= _amount;
/#/withdraw function (insecure) function withdrawBalance() public{ require(balanceOf[msg.sender] > @);
(bool s, ) = msg.sender.call{value: balanceOf[msg.sender]}(""); require(s); balanceOf[msg.sender] = 8;
Hình 4.2: Minh họa "Cross - function Reentrancy”
Trong trường hợp nay, hợp đồng của Attacker có thể gọi hàm transferTo() để chuyển một lượng số du sang địa chỉ khác trong khi hàm withdrawBalance() đang thực hiện một cuộc gọi đến nó như trường hợp trên Lúc này số dư vẫn chưa được đặt lại nên điều này hoàn toàn có thé.
Reentrancy xảy ra do việc luồng xử lý của hợp đồng phụ thuộc vào một số trạng thái biến, mà các trạng thái này lại được cập nhật sau các External Call, và không kiểm soát lượng gas sử dụng của lệnh gọi. Để ngăn chặn Reentrancy, có thể kiểm soát lượng gas được sử dụng trong mỗi External Call Trong ví dụ trên có thể thêm trường “gas” vào trong lệnh call, hoặc sử dụng phương thức transfer() (giới hạn lượng gas là 2300) dé chuyên tiền thay vì call() Hơn nữa, cho dù trong trường hợp có thể hay không thể kiểm soát lượng gas, cần phải xử lý các công việc nội bộ của hợp đồng trước khi thực hiện một External Call Và ngoài việc tránh gọi sớm các External Call, cũng cần phải tránh gọi sớm các hàm có chứa External Call.
Ngoài ra, để ngăn chặn Reentrancy hiệu quả hơn, có thé sử dụng một biến Mutex dé khóa trạng thái biến. mapping(address => uint256) balanceOf; bool lock = false;
//withdraw function (secure) function withdrawBalance() public{ require(!lock); lock = true; require(balanceOf[msg.sender] > @);
(bool s, ) = msg.sender.call{value: balanceOf[msg.sender]}(""); require(s); balanceOf[msg.sender] = 8; lock = false;
Hình 4.3: Minh họa việc sử dung biến Mutex để ngăn chặn "Reentrancy"
Khi người dùng gọi trở lại hàm withdrawBalance() trước khi lệnh gọi ban đầu hoàn thành, biến Jock sẽ ngăn chặn mọi sự ảnh hưởng của lệnh gọi đối với hàm Vì nếu hàm chưa được thực thi hoàn toàn, lock sẽ chưa được trả về trang thái false.
Lưu ý, việc sử dụng Mutex trong trường hợp ngăn chặn Reentrancy trên nhiều hợp đồng kết hợp sẽ phức tạp hơn và có thé ân chứa cam bay Cần tìm hiểu kỹ về Mutex trước khi áp dụng vào hợp đồng
Sở hữu tính bất biến của Ethereum Blockchain, hợp đồng thông minh một khi được triển khai sẽ không thé có thêm bản cập nhật hay sửa đổi nào, cho dù có phát hiện ra lỗ hồng Tuy nhiên, trên thực tế vẫn có cách cập nhật hợp đồng thông minh, giúp nó có thé phát triển theo thời gian. Để làm được điều nay, có hai hướng tiếp cận như sau:
(i) Triển khai một phiên bản hợp đồng mới, sau đó chuyền toàn bộ trạng thái từ hợp đồng cũ sang hợp đồng mới.
Hướng này sẽ phát sinh một số vấn đề Việc di chuyền trạng thái hợp đồng thực sự rất tốn kém Hơn nữa nếu làm như vậy, địa chỉ của hợp đồng sẽ bị thay đổi, việc cập nhật hợp đồng có thể sẽ rất phức tạp.
(ii) Một hướng tiếp cận tốt hơn đó là chia hợp đồng ra thành Proxy Contract và
Users Proxy Implementation stores the stores the contract state contract logic
Hình 4.4: Cập nhật hợp đồng với Proxy Contract