Bảo mật smart contract
Đây là phần 1 nằm trong series Smart Contract Security

Security là một trong những tiêu chí quan trọng cho việc lập trình smart contract. Mỗi sai lầm trong lập trình smart contract sẽ phải trả giá bằng rất nhiều tiền. Chúng ta thường nghe rất nhiều tin tức các vụ hack của rất nhiều dự án, đặc biệt là sự bùng nổ của DeFi dẫn đến bảo mật smart contract là tiêu chí bắt buộc phải có.

Các smart contract luôn công khai (public) và do đó bất kì ai cũng có thể tương tác với smart contract. Một rủi ro tiềm ẩn có thể bị khai thác dẫn đến tiền bị mất và không thể khôi phục lại.

Trong chuyên đề này, chúng ta sẽ trao đổi về các phương pháp để đảm bảo security cho smart contract nói chung và smart contract được viết bằng Solidity nói riêng. Ngoài ra, chúng ta sẽ cùng tìm hiểu về các rủi ro đã được phát hiện trong thời gian qua.

Trong bài viết đầu tiên này, chúng ta sẽ chỉ bàn về các best practices về security cho smart contract.

Security Best Practices:

Defensive programming (defensive có nghĩa là phòng thủ) là một phong cách lập trình thường được áp dụng cho lập trình smart contract. Trong đó, defensive programing nhấn mạnh các đặc tính sau:

  • Minimalism hay simplicit: tối giản
  • Code reuse: tái sử dụng
  • Code quality: chất lượng code
  • Readability hay auditability: dễ đọc được
  • Test coverage: Kiểm thử

Tối giản:

Đối với smart contract, tối giản được xem trọng hơn là phức tạp bởi “Sự phức tạp là kẻ thù của bảo mật”. Mã nguồn càng đơn giản thì càng ít khả năng xảy ra lỗi và càng tránh được các ảnh hưởng không mong muốn.

Các developer thường bị cám dỗ để viết càng nhiều code càng tốt. Tuy nhiên, các developer nên cố gắng tìm cách để viết đơn giản hơn, ít dòng code hơn và ít tính năng hơn. Nếu ai đó nói với bạn rằng dự án của họ bao gồm hàng nghìn dòng code cho các smart contract thì bạn nên đặt câu hỏi về tính bảo mật của dự án đó.

Tái sử dụng:

Trong tiếng Anh thường có câu nói sau “do not reinvent the wheel”, tạm hiểu là “đừng có phát minh lại bánh xe”. Trong lập trình smart contract cũng thế, nếu như một thư viện hay một dự án mã nguồn mở nào đã có sẵn smart contract đã được kiểm định bảo mật (audit) thì mình nên dùng những cái đó.

Tâm lí của lập trình viên thường thích lập trình mọi thứ từ đầu hơn là cải thiện cái hiện có. Hội chứng này thường được gọi là “Not Invented Here”. Nhưng bạn nên biết rằng, những mã nguồn được kiểm tra kĩ lưỡng, kiểm định bảo mật, và chấp nhận rộng rãi thường sẽ tốt hơn rất nhiều so với các đoạn code mà bạn viết mới.

Một trong những thư viện nổi tiếng về các smart contract có thể để đến là OpenZepplin. Thư viện này bao gồm các smart contract phổ biến như:

  • ERC20 và ERC721 token.
  • Role-based permission: phân quyền.
  • Utilities: các smart contract tiện ích về mã hóa, tính toán cộng trừ nhân chia, thanh toán, multicall.

😉Nếu các bạn quan tâm về OpenZepplin thì để lại comment cho mình biết nhé . Nếu có ai quan tâm thì rong tương lai, mình sẽ thêm bài viết chi tiết về OpenZepplin.

Nếu như bạn thích tuân theo cách tiêu chuẩn lập trình thì đâu đó bạn sẽ nghe về nguyên tắc DRY: Don’t Repeat Yourself. Nếu bạn thấy đoạn code nào được lặp lại nhiều lần, hãy tự hỏi liệu đoạn code đó có thể được viết dưới dạng hàm hoặc thư viện hay không.

Chất lượng code:

Bug trong smart contract có thể gây ra những tổn thất lớn về tiền bạc. Do đó, bạn không nên xem lập trình smart contract như các lập trình các ngôn ngữ lập trình khác. Viêc lập trình Dapp bằng Solidity sẽ không giống như việc tạo một tiện ích web bằng Javascript. Việc fix bug trong smart contract sẽ không dễ dàng nếu như smart contract đã được deploy và đưa vào sử dụng. Bạn nên tuân thuẩn nghiêm ngặt các phương pháp lập trình.

Dễ đọc được:

Smart contract của bạn nên rõ ràng và có thể hiểu được. Càng dễ dàng để đọc thì càng dễ để kiểm định mã nguồn. Smart contract công khai do đó bất kì ai cũng có thể đọc bytecode và dịch ngược mã nguồn (reverse engineer). Do đó, mã nguồn smart contract của các Dapp hiện nay đều công khai trên Github và phát triển theo hướng mã nguồn mở. Vì vậy nên ngoài việc viết code dễ đọc ra thì bạn cũng nên viết tài liệu thật tốt, tuân thuẩn các phong cách lập trình và thống nhất quy tắc đặt tên biến, tên hàm để các developer khác có thể dễ dàng đóng góp vào mã nguồn.

Kiểm thử:

Kiểm thử tất cả những gì bạn có thể làm. Bất kì ai đều có thể thực thi smart contract với bất kì input nào mà họ muốn. Do đó, đừng bao giờ giả định rằng mọi người sẽ nhập các tham số của các hàm theo ý mà bạn mong muốn. Hãy ràng buộc tất cả tham số tuân thủ đúng phạm vi, đúng định dạng trước khi cho phép thực thi hàm.

Kết:

Hãy luôn cố gắng viết smart contract của bạn càng đơn giản càng tốt, tái sử dụng các đoạn mã được kiểm định, dễ đọc và luôn kiểm thử mọi thứ bởi smart contract luôn công khai và ai cũng có thể khai thác lỗ hổng trong smart contract của bạn.

Bài viết tiếp theo, chúng ta sẽ đi vào chi tiết vào các lỗ hổng bảo mật đã được phát hiện.


Nhận thấy các bài viết tiếng Việt chuyên về lập trình blockchain còn ít nên tôi quyết định chuyển hướng sang chuyên viết về chủ đề blockchain dành riêng cho lập trình viên. Hi vọng những bài viết này sẽ giúp ích cho các bạn đang muốn theo đuổi lĩnh vực còn khá mới này.

Nếu bạn thấy bài viết hữu ích, bạn có thể ủng hộ tôi vài tách cà phê thông qua MoMo tại đây

Bạn cũng có thể nhờ tôi tư vấn về giải pháp công nghệ thông tin nói chung và blockchain nói riêng (có tính phí) thông qua đây

Series NavigationOverflows và Underflows: Rủi ro về tính toán trong lập trình smart contract của Solidity >>