LapTrinhBlockchain

Chia sẻ kiến thức về Lập Trình Blockchain

Kiến thức Blockchain, Kiến thức lập trình, Lập trình Blockchain, Lập trình Công cụ, Lập trình NodeJs, Nâng cao Kiến thức

Làm thế nào để biết một token ERC20 có sử dụng qua Proxy contract không?

Làm thế nào để biết một token ERC20 có sử dụng qua Proxy contract không?

Làm thế nào để biết một token ERC20 có sử dụng qua Proxy contract không?

Chia sẻ bài viết
5
(8)

Hiện nay rất nhiều token có sử dụng thông qua 1 Proxy Contract, điều này có nghĩ là chủ sở hữu token Proxy Contract này có quyền thay thế token gốc bằng một token khác, do đó tiềm ẩn nhiều vấn đề về bảo mật. Thêm nữa, lượng Gas Used sử dụng qua token Proxy lớn hơn khá nhiều so với sử dụng trực tiếp.

Nhưng với những dự án mới, hoặc một số dự án uy tín họ vẫn sử dụng cách này để giúp có thể dễ dàng nâng cấp trong tương lai khi gặp vấn đề về lỗi hoặc bảo mật với contract cũ. Đặc biệt hữu ích khi cần triển khai các thuật toán mới, chưa được kiểm chứng.

Vậy có cách nào, chúng ta có thể kiểm tra TỰ ĐỘNG một token có sử dụng qua một Proxy Contract hay không?

Tìm hiểu về Token sử dụng qua Proxy Contract

Giờ chúng ta đi sâu tìm hiểu token điển hình sử dụng Proxy Contract, đó là token USD Base Coin (USDbC) trên Base Network. Nếu nhìn trên BaseScan, chúng ta sẽ dễ dàng biết được đó có phải Proxy Contract hay không dựa vào thông tin hiển thị trong phần Contract/Code

Xác định token sử dụng Proxy Contract qua BaseScan

Xem trong code thì toàn là hàm Write, và có kiểm tra thì:

  • Nếu gọi các hàm dành cho Admin thì chỉ Admin mới gọi được, người khác gọi sẽ bị Revert
  • Nếu gọi các hàm của ERC20 thì sẽ tự động gọi tới contract của token ERC20
Một số xử lý khi thao tác với Proxy Contract

Chi tiết xem: The transparent proxy pattern

Giải pháp kiểm tra token có sử dụng Proxy Contract hay không?

Qua quá trình tìm hiểu và xem source code, tôi thấy rằng các Proxy Contract luôn có hàm implementation() trả về địa chỉ token liên quan. Tôi thử gọi hàm này bằng staticcall nhưng không thành công, hàm này luôn trả về lỗi REVERT.

Tôi thử tìm signature của hàm implementation() trên Openchain Signatures thì hàm không tham số có Signature là 0x5c60da1b, dùng web3.eth.getCode() để lấy code của contract xem trong code contract có mã 5c60da1b kết quả hơi buồn vì không có.

Tôi thử chuyển sang token ERC20 bình thường ví dụ Wrapped Ether (WETH), tôi lấy source của smart contract này về và kiểm tra xem nó có chứa Signature của một số hàm thông dụng của ERC20 không?

  • transfer(address,uint256): Có Signature là a9059cbb => Có trong code của Smart Contract.
  • balanceOf(address) => Có Signature là 70a08231 => Có trong code của Smart Contract.
  • symbol() => Có Signature là 95d89b41 => Có trong code của Smart Contract.

Đến đây chúng ta đã tìm ra Giải Pháp để kiểm tra một token có sử dụng Proxy Contract hay không?

  • B1: Dùng hàm web3.eth.getCode() để lấy code của Smart Contract.
  • B2: Kiểm tra code của Smart Contract có chứa đồng thời ba xâu: “a9059cbb“, “70a08231“, và “95d89b41
  • B3: Phân loại:
    • Nếu code chứa đồng thời cả 3 xâu trên => Là Token ERC20 bình thường
    • Ngược lại là token có sử dụng Proxy Contract.

Cài đặt code để kiểm tra token có sử dụng Proxy Contract hay không?

Dựa theo giải pháp trên, giờ chúng ta sẽ viết check-proxy-token.js để kiểm tra một token có sử dụng Proxy Contract hay không? Mã nguồn như bên dưới:

const Web3 = require('web3');

// RPC on BASE Network
let rpcNode = "https://mainnet.base.org";
let web3 = new Web3(rpcNode);

// Check token has use proxy or not?
async function checkProxyToken(token) {
    try {
        let code = await web3.eth.getCode(token);
        if (code) {
            // transfer(address,uint256) => 0xa9059cbb
            // balanceOf(address) => 0x70a08231
            // symbol() => 0x95d89b41
            if (code.indexOf("a9059cbb")>=0 && code.indexOf("70a08231") && code.indexOf("95d89b41")) return false;
            return true;
        }
    } catch(ex) {
        console.error("checkProxyToken EXCEPTION", token, ex);
    }
    return null;
}

async function main() {
    let token = "0xd9aaec86b65d86f6a7b5b1b0c42ffa531710b6ca";
	let hasProxy = await checkProxyToken(token);
    console.log(`HasProxy(${token}) = ${hasProxy}`);
}
main();

Bạn chạy bằng lệnh sau:

# Cài đặt thư viện Web3 (Lần đầu)
npm install web3

# Chạy công cụ
node check-proxy-token.js

Bài viết này có hữu ích với bạn?

Kích vào một biểu tượng ngôi sao để đánh giá bài viết!

Xếp hạng trung bình 5 / 5. Số phiếu: 8

Bài viết chưa có đánh giá! Hãy là người đầu tiên đánh giá bài viết này.

Trả lời

Giao diện bởi Anders Norén