Những kỹ năng phát triển hợp đồng học được từ mã Uniswap, so với sách giáo khoa thì thú vị hơn nhiều



Gần đây khi làm hướng dẫn phát triển sàn giao dịch phi tập trung, tôi đã nghiên cứu sâu cách thực hiện của Uniswap V3, mới phát hiện ra có vài cách viết thật sự rất hay. Trước đây chỉ viết qua hợp đồng NFT đơn giản, lần này coi như lần đầu nghiêm túc đọc mã hợp đồng DeFi, phát hiện ra nhiều thứ đáng để chia sẻ với các bạn muốn học Uniswap.

Trước tiên nói về một điều tôi rất ngạc nhiên — địa chỉ hợp đồng thậm chí có thể dự đoán được?

Thông thường khi triển khai hợp đồng, địa chỉ nhận được trông như ngẫu nhiên, nhưng Uniswap đã dùng một cách rất thông minh. Nó thông qua việc thêm tham số salt khi tạo hợp đồng, dùng mã lệnh CREATE2, để địa chỉ tạo ra có thể dự đoán trước. Cách làm cụ thể là 「pool = address(new UniswapV3Pool{salt: keccak256(abi.encode(token0, token1, fee))}());」 trong đoạn mã này. Việc này có lợi là chỉ cần biết cặp token và phí giao dịch, là có thể tính ra địa chỉ hợp đồng của pool mà không cần phải triển khai rồi mới biết. Điều này rất hữu ích trong xác thực quyền giao dịch hoặc định vị nhanh pool.

Thiết kế hàm callback cũng rất tinh tế.

Trong Uniswap, khi bạn gọi phương thức swap để thực hiện giao dịch, nó sẽ gọi hàm swapCallback, truyền về số lượng Token cần thiết đã tính sẵn, rồi bạn trong callback sẽ chuyển Token vào. Cách này giúp toàn bộ logic giao dịch được thực thi trọn vẹn, không cần chia thành nhiều bước hoặc dùng biến phức tạp để giữ trạng thái, đảm bảo an toàn. Nói đơn giản là A gọi B, B trong lúc gọi lại lại gọi A, tạo thành vòng lặp khép kín.

Phương pháp dự đoán giao dịch cũng khá "Hack" — dùng lỗi để truyền thông tin.

Vì khi dự đoán giao dịch, thực tế không thực hiện đổi Token, nên sẽ báo lỗi. Cách của Uniswap là trong callback, ném ra lỗi đặc biệt, rồi dùng try-catch bắt lỗi, phân tích nội dung lỗi để lấy dữ liệu cần thiết. Có vẻ hơi thô nhưng thực tế rất hữu dụng, không cần phải sửa đổi nhiều phương thức swap vẫn có thể làm chức năng dự đoán.

Giải pháp cho vấn đề độ chính xác cũng rất đáng học.

Khi tính toán đổi Token, nếu trực tiếp chia sẽ mất độ chính xác. Uniswap làm là trước tiên dịch trái 96 bit (tương đương nhân với 2^96), rồi mới chia, cuối cùng trong quá trình tính toán bỏ đi 2^96. Như vậy trong phạm vi uint256 vừa đảm bảo độ chính xác, vừa tránh tràn số. Trong mã, sqrtRatioAX96 và sqrtRatioBX96 chính là theo cách này, nhìn có vẻ phức tạp nhưng logic rõ ràng.

Cách tính lợi nhuận phí cũng rất thông minh.

Thay vì mỗi lần giao dịch đều ghi nhận phí của từng LP (tốn nhiều gas), họ ghi nhận tổng phí và tỷ lệ phân phối cho từng phần vốn. Khi LP rút, chỉ cần lấy lượng vốn của mình nhân với tổng phí đã tích lũy theo từng cổ phần, giống như cổ đông nhận cổ tức theo mỗi cổ phần. Cách tính Share này đã được áp dụng trong nhiều dự án.

Việc không cần tất cả thông tin đều phải lên chuỗi cũng rất quan trọng.

Danh sách pool, thông tin cơ bản, hoàn toàn có thể lưu trong database truyền thống, định kỳ đồng bộ từ chuỗi, không cần gọi RPC liên tục. Hiện nay nhiều dịch vụ blockchain cung cấp API cao cấp, giúp lấy dữ liệu nhanh, rẻ hơn — đó chính là ý tưởng tương tự.

Cuối cùng là cách tổ chức mã.

Một dự án phức tạp thường chia nhỏ hợp đồng để dễ bảo trì, Uniswap cũng kế thừa nhiều hợp đồng. Đồng thời, cũng nên tận dụng các hợp đồng chuẩn như dùng OpenZeppelin ERC721 để quản lý vị thế, vừa nâng cao hiệu quả phát triển, vừa đảm bảo chất lượng mã.

Thành thật mà nói, xem nhiều bài viết không bằng tự tay làm. Trong quá trình xây dựng một sàn giao dịch phi tập trung đơn giản, bạn mới thực sự hiểu tại sao Uniswap lại thiết kế như vậy. Khóa học WTF-DApp chính dựa trên ý tưởng này, hướng dẫn bạn từng bước hoàn thành dự án thực chiến của Uniswap, tin rằng sẽ giúp ích rất nhiều cho việc phát triển hợp đồng của bạn.
Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • Bình luận
  • Đăng lại
  • Retweed
Bình luận
Thêm một bình luận
Thêm một bình luận
Không có bình luận
  • Ghim