Đặc biệt cảm ơn Dankrad Feist và Aditya Asgaonkar đã đánh giá
Sharding là tương lai của khả năng mở rộng Ethereum và nó sẽ là chìa khóa để giúp hệ sinh thái hỗ trợ hàng nghìn giao dịch mỗi giây và cho phép phần lớn thế giới sử dụng nền tảng này thường xuyên với chi phí hợp lý. Tuy nhiên, nó cũng là một trong những khái niệm bị hiểu nhầm nhiều hơn trong hệ sinh thái Ethereum và rộng hơn là trong hệ sinh thái blockchain. Nó đề cập đến một tập hợp các ý tưởng rất cụ thể với các thuộc tính rất cụ thể, nhưng nó thường được kết hợp với các kỹ thuật có các đặc tính bảo mật rất khác nhau và thường yếu hơn nhiều. Mục đích của bài đăng này là giải thích chính xác những thuộc tính cụ thể mà sharding cung cấp, nó khác với các công nghệ khác không có tính năng sharding như thế nào và hệ thống sharded phải hy sinh những gì để đạt được những đặc tính này.
Cách tốt nhất để mô tả sharding bắt đầu từ tuyên bố vấn đề đã định hình và truyền cảm hứng cho giải pháp: Bộ ba nan giải về khả năng mở rộng.
Bộ ba về khả năng mở rộng nói rằng có ba thuộc tính mà một blockchain cố gắng có, và nếu bạn tuân theo các kỹ thuật "đơn giản", bạn chỉ có thể nhận được hai trong ba đặc tính đó . Ba thuộc tính là:
Khả năng mở rộng : chuỗi có thể xử lý nhiều giao dịch hơn so với một nút thông thường duy nhất (hãy nghĩ: một máy tính xách tay tiêu dùng) có thể xác minh.
Phi tập trung : chuỗi có thể chạy mà không có bất kỳ sự phụ thuộc tin cậy nào vào một nhóm nhỏ các tác nhân tập trung lớn. Điều này thường được hiểu là không nên có bất kỳ sự tin tưởng nào (hoặc thậm chí là giả định đa số trung thực) đối với một tập hợp các nút mà bạn không thể tham gia chỉ với một máy tính xách tay tiêu dùng.
Bảo mật : chuỗi có thể chống lại một tỷ lệ phần trăm lớn các nút tham gia đang cố gắng tấn công nó (lý tưởng là 50%; bất cứ điều gì trên 25% là ổn, 5% chắc chắn là không ổn).
Bây giờ chúng ta có thể xem xét ba loại "giải pháp dễ dàng" chỉ nhận được hai trong ba:
Các blockchain truyền thống - bao gồm Bitcoin, tiền PoS / sharding Ethereum, Litecoin và các chuỗi tương tự khác. Chúng dựa vào việc mọi người tham gia chạy một nút đầy đủ xác minh mọi giao dịch và do đó chúng có khả năng phân quyền và bảo mật, nhưng không có khả năng mở rộng.
Các chuỗi TPS cao - bao gồm họ DPoS và nhiều chuỗi khác. Chúng dựa vào một số lượng nhỏ các nút (thường là 10-100) duy trì sự đồng thuận giữa chúng với nhau, với người dùng phải tin tưởng phần lớn các nút này. Điều này có thể mở rộng và an toàn (sử dụng các định nghĩa ở trên), nhưng nó không được phân cấp.
Hệ sinh thái đa chuỗi - điều này đề cập đến khái niệm chung về "mở rộng quy mô" bằng cách để các ứng dụng khác nhau hoạt động trên các chuỗi khác nhau và sử dụng các giao thức liên lạc xuyên chuỗi để trao đổi giữa chúng. Điều này là phi tập trung và có thể mở rộng, nhưng nó không an toàn, bởi vì kẻ tấn công chỉ cần có được đa số nút đồng thuận trong một trong nhiều chuỗi (thường là <1% toàn bộ hệ sinh thái) để phá vỡ chuỗi đó và có thể gây ra các hiệu ứng gợn sóng gây ra thiệt hại lớn cho các ứng dụng trong chuỗi khác.
Sharding là một kỹ thuật giúp bạn có được cả ba. Một chuỗi khối phân mảnh là:
Phần còn lại của bài đăng sẽ mô tả cách các blockchain phân đoạn quản lý để thực hiện điều này.
Phiên bản dễ hiểu nhất của sharding là sharding thông qua lấy mẫu ngẫu nhiên. Sharding thông qua lấy mẫu ngẫu nhiên có đặc tính tin cậy yếu hơn các hình thức sharding mà chúng tôi đang xây dựng trong hệ sinh thái Ethereum, nhưng nó sử dụng công nghệ đơn giản hơn.
Ý tưởng cốt lõi như sau. Giả sử rằng bạn có bằng chứng về chuỗi cổ phần với số lượng lớn (ví dụ: 10000) trình xác thực và bạn có một số lượng lớn (ví dụ: 100) khối cần được xác minh. Không có máy tính nào đủ mạnh để xác thực tất cả các khối này trước khi tập hợp khối tiếp theo xuất hiện.
Do đó, những gì chúng tôi làm là chúng tôi chia nhỏ công việc xác minh một cách ngẫu nhiên . Chúng tôi xáo trộn ngẫu nhiên danh sách trình xác thực và chúng tôi chỉ định 100 trình xác thực đầu tiên trong danh sách được xáo trộn để xác minh khối đầu tiên, 100 trình xác thực thứ hai trong danh sách được xáo trộn để xác minh khối thứ hai, v.v. Một nhóm trình xác thực được chọn ngẫu nhiên được chỉ định cho xác minh một khối (hoặc thực hiện một số nhiệm vụ khác) được gọi là một ủy ban .
Khi trình xác thực xác minh một khối, họ sẽ xuất bản một chữ ký chứng thực rằng họ đã làm như vậy. Những người khác, thay vì xác minh toàn bộ 100 khối, giờ chỉ xác minh 10000 chữ ký - một khối lượng công việc nhỏ hơn nhiều, đặc biệt là với tập hợp chữ ký BLS . Thay vì mọi khối được phát thông qua cùng một mạng P2P, mỗi khối được phát trên một mạng con khác nhau và các nút chỉ cần tham gia các mạng con tương ứng với các khối mà chúng chịu trách nhiệm (hoặc quan tâm đến các lý do khác).
Hãy xem xét điều gì sẽ xảy ra nếu sức mạnh tính toán của mỗi nút tăng gấp 2 lần. Bởi vì mỗi nút hiện có thể xác thực an toàn thêm 2 lần chữ ký, bạn có thể cắt giảm kích thước tiền gửi đặt cược tối thiểu để hỗ trợ thêm 2 lần người xác thực và do đó bạn có thể tạo 200 ủy ban thay vì 100.
Do đó, bạn có thể xác minh 200 khối trên mỗi vị trí thay vì 100. Hơn nữa, mỗi khối riêng lẻ có thể lớn hơn gấp đôi. Do đó, bạn có thêm 2 lần khối có kích thước gấp 2 lần hoặc gấp 4 lần tổng công suất chuỗi.
Chúng ta có thể giới thiệu một số biệt ngữ toán học để nói về những gì đang xảy ra. Sử dụng ký hiệu Big O , chúng tôi sử dụng " O (C) " để chỉ khả năng tính toán của một nút duy nhất. Một blockchain truyền thống có thể xử lý các khối có kích thước O (C) . Một chuỗi phân đoạn như được mô tả ở trên có thể xử lý song song các khối O (C) (hãy nhớ rằng chi phí cho mỗi nút để xác minh gián tiếp từng khối là O (1) vì mỗi nút chỉ cần xác minh một số lượng chữ ký cố định), và mỗi khối có công suất O (C) , và do đó tổng công suất của chuỗi phân đoạn là O (C2) . Đây là lý do tại sao chúng tôi gọi đây là loại hình sharding bậc hai , và hiệu ứng này là lý do chính khiến chúng tôi nghĩ rằng về lâu dài, sharding là cách tốt nhất để mở rộng quy mô blockchain.
Có hai điểm khác biệt chính:
Cả hai sự khác biệt này đảm bảo rằng sharding tạo ra một môi trường cho các ứng dụng duy trì các thuộc tính an toàn chính của môi trường chuỗi đơn, theo cách mà các hệ sinh thái đa nhóm về cơ bản không làm được.
Một biện pháp phổ biến trong giới Bitcoin, và tôi hoàn toàn đồng ý, đó là các blockchain như Bitcoin (hoặc Ethereum) KHÔNG hoàn toàn dựa vào giả định đa số trung thực . Nếu có một cuộc tấn công 51% vào một blockchain như vậy, thì kẻ tấn công có thể làm một số việc khó chịu, như hoàn nguyên hoặc kiểm duyệt các giao dịch, nhưng chúng không thể chèn các giao dịch không hợp lệ. Và ngay cả khi họ thực hiện hoàn nguyên hoặc kiểm duyệt các giao dịch, người dùng chạy các nút thông thường có thể dễ dàng phát hiện ra hành vi đó, vì vậy nếu cộng đồng muốn phối hợp để giải quyết cuộc tấn công bằng một ngã ba làm mất đi sức mạnh của kẻ tấn công, họ có thể thực hiện một cách nhanh chóng.
Việc thiếu bảo mật bổ sung này là điểm yếu chính của các chuỗi TPS tập trung hơn . Các chuỗi như vậy không và không thể có văn hóa người dùng thường xuyên chạy các nút, và do đó các nút chính và những người chơi trong hệ sinh thái có thể dễ dàng kết hợp với nhau hơn và áp đặt một sự thay đổi giao thức mà cộng đồng rất không thích. Thậm chí tệ hơn, các nút của người dùng theo mặc định sẽ chấp nhận nó. Sau một thời gian, người dùng sẽ nhận thấy, nhưng khi đó sự thay đổi giao thức bắt buộc sẽ là một lỗi lầm: gánh nặng điều phối sẽ thuộc về người dùng để từ chối thay đổi và họ sẽ phải đưa ra quyết định đau đớn là hoàn nguyên giá trị của một ngày hoặc hơn hoạt động mà mọi người nghĩ đã được hoàn thành.
Lý tưởng nhất là chúng tôi muốn có một hình thức sharding tránh các giả định về tính hợp lệ của 51% tin cậy và duy trì sức mạnh bảo mật mà các blockchain truyền thống có được từ quá trình xác minh đầy đủ. Và đây chính xác là phần lớn nghiên cứu của chúng tôi trong vài năm qua.
Chúng ta có thể chia vấn đề xác thực khả năng mở rộng chống được 51% -attack thành hai trường hợp:
Xác thực tính toán : kiểm tra xem một số tính toán đã được thực hiện chính xác hay chưa, giả sử bạn có tất cả các đầu vào cho tính toán.
Xác thực tính khả dụng của dữ liệu : kiểm tra xem bản thân các đầu vào cho phép tính có được lưu trữ ở dạng nào đó mà bạn có thể tải xuống nếu bạn thực sự cần; việc kiểm tra này nên được thực hiện mà không thực sự tải xuống toàn bộ dữ liệu đầu vào (vì dữ liệu có thể quá lớn để tải xuống cho mọi khối).
Xác thực một khối trong chuỗi khối liên quan đến cả tính toán và kiểm tra tính khả dụng của dữ liệu: bạn cần phải tin rằng các giao dịch trong khối là hợp lệ và băm gốc trạng thái mới được xác nhận trong khối là kết quả chính xác của việc thực hiện các giao dịch đó, nhưng bạn cũng cần được thuyết phục rằng đủ dữ liệu từ khối đã thực sự được xuất bản để người dùng tải xuống dữ liệu đó có thể tính toán trạng thái và tiếp tục xử lý chuỗi khối. Phần thứ hai này là một khái niệm rất tinh tế nhưng quan trọng được gọi là vấn đề về tính khả dụng của dữ liệu ; thêm về điều này sau.
Tính toán xác thực theo quy mô tương đối dễ dàng; có hai nhóm kỹ thuật: bằng chứng gian lận và ZK-SNARK .
Hai công nghệ có thể được mô tả đơn giản như sau:
C
với đầu vào X
, bạn sẽ nhận được đầu ra Y
". Bạn tin tưởng những tin nhắn này theo mặc định, nhưng bạn lại để ngỏ cơ hội cho người khác có tiền đặt cọc thực hiện một thách thức (tin nhắn có chữ ký nói rằng "Tôi không đồng ý, đầu ra là Z"). Chỉ khi có một thử thách, tất cả các nút mới chạy tính toán. Bất kỳ bên nào sai trong hai bên sẽ mất tiền đặt cọc và tất cả các phép tính phụ thuộc vào kết quả của phép tính đó sẽ được tính lại.C
trên đầu vào X
cho đầu ra Y
". Bằng chứng là "âm thanh" về mặt mật mã: nếu C(x)
không bằng Y
, thì về mặt tính toán không thể tạo ra một bằng chứng hợp lệ. Bằng chứng cũng nhanh chóng được xác minh, ngay cả khi bản thân việc chạy C
mất rất nhiều thời gian. Xem bài đăng này để biết thêm chi tiết toán học về ZK-SNARKs.
Tính toán dựa trên bằng chứng gian lận có thể mở rộng vì "trong trường hợp thông thường" bạn thay thế việc chạy một phép tính phức tạp bằng việc xác minh một chữ ký. Có một trường hợp ngoại lệ, trong đó bạn phải xác minh tính toán trên chuỗi vì có một thử thách, nhưng trường hợp đặc biệt là rất hiếm vì việc kích hoạt nó rất tốn kém (người yêu cầu ban đầu hoặc người thách thức mất một khoản tiền gửi lớn). ZK-SNARK đơn giản hơn về mặt khái niệm - chúng chỉ thay thế một phép tính bằng một xác minh bằng chứng rẻ hơn nhiều - nhưng toán học đằng sau cách chúng hoạt động phức tạp hơn đáng kể.
Có một lớp hệ thống bán mở rộng chỉ xác minh tính toán theo quy mô, trong khi vẫn yêu cầu mọi nút xác minh tất cả dữ liệu. Điều này có thể được thực hiện khá hiệu quả bằng cách sử dụng một tập hợp các thủ thuật nén để thay thế hầu hết dữ liệu bằng tính toán. Đây là lĩnh vực của cuộn lên .
Không thể sử dụng biện pháp chống gian lận để xác minh tính khả dụng của dữ liệu. Các bằng chứng gian lận để tính toán dựa trên thực tế là các đầu vào cho phép tính được xuất bản trực tuyến tại thời điểm yêu cầu ban đầu được gửi và vì vậy nếu ai đó thách thức, việc thực thi thử thách sẽ diễn ra trong cùng một "môi trường" mà lần thực thi ban đầu là đang xảy ra. Trong trường hợp kiểm tra tính khả dụng của dữ liệu, bạn không thể làm điều này, vì vấn đề chính xác là có quá nhiều dữ liệu cần kiểm tra để xuất bản nó trên chuỗi. Do đó, một kế hoạch chống gian lận để cung cấp dữ liệu gặp phải một vấn đề chính: ai đó có thể tuyên bố "dữ liệu X khả dụng" mà không xuất bản nó, đợi để được thử thách và chỉ sau đó xuất bản dữ liệu X và làm cho người thách thức xuất hiện với phần còn lại của mạng không chính xác.
Điều này được mở rộng trong tình thế tiến thoái lưỡng nan của ngư dân :
Ý tưởng cốt lõi là hai "thế giới", một trong đó V1 là một nhà xuất bản xấu xa và V2 là một kẻ thách thức trung thực và một nơi mà V1 là một nhà xuất bản trung thực và V2 là một kẻ thách thức ác, không thể phân biệt được với bất kỳ ai không cố gắng tải xuống phần dữ liệu cụ thể đó vào thời điểm đó. Và tất nhiên, trong một blockchain phi tập trung có thể mở rộng, mỗi nút riêng lẻ chỉ có thể hy vọng tải xuống một phần nhỏ dữ liệu, vì vậy chỉ một phần nhỏ các nút sẽ thấy bất kỳ điều gì về những gì đã xảy ra ngoại trừ thực tế là có bất đồng.
Thực tế là không thể phân biệt được ai đúng ai sai khiến không thể có một kế hoạch chống gian lận hoạt động để cung cấp dữ liệu.
Thật không may, tính hợp lệ đơn thuần là không đủ để đảm bảo một blockchain chạy chính xác. Điều này là do nếu blockchain hợp lệ nhưng tất cả dữ liệu không có sẵn , thì người dùng không có cách nào cập nhật dữ liệu mà họ cần để tạo bằng chứng rằng bất kỳ khối nào trong tương lai là hợp lệ. Kẻ tấn công tạo ra một khối hợp lệ nhưng không khả dụng nhưng sau đó biến mất có thể làm ngưng trệ chuỗi một cách hiệu quả. Ai đó cũng có thể giữ lại dữ liệu tài khoản của một người dùng cụ thể cho đến khi người dùng trả tiền chuộc, do đó, vấn đề không hoàn toàn là vấn đề tồn tại.
Có một số lập luận lý thuyết-thông tin mạnh mẽ cho rằng vấn đề này là cơ bản và không có thủ thuật thông minh nào (ví dụ: liên quan đến bộ tích lũy mật mã ) có thể giải quyết được vấn đề này. Xem bài báo này để biết chi tiết.
Chìa khóa là một công nghệ được gọi là lấy mẫu tính khả dụng của dữ liệu. Lấy mẫu tính khả dụng của dữ liệu hoạt động như sau:
Mã xóa chuyển đổi vấn đề "kiểm tra 100% tính khả dụng" (mọi phần dữ liệu đều có sẵn) thành vấn đề "kiểm tra 50% tính khả dụng" (ít nhất một nửa số dữ liệu có sẵn). Lấy mẫu ngẫu nhiên giải quyết vấn đề 50% tính khả dụng. Nếu ít hơn 50% dữ liệu có sẵn, thì ít nhất một trong các lần kiểm tra gần như chắc chắn sẽ không thành công và nếu ít nhất 50% dữ liệu có sẵn sau đó, trong khi một số nút có thể không nhận ra một khối là có sẵn, thì phải chỉ một nút trung thực để chạy quy trình xây dựng lại mã xóa để mang lại 50% khối còn lại. Và do đó, thay vì cần tải xuống 1 MB để kiểm tra tính khả dụng của khối 1 MB, bạn chỉ cần tải xuống một vài kilobyte. Điều này làm cho việc chạy kiểm tra tính khả dụng của dữ liệu trên mọi khối trở nên khả thi. Xem bài đăng này để biết cách kiểm tra này có thể được triển khai hiệu quả với các mạng con ngang hàng.
Một ZK-SNARK có thể được sử dụng để xác minh rằng quá trình mã hóa xóa trên một phần dữ liệu đã được thực hiện chính xác và sau đó các nhánh Merkle có thể được sử dụng để xác minh các phần riêng lẻ. Ngoài ra, bạn có thể sử dụng các cam kết đa thức (ví dụ: cam kết Kate (hay còn gọi là KZG) ), về cơ bản thực hiện xóa mã hóa và chứng minh các yếu tố riêng lẻ và xác minh tính đúng đắn tất cả trong một thành phần đơn giản - và đó là những gì Ethereum sharding đang sử dụng.
Giả sử rằng bạn có 100 khối và bạn muốn xác minh tính đúng đắn một cách hiệu quả cho tất cả chúng mà không cần dựa vào các ủy ban. Chúng ta cần thực hiện những việc sau:
Mỗi máy khách thực hiện lấy mẫu tính khả dụng của dữ liệu trên mỗi khối, xác minh rằng dữ liệu trong mỗi khối có sẵn, trong khi chỉ tải xuống một vài kilobyte mỗi khối ngay cả khi toàn bộ khối có kích thước là megabyte hoặc lớn hơn. Khách hàng chỉ chấp nhận một khối khi tất cả dữ liệu về các thách thức về tính khả dụng của họ đã được phản hồi chính xác.
Bây giờ chúng tôi đã xác minh tính khả dụng của dữ liệu, việc xác minh tính đúng đắn trở nên dễ dàng hơn. Có hai kỹ thuật:
Trong một trong hai trường hợp trên, mỗi khách hàng chỉ cần thực hiện một lượng nhỏ công việc xác minh cho mỗi khối, bất kể khối đó lớn đến mức nào. Trong trường hợp bằng chứng gian lận, đôi khi các khối sẽ cần được xác minh đầy đủ trên chuỗi, nhưng điều này cực kỳ hiếm vì việc kích hoạt dù chỉ một thử thách cũng rất tốn kém.
Và đó là tất cả những gì cần làm! Trong trường hợp của Ethereum sharding, kế hoạch ngắn hạn là chỉ làm dữ liệu các khối phân mảnh; nghĩa là, các phân đoạn hoàn toàn là một "công cụ cung cấp dữ liệu" và nhiệm vụ của các cuộn dữ liệu lớp 2 là sử dụng không gian dữ liệu an toàn đó, cộng với bằng chứng gian lận hoặc ZK-SNARK, để triển khai các khả năng xử lý giao dịch an toàn thông lượng cao. Tuy nhiên, bạn hoàn toàn có thể tạo một hệ thống tích hợp như vậy để thêm thực thi thông lượng cao "nguyên bản".
Mục tiêu chính của sharding là tiến gần nhất có thể để tái tạo các thuộc tính bảo mật quan trọng nhất của các blockchain truyền thống (không phân đoạn) nhưng không cần mỗi nút phải xác minh cá nhân từng giao dịch.
Sharding đến khá gần. Trong một blockchain truyền thống:
Trong một chuỗi khối phân mảnh với các tính năng bảo mật nâng cao:
Các khối không hợp lệ không thể vượt qua bởi vì:
Các khối không khả dụng không thể vượt qua được vì:
Các chuỗi TPS cao truyền thống không có sharding không có cách cung cấp những đảm bảo này. Hệ sinh thái Multichain không có cách nào để tránh vấn đề kẻ tấn công chọn một chuỗi để tấn công và dễ dàng chiếm đoạt nó (các chuỗi có thể chia sẻ bảo mật, nhưng nếu điều này được thực hiện kém, nó sẽ biến thành một chuỗi TPS truyền thống trên thực tế với tất cả các nhược điểm của nó, và nếu nó được thực hiện tốt, nó sẽ chỉ là một quá trình thực hiện phức tạp hơn của các kỹ thuật sharding ở trên).
Sidechains phụ thuộc nhiều vào việc triển khai, nhưng chúng thường dễ bị ảnh hưởng bởi những điểm yếu của chuỗi TPS cao truyền thống (điều này xảy ra nếu chúng chia sẻ trình khai thác / trình xác thực) hoặc điểm yếu của hệ sinh thái đa phương thức (điều này xảy ra nếu chúng không chia sẻ trình khai thác / trình xác thực ). Chuỗi phân mảnh tránh những vấn đề này.
Tuy nhiên, có một số vết nứt trong áo giáp của hệ thống mảnh vỡ . Đáng chú ý:
Đây là những lo ngại hợp lệ, mặc dù theo quan điểm của chúng tôi, chúng còn bị vượt xa bởi việc giảm tập trung cấp độ người dùng được kích hoạt bằng cách cho phép nhiều ứng dụng hơn chạy trên chuỗi thay vì thông qua các dịch vụ tập trung lớp 2. Điều đó nói rằng, những mối quan tâm này, đặc biệt là hai mối quan tâm cuối cùng, trên thực tế là hạn chế thực sự đối với việc tăng thông lượng của một chuỗi phân đoạn vượt quá một điểm nhất định. Có một giới hạn đối với tính bậc hai của phép phân chia bậc hai.
Ngẫu nhiên, rủi ro an toàn ngày càng tăng của các blockchain phân đoạn nếu thông lượng của chúng trở nên quá cao cũng là lý do chính khiến nỗ lực mở rộng sang phân đoạn siêu bậc hai đã bị bỏ rơi phần lớn; có vẻ như việc giữ nét bậc hai chỉ bậc hai thực sự là phương tiện tốt.
Một giải pháp thay thế cho sharding thường được đề xuất là có một chuỗi có cấu trúc giống như một chuỗi TPS cao tập trung, ngoại trừ nó sử dụng lấy mẫu dữ liệu và tính sẵn sàng trên cùng để cho phép xác minh tính hợp lệ và tính khả dụng.
Điều này cải thiện trên các chuỗi TPS tập trung cao như chúng tồn tại ngày nay, nhưng nó vẫn yếu hơn đáng kể so với hệ thống phân đoạn. Điều này là vì một vài lý do:
Các hệ thống được phân đoạn đúng cách sẽ tốt hơn như một lớp cơ sở. Với một lớp cơ sở được phân đoạn, bạn luôn có thể tạo một hệ thống sản xuất tập trung (ví dụ: vì bạn muốn một miền thông lượng cao với khả năng tổng hợp đồng bộ cho defi ) được xếp lớp trên cùng bằng cách xây dựng nó dưới dạng một bản tổng hợp. Nhưng nếu bạn có lớp cơ sở phụ thuộc vào sản xuất khối tập trung, bạn không thể xây dựng lớp 2 phi tập trung hơn ở trên cùng.
Cũng được xuất bản ở đây .