diff --git a/public/content/translations/vi/developers/docs/scaling/zk-rollups/index.md b/public/content/translations/vi/developers/docs/scaling/zk-rollups/index.md new file mode 100644 index 00000000000..3ce3520b47a --- /dev/null +++ b/public/content/translations/vi/developers/docs/scaling/zk-rollups/index.md @@ -0,0 +1,257 @@ +--- +title: "Tổng hợp không cần kiến thức" +description: "Giới thiệu về tổng hợp không cần thông tin - một giải pháp mở rộng được sử dụng bởi cộng đồng Ethereum." +lang: vi +--- + +Rollup không kiến thức (rollup ZK) là các [giải pháp thay đổi quy mô](/developers/docs/scaling/) lớp 2 giúp tăng thông lượng trên Mạng chính Ethereum bằng cách chuyển việc tính toán và lưu trữ trạng thái ra ngoài chuỗi. ZK-rollups có thể xử lý hàng ngàn giao dịch thành 1 gói và sau đó chuyển một số dữ liệu tóm tắt tối thiếu lên Mạng chính. Các dữ liệu tóm tắt này xác định những thay đổi cần được thực hiện trên trạng thái Ethereum và một số mật mã chứng minh các thay đổi đó là chính xác. + +## Điều kiện tiên quyết {#prerequisites} + +Bạn nên đọc và hiểu trang của chúng tôi về [mở rộng quy mô Ethereum](/developers/docs/scaling/) và [lớp 2](/layer-2). + +## Tổng hợp không cần thông tin là gì? {#what-are-zk-rollups} + +**Rollup không kiến thức (rollup ZK)** gộp (hoặc 'cuộn lại') các giao dịch thành các lô được thực thi ngoài chuỗi. Tính toán ngoài chuỗi giúp giảm lượng dữ liệu phải đăng lên chuỗi khối. Những nhà vận hành ZK-rollup gửi bản tóm tắt các thay đổi cần thiết để thể hiện cho tất cả các giao dịch trong một đợt thay vì gửi từng giao dịch đơn lẻ. Chúng cũng tạo ra [bằng chứng hợp lệ](/glossary/#validity-proof) để chứng minh tính đúng đắn của các thay đổi. + +Trạng thái của rollup ZK được duy trì bởi một hợp đồng thông minh được triển khai trên mạng Ethereum. Để cập nhật trạng thái này, các nút rollup ZK phải gửi bằng chứng hợp lệ để xác minh. Như đã đề cập, bằng chứng hợp lệ là một đảm bảo mật mã học rằng thay đổi trạng thái do rollup đề xuất thực sự là kết quả của việc thực thi một lô giao dịch nhất định. Điều này có nghĩa là các rollup ZK chỉ cần cung cấp bằng chứng hợp lệ để hoàn tất giao dịch trên Ethereum thay vì đăng tất cả dữ liệu giao dịch trên chuỗi như [gộp giao dịch lạc quan](/developers/docs/scaling/optimistic-rollups/). + +Không có độ trễ khi chuyển tiền từ rollup ZK sang Ethereum vì các giao dịch rút tiền được thực thi ngay khi hợp đồng rollup ZK xác minh bằng chứng hợp lệ. Ngược lại, việc rút tiền từ các gộp giao dịch lạc quan phải chịu một độ trễ để cho phép bất kỳ ai thách thức giao dịch rút tiền bằng một [bằng chứng gian lận](/glossary/#fraud-proof). + +Các rollup ZK ghi giao dịch vào Ethereum dưới dạng `calldata`. `calldata` là nơi dữ liệu được bao gồm trong các lệnh gọi bên ngoài đến các hàm của hợp đồng thông minh được lưu trữ. Thông tin trong `calldata` được công bố trên chuỗi khối, cho phép bất kỳ ai có thể tự tái tạo lại trạng thái của rollup một cách độc lập. Các rollup ZK sử dụng các kỹ thuật nén để giảm dữ liệu giao dịch—ví dụ, tài khoản được biểu thị bằng một chỉ mục thay vì một địa chỉ, giúp tiết kiệm 28 byte dữ liệu. Việc công bố dữ liệu trên chuỗi là một chi phí đáng kể đối với các rollup, do đó việc nén dữ liệu có thể giảm phí cho người dùng. + +## Các rollup ZK tương tác với Ethereum như thế nào? {#zk-rollups-and-ethereum} + +Một chuỗi rollup ZK là một giao thức ngoài chuỗi hoạt động trên chuỗi khối Ethereum và được quản lý bởi các hợp đồng thông minh Ethereum trên chuỗi. Các rollup ZK thực thi giao dịch bên ngoài Mạng chính, nhưng định kỳ cam kết các lô giao dịch ngoài chuỗi vào một hợp đồng rollup trên chuỗi. Bản ghi giao dịch này là bất biến, giống như chuỗi khối Ethereum, và tạo thành chuỗi rollup ZK. + +Kiến trúc cốt lõi của rollup ZK bao gồm các thành phần sau: + +1. **Các hợp đồng trên chuỗi**: Như đã đề cập, giao thức rollup ZK được kiểm soát bởi các hợp đồng thông minh chạy trên Ethereum. Điều này bao gồm hợp đồng chính lưu trữ các khối rollup, theo dõi các khoản tiền gửi và giám sát các bản cập nhật trạng thái. Một hợp đồng trên chuỗi khác (hợp đồng trình xác minh) xác minh các bằng chứng không kiến thức được gửi bởi các nhà sản xuất khối. Do đó, Ethereum đóng vai trò là lớp cơ sở hoặc "lớp 1" cho rollup ZK. + +2. **Máy ảo ngoài chuỗi (VM)**: Trong khi giao thức rollup ZK tồn tại trên Ethereum, việc thực thi giao dịch và lưu trữ trạng thái diễn ra trên một máy ảo riêng biệt độc lập với [máy ảo Ethereum](/developers/docs/evm/). VM ngoài chuỗi này là môi trường thực thi cho các giao dịch trên rollup ZK và đóng vai trò là lớp thứ cấp hoặc "lớp 2" cho giao thức rollup ZK. Các bằng chứng hợp lệ được xác minh trên Mạng chính Ethereum đảm bảo tính đúng đắn của các chuyển đổi trạng thái trong VM ngoài chuỗi. + +Các rollup ZK là "giải pháp thay đổi quy mô kết hợp"—các giao thức ngoài chuỗi hoạt động độc lập nhưng lấy được sự bảo mật từ Ethereum. Cụ thể, mạng Ethereum thực thi tính hợp lệ của các bản cập nhật trạng thái trên rollup ZK và đảm bảo tính sẵn có của dữ liệu đằng sau mỗi bản cập nhật cho trạng thái của rollup. Do đó, các rollup ZK an toàn hơn đáng kể so với các giải pháp thay đổi quy mô hoàn toàn ngoài chuỗi, chẳng hạn như [chuỗi bên](/developers/docs/scaling/sidechains/), vốn chịu trách nhiệm về các thuộc tính bảo mật của chúng, hoặc [validium](/developers/docs/scaling/validium/), vốn cũng xác minh các giao dịch trên Ethereum bằng các bằng chứng hợp lệ, nhưng lưu trữ dữ liệu giao dịch ở nơi khác. + +Các rollup ZK dựa vào giao thức chính của Ethereum cho những điều sau đây: + +### Tính khả dụng của dữ liệu {#data-availability} + +Các rollup ZK công bố dữ liệu trạng thái cho mọi giao dịch được xử lý ngoài chuỗi tới Ethereum. Với dữ liệu này, các cá nhân hoặc doanh nghiệp có thể tái tạo trạng thái của rollup và tự xác thực chuỗi. Ethereum cung cấp dữ liệu này cho tất cả những người tham gia mạng dưới dạng `calldata`. + +Các rollup ZK không cần công bố nhiều dữ liệu giao dịch trên chuỗi vì các bằng chứng hợp lệ đã xác minh tính xác thực của các chuyển đổi trạng thái. Tuy nhiên, việc lưu trữ dữ liệu trên chuỗi vẫn rất quan trọng vì nó cho phép xác minh độc lập, không cần cấp phép trạng thái của chuỗi L2, từ đó cho phép bất kỳ ai gửi các lô giao dịch, ngăn chặn các nhà khai thác độc hại kiểm duyệt hoặc đóng băng chuỗi. + +Dữ liệu trên chuỗi là cần thiết để người dùng tương tác với rollup. Nếu không có quyền truy cập vào dữ liệu trạng thái, người dùng không thể truy vấn số dư tài khoản của họ hoặc khởi tạo các giao dịch (ví dụ: rút tiền) dựa vào thông tin trạng thái. + +### Tính cuối cùng của giao dịch {#transaction-finality} + +Ethereum hoạt động như một lớp thanh toán cho các rollup ZK: các giao dịch L2 chỉ được hoàn tất nếu hợp đồng L1 chấp nhận bằng chứng hợp lệ. Điều này loại bỏ rủi ro các nhà khai thác độc hại làm hỏng chuỗi (ví dụ: đánh cắp tiền của rollup) vì mọi giao dịch phải được phê duyệt trên Mạng chính. Ngoài ra, Ethereum đảm bảo rằng các hoạt động của người dùng không thể bị đảo ngược sau khi được hoàn tất trên L1. + +### Chống kiểm duyệt {#censorship-resistance} + +Hầu hết các rollup ZK sử dụng một "siêu nút" (nhà khai thác) để thực thi giao dịch, sản xuất các lô và gửi các khối đến L1. Mặc dù điều này đảm bảo hiệu quả, nó làm tăng rủi ro bị kiểm duyệt: các nhà khai thác rollup ZK độc hại có thể kiểm duyệt người dùng bằng cách từ chối đưa giao dịch của họ vào các lô. + +Như một biện pháp bảo mật, các rollup ZK cho phép người dùng gửi giao dịch trực tiếp đến hợp đồng rollup trên Mạng chính nếu họ nghĩ rằng mình đang bị nhà khai thác kiểm duyệt. Điều này cho phép người dùng buộc thoát khỏi rollup ZK để về Ethereum mà không cần phải dựa vào sự cho phép của nhà khai thác. + +## ZK-rollups hoạt động như thế nào? {#how-do-zk-rollups-work} + +### Các giao dịch {#transactions} + +Người dùng trong rollup ZK ký giao dịch và gửi cho các nhà khai thác L2 để xử lý và đưa vào lô tiếp theo. Trong một số trường hợp, nhà khai thác là một thực thể tập trung, được gọi là trình sắp xếp thứ tự, người thực thi giao dịch, tổng hợp chúng thành các lô và gửi đến L1. Trình sắp xếp thứ tự trong hệ thống này là thực thể duy nhất được phép sản xuất các khối L2 và thêm các giao dịch rollup vào hợp đồng rollup ZK. + +Các rollup ZK khác có thể luân chuyển vai trò nhà khai thác bằng cách sử dụng một tập hợp trình xác thực [bằng chứng cổ phần](/developers/docs/consensus-mechanisms/pos/). Các nhà khai thác tiềm năng gửi tiền vào hợp đồng rollup, với kích thước của mỗi khoản cổ phần ảnh hưởng đến cơ hội của người đặt cược được chọn để sản xuất lô rollup tiếp theo. Cổ phần của nhà khai thác có thể bị cắt giảm nếu họ hành động độc hại, điều này khuyến khích họ đăng các khối hợp lệ. + +#### Cách các rollup ZK công bố dữ liệu giao dịch trên Ethereum {#how-zk-rollups-publish-transaction-data-on-ethereum} + +Như đã giải thích, dữ liệu giao dịch được công bố trên Ethereum dưới dạng `calldata`. `calldata` là một vùng dữ liệu trong một hợp đồng thông minh được sử dụng để truyền các đối số cho một hàm và hoạt động tương tự như [bộ nhớ](/developers/docs/smart-contracts/anatomy/#memory). Mặc dù `calldata` không được lưu trữ như một phần của trạng thái Ethereum, nó vẫn tồn tại trên chuỗi như một phần của [nhật ký lịch sử](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html?highlight=memory#logs) của chuỗi Ethereum. `calldata` không ảnh hưởng đến trạng thái của Ethereum, khiến nó trở thành một cách rẻ tiền để lưu trữ dữ liệu trên chuỗi. + +Từ khóa `calldata` thường xác định phương thức hợp đồng thông minh đang được gọi bởi một giao dịch và giữ các đầu vào cho phương thức dưới dạng một chuỗi byte tùy ý. Các rollup ZK sử dụng `calldata` để công bố dữ liệu giao dịch đã nén trên chuỗi; nhà khai thác rollup chỉ cần thêm một lô mới bằng cách gọi hàm yêu cầu trong hợp đồng rollup và truyền dữ liệu đã nén dưới dạng các đối số của hàm. Điều này giúp giảm chi phí cho người dùng vì một phần lớn phí rollup được dùng để lưu trữ dữ liệu giao dịch trên chuỗi. + +### Cam kết trạng thái {#state-commitments} + +Trạng thái của rollup ZK, bao gồm các tài khoản và số dư L2, được biểu diễn dưới dạng một [cây Merkle](/whitepaper/#merkle-trees). Một hàm băm mật mã học của gốc cây Merkle (gốc Merkle) được lưu trữ trong hợp đồng trên chuỗi, cho phép giao thức rollup theo dõi các thay đổi trong trạng thái của rollup ZK. + +Rollup chuyển sang một trạng thái mới sau khi thực hiện một tập hợp các giao dịch mới. Nhà khai thác đã khởi tạo quá trình chuyển đổi trạng thái được yêu cầu tính toán một gốc trạng thái mới và gửi đến hợp đồng trên chuỗi. Nếu bằng chứng hợp lệ liên quan đến lô được xác thực bởi hợp đồng trình xác minh, gốc Merkle mới sẽ trở thành gốc trạng thái chính tắc của rollup ZK. + +Bên cạnh việc tính toán các gốc trạng thái, nhà khai thác rollup ZK cũng tạo ra một gốc lô—gốc của một cây Merkle bao gồm tất cả các giao dịch trong một lô. Khi một lô mới được gửi, hợp đồng rollup sẽ lưu trữ gốc lô, cho phép người dùng chứng minh một giao dịch (ví dụ: một yêu cầu rút tiền) đã được bao gồm trong lô. Người dùng sẽ phải cung cấp chi tiết giao dịch, gốc lô và một [bằng chứng Merkle](/developers/tutorials/merkle-proofs-for-offline-data-integrity/) cho thấy đường dẫn bao gồm. + +### Bằng chứng hợp lệ {#validity-proofs} + +Gốc trạng thái mới mà nhà khai thác rollup ZK gửi đến hợp đồng L1 là kết quả của các bản cập nhật cho trạng thái của rollup. Giả sử Alice gửi 10 token cho Bob, nhà khai thác chỉ cần giảm số dư của Alice đi 10 và tăng số dư của Bob lên 10. Sau đó, nhà khai thác sẽ băm dữ liệu tài khoản đã cập nhật, xây dựng lại cây Merkle của rollup và gửi gốc Merkle mới đến hợp đồng trên chuỗi. + +Nhưng hợp đồng rollup sẽ không tự động chấp nhận cam kết trạng thái được đề xuất cho đến khi nhà khai thác chứng minh rằng gốc Merkle mới là kết quả của các bản cập nhật chính xác cho trạng thái của rollup. Nhà khai thác rollup ZK thực hiện điều này bằng cách tạo ra một bằng chứng hợp lệ, một cam kết mật mã học ngắn gọn xác minh tính đúng đắn của các giao dịch đã được gộp thành lô. + +Bằng chứng hợp lệ cho phép các bên chứng minh tính đúng đắn của một tuyên bố mà không tiết lộ chính tuyên bố đó—do đó, chúng còn được gọi là bằng chứng không kiến thức. Các rollup ZK sử dụng bằng chứng hợp lệ để xác nhận tính đúng đắn của các chuyển đổi trạng thái ngoài chuỗi mà không cần phải thực thi lại các giao dịch trên Ethereum. Những bằng chứng này có thể ở dạng [ZK-SNARK](https://arxiv.org/abs/2202.06877) (Bằng chứng tri thức ngắn gọn không tương tác không kiến thức) hoặc [ZK-STARK](https://eprint.iacr.org/2018/046) (Bằng chứng tri thức minh bạch có thể mở rộng không kiến thức). + +Cả SNARK và STARK đều giúp chứng thực tính toàn vẹn của việc tính toán ngoài chuỗi trong các rollup ZK, mặc dù mỗi loại bằng chứng đều có những đặc điểm riêng biệt. + +**ZK-SNARKs** + +Để giao thức ZK-SNARK hoạt động, việc tạo ra một Chuỗi tham chiếu chung (CRS) là cần thiết: CRS cung cấp các tham số công khai để chứng minh và xác minh các bằng chứng hợp lệ. Tính bảo mật của hệ thống chứng minh phụ thuộc vào việc thiết lập CRS; nếu thông tin được sử dụng để tạo các tham số công khai rơi vào tay các tác nhân độc hại, chúng có thể tạo ra các bằng chứng hợp lệ giả. + +Một số rollup ZK cố gắng giải quyết vấn đề này bằng cách sử dụng một [nghi thức tính toán đa bên (MPC)](https://zkproof.org/2021/06/30/setup-ceremonies/amp/), liên quan đến các cá nhân đáng tin cậy, để tạo ra các tham số công khai cho mạch ZK-SNARK. Mỗi bên đóng góp một chút ngẫu nhiên (được gọi là "chất thải độc hại") vào việc xây dựng CRS, mà họ phải phá hủy ngay lập tức. + +Các thiết lập đáng tin cậy được sử dụng vì chúng làm tăng tính bảo mật của việc thiết lập CRS. Miễn là có một người tham gia trung thực phá hủy đầu vào của họ, tính bảo mật của hệ thống ZK-SNARK được đảm bảo. Tuy nhiên, cách tiếp cận này đòi hỏi phải tin tưởng những người liên quan sẽ xóa đi sự ngẫu nhiên đã lấy mẫu của họ và không làm suy yếu các đảm bảo bảo mật của hệ thống. + +Ngoài các giả định về sự tin cậy, ZK-SNARK phổ biến vì kích thước bằng chứng nhỏ và thời gian xác minh không đổi. Vì việc xác minh bằng chứng trên L1 chiếm phần lớn chi phí vận hành một rollup ZK, các L2 sử dụng ZK-SNARK để tạo ra các bằng chứng có thể được xác minh nhanh chóng và rẻ tiền trên Mạng chính. + +**ZK-STARKs** + +Giống như ZK-SNARK, ZK-STARK chứng minh tính hợp lệ của việc tính toán ngoài chuỗi mà không tiết lộ các đầu vào. Tuy nhiên, ZK-STARK được coi là một cải tiến so với ZK-SNARK vì khả năng mở rộng và tính minh bạch của chúng. + +ZK-STARK 'minh bạch', vì chúng có thể hoạt động mà không cần thiết lập đáng tin cậy của một Chuỗi tham chiếu chung (CRS). Thay vào đó, ZK-STARK dựa vào sự ngẫu nhiên có thể xác minh công khai để thiết lập các tham số cho việc tạo và xác minh bằng chứng. + +ZK-STARK cũng cung cấp khả năng mở rộng cao hơn vì thời gian cần thiết để chứng minh và xác minh bằng chứng hợp lệ tăng _gần như tuyến tính_ so với độ phức tạp của phép tính toán cơ bản. Với ZK-SNARK, thời gian chứng minh và xác minh thay đổi quy mô _tuyến tính_ so với kích thước của phép tính toán cơ bản. Điều này có nghĩa là ZK-STARK đòi hỏi ít thời gian hơn ZK-SNARK để chứng minh và xác minh khi có liên quan đến các bộ dữ liệu lớn, làm cho chúng hữu ích cho các ứng dụng có khối lượng lớn. + +ZK-STARK cũng an toàn trước các máy tính lượng tử, trong khi Mật mã đường cong Elliptic (ECC) được sử dụng trong ZK-SNARK được nhiều người tin là dễ bị tấn công bởi máy tính lượng tử. Nhược điểm của ZK-STARK là chúng tạo ra kích thước bằng chứng lớn hơn, đắt hơn để xác minh trên Ethereum. + +#### Bằng chứng hợp lệ hoạt động như thế nào trong các rollup ZK? {#validity-proofs-in-zk-rollups} + +##### Tạo bằng chứng + +Trước khi chấp nhận giao dịch, nhà khai thác sẽ thực hiện các kiểm tra thông thường. Điều này bao gồm việc xác nhận rằng: + +- Các tài khoản người gửi và người nhận là một phần của cây trạng thái. +- Người gửi có đủ tiền để xử lý giao dịch. +- Giao dịch là chính xác và khớp với khóa công khai của người gửi trên rollup. +- Nonce của người gửi là chính xác, v.v. + +Khi nút rollup ZK có đủ giao dịch, nó sẽ tổng hợp chúng thành một lô và biên dịch các đầu vào cho mạch chứng minh để biên dịch thành một bằng chứng ZK ngắn gọn. Điều này bao gồm: + +- Một gốc cây Merkle bao gồm tất cả các giao dịch trong lô. +- Các bằng chứng Merkle cho các giao dịch để chứng minh việc bao gồm trong lô. +- Các bằng chứng Merkle cho mỗi cặp người gửi-người nhận trong các giao dịch để chứng minh các tài khoản đó là một phần của cây trạng thái của rollup. +- Một tập hợp các gốc trạng thái trung gian, được lấy từ việc cập nhật gốc trạng thái sau khi áp dụng các bản cập nhật trạng thái cho mỗi giao dịch (tức là, giảm tài khoản người gửi và tăng tài khoản người nhận). + +Mạch chứng minh tính toán bằng chứng hợp lệ bằng cách "lặp" qua mỗi giao dịch và thực hiện các kiểm tra tương tự mà nhà khai thác đã hoàn thành trước khi xử lý giao dịch. Đầu tiên, nó xác minh tài khoản của người gửi là một phần của gốc trạng thái hiện có bằng cách sử dụng bằng chứng Merkle được cung cấp. Sau đó, nó giảm số dư của người gửi, tăng nonce của họ, băm dữ liệu tài khoản đã cập nhật và kết hợp nó với bằng chứng Merkle để tạo ra một gốc Merkle mới. + +Gốc Merkle này phản ánh sự thay đổi duy nhất trong trạng thái của rollup ZK: một sự thay đổi trong số dư và nonce của người gửi. Điều này có thể thực hiện được vì bằng chứng Merkle được sử dụng để chứng minh sự tồn tại của tài khoản được sử dụng để lấy ra gốc trạng thái mới. + +Mạch chứng minh thực hiện quy trình tương tự trên tài khoản của người nhận. Nó kiểm tra xem tài khoản của người nhận có tồn tại dưới gốc trạng thái trung gian không (sử dụng bằng chứng Merkle), tăng số dư của họ, băm lại dữ liệu tài khoản và kết hợp nó với bằng chứng Merkle để tạo ra một gốc trạng thái mới. + +Quá trình này lặp lại cho mọi giao dịch; mỗi "vòng lặp" tạo ra một gốc trạng thái mới từ việc cập nhật tài khoản của người gửi và một gốc mới tiếp theo từ việc cập nhật tài khoản của người nhận. Như đã giải thích, mỗi bản cập nhật cho gốc trạng thái đại diện cho một phần của cây trạng thái của rollup đang thay đổi. + +Mạch chứng minh ZK lặp lại trên toàn bộ lô giao dịch, xác minh chuỗi các bản cập nhật dẫn đến một gốc trạng thái cuối cùng sau khi giao dịch cuối cùng được thực thi. Gốc Merkle cuối cùng được tính toán sẽ trở thành gốc trạng thái chính tắc mới nhất của rollup ZK. + +##### Xác minh bằng chứng + +Sau khi mạch chứng minh xác minh tính đúng đắn của các bản cập nhật trạng thái, nhà khai thác L2 gửi bằng chứng hợp lệ đã được tính toán đến hợp đồng trình xác minh trên L1. Mạch xác minh của hợp đồng sẽ xác minh tính hợp lệ của bằng chứng và cũng kiểm tra các đầu vào công khai là một phần của bằng chứng: + +- **Gốc trạng thái trước**: Gốc trạng thái cũ của rollup ZK (tức là, trước khi các giao dịch được gộp thành lô được thực thi), phản ánh trạng thái hợp lệ cuối cùng được biết của chuỗi L2. + +- **Gốc trạng thái sau**: Gốc trạng thái mới của rollup ZK (tức là, sau khi thực thi các giao dịch được gộp thành lô), phản ánh trạng thái mới nhất của chuỗi L2. Gốc trạng thái sau là gốc cuối cùng được lấy ra sau khi áp dụng các bản cập nhật trạng thái trong mạch chứng minh. + +- **Gốc lô**: Gốc Merkle của lô, được lấy ra bằng cách _merklize_ các giao dịch trong lô và băm gốc của cây. + +- **Đầu vào giao dịch**: Dữ liệu liên quan đến các giao dịch được thực thi như một phần của lô đã gửi. + +Nếu bằng chứng thỏa mãn mạch (tức là, nó hợp lệ), điều đó có nghĩa là tồn tại một chuỗi các giao dịch hợp lệ chuyển rollup từ trạng thái trước đó (được đánh dấu bằng mật mã bởi gốc trạng thái trước) sang một trạng thái mới (được đánh dấu bằng mật mã bởi gốc trạng thái sau). Nếu gốc trạng thái trước khớp với gốc được lưu trữ trong hợp đồng rollup, và bằng chứng là hợp lệ, hợp đồng rollup sẽ lấy gốc trạng thái sau từ bằng chứng và cập nhật cây trạng thái của nó để phản ánh trạng thái đã thay đổi của rollup. + +### Vào và thoát {#entries-and-exits} + +Người dùng tham gia vào rollup ZK bằng cách gửi token vào hợp đồng của rollup được triển khai trên chuỗi L1. Giao dịch này được xếp hàng đợi vì chỉ có các nhà khai thác mới có thể gửi giao dịch đến hợp đồng rollup. + +Nếu hàng đợi tiền gửi đang chờ bắt đầu đầy, nhà khai thác rollup ZK sẽ lấy các giao dịch tiền gửi và gửi chúng đến hợp đồng rollup. Khi tiền của người dùng đã ở trong rollup, họ có thể bắt đầu giao dịch bằng cách gửi giao dịch cho nhà khai thác để xử lý. Người dùng có thể xác minh số dư trên rollup bằng cách băm dữ liệu tài khoản của họ, gửi hàm băm đến hợp đồng rollup và cung cấp một bằng chứng Merkle để xác minh so với gốc trạng thái hiện tại. + +Rút tiền từ một rollup ZK về L1 rất đơn giản. Người dùng khởi tạo giao dịch rút tiền bằng cách gửi tài sản của họ trên rollup đến một tài khoản được chỉ định để đốt. Nếu nhà khai thác bao gồm giao dịch trong lô tiếp theo, người dùng có thể gửi yêu cầu rút tiền đến hợp đồng trên chuỗi. Yêu cầu rút tiền này sẽ bao gồm: + +- Bằng chứng Merkle chứng minh việc bao gồm giao dịch của người dùng vào tài khoản đốt trong một lô giao dịch + +- Dữ liệu giao dịch + +- Gốc lô + +- Địa chỉ L1 để nhận tiền đã gửi + +Hợp đồng rollup băm dữ liệu giao dịch, kiểm tra xem gốc lô có tồn tại không và sử dụng bằng chứng Merkle để kiểm tra xem hàm băm giao dịch có phải là một phần của gốc lô không. Sau đó, hợp đồng thực hiện giao dịch rút tiền và gửi tiền đến địa chỉ đã chọn của người dùng trên L1. + +## Rollup ZK và khả năng tương thích với EVM {#zk-rollups-and-evm-compatibility} + +Không giống như các gộp giao dịch lạc quan, các rollup ZK không dễ dàng tương thích với [Máy ảo Ethereum (EVM)](/developers/docs/evm/). Việc chứng minh các phép tính EVM đa dụng trong các mạch khó khăn và tốn nhiều tài nguyên hơn so với việc chứng minh các phép tính đơn giản (như việc chuyển token được mô tả trước đó). + +Tuy nhiên, [những tiến bộ trong công nghệ không kiến thức](https://hackmd.io/@yezhang/S1_KMMbGt#Why-possible-now) đang khơi dậy sự quan tâm mới đối với việc gói gọn các phép tính EVM trong các bằng chứng không kiến thức. Những nỗ lực này hướng tới việc tạo ra một triển khai EVM không kiến thức (zkEVM) có thể xác minh hiệu quả tính đúng đắn của việc thực thi chương trình. Một zkEVM tái tạo các mã vận hành EVM hiện có để chứng minh/xác minh trong các mạch, cho phép thực thi các hợp đồng thông minh. + +Giống như EVM, một zkEVM chuyển đổi giữa các trạng thái sau khi phép tính được thực hiện trên một số đầu vào. Sự khác biệt là zkEVM cũng tạo ra các bằng chứng không kiến thức để xác minh tính đúng đắn của mỗi bước trong quá trình thực thi chương trình. Bằng chứng hợp lệ có thể xác minh tính đúng đắn của các hoạt động chạm đến trạng thái của VM (bộ nhớ, ngăn xếp, lưu trữ) và chính phép tính (tức là, hoạt động có gọi đúng mã vận hành và thực thi chúng một cách chính xác không?). + +Sự ra đời của các rollup ZK tương thích với EVM được kỳ vọng sẽ giúp các nhà phát triển tận dụng các đảm bảo về khả năng mở rộng và bảo mật của các bằng chứng không kiến thức. Quan trọng hơn, khả năng tương thích với cơ sở hạ tầng gốc của Ethereum có nghĩa là các nhà phát triển có thể xây dựng các ứng dụng phi tập trung thân thiện với ZK bằng cách sử dụng các bộ công cụ và ngôn ngữ quen thuộc (và đã được thử nghiệm thực tế). + +## Phí rollup ZK hoạt động như thế nào? {#how-do-zk-rollup-fees-work} + +Số tiền người dùng phải trả cho các giao dịch trên các rollup ZK phụ thuộc vào phí gas, giống như trên Mạng chính Ethereum. Tuy nhiên, phí gas hoạt động khác nhau trên L2 và bị ảnh hưởng bởi các chi phí sau: + +1. **Ghi trạng thái**: Có một chi phí cố định để ghi vào trạng thái của Ethereum (tức là, gửi một giao dịch trên chuỗi khối Ethereum). Các rollup ZK giảm chi phí này bằng cách gộp các giao dịch thành lô và phân bổ chi phí cố định cho nhiều người dùng. + +2. **Công bố dữ liệu**: Các rollup ZK công bố dữ liệu trạng thái cho mọi giao dịch tới Ethereum dưới dạng `calldata`. Chi phí `calldata` hiện được điều chỉnh bởi [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), quy định chi phí là 16 gas cho các byte khác không và 4 gas cho các byte bằng không của `calldata`. Chi phí phải trả cho mỗi giao dịch bị ảnh hưởng bởi lượng `calldata` cần được đăng trên chuỗi cho nó. + +3. **Phí nhà khai thác L2**: Đây là số tiền trả cho nhà khai thác rollup để bù đắp cho các chi phí tính toán phát sinh trong quá trình xử lý giao dịch, giống như [phí giao dịch "phí ưu tiên (tiền boa)"](/developers/docs/gas/#how-are-gas-fees-calculated) trên Mạng chính Ethereum. + +4. **Tạo và xác minh bằng chứng**: Các nhà khai thác rollup ZK phải tạo ra các bằng chứng hợp lệ cho các lô giao dịch, điều này tốn nhiều tài nguyên. Việc xác minh các bằng chứng không kiến thức trên Mạng chính cũng tốn gas (~ 500.000 gas). + +Ngoài việc gộp các giao dịch thành lô, các rollup ZK còn giảm phí cho người dùng bằng cách nén dữ liệu giao dịch. Bạn có thể [xem tổng quan theo thời gian thực](https://l2fees.info/) về chi phí sử dụng các rollup ZK của Ethereum. + +## Các rollup ZK thay đổi quy mô của Ethereum như thế nào? {#scaling-ethereum-with-zk-rollups} + +### Nén dữ liệu giao dịch {#transaction-data-compression} + +Các rollup ZK mở rộng thông lượng trên lớp cơ sở của Ethereum bằng cách đưa việc tính toán ra ngoài chuỗi, nhưng sự thúc đẩy thực sự cho việc thay đổi quy mô đến từ việc nén dữ liệu giao dịch. [Kích thước khối](/developers/docs/blocks/#block-size) của Ethereum giới hạn dữ liệu mà mỗi khối có thể chứa và do đó, số lượng giao dịch được xử lý trên mỗi khối. Bằng cách nén dữ liệu liên quan đến giao dịch, các rollup ZK tăng đáng kể số lượng giao dịch được xử lý trên mỗi khối. + +Các rollup ZK có thể nén dữ liệu giao dịch tốt hơn các gộp giao dịch lạc quan vì chúng không phải đăng tất cả dữ liệu cần thiết để xác thực mỗi giao dịch. Chúng chỉ phải đăng dữ liệu tối thiểu cần thiết để xây dựng lại trạng thái mới nhất của các tài khoản và số dư trên rollup. + +### Bằng chứng đệ quy {#recursive-proofs} + +Một lợi thế của các bằng chứng không kiến thức là các bằng chứng có thể xác minh các bằng chứng khác. Ví dụ, một ZK-SNARK duy nhất có thể xác minh các ZK-SNARK khác. Những "bằng chứng của bằng chứng" như vậy được gọi là bằng chứng đệ quy và làm tăng đáng kể thông lượng trên các rollup ZK. + +Hiện tại, các bằng chứng hợp lệ được tạo ra trên cơ sở từng khối và được gửi đến hợp đồng L1 để xác minh. Tuy nhiên, việc xác minh các bằng chứng khối đơn lẻ giới hạn thông lượng mà các rollup ZK có thể đạt được vì chỉ có một khối có thể được hoàn tất khi nhà khai thác gửi một bằng chứng. + +Tuy nhiên, các bằng chứng đệ quy cho phép hoàn tất nhiều khối với một bằng chứng hợp lệ duy nhất. Điều này là do mạch chứng minh tổng hợp đệ quy nhiều bằng chứng khối cho đến khi một bằng chứng cuối cùng được tạo ra. Nhà khai thác L2 gửi bằng chứng đệ quy này, và nếu hợp đồng chấp nhận nó, tất cả các khối liên quan sẽ được hoàn tất ngay lập tức. Với các bằng chứng đệ quy, số lượng giao dịch rollup ZK có thể được hoàn tất trên Ethereum theo từng khoảng thời gian sẽ tăng lên. + +### Ưu và nhược điểm của rollup ZK {#zk-rollups-pros-and-cons} + +| Ưu điểm | Nhược điểm | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Các bằng chứng hợp lệ đảm bảo tính đúng đắn của các giao dịch ngoài chuỗi và ngăn các nhà khai thác thực hiện các chuyển đổi trạng thái không hợp lệ. | Chi phí liên quan đến việc tính toán và xác minh bằng chứng hợp lệ là đáng kể và có thể làm tăng phí cho người dùng rollup. | +| Cung cấp tính cuối cùng của giao dịch nhanh hơn vì các bản cập nhật trạng thái được phê duyệt ngay khi các bằng chứng hợp lệ được xác minh trên L1. | Việc xây dựng các rollup ZK tương thích với EVM rất khó khăn do sự phức tạp của công nghệ không kiến thức. | +| Dựa vào các cơ chế mật mã học phi tín nhiệm để bảo mật, không phải sự trung thực của các tác nhân được khuyến khích như với [gộp giao dịch lạc quan](/developers/docs/scaling/optimistic-rollups/#optimistic-pros-and-cons). | Việc tạo ra các bằng chứng hợp lệ đòi hỏi phần cứng chuyên dụng, điều này có thể khuyến khích sự kiểm soát tập trung của chuỗi bởi một vài bên. | +| Lưu trữ dữ liệu cần thiết để khôi phục trạng thái ngoài chuỗi trên L1, đảm bảo tính bảo mật, chống kiểm duyệt và phi tập trung hóa. | Các nhà khai thác tập trung (trình sắp xếp thứ tự) có thể ảnh hưởng đến thứ tự của các giao dịch. | +| Người dùng được hưởng lợi từ hiệu quả vốn cao hơn và có thể rút tiền từ L2 mà không có sự chậm trễ. | Các yêu cầu về phần cứng có thể làm giảm số lượng người tham gia có thể buộc chuỗi phải tiến triển, làm tăng nguy cơ các nhà khai thác độc hại đóng băng trạng thái của rollup và kiểm duyệt người dùng. | +| Không phụ thuộc vào các giả định về tính sống động và người dùng không phải xác thực chuỗi để bảo vệ tiền của họ. | Một số hệ thống chứng minh (ví dụ: ZK-SNARK) yêu cầu một thiết lập đáng tin cậy, nếu bị xử lý sai, có thể gây nguy hiểm cho mô hình bảo mật của một rollup ZK. | +| Việc nén dữ liệu tốt hơn có thể giúp giảm chi phí công bố `calldata` trên Ethereum và giảm thiểu phí rollup cho người dùng. | | + +### Giải thích trực quan về các rollup ZK {#zk-video} + +Xem Finematics giải thích về các rollup ZK: + + + +## Ai đang làm việc trên một zkEVM? {#zkevm-projects} + +Các dự án đang làm việc trên zkEVM bao gồm: + +- **[zkEVM](https://github.com/privacy-scaling-explorations/zkevm-specs)** - _zkEVM là một dự án được tài trợ bởi Ethereum Foundation để phát triển một rollup ZK tương thích với EVM và một cơ chế để tạo ra các bằng chứng hợp lệ cho các khối Ethereum._ + +- **[Polygon zkEVM](https://polygon.technology/solutions/polygon-zkevm)** - _là một ZK Rollup phi tập trung trên mạng chính Ethereum đang làm việc trên một Máy ảo Ethereum không kiến thức (zkEVM) thực thi các giao dịch Ethereum một cách minh bạch, bao gồm cả các hợp đồng thông minh với các xác thực bằng chứng không kiến thức._ + +- **[Scroll](https://scroll.io/blog/zkEVM)** - _Scroll là một công ty định hướng công nghệ đang làm việc để xây dựng một Giải pháp Lớp 2 zkEVM gốc cho Ethereum._ + +- **[Taiko](https://taiko.xyz)** - _Taiko là một rollup ZK phi tập trung, tương đương với Ethereum (một [ZK-EVM Loại 1](https://vitalik.eth.limo/general/2022/08/04/zkevm.html))._ + +- **[ZKsync](https://docs.zksync.io/)** - _ZKsync Era là một ZK Rollup tương thích với EVM được xây dựng bởi Matter Labs, được cung cấp bởi zkEVM của riêng nó._ + +- **[Starknet](https://starkware.co/starknet/)** - _StarkNet là một giải pháp thay đổi quy mô lớp 2 tương thích với EVM được xây dựng bởi StarkWare._ + +- **[Morph](https://www.morphl2.io/)** - _Morph là một giải pháp thay đổi quy mô rollup kết hợp sử dụng bằng chứng zk để giải quyết vấn đề thách thức về trạng thái Lớp 2._ + +- **[Linea](https://linea.build)** - _Linea là một Lớp 2 zkEVM tương đương Ethereum được xây dựng bởi Consensys, hoàn toàn phù hợp với hệ sinh thái Ethereum._ + +## Đọc thêm về rollup ZK {#further-reading-on-zk-rollups} + +- [Rollup không kiến thức là gì?](https://coinmarketcap.com/alexandria/glossary/zero-knowledge-rollups) +- [Rollup không kiến thức là gì?](https://alchemy.com/blog/zero-knowledge-rollups) +- [Hướng dẫn thực hành về các gộp giao dịch Ethereum](https://web.archive.org/web/20241108192208/https://research.2077.xyz/the-practical-guide-to-ethereum-rollups) +- [STARKs so với SNARKs](https://consensys.net/blog/blockchain-explained/zero-knowledge-proofs-starks-vs-snarks/) +- [zkEVM là gì?](https://www.alchemy.com/overviews/zkevm) +- [Các loại ZK-EVM: Tương đương Ethereum, tương đương EVM, Loại 1, Loại 4 và các từ thông dụng khó hiểu khác](https://taiko.mirror.xyz/j6KgY8zbGTlTnHRFGW6ZLVPuT0IV0_KmgowgStpA0K4) +- [Giới thiệu về zkEVM](https://hackmd.io/@yezhang/S1_KMMbGt) +- [L2 ZK-EVM là gì?](https://linea.mirror.xyz/qD18IaQ4BROn_Y40EBMTUTdJHYghUtdECscSWyMvm8M) +- [Tài nguyên Awesome-zkEVM](https://github.com/LuozhuZhang/awesome-zkevm) +- [ZK-SNARKS dưới góc nhìn kỹ thuật](https://vitalik.eth.limo/general/2017/02/01/zk_snarks.html) +- [Làm thế nào SNARK có thể tồn tại?](https://vitalik.eth.limo/general/2021/01/26/snarks.html) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/anatomy/index.md b/public/content/translations/vi/developers/docs/smart-contracts/anatomy/index.md new file mode 100644 index 00000000000..983ebb026f8 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/anatomy/index.md @@ -0,0 +1,658 @@ +--- +title: "Cấu trúc của các hợp đồng thông minh" +description: "Hiểu rõ hơn về cấu trúc của một hợp đồng thông minh - các hàm, dữ liệu và các biến." +lang: vi +--- + +Hợp đồng thông minh là một chương trình chạy tại một địa chỉ của người dùng trên mạng Ethereum. Chúng được tạo nên bởi dữ liệu và các hàm. Khi nhận được một giao dịch, các hợp đồng thông minh sẽ thực thi. Dưới đây là tổng quan về những gì tạo nên một hợp đồng thông minh. + +## Điều kiện tiên quyết {#prerequisites} + +Hãy đảm bảo rằng bạn đã đọc về [hợp đồng thông minh](/developers/docs/smart-contracts/) trước tiên. Tài liệu này giả định rằng bạn đã biết rõ các ngôn ngữ lập trình như JavaScript hoặc Python. + +## Dữ liệu {#data} + +Bất kỳ dữ liệu hợp đồng nào cũng phải được gán cho một vị trí: `storage` hoặc `memory`. Việc chỉnh sửa nơi lưu trữ trong một hợp đồng thông minh rất tốn kém, vì vậy bạn cần cân nhắc xem dữ liệu của mình sẽ được lưu ở đâu. + +### Lưu trữ {#storage} + +Storage là nơi lưu trữ các dữ liệu truy cập không thường xuyên, ít khi được sửa đổi và được đại diện bởi các biến trạng thái. Các giá trị này được lưu trữ vĩnh viễn trên chuỗi khối. Bạn cần khai báo kiểu dữ liệu để hợp đồng có thể theo dõi được dung lượng lưu trữ trên chuỗi khối mà nó cần khi biên dịch. + +```solidity +// Ví dụ về Solidity +contract SimpleStorage { + uint storedData; // Biến trạng thái + // ... +} +``` + +```python +# Ví dụ về Vyper +storedData: int128 +``` + +Nếu bạn đã từng lập trình hướng đối tượng, bạn có thể sẽ quen với hầu hết các loại ngôn ngữ. Tuy nhiên, `address` có thể sẽ là một khái niệm mới đối với bạn nếu bạn mới bắt đầu phát triển trên Ethereum. + +Một loại `address` có thể chứa một địa chỉ Ethereum tương đương với 20 byte hoặc 160 bit. Nó trả về một giá trị bắt đầu bằng 0x ở dạng thập lục phân. + +Các loại kiểu dữ liệu khác: + +- boolean +- interger +- fixed point numbers +- mảng tĩnh +- mảng byte có kích thước động +- giá trị cố định hữu tỉ và số nguyên +- giá trị cố định chuỗi +- giá trị cố định thập lục phân +- enums + +Để rõ hơn, hãy tìm hiểu thêm các tài liệu: + +- [Xem các loại Vyper](https://docs.vyperlang.org/en/v0.1.0-beta.6/types.html#value-types) +- [Xem các loại Solidity](https://docs.soliditylang.org/en/latest/types.html#value-types) + +### Bộ nhớ {#memory} + +Memory là nơi lưu trữ các giá trị chỉ được sử dụng trong khi thực thi một hàm của hợp đồng và được đại diện bởi các biến memory. Vì các giá trị đó không được lưu trữ vĩnh viễn trên chuỗi khối nên chúng không tốn nhiều tài nguyên khi sử dụng. + +Tìm hiểu thêm về cách Máy ảo Ethereum (EVM) lưu trữ dữ liệu (Storage, Memory và Stack) trong [tài liệu Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#storage-memory-and-the-stack). + +### Các biến môi trường {#environment-variables} + +Bên cạnh những biến mà bạn định nghĩa trong hợp đồng của bạn, có một số biến toàn cục đặc biệt. Chúng được sử dụng chủ yếu để cung cấp thông tin về chuỗi khối hoặc giao dịch hiện tại. + +Ví dụ: + +| **Thuộc tính** | **Biến trạng thái** | **Mô tả** | +| ----------------- | ------------------- | ----------------------------------------------------------- | +| `block.timestamp` | uint256 | Khối epoch timestamp hiện tại | +| `msg.sender` | địa chỉ | Người gửi thông điệp (cuộc gọi hiện tại) | + +## Các hàm {#functions} + +Nói một cách đơn giản, các hàm được dùng để lấy thông tin hoặc thiết lập thông tin để phản hồi các giao dịch đến. + +Có hai loại lời gọi hàm: + +- `internal` – các hàm này không tạo lệnh gọi EVM + - Các hàm nội bộ và biến trạng thái chỉ có thể được truy cập nội bộ (tức là từ bên trong hợp đồng hiện tại hoặc các hợp đồng kế thừa từ nó) +- `external` – các hàm này tạo lệnh gọi EVM + - Các hàm external là một phần của giao diện hợp đồng, điều này có nghĩa là các hàm này có thể được gọi từ các hợp đồng khác và qua các giao dịch. Một hàm bên ngoài `f` không thể được gọi nội bộ (tức là `f()` không hoạt động, nhưng `this.f()` thì hoạt động). + +Chúng cũng có thể là `public` hoặc `private` + +- Các hàm `public` có thể được gọi nội bộ từ bên trong hợp đồng hoặc bên ngoài thông qua các thông điệp +- Các hàm `private` chỉ hiển thị đối với hợp đồng mà chúng được định nghĩa và không hiển thị trong các hợp đồng phái sinh + +Tất cả các hàm và các biến trạng thái đều có thể được khởi tạo là public hoặc private + +Dưới đây là một hàm có chức năng cập nhật một biến trạng thái cho một hợp đồng: + +```solidity +// Ví dụ về Solidity +function update_name(string value) public { + dapp_name = value; +} +``` + +- Tham số `value` của loại `string` được chuyển vào hàm: `update_name` +- Hàm được khai báo là `public`, nghĩa là bất kỳ ai cũng có thể truy cập +- Hàm không được khai báo `view` nên có thể sửa đổi trạng thái hợp đồng + +### Các hàm View {#view-functions} + +Các hàm này không được phép chỉnh sửa trạng thái dữ liệu của hợp đồng. Ví dụ phổ biến là hàm "getter" - bạn có thể sử dụng hàm này để lấy thông tin số dư của người dùng chẳng hạn. + +```solidity +// Ví dụ về Solidity +function balanceOf(address _owner) public view returns (uint256 _balance) { + return ownerPizzaCount[_owner]; +} +``` + +```python +dappName: public(string) + +@view +@public +def readName() -> string: + return dappName +``` + +Những điều được coi là thay đổi trạng thái hợp đồng: + +1. Ghi vào các biến trạng thái. +2. [Phát sự kiện](https://docs.soliditylang.org/en/v0.7.0/contracts.html#events). +3. [Tạo các hợp đồng khác](https://docs.soliditylang.org/en/v0.7.0/control-structures.html#creating-contracts). +4. Sử dụng `selfdestruct`. +5. Gửi Ethers qua các lời gọi. +6. Gọi bất kỳ hàm nào không được đánh dấu là `view` hoặc `pure`. +7. Sử dụng các lời gọi cấp thấp. +8. Sử dụng mã assembly nội dòng có chứa các mã vận hành nhất định. + +### Các hàm constructor {#constructor-functions} + +Các hàm `constructor` chỉ được thực thi một lần khi hợp đồng được triển khai lần đầu tiên. Giống như `constructor` trong nhiều ngôn ngữ lập trình dựa trên lớp, các hàm này thường khởi tạo các biến trạng thái theo các giá trị được chỉ định của chúng. + +```solidity +// Ví dụ về Solidity +// Khởi tạo dữ liệu của hợp đồng, đặt `owner` +// thành địa chỉ của người tạo hợp đồng. +constructor() public { + // Tất cả các hợp đồng thông minh đều dựa vào các giao dịch bên ngoài để kích hoạt các hàm của chúng. + // `msg` là một biến toàn cục bao gồm dữ liệu liên quan về giao dịch nhất định, + // chẳng hạn như địa chỉ của người gửi và giá trị ETH có trong giao dịch. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties + owner = msg.sender; +} +``` + +```python +# Ví dụ về Vyper + +@external +def __init__(_beneficiary: address, _bidding_time: uint256): + self.beneficiary = _beneficiary + self.auctionStart = block.timestamp + self.auctionEnd = self.auctionStart + _bidding_time +``` + +### Các hàm dựng sẵn {#built-in-functions} + +Ngoài các biến và các hàm bạn định nghĩa trong hợp đồng của bạn, còn có một số hàm tích hợp đặc biệt. Ví dụ rõ ràng nhất là: + +- `address.send()` – Solidity +- `send(address)` – Vyper + +Hai hàm trên cho phép những hợp đồng gửi ETH đến các tài khoản khác. + +## Viết hàm {#writing-functions} + +Hàm của bạn cần: + +- biến tham số và kiểu dữ liệu của nó (nếu hàm đó cho phép truyền các tham số) +- khai báo internal/external +- khai báo pure/view/payable +- kiểu dữ liệu trả về (nếu hàm đó trả về một giá trị) + +```solidity +pragma solidity >=0.4.0 <=0.6.0; + +contract ExampleDapp { + string dapp_name; // biến trạng thái + + // Được gọi khi hợp đồng được triển khai và khởi tạo giá trị + constructor() public { + dapp_name = "Ứng dụng phi tập trung ví dụ của tôi"; + } + + // Hàm Get + function read_name() public view returns(string) { + return dapp_name; + } + + // Hàm Set + function update_name(string value) public { + dapp_name = value; + } +} +``` + +Một hợp đồng hoàn chỉnh có thể trông giống như trên. Ở đây, hàm `constructor` cung cấp một giá trị ban đầu cho biến `dapp_name`. + +## Các sự kiện và nhật ký {#events-and-logs} + +Sự kiện cho phép hợp đồng thông minh của bạn giao tiếp với giao diện người dùng hoặc các ứng dụng đăng ký khác. Khi một giao dịch được xác thực và thêm vào một khối, các hợp đồng thông minh có thể phát ra tín hiệu và ghi lại thông tin, điều này sẽ được phần mềm phía trước xử lý và sử dụng. + +## Các ví dụ có chú thích {#annotated-examples} + +Dưới đây là một vài ví dụ được viết bằng Solidity. Nếu bạn muốn thử nghiệm với mã, bạn có thể tương tác với chúng trong [Remix](http://remix.ethereum.org). + +### Xin chào thế giới {#hello-world} + +```solidity +// Chỉ định phiên bản của Solidity, sử dụng lập phiên bản ngữ nghĩa. +// Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma +pragma solidity ^0.5.10; + +// Định nghĩa một hợp đồng có tên là `HelloWorld`. +// Hợp đồng là một tập hợp các hàm và dữ liệu (trạng thái của nó). +// Sau khi được triển khai, một hợp đồng sẽ nằm tại một địa chỉ cụ thể trên chuỗi khối Ethereum. +// Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html +contract HelloWorld { + + // Khai báo một biến trạng thái `message` thuộc loại `string`. + // Các biến trạng thái là các biến có giá trị được lưu trữ vĩnh viễn trong bộ lưu trữ hợp đồng. + // Từ khóa `public` giúp các biến có thể truy cập được từ bên ngoài hợp đồng + // và tạo một hàm mà các hợp đồng hoặc ứng dụng khách khác có thể gọi để truy cập giá trị. + string public message; + + // Tương tự như nhiều ngôn ngữ lập trình hướng đối tượng dựa trên lớp, một hàm constructor là + // một hàm đặc biệt chỉ được thực thi khi tạo hợp đồng. + // Các hàm constructor được sử dụng để khởi tạo dữ liệu của hợp đồng. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors + constructor(string memory initMessage) public { + // Chấp nhận một đối số chuỗi `initMessage` và đặt giá trị + // vào biến lưu trữ `message` của hợp đồng). + message = initMessage; + } + + // Một hàm public chấp nhận một đối số chuỗi + // và cập nhật biến lưu trữ `message`. + function update(string memory newMessage) public { + message = newMessage; + } +} +``` + +### Token {#token} + +```solidity +pragma solidity ^0.5.10; + +contract Token { + // Một `address` có thể so sánh với một địa chỉ email - nó được dùng để xác định một tài khoản trên Ethereum. + // Các địa chỉ có thể đại diện cho một hợp đồng thông minh hoặc tài khoản bên ngoài (người dùng). + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/types.html#address + address public owner; + + // Một `mapping` về cơ bản là một cấu trúc dữ liệu bảng băm. + // `mapping` này gán một số nguyên không dấu (số dư token) cho một địa chỉ (người nắm giữ token). + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types + mapping (address => uint) public balances; + + // Các sự kiện cho phép ghi lại hoạt động trên chuỗi khối. + // Các ứng dụng khách Ethereum có thể lắng nghe các sự kiện để phản ứng với các thay đổi trạng thái hợp đồng. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events + event Transfer(address from, address to, uint amount); + + // Khởi tạo dữ liệu của hợp đồng, đặt `owner` + // thành địa chỉ của người tạo hợp đồng. + constructor() public { + // Tất cả các hợp đồng thông minh đều dựa vào các giao dịch bên ngoài để kích hoạt các hàm của chúng. + // `msg` là một biến toàn cục bao gồm dữ liệu liên quan về giao dịch nhất định, + // chẳng hạn như địa chỉ của người gửi và giá trị ETH có trong giao dịch. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties + owner = msg.sender; + } + + // Tạo một lượng token mới và gửi chúng đến một địa chỉ. + function mint(address receiver, uint amount) public { + // `require` là một cấu trúc điều khiển được sử dụng để thực thi các điều kiện nhất định. + // Nếu câu lệnh `require` ước tính là `false`, một ngoại lệ sẽ được kích hoạt, + // hoàn nguyên tất cả các thay đổi được thực hiện đối với trạng thái trong lệnh gọi hiện tại. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions + + // Chỉ chủ sở hữu hợp đồng mới có thể gọi hàm này + require(msg.sender == owner, "Bạn không phải là chủ sở hữu."); + + // Thực thi số lượng token tối đa + require(amount < 1e60, "Vượt quá mức phát hành tối đa"); + + // Tăng số dư của `receiver` lên `amount` + balances[receiver] += amount; + } + + // Gửi một lượng token hiện có từ bất kỳ người gọi nào đến một địa chỉ. + function transfer(address receiver, uint amount) public { + // Người gửi phải có đủ token để gửi + require(amount <= balances[msg.sender], "Số dư không đủ."); + + // Điều chỉnh số dư token của hai địa chỉ + balances[msg.sender] -= amount; + balances[receiver] += amount; + + // Phát sự kiện được xác định trước đó + emit Transfer(msg.sender, receiver, amount); + } +} +``` + +### Tài sản kỹ thuật số duy nhất {#unique-digital-asset} + +```solidity +pragma solidity ^0.5.10; + +// Nhập các ký hiệu từ các tệp khác vào hợp đồng hiện tại. +// Trong trường hợp này, một loạt các hợp đồng trợ giúp từ OpenZeppelin. +// Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files + +import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol"; +import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; +import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol"; +import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol"; + +// Từ khóa `is` được sử dụng để kế thừa các hàm và từ khóa từ các hợp đồng bên ngoài. +// Trong trường hợp này, `CryptoPizza` kế thừa từ các hợp đồng `IERC721` và `ERC165`. +// Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance +contract CryptoPizza is IERC721, ERC165 { + // Sử dụng thư viện SafeMath của OpenZeppelin để thực hiện các phép toán số học một cách an toàn. + // Tìm hiểu thêm: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath + using SafeMath for uint256; + + // Các biến trạng thái không đổi trong Solidity tương tự như các ngôn ngữ khác + // nhưng bạn phải gán từ một biểu thức không đổi tại thời điểm biên dịch. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables + uint256 constant dnaDigits = 10; + uint256 constant dnaModulus = 10 ** dnaDigits; + bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; + + // Các loại cấu trúc cho phép bạn xác định loại của riêng mình + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs + struct Pizza { + string name; + uint256 dna; + } + + // Tạo một mảng trống gồm các cấu trúc Pizza + Pizza[] public pizzas; + + // Ánh xạ từ ID pizza đến địa chỉ của chủ sở hữu + mapping(uint256 => address) public pizzaToOwner; + + // Ánh xạ từ địa chỉ của chủ sở hữu đến số lượng token sở hữu + mapping(address => uint256) public ownerPizzaCount; + + // Ánh xạ từ ID token đến địa chỉ được phê duyệt + mapping(uint256 => address) pizzaApprovals; + + // Bạn có thể lồng các ánh xạ, ví dụ này ánh xạ chủ sở hữu với các phê duyệt của nhà điều hành + mapping(address => mapping(address => bool)) private operatorApprovals; + + // Hàm nội bộ để tạo một Pizza ngẫu nhiên từ chuỗi (tên) và DNA + function _createPizza(string memory _name, uint256 _dna) + // Từ khóa `internal` có nghĩa là hàm này chỉ hiển thị + // trong hợp đồng này và các hợp đồng kế thừa từ hợp đồng này + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters + internal + // `isUnique` là một bộ điều chỉnh hàm kiểm tra xem pizza đã tồn tại chưa + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers + isUnique(_name, _dna) + { + // Thêm Pizza vào mảng Pizza và lấy id + uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1); + + // Kiểm tra xem chủ sở hữu Pizza có giống với người dùng hiện tại không + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions + + // lưu ý rằng address(0) là địa chỉ không, + // cho biết rằng pizza[id] chưa được phân bổ cho một người dùng cụ thể. + + assert(pizzaToOwner[id] == address(0)); + + // Ánh xạ Pizza cho chủ sở hữu + pizzaToOwner[id] = msg.sender; + ownerPizzaCount[msg.sender] = SafeMath.add( + ownerPizzaCount[msg.sender], + 1 + ); + } + + // Tạo một Pizza ngẫu nhiên từ chuỗi (tên) + function createRandomPizza(string memory _name) public { + uint256 randDna = generateRandomDna(_name, msg.sender); + _createPizza(_name, randDna); + } + + // Tạo DNA ngẫu nhiên từ chuỗi (tên) và địa chỉ của chủ sở hữu (người tạo) + function generateRandomDna(string memory _str, address _owner) + public + // Các hàm được đánh dấu là `pure` cam kết không đọc hoặc sửa đổi trạng thái + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions + pure + returns (uint256) + { + // Tạo uint ngẫu nhiên từ chuỗi (tên) + địa chỉ (chủ sở hữu) + uint256 rand = uint256(keccak256(abi.encodePacked(_str))) + + uint256(_owner); + rand = rand % dnaModulus; + return rand; + } + + // Trả về mảng Pizza được tìm thấy bởi chủ sở hữu + function getPizzasByOwner(address _owner) + public + // Các hàm được đánh dấu là `view` cam kết không sửa đổi trạng thái + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions + view + returns (uint256[] memory) + { + // Sử dụng vị trí lưu trữ `memory` để lưu trữ các giá trị chỉ trong + // vòng đời của lệnh gọi hàm này. + // Tìm hiểu thêm: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack + uint256[] memory result = new uint256[](ownerPizzaCount[_owner]); + uint256 counter = 0; + for (uint256 i = 0; i < pizzas.length; i++) { + if (pizzaToOwner[i] == _owner) { + result[counter] = i; + counter++; + } + } + return result; + } + + // Chuyển Pizza và quyền sở hữu cho địa chỉ khác + function transferFrom(address _from, address _to, uint256 _pizzaId) public { + require(_from != address(0) && _to != address(0), "Địa chỉ không hợp lệ."); + require(_exists(_pizzaId), "Pizza không tồn tại."); + require(_from != _to, "Không thể chuyển đến cùng một địa chỉ."); + require(_isApprovedOrOwner(msg.sender, _pizzaId), "Địa chỉ không được phê duyệt."); + + ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1); + ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1); + pizzaToOwner[_pizzaId] = _to; + + // Phát sự kiện được xác định trong hợp đồng IERC721 đã nhập + emit Transfer(_from, _to, _pizzaId); + _clearApproval(_to, _pizzaId); + } + + /** + * Chuyển quyền sở hữu của một ID token nhất định sang một địa chỉ khác một cách an toàn + * Nếu địa chỉ mục tiêu là một hợp đồng, nó phải triển khai `onERC721Received`, + * được gọi khi thực hiện một lần chuyển an toàn và trả về giá trị đặc biệt + * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; + * nếu không, việc chuyển khoản sẽ bị hoàn nguyên. + */ + function safeTransferFrom(address from, address to, uint256 pizzaId) + public + { + // solium-disable-next-line arg-overflow + this.safeTransferFrom(from, to, pizzaId, ""); + } + + /** + * Chuyển quyền sở hữu của một ID token nhất định sang một địa chỉ khác một cách an toàn + * Nếu địa chỉ mục tiêu là một hợp đồng, nó phải triển khai `onERC721Received`, + * được gọi khi thực hiện một lần chuyển an toàn và trả về giá trị đặc biệt + * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; + * nếu không, việc chuyển khoản sẽ bị hoàn nguyên. + */ + function safeTransferFrom( + address from, + address to, + uint256 pizzaId, + bytes memory _data + ) public { + this.transferFrom(from, to, pizzaId); + require(_checkOnERC721Received(from, to, pizzaId, _data), "Phải triển khai onERC721Received."); + } + + /** + * Hàm nội bộ để gọi `onERC721Received` trên một địa chỉ mục tiêu + * Lệnh gọi không được thực thi nếu địa chỉ mục tiêu không phải là hợp đồng + */ + function _checkOnERC721Received( + address from, + address to, + uint256 pizzaId, + bytes memory _data + ) internal returns (bool) { + if (!isContract(to)) { + return true; + } + + bytes4 retval = IERC721Receiver(to).onERC721Received( + msg.sender, + from, + pizzaId, + _data + ); + return (retval == _ERC721_RECEIVED); + } + + // Đốt một Pizza - phá hủy hoàn toàn Token + // Bộ điều chỉnh hàm `external` có nghĩa là hàm này là + // một phần của giao diện hợp đồng và các hợp đồng khác có thể gọi nó + function burn(uint256 _pizzaId) external { + require(msg.sender != address(0), "Địa chỉ không hợp lệ."); + require(_exists(_pizzaId), "Pizza không tồn tại."); + require(_isApprovedOrOwner(msg.sender, _pizzaId), "Địa chỉ không được phê duyệt."); + + ownerPizzaCount[msg.sender] = SafeMath.sub( + ownerPizzaCount[msg.sender], + 1 + ); + pizzaToOwner[_pizzaId] = address(0); + } + + // Trả về số lượng Pizza theo địa chỉ + function balanceOf(address _owner) public view returns (uint256 _balance) { + return ownerPizzaCount[_owner]; + } + + // Trả về chủ sở hữu của Pizza được tìm thấy bằng id + function ownerOf(uint256 _pizzaId) public view returns (address _owner) { + address owner = pizzaToOwner[_pizzaId]; + require(owner != address(0), "ID Pizza không hợp lệ."); + return owner; + } + + // Phê duyệt địa chỉ khác để chuyển quyền sở hữu Pizza + function approve(address _to, uint256 _pizzaId) public { + require(msg.sender == pizzaToOwner[_pizzaId], "Phải là chủ sở hữu Pizza."); + pizzaApprovals[_pizzaId] = _to; + emit Approval(msg.sender, _to, _pizzaId); + } + + // Trả về địa chỉ được phê duyệt cho Pizza cụ thể + function getApproved(uint256 _pizzaId) + public + view + returns (address operator) + { + require(_exists(_pizzaId), "Pizza không tồn tại."); + return pizzaApprovals[_pizzaId]; + } + + /** + * Hàm riêng tư để xóa phê duyệt hiện tại của một ID token nhất định + * Hoàn nguyên nếu địa chỉ đã cho thực sự không phải là chủ sở hữu của token + */ + function _clearApproval(address owner, uint256 _pizzaId) private { + require(pizzaToOwner[_pizzaId] == owner, "Phải là chủ sở hữu pizza."); + require(_exists(_pizzaId), "Pizza không tồn tại."); + if (pizzaApprovals[_pizzaId] != address(0)) { + pizzaApprovals[_pizzaId] = address(0); + } + } + + /* + * Đặt hoặc bỏ đặt phê duyệt của một nhà điều hành nhất định + * Một nhà điều hành được phép chuyển tất cả các token của người gửi thay mặt họ + */ + function setApprovalForAll(address to, bool approved) public { + require(to != msg.sender, "Không thể phê duyệt địa chỉ của chính mình"); + operatorApprovals[msg.sender][to] = approved; + emit ApprovalForAll(msg.sender, to, approved); + } + + // Cho biết một nhà điều hành có được một chủ sở hữu nhất định phê duyệt hay không + function isApprovedForAll(address owner, address operator) + public + view + returns (bool) + { + return operatorApprovals[owner][operator]; + } + + // Nhận quyền sở hữu Pizza - chỉ dành cho người dùng được phê duyệt + function takeOwnership(uint256 _pizzaId) public { + require(_isApprovedOrOwner(msg.sender, _pizzaId), "Địa chỉ không được phê duyệt."); + address owner = this.ownerOf(_pizzaId); + this.transferFrom(owner, msg.sender, _pizzaId); + } + + // Kiểm tra xem Pizza có tồn tại không + function _exists(uint256 pizzaId) internal view returns (bool) { + address owner = pizzaToOwner[pizzaId]; + return owner != address(0); + } + + // Kiểm tra xem địa chỉ có phải là chủ sở hữu hoặc được phê duyệt để chuyển Pizza không + function _isApprovedOrOwner(address spender, uint256 pizzaId) + internal + view + returns (bool) + { + address owner = pizzaToOwner[pizzaId]; + // Disable solium check because of + // https://github.com/duaraghav8/Solium/issues/175 + // solium-disable-next-line operator-whitespace + return (spender == owner || + this.getApproved(pizzaId) == spender || + this.isApprovedForAll(owner, spender)); + } + + // Kiểm tra xem Pizza có phải là duy nhất và chưa tồn tại không + modifier isUnique(string memory _name, uint256 _dna) { + bool result = true; + for (uint256 i = 0; i < pizzas.length; i++) { + if ( + keccak256(abi.encodePacked(pizzas[i].name)) == + keccak256(abi.encodePacked(_name)) && + pizzas[i].dna == _dna + ) { + result = false; + } + } + require(result, "Pizza với tên như vậy đã tồn tại."); + _; + } + + // Trả về việc địa chỉ mục tiêu có phải là một hợp đồng không + function isContract(address account) internal view returns (bool) { + uint256 size; + // Hiện tại không có cách nào tốt hơn để kiểm tra xem có hợp đồng trong một địa chỉ hay không + // ngoài việc kiểm tra kích thước của mã tại địa chỉ đó. + // Xem https://ethereum.stackexchange.com/a/14016/36603 + // để biết thêm chi tiết về cách hoạt động của nó. + // TODO Kiểm tra lại điều này trước khi phát hành Serenity, bởi vì tất cả các địa chỉ sau đó sẽ là + // hợp đồng. + // solium-disable-next-line security/no-inline-assembly + assembly { + size := extcodesize(account) + } + return size > 0; + } +} +``` + +## Đọc thêm {#further-reading} + +Xem thêm tài liệu của Solidity và Vyper để có cái nhìn tổng quát hơn về các hợp đồng thông minh: + +- [Solidity](https://docs.soliditylang.org/) +- [Vyper](https://docs.vyperlang.org/en/stable/) + +## Các chủ đề liên quan {#related-topics} + +- [Hợp đồng thông minh](/developers/docs/smart-contracts/) +- [Máy ảo Ethereum](/developers/docs/evm/) + +## Các hướng dẫn liên quan {#related-tutorials} + +- [Thu nhỏ hợp đồng để chống lại giới hạn kích thước hợp đồng](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _– Một số mẹo thực tế để giảm kích thước hợp đồng thông minh của bạn._ +- [Ghi dữ liệu từ các hợp đồng thông minh bằng các sự kiện](/developers/tutorials/logging-events-smart-contracts/) _– Giới thiệu về các sự kiện hợp đồng thông minh và cách bạn có thể sử dụng chúng để ghi dữ liệu._ +- [Tương tác với các hợp đồng khác từ Solidity](/developers/tutorials/interact-with-other-contracts-from-solidity/) _– Cách triển khai một hợp đồng thông minh từ một hợp đồng hiện có và tương tác với nó._ diff --git a/public/content/translations/vi/developers/docs/smart-contracts/compiling/index.md b/public/content/translations/vi/developers/docs/smart-contracts/compiling/index.md new file mode 100644 index 00000000000..f10edf84add --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/compiling/index.md @@ -0,0 +1,282 @@ +--- +title: "Biên soạn hợp đồng thông minh" +description: "Lí do tại sao bạn cần biên dịch các hợp đồng thông minh và quá trình biên dịch thực chất là làm gì." +lang: vi +incomplete: true +--- + +Bạn cần biên dịch hợp đồng để ứng dụng web của bạn và Máy ảo Ethereum (EVM) có thể hiểu nó. + +## Điều kiện tiên quyết {#prerequisites} + +Có thể hữu ích cho bạn khi đọc phần giới thiệu của chúng tôi về [hợp đồng thông minh](/developers/docs/smart-contracts/) và [máy ảo Ethereum](/developers/docs/evm/) trước khi đọc về biên dịch. + +## EVM {#the-evm} + +Để [EVM](/developers/docs/evm/) có thể chạy hợp đồng của bạn, nó cần phải ở dạng **bytecode**. Biên dịch hợp đồng này: + +```solidity +pragma solidity 0.4.24; + +contract Greeter { + + function greet() public view returns (string memory) { + return "Hello"; + } + +} +``` + +**thành bytecode này** + +``` +PUSH1 0x80 PUSH1 0x40 MSTORE PUSH1 0x4 CALLDATASIZE LT PUSH2 0x41 JUMPI PUSH1 0x0 CALLDATALOAD PUSH29 0x100000000000000000000000000000000000000000000000000000000 SWAP1 DIV PUSH4 0xFFFFFFFF AND DUP1 PUSH4 0xCFAE3217 EQ PUSH2 0x46 JUMPI JUMPDEST PUSH1 0x0 DUP1 REVERT JUMPDEST CALLVALUE DUP1 ISZERO PUSH2 0x52 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP PUSH2 0x5B PUSH2 0xD6 JUMP JUMPDEST PUSH1 0x40 MLOAD DUP1 DUP1 PUSH1 0x20 ADD DUP3 DUP2 SUB DUP3 MSTORE DUP4 DUP2 DUP2 MLOAD DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP DUP1 MLOAD SWAP1 PUSH1 0x20 ADD SWAP1 DUP1 DUP4 DUP4 PUSH1 0x0 JUMPDEST DUP4 DUP2 LT ISZERO PUSH2 0x9B JUMPI DUP1 DUP3 ADD MLOAD DUP2 DUP5 ADD MSTORE PUSH1 0x20 DUP2 ADD SWAP1 POP PUSH2 0x80 JUMP JUMPDEST POP POP POP POP SWAP1 POP SWAP1 DUP2 ADD SWAP1 PUSH1 0x1F AND DUP1 ISZERO PUSH2 0xC8 JUMPI DUP1 DUP3 SUB DUP1 MLOAD PUSH1 0x1 DUP4 PUSH1 0x20 SUB PUSH2 0x100 EXP SUB NOT AND DUP2 MSTORE PUSH1 0x20 ADD SWAP2 POP JUMPDEST POP SWAP3 POP POP POP PUSH1 0x40 MLOAD DUP1 SWAP2 SUB SWAP1 RETURN JUMPDEST PUSH1 0x60 PUSH1 0x40 DUP1 MLOAD SWAP1 DUP2 ADD PUSH1 0x40 MSTORE DUP1 PUSH1 0x5 DUP2 MSTORE PUSH1 0x20 ADD PUSH32 0x48656C6C6F000000000000000000000000000000000000000000000000000000 DUP2 MSTORE POP SWAP1 POP SWAP1 JUMP STOP LOG1 PUSH6 0x627A7A723058 KECCAK256 SLT 0xec 0xe 0xf5 0xf8 SLT 0xc7 0x2d STATICCALL ADDRESS SHR 0xdb COINBASE 0xb1 BALANCE 0xe8 0xf8 DUP14 0xda 0xad DUP13 LOG1 0x4c 0xb4 0x26 0xc2 DELEGATECALL PUSH7 0x8994D3E002900 +``` + +Đây được gọi là **mã vận hành**. Các mã lệnh EVM là những hướng dẫn cấp thấp mà Máy ảo Ethereum (EVM) có thể thực thi. Mỗi opcode đại diện cho một thao tác cụ thể, như là các phép toán số học, thao tác logic, xử lý dữ liệu, điều khiển luồng, v.v. + +[Tìm hiểu thêm về mã vận hành](/developers/docs/evm/opcodes/) + +## Ứng dụng web {#web-applications} + +Trình biên dịch cũng sẽ tạo ra **Giao diện nhị phân ứng dụng (ABI)** mà bạn cần để ứng dụng của bạn có thể hiểu hợp đồng và gọi các hàm của hợp đồng. + +Giao diện nhị phân ứng dụng là một file JSON miêu tả hợp đồng đã triển khai và các hàm của hợp đồng thông minh đó. Điều này giúp thu hẹp khoảng cách giữa web2 và web3 + +Một [thư viện máy khách JavaScript](/developers/docs/apis/javascript/) sẽ đọc **ABI** để bạn có thể gọi hợp đồng thông minh của mình trong giao diện ứng dụng web của bạn. + +Bên dưới là giao diện nhị phân ứng dụng của hợp đồng ERC-20 token. Một ERC-20 là một token bạn có thể giao dịch trên Ethereum. + +```json +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] +``` + +## Đọc thêm {#further-reading} + +- [Đặc tả ABI](https://solidity.readthedocs.io/en/v0.7.0/abi-spec.html) _– Solidity_ + +## Các chủ đề liên quan {#related-topics} + +- [Các thư viện máy khách JavaScript](/developers/docs/apis/javascript/) +- [Máy ảo Ethereum](/developers/docs/evm/) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/composability/index.md b/public/content/translations/vi/developers/docs/smart-contracts/composability/index.md new file mode 100644 index 00000000000..0a8cb38a6a3 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/composability/index.md @@ -0,0 +1,76 @@ +--- +title: "Tính khả thi của hợp đồng thông minh" +description: "Tìm hiểu cách các hợp đồng thông minh có thể được kết hợp như các khối Lego để xây dựng các dapps phức tạp bằng cách tái sử dụng các thành phần có sẵn." +lang: vi +incomplete: true +--- + +## Giới thiệu ngắn gọn {#a-brief-introduction} + +Hợp đồng thông minh trên Ethereum là công khai và có thể xem như là các API mở. Bạn không cần phải viết hợp đồng thông minh của riêng mình để trở thành một nhà phát triển dapp, bạn chỉ cần biết cách tương tác với chúng. Ví dụ: bạn có thể sử dụng các hợp đồng thông minh hiện có của [Uniswap](https://uniswap.exchange/swap), một sàn giao dịch phi tập trung, để xử lý tất cả logic hoán đổi token trong ứng dụng của bạn – bạn không cần phải bắt đầu từ đầu. Hãy xem một số hợp đồng [v2](https://github.com/Uniswap/uniswap-v2-core/tree/master/contracts) và [v3](https://github.com/Uniswap/uniswap-v3-core/tree/main/contracts) của họ. + +## Khái niệm tính khả hợp thành là gì? {#what-is-composability} + +Tính khả hợp thành là việc kết hợp các yếu tố khác nhau để tạo ra hệ thống hoặc kết quả mới. Trong phát triển phần mềm, khả năng kết hợp có nghĩa là các nhà phát triển có thể tái sử dụng các thành phần phần mềm hiện có để xây dựng các ứng dụng mới. Một cách tốt để hiểu tính khả thi của việc kết hợp là xem các yếu tố có thể kết hợp như những viên gạch Lego. Mỗi viên Lego có thể kết hợp với nhau, cho phép bạn xây dựng những cấu trúc phức tạp bằng cách kết hợp các viên Lego khác nhau. + +Trong Ethereum, mỗi hợp đồng thông minh đều có thể được coi như một viên Lego—bạn có thể sử dụng các hợp đồng thông minh từ các dự án khác như những khối xây dựng cho dự án của mình. Điều này có nghĩa là bạn không cần phải tốn thời gian để phát minh lại bánh xe hoặc xây dựng từ đầu. + +## Cách thức hoạt động của tính khả hợp thành là gì? {#how-does-composability-work} + +Hợp đồng thông minh Ethereum giống như các API công cộng, vì vậy bất kỳ ai cũng có thể tương tác với hợp đồng hoặc tích hợp chúng vào các ứng dụng phi tập trung (dapps) để tăng cường chức năng. Tính khả hợp thành của hợp đồng thông minh thường dựa trên ba nguyên tắc: tính mô-đun, tự trị và khả năng khám phá. + +\*\*1. **Tính mô-đun**: Đây là khả năng của các thành phần riêng lẻ để thực hiện một nhiệm vụ cụ thể. Trong Ethereum, mỗi hợp đồng thông minh đều có một trường hợp sử dụng cụ thể (như đã trình bày trong ví dụ về Uniswap). + +\*\*2. **Tính tự chủ**: Các thành phần có thể kết hợp phải có khả năng hoạt động độc lập. Mỗi hợp đồng thông minh trong Ethereum đều tự thực thi và có thể hoạt động mà không cần dựa vào các thành phần khác của hệ thống. + +\*\*3. **Khả năng khám phá**: Các nhà phát triển không thể gọi các hợp đồng bên ngoài hoặc tích hợp các thư viện phần mềm vào các ứng dụng nếu chúng không được công khai. Theo thiết kế, các hợp đồng thông minh là mã nguồn mở; bất kỳ ai cũng có thể gọi một hợp đồng thông minh hoặc sao chép cơ sở mã. + +## Lợi ích của khả năng kết hợp {#benefits-of-composability} + +### Chu kỳ phát triển ngắn hơn {#shorter-development-cycle} + +Khả năng kết hợp giúp giảm bớt công việc mà các nhà phát triển phải làm khi tạo [các ứng dụng phi tập trung](/apps/#what-are-dapps). [Như Naval Ravikant đã nói:](https://twitter.com/naval/status/1444366754650656770) "Mã nguồn mở có nghĩa là mọi vấn đề chỉ cần được giải quyết một lần." + +Nếu có một hợp đồng thông minh giải quyết một vấn đề nào đó, các nhà phát triển khác có thể tái sử dụng nó, vì vậy họ không cần phải giải quyết cùng một vấn đề. Bằng cách này, các nhà phát triển có thể tận dụng các thư viện phần mềm hiện có và thêm chức năng bổ sung để tạo ra các dapp mới. + +### Sự đổi mới lớn hơn {#greater-innovation} + +Tính khả thi cho phép các lập trình viên thoải mái sáng tạo và thử nghiệm, vì họ có thể sử dụng lại, chỉnh sửa, sao chép hoặc tích hợp mã nguồn mở để đạt được kết quả mong muốn. Do đó, các đội ngũ phát triển dành ít thời gian cho các chức năng cơ bản và có thể dành nhiều thời gian hơn để thử nghiệm các tính năng mới. + +### Trải nghiệm người dùng tốt hơn {#better-user-experience} + +Khả năng tương tác giữa các thành phần của hệ sinh thái Ethereum cải thiện trải nghiệm của người dùng. Người dùng có thể truy cập vào chức năng cao hơn khi các ứng dụng phi tập trung (dapps) tích hợp các hợp đồng thông minh bên ngoài so với một hệ sinh thái phân mảnh, nơi mà các ứng dụng không thể giao tiếp với nhau. + +Chúng ta sẽ lấy một ví dụ từ giao dịch arbitrage để minh họa lợi ích của việc tương tác với nhau: + +Nếu một token đang được giao dịch ở mức giá cao hơn trên `sàn giao dịch A` so với `sàn giao dịch B`, bạn có thể tận dụng sự chênh lệch giá để kiếm lợi nhuận. Tuy nhiên, bạn chỉ có thể làm điều đó nếu có đủ vốn để tài trợ cho giao dịch (tức là mua token từ `sàn giao dịch B` và bán trên `sàn giao dịch A`). + +Trong một trường hợp bạn không có đủ vốn để giao dịch, một khoản vay nóng có thể là lựa chọn lý tưởng. [Các khoản vay nhanh](/defi/#flash-loans) có tính kỹ thuật cao, nhưng ý tưởng cơ bản là bạn có thể vay tài sản (không cần tài sản thế chấp) và trả lại chúng trong _một_ giao dịch duy nhất. + +Quay lại ví dụ ban đầu, một nhà giao dịch chênh lệch giá có thể vay một khoản vay nhanh lớn, mua token từ `sàn giao dịch B`, bán chúng trên `sàn giao dịch A`, trả lại vốn + lãi và giữ lại lợi nhuận, tất cả trong cùng một giao dịch. Logic phức tạp này yêu cầu kết hợp các lệnh gọi đến nhiều hợp đồng, điều này sẽ không khả thi nếu các hợp đồng thông minh thiếu tính tương tác. + +## Các ví dụ về khả năng kết hợp trong Ethereum {#composability-in-ethereum} + +### Hoán đổi token {#token-swaps} + +Nếu bạn tạo một ứng dụng phi tập trung (dapp) yêu cầu thanh toán giao dịch bằng ETH, bạn có thể cho phép người dùng thanh toán bằng các token ERC-20 khác bằng cách tích hợp logic hoán đổi token. Đoạn mã sẽ tự động chuyển đổi token của người dùng sang ETH trước khi hợp đồng thực hiện hàm gọi. + +### Quản trị {#governance} + +Xây dựng các hệ thống quản trị riêng cho một [DAO](/dao/) có thể tốn kém và mất nhiều thời gian. Thay vào đó, bạn có thể sử dụng một bộ công cụ quản trị mã nguồn mở, chẳng hạn như [Aragon Client](https://client.aragon.org/), để khởi tạo DAO của mình nhằm nhanh chóng tạo ra một khuôn khổ quản trị. + +### Quản lý danh tính {#identity-management} + +Thay vì xây dựng một hệ thống xác thực tùy chỉnh hoặc dựa vào các nhà cung cấp tập trung, bạn có thể tích hợp các công cụ danh tính phi tập trung (DID) để quản lý xác thực cho người dùng. Một ví dụ là [SpruceID](https://www.spruceid.com/), một bộ công cụ mã nguồn mở cung cấp chức năng "Đăng nhập bằng Ethereum" cho phép người dùng xác thực danh tính bằng ví Ethereum. + +## Các hướng dẫn liên quan {#related-tutorials} + +- [Khởi động phát triển giao diện người dùng cho ứng dụng phi tập trung của bạn với create-eth-app](/developers/tutorials/kickstart-your-dapp-frontend-development-with-create-eth-app/) _– Tổng quan về cách sử dụng create-eth-app để tạo ra các ứng dụng với các hợp đồng thông minh phổ biến có sẵn._ + +## Đọc thêm {#further-reading} + +_Biết về nguồn lực cộng đồng đã giúp đỡ bạn? Chỉnh sửa trang này và bổ sung!_ + +- [Khả năng kết hợp là sự đổi mới](https://a16zcrypto.com/posts/article/how-composability-unlocks-crypto-and-everything-else/) +- [Tại sao khả năng kết hợp lại quan trọng đối với Web3](https://hackernoon.com/why-composability-matters-for-web3) +- [Khả năng kết hợp là gì?](https://blog.aragon.org/what-is-composability/#:~:text=Aragon,connect%20to%20every%20other%20piece.) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/deploying/index.md b/public/content/translations/vi/developers/docs/smart-contracts/deploying/index.md new file mode 100644 index 00000000000..6e097023fc5 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/deploying/index.md @@ -0,0 +1,81 @@ +--- +title: "Triển khai hợp đồng thông minh" +description: "Hãy học cách triển khai hợp đồng thông minh lên các mạng Ethereum, bao gồm các yêu cầu trước, công cụ và các bước triển khai." +lang: vi +--- + +Bạn cần phải triển khai hợp đồng thông minh của bạn để nó có thể khả thi cho tất cả người dùng trên một mạng Ethereum. + +Để triển khai một hợp đồng thông minh, bạn chỉ cần gửi một giao dịch Ethereum có chứa mã đã được biên dịch của hợp đồng thông minh đó mà không chỉ định bất kỳ người nhận nào. + +## Điều kiện tiên quyết {#prerequisites} + +Bạn nên hiểu về [mạng Ethereum](/developers/docs/networks/), [các giao dịch](/developers/docs/transactions/) và [cấu trúc của hợp đồng thông minh](/developers/docs/smart-contracts/anatomy/) trước khi triển khai hợp đồng thông minh. + +Việc triển khai một hợp đồng cũng tốn ether (ETH) vì chúng được lưu trữ trên chuỗi khối, vì vậy bạn nên làm quen với [gas và phí](/developers/docs/gas/) trên Ethereum. + +Cuối cùng, bạn sẽ cần phải biên dịch hợp đồng của mình trước khi triển khai, vì vậy hãy chắc chắn rằng bạn đã đọc về [việc biên dịch các hợp đồng thông minh](/developers/docs/smart-contracts/compiling/). + +## Cách triển khai một hợp đồng thông minh {#how-to-deploy-a-smart-contract} + +### Những gì bạn sẽ cần {#what-youll-need} + +- Mã bytecode của hợp đồng của bạn – mã này được tạo ra thông qua [quá trình biên dịch](/developers/docs/smart-contracts/compiling/) +- ETH cho Gas - bạn sẽ thiết lập giới hạn gas của bạn như các giao dịch khác, vì vậy hãy lưu ý rằng sự triển khai hợp đồng cần rất nhiều gas hơn là một giao dịch ETH đơn giản +- một tập lệnh triển khai hoặc plugin +- quyền truy cập vào một [nút Ethereum](/developers/docs/nodes-and-clients/), bằng cách tự chạy nút của riêng bạn, kết nối với một nút công khai hoặc thông qua khóa API bằng cách sử dụng một [dịch vụ nút](/developers/docs/nodes-and-clients/nodes-as-a-service/) + +### Các bước để triển khai một hợp đồng thông minh {#steps-to-deploy} + +Các bước cụ thể sẽ phụ thuộc vào sự phát triển framework được đề cập. Ví dụ, bạn có thể xem qua [tài liệu của Hardhat về việc triển khai hợp đồng của bạn](https://hardhat.org/docs/tutorial/deploying) hoặc [tài liệu của Foundry về việc triển khai và xác minh một hợp đồng thông minh](https://book.getfoundry.sh/forge/deploying). Sau khi được triển khai, hợp đồng của bạn sẽ có một địa chỉ Ethereum giống như các [tài khoản](/developers/docs/accounts/) khác và có thể được xác minh bằng cách sử dụng [các công cụ xác minh mã nguồn](/developers/docs/smart-contracts/verifying/#source-code-verification-tools). + +## Các công cụ liên quan {#related-tools} + +**Remix - _Remix IDE cho phép phát triển, triển khai và quản lý các hợp đồng thông minh cho các chuỗi khối giống như Ethereum_** + +- [Remix](https://remix.ethereum.org) + +**Tenderly - _Nền tảng phát triển Web3 cung cấp các tính năng gỡ lỗi, theo dõi và các khối xây dựng cơ sở hạ tầng cho việc phát triển, thử nghiệm, giám sát và vận hành các hợp đồng thông minh_** + +- [tenderly.co](https://tenderly.co/) +- [Tài liệu](https://docs.tenderly.co/) +- [GitHub](https://github.com/Tenderly) +- [Discord](https://discord.gg/eCWjuvt) + +**Hardhat - _Một môi trường phát triển để biên dịch, triển khai, thử nghiệm và gỡ lỗi phần mềm Ethereum của bạn_** + +- [hardhat.org](https://hardhat.org/getting-started/) +- [Tài liệu về việc triển khai hợp đồng của bạn](https://hardhat.org/docs/tutorial/deploying) +- [GitHub](https://github.com/nomiclabs/hardhat) +- [Discord](https://discord.com/invite/TETZs2KK4k) + +**thirdweb - _Dễ dàng triển khai bất kỳ hợp đồng nào tới bất kỳ chuỗi tương thích EVM nào, bằng một lệnh duy nhất_** + +- [Tài liệu tham khảo](https://portal.thirdweb.com/deploy/) + +**Crossmint - _Nền tảng phát triển Web3 cấp doanh nghiệp để triển khai hợp đồng thông minh, hỗ trợ thanh toán bằng thẻ tín dụng và đa chuỗi, đồng thời sử dụng API để tạo, phân phối, bán, lưu trữ và chỉnh sửa NFT._** + +- [crossmint.com](https://www.crossmint.com) +- [Tài liệu tham khảo](https://docs.crossmint.com) +- [Discord](https://discord.com/invite/crossmint) +- [Blog](https://blog.crossmint.com) + +## Các hướng dẫn liên quan {#related-tutorials} + +- [Triển khai hợp đồng thông minh đầu tiên của bạn](/developers/tutorials/deploying-your-first-smart-contract/) _– Lời giới thiệu về việc triển khai hợp đồng thông minh đầu tiên của bạn trên một mạng thử nghiệm Ethereum._ +- [Hello World | hướng dẫn về hợp đồng thông minh](/developers/tutorials/hello-world-smart-contract/) _– Một hướng dẫn dễ thực hiện để tạo và triển khai một hợp đồng thông minh cơ bản trên Ethereum._ +- [Tương tác với các hợp đồng khác từ Solidity](/developers/tutorials/interact-with-other-contracts-from-solidity/) _– Cách triển khai một hợp đồng thông minh từ một hợp đồng hiện có và tương tác với nó._ +- [Cách thu nhỏ kích thước hợp đồng của bạn](/developers/tutorials/downsizing-contracts-to-fight-the-contract-size-limit/) _- Cách giảm kích thước hợp đồng của bạn để giữ nó không vượt quá giới hạn và tiết kiệm gas_ + +## Đọc thêm {#further-reading} + +- [https://docs.openzeppelin.com/learn/deploying-and-interacting](https://docs.openzeppelin.com/learn/deploying-and-interacting) - _OpenZeppelin_ +- [Triển khai hợp đồng của bạn với Hardhat](https://hardhat.org/docs/tutorial/deploying) - _Nomic Labs_ + +_Biết về nguồn lực cộng đồng đã giúp đỡ bạn? Chỉnh sửa trang này và bổ sung!_ + +## Các chủ đề liên quan {#related-topics} + +- [Các khung phát triển](/developers/docs/frameworks/) +- [Chạy một nút Ethereum](/developers/docs/nodes-and-clients/run-a-node/) +- [Nút dưới dạng dịch vụ](/developers/docs/nodes-and-clients/nodes-as-a-service) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/formal-verification/index.md b/public/content/translations/vi/developers/docs/smart-contracts/formal-verification/index.md new file mode 100644 index 00000000000..2a862f95c3a --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/formal-verification/index.md @@ -0,0 +1,284 @@ +--- +title: "Xác minh hình thức của các hợp đồng thông minh" +description: "Tổng quan về xác minh hình thức cho các hợp đồng thông minh Ethereum" +lang: vi +--- + +[Hợp đồng thông minh](/developers/docs/smart-contracts/) đang tạo điều kiện để tạo ra các ứng dụng phi tập trung, không cần tin cậy và mạnh mẽ, giới thiệu các trường hợp sử dụng mới và mở khóa giá trị cho người dùng. Bởi vì các hợp đồng thông minh xử lý lượng giá trị lớn, bảo mật là một yếu tố quan trọng cần cân nhắc đối với các nhà phát triển. + +Xác minh hình thức là một trong những kỹ thuật được khuyến nghị để cải thiện [bảo mật hợp đồng thông minh](/developers/docs/smart-contracts/security/). Xác minh hình thức, sử dụng [các phương pháp hình thức](https://www.brookings.edu/techstream/formal-methods-as-a-path-toward-better-cybersecurity/) để đặc tả, thiết kế và xác minh các chương trình, đã được sử dụng trong nhiều năm để đảm bảo tính đúng đắn của các hệ thống phần cứng và phần mềm quan trọng. + +Khi được triển khai trong các hợp đồng thông minh, xác minh hình thức có thể chứng minh rằng logic nghiệp vụ của hợp đồng đáp ứng một đặc tả được xác định trước. So với các phương pháp khác để đánh giá tính đúng đắn của mã hợp đồng, chẳng hạn như kiểm thử, xác minh hình thức đưa ra những đảm bảo mạnh mẽ hơn rằng một hợp đồng thông minh là đúng về mặt chức năng. + +## Xác minh hình thức là gì? {#what-is-formal-verification} + +Xác minh hình thức đề cập đến quá trình đánh giá tính đúng đắn của một hệ thống đối với một đặc tả hình thức. Nói một cách đơn giản, xác minh hình thức cho phép chúng tôi kiểm tra xem hành vi của một hệ thống có thỏa mãn một số yêu cầu hay không (tức là nó có làm những gì chúng ta muốn hay không). + +Các hành vi dự kiến của hệ thống (trong trường hợp này là một hợp đồng thông minh) được mô tả bằng cách sử dụng mô hình hóa hình thức, trong khi các ngôn ngữ đặc tả cho phép tạo ra các thuộc tính hình thức. Các kỹ thuật xác minh hình thức sau đó có thể xác minh rằng việc triển khai của một hợp đồng tuân thủ đặc tả của nó và suy ra bằng chứng toán học về tính đúng đắn của việc triển khai đó. Khi một hợp đồng thỏa mãn đặc tả của nó, nó được mô tả là “đúng về mặt chức năng”, “đúng theo thiết kế” hoặc “đúng theo cấu trúc”. + +### Mô hình hình thức là gì? {#what-is-a-formal-model} + +Trong khoa học máy tính, [mô hình hình thức](https://en.wikipedia.org/wiki/Model_of_computation) là một mô tả toán học về một quá trình tính toán. Các chương trình được trừu tượng hóa thành các hàm toán học (phương trình), với mô hình mô tả cách kết quả đầu ra của các hàm được tính toán dựa trên một đầu vào nhất định. + +Các mô hình hình thức cung cấp một mức độ trừu tượng mà trên đó việc phân tích hành vi của một chương trình có thể được đánh giá. Sự tồn tại của các mô hình hình thức cho phép tạo ra một _đặc tả hình thức_, mô tả các thuộc tính mong muốn của mô hình được đề cập. + +Các kỹ thuật khác nhau được sử dụng để mô hình hóa các hợp đồng thông minh cho việc xác minh hình thức. Ví dụ, một số mô hình được sử dụng để suy luận về hành vi cấp cao của một hợp đồng thông minh. Những kỹ thuật mô hình hóa này áp dụng quan điểm hộp đen cho các hợp đồng thông minh, xem chúng như các hệ thống chấp nhận đầu vào và thực hiện tính toán dựa trên các đầu vào đó. + +Các mô hình cấp cao tập trung vào mối quan hệ giữa các hợp đồng thông minh và các tác nhân bên ngoài, chẳng hạn như tài khoản sở hữu bên ngoài (EOA), tài khoản hợp đồng và môi trường chuỗi khối. Các mô hình như vậy hữu ích cho việc xác định các thuộc tính đặc tả cách một hợp đồng nên hoạt động để phản hồi lại các tương tác nhất định của người dùng. + +Ngược lại, các mô hình hình thức khác tập trung vào hành vi cấp thấp của một hợp đồng thông minh. Mặc dù các mô hình cấp cao có thể giúp suy luận về chức năng của hợp đồng, chúng có thể không nắm bắt được các chi tiết về hoạt động bên trong của việc triển khai. Các mô hình cấp thấp áp dụng quan điểm hộp trắng để phân tích chương trình và dựa vào các biểu diễn cấp thấp hơn của các ứng dụng hợp đồng thông minh, chẳng hạn như dấu vết chương trình và [đồ thị luồng điều khiển](https://en.wikipedia.org/wiki/Control-flow_graph), để suy luận về các thuộc tính liên quan đến việc thực thi của hợp đồng. + +Các mô hình cấp thấp được coi là lý tưởng vì chúng đại diện cho việc thực thi thực tế của một hợp đồng thông minh trong môi trường thực thi của Ethereum (tức là [EVM](/developers/docs/evm/)). Các kỹ thuật mô hình hóa cấp thấp đặc biệt hữu ích trong việc thiết lập các thuộc tính an toàn quan trọng trong các hợp đồng thông minh và phát hiện các lỗ hổng tiềm ẩn. + +### Đặc tả hình thức là gì? {#what-is-a-formal-specification} + +Đặc tả đơn giản là một yêu cầu kỹ thuật mà một hệ thống cụ thể phải thỏa mãn. Trong lập trình, các đặc tả đại diện cho các ý tưởng chung về việc thực thi của một chương trình (tức là, chương trình nên làm gì). + +Trong bối cảnh của các hợp đồng thông minh, các đặc tả hình thức đề cập đến _các thuộc tính_—các mô tả hình thức về các yêu cầu mà một hợp đồng phải thỏa mãn. Các thuộc tính như vậy được mô tả là "bất biến" và đại diện cho các khẳng định logic về việc thực thi của một hợp đồng phải luôn đúng trong mọi hoàn cảnh có thể xảy ra, không có bất kỳ ngoại lệ nào. + +Do đó, chúng ta có thể coi một đặc tả hình thức là một tập hợp các câu lệnh được viết bằng một ngôn ngữ hình thức mô tả việc thực thi dự kiến của một hợp đồng thông minh. Các đặc tả bao gồm các thuộc tính của một hợp đồng và xác định cách hợp đồng nên hoạt động trong các hoàn cảnh khác nhau. Mục đích của xác minh hình thức là để xác định xem một hợp đồng thông minh có sở hữu những thuộc tính này (bất biến) hay không và những thuộc tính này không bị vi phạm trong quá trình thực thi. + +Các đặc tả hình thức rất quan trọng trong việc phát triển các triển khai bảo mật của các hợp đồng thông minh. Các hợp đồng không triển khai các bất biến hoặc có các thuộc tính bị vi phạm trong quá trình thực thi dễ bị tổn thương bởi các lỗ hổng có thể gây hại cho chức năng hoặc gây ra các khai thác độc hại. + +## Các loại đặc tả hình thức cho hợp đồng thông minh {#formal-specifications-for-smart-contracts} + +Các đặc tả hình thức cho phép suy luận toán học về tính đúng đắn của việc thực thi chương trình. Cũng như các mô hình hình thức, các đặc tả hình thức có thể nắm bắt các thuộc tính cấp cao hoặc hành vi cấp thấp của một triển khai hợp đồng. + +Các đặc tả hình thức được bắt nguồn bằng cách sử dụng các yếu tố của [logic chương trình](https://en.wikipedia.org/wiki/Logic_programming), cho phép suy luận hình thức về các thuộc tính của một chương trình. Một logic chương trình có các quy tắc hình thức thể hiện (bằng ngôn ngữ toán học) hành vi dự kiến của một chương trình. Nhiều logic chương trình khác nhau được sử dụng trong việc tạo ra các đặc tả hình thức, bao gồm [logic khả năng tiếp cận](https://en.wikipedia.org/wiki/Reachability_problem), [logic thời gian](https://en.wikipedia.org/wiki/Temporal_logic), và [logic Hoare](https://en.wikipedia.org/wiki/Hoare_logic). + +Các đặc tả hình thức cho các hợp đồng thông minh có thể được phân loại rộng rãi thành các đặc tả **cấp cao** hoặc **cấp thấp**. Bất kể một đặc tả thuộc loại nào, nó phải mô tả một cách đầy đủ và rõ ràng thuộc tính của hệ thống đang được phân tích. + +### Đặc tả cấp cao {#high-level-specifications} + +Như tên gọi, một đặc tả cấp cao (còn được gọi là "đặc tả hướng mô hình") mô tả hành vi cấp cao của một chương trình. Các đặc tả cấp cao mô hình hóa một hợp đồng thông minh như một [máy trạng thái hữu hạn](https://en.wikipedia.org/wiki/Finite-state_machine) (FSM), có thể chuyển đổi giữa các trạng thái bằng cách thực hiện các hoạt động, với logic thời gian được sử dụng để xác định các thuộc tính hình thức cho mô hình FSM. + +[Logic thời gian](https://en.wikipedia.org/wiki/Temporal_logic) là "các quy tắc để suy luận về các mệnh đề được xác định theo thời gian (ví dụ: "Tôi _luôn_ đói" hoặc "Tôi sẽ _cuối cùng_ cũng đói")." Khi được áp dụng vào xác minh hình thức, logic thời gian được sử dụng để nêu ra các khẳng định về hành vi đúng của các hệ thống được mô hình hóa dưới dạng máy trạng thái. Cụ thể, một logic thời gian mô tả các trạng thái tương lai mà một hợp đồng thông minh có thể ở trong và cách nó chuyển đổi giữa các trạng thái. + +Các đặc tả cấp cao thường nắm bắt hai thuộc tính thời gian quan trọng cho các hợp đồng thông minh: **an toàn** và **tính sống động**. Các thuộc tính an toàn đại diện cho ý tưởng rằng “không có điều tồi tệ nào xảy ra” và thường thể hiện tính bất biến. Một thuộc tính an toàn có thể xác định các yêu cầu phần mềm chung, chẳng hạn như không bị [bế tắc](https://www.techtarget.com/whatis/definition/deadlock), hoặc thể hiện các thuộc tính dành riêng cho miền cho các hợp đồng (ví dụ: các bất biến về kiểm soát truy cập cho các hàm, các giá trị có thể chấp nhận của các biến trạng thái hoặc các điều kiện cho việc chuyển token). + +Lấy ví dụ yêu cầu an toàn này, bao gồm các điều kiện để sử dụng `transfer()` hoặc `transferFrom()` trong các hợp đồng token ERC-20: _“Số dư của người gửi không bao giờ thấp hơn số lượng token được yêu cầu gửi đi.”_. Mô tả bằng ngôn ngữ tự nhiên này của một bất biến của hợp đồng có thể được dịch thành một đặc tả hình thức (toán học), sau đó có thể được kiểm tra nghiêm ngặt về tính hợp lệ. + +Các thuộc tính sống động khẳng định rằng “cuối cùng điều tốt đẹp sẽ xảy ra” và liên quan đến khả năng của một hợp đồng để tiến triển qua các trạng thái khác nhau. Một ví dụ về thuộc tính sống động là “tính thanh khoản”, đề cập đến khả năng của một hợp đồng để chuyển số dư của nó cho người dùng theo yêu cầu. Nếu thuộc tính này bị vi phạm, người dùng sẽ không thể rút tài sản được lưu trữ trong hợp đồng, giống như những gì đã xảy ra với [sự cố ví Parity](https://www.cnbc.com/2017/11/08/accidental-bug-may-have-frozen-280-worth-of-ether-on-parity-wallet.html). + +### Các đặc tả cấp thấp {#low-level-specifications} + +Các đặc tả cấp cao lấy điểm khởi đầu là một mô hình trạng thái hữu hạn của một hợp đồng và xác định các thuộc tính mong muốn của mô hình này. Ngược lại, các đặc tả cấp thấp (còn được gọi là "đặc tả hướng thuộc tính") thường mô hình hóa các chương trình (hợp đồng thông minh) như các hệ thống bao gồm một tập hợp các hàm toán học và mô tả hành vi đúng của các hệ thống như vậy. + +Nói một cách đơn giản, các đặc tả cấp thấp phân tích _dấu vết chương trình_ và cố gắng xác định các thuộc tính của một hợp đồng thông minh trên các dấu vết này. Dấu vết đề cập đến các chuỗi thực thi hàm làm thay đổi trạng thái của một hợp đồng thông minh; do đó, các đặc tả cấp thấp giúp đặc tả các yêu cầu cho việc thực thi nội bộ của một hợp đồng. + +Các đặc tả hình thức cấp thấp có thể được đưa ra dưới dạng các thuộc tính kiểu Hoare hoặc các bất biến trên các đường dẫn thực thi. + +### Thuộc tính kiểu Hoare {#hoare-style-properties} + +[Logic Hoare](https://en.wikipedia.org/wiki/Hoare_logic) cung cấp một bộ quy tắc hình thức để suy luận về tính đúng đắn của các chương trình, bao gồm cả các hợp đồng thông minh. Một thuộc tính kiểu Hoare được biểu diễn bằng một bộ ba Hoare `{P}c{Q}`, trong đó `c` là một chương trình và `P` và `Q` là các vị từ trên trạng thái của `c` (tức là chương trình), được mô tả chính thức là _tiền điều kiện_ và _hậu điều kiện_, tương ứng. + +Tiền điều kiện là một vị từ mô tả các điều kiện cần thiết để thực thi đúng một hàm; người dùng gọi vào hợp đồng phải thỏa mãn yêu cầu này. Hậu điều kiện là một vị từ mô tả điều kiện mà một hàm thiết lập nếu được thực thi đúng; người dùng có thể mong đợi điều kiện này là đúng sau khi gọi vào hàm. Một _bất biến_ trong logic Hoare là một vị từ được bảo toàn bởi việc thực thi một hàm (tức là nó không thay đổi). + +Các đặc tả kiểu Hoare có thể đảm bảo _tính đúng đắn một phần_ hoặc _tính đúng đắn toàn phần_. Việc triển khai một hàm hợp đồng là "đúng một phần" nếu tiền điều kiện đúng trước khi hàm được thực thi, và nếu việc thực thi kết thúc, hậu điều kiện cũng đúng. Bằng chứng về tính đúng đắn toàn phần có được nếu một tiền điều kiện là đúng trước khi hàm thực thi, việc thực thi được đảm bảo sẽ kết thúc và khi kết thúc, hậu điều kiện là đúng. + +Việc có được bằng chứng về tính đúng đắn toàn phần là khó khăn vì một số lần thực thi có thể bị trì hoãn trước khi kết thúc, hoặc không bao giờ kết thúc. Tuy nhiên, câu hỏi về việc liệu việc thực thi có kết thúc hay không có thể coi là một điểm tranh luận vì cơ chế Gas của Ethereum ngăn chặn các vòng lặp chương trình vô hạn (việc thực thi kết thúc thành công hoặc kết thúc do lỗi 'hết gas'). + +Các đặc tả hợp đồng thông minh được tạo bằng logic Hoare sẽ có các tiền điều kiện, hậu điều kiện và các bất biến được xác định cho việc thực thi các hàm và vòng lặp trong một hợp đồng. Các tiền điều kiện thường bao gồm khả năng có các đầu vào sai cho một hàm, với các hậu điều kiện mô tả phản hồi dự kiến cho các đầu vào như vậy (ví dụ: đưa ra một ngoại lệ cụ thể). Bằng cách này, các thuộc tính kiểu Hoare có hiệu quả trong việc đảm bảo tính đúng đắn của các triển khai hợp đồng. + +Nhiều khung xác minh hình thức sử dụng các đặc tả kiểu Hoare để chứng minh tính đúng đắn về mặt ngữ nghĩa của các hàm. Cũng có thể thêm các thuộc tính kiểu Hoare (dưới dạng các khẳng định) trực tiếp vào mã hợp đồng bằng cách sử dụng các câu lệnh `require` và `assert` trong Solidity. + +`require` thể hiện một tiền điều kiện hoặc bất biến và thường được sử dụng để xác thực đầu vào của người dùng, trong khi `assert` nắm bắt một hậu điều kiện cần thiết cho sự an toàn. Ví dụ, việc kiểm soát truy cập hợp lý cho các hàm (một ví dụ về thuộc tính an toàn) có thể đạt được bằng cách sử dụng `require` như một kiểm tra tiền điều kiện về danh tính của tài khoản gọi. Tương tự, một bất biến về các giá trị cho phép của các biến trạng thái trong một hợp đồng (ví dụ: tổng số token đang lưu hành) có thể được bảo vệ khỏi bị vi phạm bằng cách sử dụng `assert` để xác nhận trạng thái của hợp đồng sau khi thực thi hàm. + +### Các thuộc tính cấp dấu vết {#trace-level-properties} + +Các đặc tả dựa trên dấu vết mô tả các hoạt động chuyển đổi một hợp đồng giữa các trạng thái khác nhau và các mối quan hệ giữa các hoạt động này. Như đã giải thích trước đó, dấu vết là các chuỗi hoạt động làm thay đổi trạng thái của một hợp đồng theo một cách cụ thể. + +Cách tiếp cận này dựa trên mô hình của các hợp đồng thông minh như là các hệ thống chuyển đổi trạng thái với một số trạng thái được xác định trước (được mô tả bởi các biến trạng thái) cùng với một bộ các chuyển đổi được xác định trước (được mô tả bởi các hàm hợp đồng). Hơn nữa, một [đồ thị luồng điều khiển](https://www.geeksforgeeks.org/software-engineering-control-flow-graph-cfg/) (CFG), là một biểu diễn đồ họa của luồng thực thi của một chương trình, thường được sử dụng để mô tả ngữ nghĩa hoạt động của một hợp đồng. Ở đây, mỗi dấu vết được biểu diễn như một đường đi trên đồ thị luồng điều khiển. + +Chủ yếu, các đặc tả cấp dấu vết được sử dụng để suy luận về các mẫu thực thi nội bộ trong các hợp đồng thông minh. Bằng cách tạo các đặc tả cấp dấu vết, chúng ta khẳng định các đường dẫn thực thi có thể chấp nhận (tức là các chuyển đổi trạng thái) cho một hợp đồng thông minh. Sử dụng các kỹ thuật, chẳng hạn như thực thi biểu tượng, chúng ta có thể xác minh một cách hình thức rằng việc thực thi không bao giờ đi theo một đường dẫn không được xác định trong mô hình hình thức. + +Hãy sử dụng một ví dụ về một hợp đồng [DAO](/dao/) có một số hàm có thể truy cập công khai để mô tả các thuộc tính cấp dấu vết. Ở đây, chúng tôi giả định hợp đồng DAO cho phép người dùng thực hiện các hoạt động sau: + +- Gửi tiền + +- Bỏ phiếu cho một đề xuất sau khi gửi tiền + +- Yêu cầu hoàn tiền nếu họ không bỏ phiếu cho một đề xuất + +Ví dụ về các thuộc tính cấp dấu vết có thể là _"những người dùng không gửi tiền không thể bỏ phiếu cho một đề xuất"_ hoặc _"những người dùng không bỏ phiếu cho một đề xuất phải luôn có thể yêu cầu hoàn tiền"_. Cả hai thuộc tính đều khẳng định các chuỗi thực thi ưu tiên (việc bỏ phiếu không thể xảy ra _trước khi_ gửi tiền và việc yêu cầu hoàn tiền không thể xảy ra _sau khi_ bỏ phiếu cho một đề xuất). + +## Các kỹ thuật xác minh hình thức của hợp đồng thông minh {#formal-verification-techniques} + +### Kiểm tra mô hình {#model-checking} + +Kiểm tra mô hình là một kỹ thuật xác minh hình thức trong đó một thuật toán kiểm tra một mô hình hình thức của một hợp đồng thông minh so với đặc tả của nó. Trong việc kiểm tra mô hình, các hợp đồng thông minh thường được biểu diễn dưới dạng các hệ thống chuyển đổi trạng thái, trong khi các thuộc tính về các trạng thái hợp đồng được phép được xác định bằng logic thời gian. + +Việc kiểm tra mô hình đòi hỏi phải tạo ra một biểu diễn toán học trừu tượng của một hệ thống (tức là một hợp đồng) và thể hiện các thuộc tính của hệ thống này bằng các công thức bắt nguồn từ [logic mệnh đề](https://www.baeldung.com/cs/propositional-logic). Điều này đơn giản hóa nhiệm vụ của thuật toán kiểm tra mô hình, cụ thể là chứng minh rằng một mô hình toán học thỏa mãn một công thức logic đã cho. + +Việc kiểm tra mô hình trong xác minh hình thức chủ yếu được sử dụng để đánh giá các thuộc tính thời gian mô tả hành vi của một hợp đồng theo thời gian. Các thuộc tính thời gian cho các hợp đồng thông minh bao gồm _an toàn_ và _tính sống động_, mà chúng tôi đã giải thích trước đó. + +Ví dụ, một thuộc tính bảo mật liên quan đến kiểm soát truy cập (ví dụ: _Chỉ chủ sở hữu của hợp đồng mới có thể gọi `selfdestruct`_) có thể được viết bằng logic hình thức. Sau đó, thuật toán kiểm tra mô hình có thể xác minh xem hợp đồng có thỏa mãn đặc tả hình thức này không. + +Việc kiểm tra mô hình sử dụng kỹ thuật khám phá không gian trạng thái, bao gồm việc xây dựng tất cả các trạng thái có thể có của một hợp đồng thông minh và cố gắng tìm các trạng thái có thể đạt được dẫn đến vi phạm thuộc tính. Tuy nhiên, điều này có thể dẫn đến một số lượng trạng thái vô hạn (được gọi là "vấn đề bùng nổ trạng thái"), do đó các trình kiểm tra mô hình dựa vào các kỹ thuật trừu tượng để có thể phân tích hiệu quả các hợp đồng thông minh. + +### Chứng minh định lý {#theorem-proving} + +Chứng minh định lý là một phương pháp suy luận toán học về tính đúng đắn của các chương trình, bao gồm cả các hợp đồng thông minh. Nó bao gồm việc chuyển đổi mô hình của hệ thống hợp đồng và các đặc tả của nó thành các công thức toán học (các câu lệnh logic). + +Mục tiêu của việc chứng minh định lý là xác minh sự tương đương logic giữa các câu lệnh này. “Tương đương logic” (còn gọi là “song suy luận logic”) là một loại mối quan hệ giữa hai câu lệnh sao cho câu lệnh đầu tiên là đúng _khi và chỉ khi_ câu lệnh thứ hai là đúng. + +Mối quan hệ cần thiết (tương đương logic) giữa các câu lệnh về mô hình của một hợp đồng và thuộc tính của nó được xây dựng như một câu lệnh có thể chứng minh được (gọi là một định lý). Sử dụng một hệ thống suy luận hình thức, trình chứng minh định lý tự động có thể xác minh tính hợp lệ của định lý. Nói cách khác, một trình chứng minh định lý có thể chứng minh một cách kết luận rằng mô hình của một hợp đồng thông minh khớp chính xác với các đặc tả của nó. + +Trong khi việc kiểm tra mô hình mô hình hóa các hợp đồng như các hệ thống chuyển đổi với các trạng thái hữu hạn, việc chứng minh định lý có thể xử lý việc phân tích các hệ thống trạng thái vô hạn. Tuy nhiên, điều này có nghĩa là một trình chứng minh định lý tự động không phải lúc nào cũng có thể biết liệu một vấn đề logic có "quyết định được" hay không. + +Do đó, thường cần có sự trợ giúp của con người để hướng dẫn trình chứng minh định lý trong việc suy ra các bằng chứng về tính đúng đắn. Việc sử dụng nỗ lực của con người trong việc chứng minh định lý làm cho nó tốn kém hơn so với việc kiểm tra mô hình, vốn được tự động hóa hoàn toàn. + +### Thực thi biểu tượng {#symbolic-execution} + +Thực thi biểu tượng là một phương pháp phân tích một hợp đồng thông minh bằng cách thực thi các hàm sử dụng _giá trị biểu tượng_ (ví dụ: `x > 5`) thay vì _giá trị cụ thể_ (ví dụ: `x == 5`). Là một kỹ thuật xác minh hình thức, thực thi biểu tượng được sử dụng để suy luận hình thức về các thuộc tính cấp dấu vết trong mã của một hợp đồng. + +Thực thi biểu tượng biểu diễn một dấu vết thực thi dưới dạng một công thức toán học trên các giá trị đầu vào biểu tượng, còn được gọi là _vị từ đường dẫn_. Một [trình giải SMT](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories) được sử dụng để kiểm tra xem một vị từ đường dẫn có "thỏa mãn được" hay không (tức là có tồn tại một giá trị có thể thỏa mãn công thức). Nếu một đường dẫn dễ bị tổn thương có thể thỏa mãn được, trình giải SMT sẽ tạo ra một giá trị cụ thể kích hoạt việc điều khiển thực thi đến đường dẫn đó. + +Giả sử một hàm của hợp đồng thông minh nhận đầu vào là một giá trị `uint` (`x`) và hoàn nguyên khi `x` lớn hơn `5` và cũng nhỏ hơn `10`. Việc tìm một giá trị cho `x` gây ra lỗi bằng quy trình kiểm thử thông thường sẽ đòi hỏi phải chạy qua hàng chục trường hợp kiểm thử (hoặc nhiều hơn) mà không có sự đảm bảo thực sự tìm thấy một đầu vào gây lỗi. + +Ngược lại, một công cụ thực thi biểu tượng sẽ thực thi hàm với giá trị biểu tượng: `X > 5 ∧ X < 10` (tức là `x` lớn hơn 5 VÀ `x` nhỏ hơn 10). Vị từ đường dẫn liên quan `x = X > 5 ∧ X < 10` sau đó sẽ được đưa cho một trình giải SMT để giải quyết. Nếu một giá trị cụ thể thỏa mãn công thức `x = X > 5 ∧ X < 10`, trình giải SMT sẽ tính toán nó—ví dụ, trình giải có thể tạo ra `7` làm giá trị cho `x`. + +Bởi vì thực thi biểu tượng dựa trên các đầu vào của một chương trình, và tập hợp các đầu vào để khám phá tất cả các trạng thái có thể đạt được có khả năng là vô hạn, nó vẫn là một hình thức kiểm thử. Tuy nhiên, như được hiển thị trong ví dụ, thực thi biểu tượng hiệu quả hơn so với kiểm thử thông thường để tìm các đầu vào gây ra vi phạm thuộc tính. + +Hơn nữa, thực thi biểu tượng tạo ra ít kết quả dương tính giả hơn so với các kỹ thuật dựa trên thuộc tính khác (ví dụ: fuzzing) tạo ra các đầu vào ngẫu nhiên cho một hàm. Nếu một trạng thái lỗi được kích hoạt trong quá trình thực thi biểu tượng, thì có thể tạo ra một giá trị cụ thể gây ra lỗi và tái tạo vấn đề. + +Thực thi biểu tượng cũng có thể cung cấp một mức độ chứng minh toán học về tính đúng đắn. Hãy xem xét ví dụ sau về một hàm hợp đồng có bảo vệ chống tràn số: + +``` +function safe_add(uint x, uint y) returns(uint z){ + + z = x + y; + require(z>=x); + require(z>=y); + + return z; +} +``` + +Một dấu vết thực thi dẫn đến tràn số nguyên sẽ cần thỏa mãn công thức: `z = x + y AND (z >= x) AND (z >= y) AND (z < x OR z < y)` Một công thức như vậy khó có thể được giải quyết, do đó nó đóng vai trò như một bằng chứng toán học rằng hàm `safe_add` không bao giờ bị tràn. + +### Tại sao sử dụng xác minh hình thức cho các hợp đồng thông minh? {#benefits-of-formal-verification} + +#### Nhu cầu về độ tin cậy {#need-for-reliability} + +Xác minh hình thức được sử dụng để đánh giá tính đúng đắn của các hệ thống quan trọng về an toàn mà sự cố của chúng có thể gây ra những hậu quả tàn khốc, chẳng hạn như tử vong, thương tích hoặc phá sản tài chính. Các hợp đồng thông minh là các ứng dụng có giá trị cao kiểm soát lượng giá trị khổng lồ, và những lỗi đơn giản trong thiết kế có thể dẫn đến [những tổn thất không thể phục hồi cho người dùng](https://www.freecodecamp.org/news/a-hacker-stole-31m-of-ether-how-it-happened-and-what-it-means-for-ethereum-9e5dc29e33ce/amp/). Tuy nhiên, việc xác minh hình thức một hợp đồng trước khi triển khai có thể tăng cường đảm bảo rằng nó sẽ hoạt động như mong đợi một khi chạy trên chuỗi khối. + +Độ tin cậy là một chất lượng rất được mong đợi trong bất kỳ hợp đồng thông minh nào, đặc biệt là vì mã được triển khai trong Máy ảo Ethereum (EVM) thường là bất biến. Với việc nâng cấp sau khi ra mắt không dễ dàng tiếp cận, nhu cầu đảm bảo độ tin cậy của các hợp đồng làm cho việc xác minh hình thức trở nên cần thiết. Xác minh hình thức có thể phát hiện các vấn đề phức tạp, chẳng hạn như tràn số nguyên và thiếu số, tái hòa nhập và tối ưu hóa Gas kém, mà có thể bị các kiểm toán viên và người kiểm thử bỏ qua. + +#### Chứng minh tính đúng đắn về chức năng {#prove-functional-correctness} + +Kiểm thử chương trình là phương pháp phổ biến nhất để chứng minh rằng một hợp đồng thông minh thỏa mãn một số yêu cầu. Điều này bao gồm việc thực thi một hợp đồng với một mẫu dữ liệu mà nó dự kiến sẽ xử lý và phân tích hành vi của nó. Nếu hợp đồng trả về các kết quả mong đợi cho dữ liệu mẫu, thì các nhà phát triển có bằng chứng khách quan về tính đúng đắn của nó. + +Tuy nhiên, cách tiếp cận này không thể chứng minh việc thực thi đúng cho các giá trị đầu vào không phải là một phần của mẫu. Do đó, việc kiểm thử một hợp đồng có thể giúp phát hiện lỗi (tức là, nếu một số đường dẫn mã không trả về kết quả mong muốn trong quá trình thực thi), nhưng **nó không thể chứng minh một cách kết luận sự vắng mặt của lỗi**. + +Ngược lại, xác minh hình thức có thể chứng minh một cách hình thức rằng một hợp đồng thông minh thỏa mãn các yêu cầu cho một phạm vi vô hạn các lần thực thi _mà không_ cần chạy hợp đồng. Điều này đòi hỏi phải tạo ra một đặc tả hình thức mô tả chính xác các hành vi đúng của hợp đồng và phát triển một mô hình hình thức (toán học) của hệ thống hợp đồng. Sau đó, chúng ta có thể theo một quy trình chứng minh hình thức để kiểm tra tính liên tục giữa mô hình của hợp đồng và đặc tả của nó. + +Với xác minh hình thức, câu hỏi về việc xác minh liệu logic nghiệp vụ của một hợp đồng có thỏa mãn các yêu cầu hay không là một mệnh đề toán học có thể được chứng minh hoặc bác bỏ. Bằng cách chứng minh hình thức một mệnh đề, chúng ta có thể xác minh một số lượng vô hạn các trường hợp kiểm thử với một số lượng hữu hạn các bước. Bằng cách này, xác minh hình thức có triển vọng tốt hơn trong việc chứng minh một hợp đồng là đúng về mặt chức năng đối với một đặc tả. + +#### Các mục tiêu xác minh lý tưởng {#ideal-verification-targets} + +Mục tiêu xác minh mô tả hệ thống sẽ được xác minh hình thức. Xác minh hình thức được sử dụng tốt nhất trong "các hệ thống nhúng" (các phần mềm nhỏ, đơn giản là một phần của một hệ thống lớn hơn). Chúng cũng lý tưởng cho các lĩnh vực chuyên biệt có ít quy tắc, vì điều này giúp dễ dàng sửa đổi các công cụ để xác minh các thuộc tính dành riêng cho lĩnh vực đó. + +Các hợp đồng thông minh—ít nhất, ở một mức độ nào đó—đáp ứng cả hai yêu cầu. Ví dụ, kích thước nhỏ của các hợp đồng Ethereum làm cho chúng dễ dàng cho việc xác minh hình thức. Tương tự, EVM tuân theo các quy tắc đơn giản, giúp việc đặc tả và xác minh các thuộc tính ngữ nghĩa cho các chương trình chạy trong EVM trở nên dễ dàng hơn. + +### Chu kỳ phát triển nhanh hơn {#faster-development-cycle} + +Các kỹ thuật xác minh hình thức, chẳng hạn như kiểm tra mô hình và thực thi biểu tượng, thường hiệu quả hơn so với việc phân tích thông thường mã hợp đồng thông minh (được thực hiện trong quá trình kiểm thử hoặc kiểm toán). Điều này là do xác minh hình thức dựa trên các giá trị biểu tượng để kiểm tra các khẳng định ("điều gì sẽ xảy ra nếu người dùng cố gắng rút _n_ ether?") không giống như kiểm thử sử dụng các giá trị cụ thể ("điều gì sẽ xảy ra nếu người dùng cố gắng rút 5 ether?"). + +Các biến đầu vào biểu tượng có thể bao gồm nhiều lớp giá trị cụ thể, do đó các phương pháp xác minh hình thức hứa hẹn độ bao phủ mã lớn hơn trong một khung thời gian ngắn hơn. Khi được sử dụng hiệu quả, xác minh hình thức có thể đẩy nhanh chu kỳ phát triển cho các nhà phát triển. + +Xác minh hình thức cũng cải thiện quy trình xây dựng các ứng dụng phi tập trung (dapps) bằng cách giảm các lỗi thiết kế tốn kém. Việc nâng cấp các hợp đồng (nếu có thể) để sửa các lỗ hổng đòi hỏi phải viết lại nhiều codebase và tốn nhiều công sức hơn cho việc phát triển. Xác minh hình thức có thể phát hiện nhiều lỗi trong các triển khai hợp đồng mà có thể bị các người kiểm thử và kiểm toán viên bỏ qua và cung cấp cơ hội lớn để khắc phục các vấn đề đó trước khi triển khai một hợp đồng. + +## Nhược điểm của xác minh hình thức {#drawbacks-of-formal-verification} + +### Chi phí lao động thủ công {#cost-of-manual-labor} + +Xác minh hình thức, đặc biệt là xác minh bán tự động trong đó con người hướng dẫn trình chứng minh suy ra các bằng chứng về tính đúng đắn, đòi hỏi nhiều lao động thủ công. Hơn nữa, việc tạo ra đặc tả hình thức là một hoạt động phức tạp đòi hỏi trình độ kỹ năng cao. + +Những yếu tố này (nỗ lực và kỹ năng) làm cho việc xác minh hình thức trở nên đòi hỏi và tốn kém hơn so với các phương pháp thông thường để đánh giá tính đúng đắn trong các hợp đồng, chẳng hạn như kiểm thử và kiểm toán. Tuy nhiên, việc trả chi phí cho một cuộc kiểm toán xác minh đầy đủ là thực tế, xét đến chi phí của các lỗi trong các triển khai hợp đồng thông minh. + +### Kết quả âm tính giả {#false-negatives} + +Xác minh hình thức chỉ có thể kiểm tra xem việc thực thi của hợp đồng thông minh có khớp với đặc tả hình thức hay không. Do đó, điều quan trọng là phải đảm bảo đặc tả mô tả đúng các hành vi dự kiến của một hợp đồng thông minh. + +Nếu các đặc tả được viết kém, các vi phạm thuộc tính—chỉ ra các lần thực thi dễ bị tổn thương—không thể được phát hiện bởi cuộc kiểm toán xác minh hình thức. Trong trường hợp này, một nhà phát triển có thể giả định sai rằng hợp đồng không có lỗi. + +### Vấn đề về hiệu suất {#performance-issues} + +Xác minh hình thức gặp phải một số vấn đề về hiệu suất. Ví dụ, các vấn đề bùng nổ trạng thái và đường dẫn gặp phải trong quá trình kiểm tra mô hình và kiểm tra biểu tượng, tương ứng, có thể ảnh hưởng đến các quy trình xác minh. Ngoài ra, các công cụ xác minh hình thức thường sử dụng các trình giải SMT và các trình giải ràng buộc khác trong lớp cơ sở của chúng, và các trình giải này dựa vào các quy trình tính toán chuyên sâu. + +Ngoài ra, không phải lúc nào các trình xác minh chương trình cũng có thể xác định được một thuộc tính (được mô tả dưới dạng một công thức logic) có thể được thỏa mãn hay không (vấn đề "[tính quyết định được](https://en.wikipedia.org/wiki/Decision_problem)") bởi vì một chương trình có thể không bao giờ kết thúc. Do đó, có thể không thể chứng minh một số thuộc tính cho một hợp đồng ngay cả khi nó được đặc tả tốt. + +## Công cụ xác minh hình thức cho các hợp đồng thông minh Ethereum {#formal-verification-tools} + +### Các ngôn ngữ đặc tả để tạo đặc tả hình thức {#specification-languages} + +**Act**: __Act cho phép đặc tả các cập nhật lưu trữ, các điều kiện trước/sau và các bất biến của hợp đồng. Bộ công cụ của nó cũng có các backend chứng minh có thể chứng minh nhiều thuộc tính thông qua Coq, các trình giải SMT, hoặc hevm.__ + +- [GitHub](https://github.com/ethereum/act) +- [Tài liệu tham khảo](https://github.com/argotorg/act) + +**Scribble** - __Scribble chuyển đổi các chú thích mã trong ngôn ngữ đặc tả Scribble thành các khẳng định cụ thể kiểm tra đặc tả.__ + +- [Tài liệu tham khảo](https://docs.scribble.codes/) + +**Dafny** - __Dafny là một ngôn ngữ lập trình sẵn sàng cho việc xác minh, dựa vào các chú thích cấp cao để suy luận và chứng minh tính đúng đắn của mã.__ + +- [GitHub](https://github.com/dafny-lang/dafny) + +### Các trình xác minh chương trình để kiểm tra tính đúng đắn {#program-verifiers} + +**Certora Prover** - _Certora Prover là một công cụ xác minh hình thức tự động để kiểm tra tính đúng đắn của mã trong các hợp đồng thông minh. Các đặc tả được viết bằng CVL (Ngôn ngữ xác minh Certora), với các vi phạm thuộc tính được phát hiện bằng sự kết hợp giữa phân tích tĩnh và giải quyết ràng buộc._ + +- [Trang web](https://www.certora.com/) +- [Tài liệu tham khảo](https://docs.certora.com/en/latest/index.html) + +**Solidity SMTChecker** - __SMTChecker của Solidity là một trình kiểm tra mô hình tích hợp dựa trên SMT (Lý thuyết mô đun thỏa mãn) và giải Horn. Nó xác nhận xem mã nguồn của hợp đồng có khớp với các đặc tả trong quá trình biên dịch hay không và kiểm tra tĩnh các vi phạm về thuộc tính an toàn.__ + +- [GitHub](https://github.com/ethereum/solidity) + +**solc-verify** - __solc-verify là một phiên bản mở rộng của trình biên dịch Solidity có thể thực hiện xác minh hình thức tự động trên mã Solidity bằng cách sử dụng các chú thích và xác minh chương trình theo mô-đun.__ + +- [GitHub](https://github.com/SRI-CSL/solidity) + +**KEVM** - __KEVM là một ngữ nghĩa hình thức của Máy ảo Ethereum (EVM) được viết bằng khung K. KEVM có thể thực thi và có thể chứng minh một số khẳng định liên quan đến thuộc tính bằng cách sử dụng logic khả năng tiếp cận.__ + +- [GitHub](https://github.com/runtimeverification/evm-semantics) +- [Tài liệu tham khảo](https://jellopaper.org/) + +### Các khung logic để chứng minh định lý {#theorem-provers} + +**Isabelle** - _Isabelle/HOL là một trợ lý chứng minh cho phép các công thức toán học được biểu diễn bằng một ngôn ngữ hình thức và cung cấp các công cụ để chứng minh các công thức đó. Ứng dụng chính là việc hình thức hóa các chứng minh toán học và đặc biệt là xác minh hình thức, bao gồm việc chứng minh tính đúng đắn của phần cứng hoặc phần mềm máy tính và chứng minh các thuộc tính của các ngôn ngữ và giao thức máy tính._ + +- [GitHub](https://github.com/isabelle-prover) +- [Tài liệu tham khảo](https://isabelle.in.tum.de/documentation.html) + +**Rocq** - _Rocq là một trình chứng minh định lý tương tác cho phép bạn xác định các chương trình bằng các định lý và tạo ra các bằng chứng về tính đúng đắn được kiểm tra bằng máy một cách tương tác._ + +- [GitHub](https://github.com/rocq-prover/rocq) +- [Tài liệu tham khảo](https://rocq-prover.org/docs) + +### Các công cụ dựa trên thực thi biểu tượng để phát hiện các mẫu dễ bị tổn thương trong các hợp đồng thông minh {#symbolic-execution-tools} + +**Manticore** - __Một công cụ để phân tích mã byte EVM dựa trên thực thi biểu tượng_._ + +- [GitHub](https://github.com/trailofbits/manticore) +- [Tài liệu tham khảo](https://github.com/trailofbits/manticore/wiki) + +**hevm** - __hevm là một công cụ thực thi biểu tượng và trình kiểm tra tương đương cho mã byte EVM.__ + +- [GitHub](https://github.com/dapphub/dapptools/tree/master/src/hevm) + +**Mythril** - _Một công cụ thực thi biểu tượng để phát hiện các lỗ hổng trong các hợp đồng thông minh Ethereum_ + +- [GitHub](https://github.com/ConsenSys/mythril-classic) +- [Tài liệu tham khảo](https://mythril-classic.readthedocs.io/en/develop/) + +## Đọc thêm {#further-reading} + +- [Cách Hoạt động của Xác minh Hình thức đối với Hợp đồng Thông minh](https://runtimeverification.com/blog/how-formal-verification-of-smart-contracts-works/) +- [Cách Xác minh Hình thức có thể Đảm bảo Hợp đồng Thông minh Không có Lỗi](https://media.consensys.net/how-formal-verification-can-ensure-flawless-smart-contracts-cbda8ad99bd1) +- [Tổng quan về các Dự án Xác minh Hình thức trong Hệ sinh thái Ethereum](https://github.com/leonardoalt/ethereum_formal_verification_overview) +- [Xác minh Hình thức Từ đầu đến cuối Hợp đồng Thông minh Ký gửi Ethereum 2.0](https://runtimeverification.com/blog/end-to-end-formal-verification-of-ethereum-2-0-deposit-smart-contract/) +- [Xác minh hình thức Hợp đồng thông minh phổ biến nhất thế giới](https://www.zellic.io/blog/formal-verification-weth) +- [SMTChecker và Xác minh Hình thức](https://docs.soliditylang.org/en/v0.8.15/smtchecker.html) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/index.md b/public/content/translations/vi/developers/docs/smart-contracts/index.md new file mode 100644 index 00000000000..9279749f175 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/index.md @@ -0,0 +1,112 @@ +--- +title: "Giới thiệu về hợp đồng thông minh" +description: "Một cái nhìn tổng quan về hợp đồng thông minh, tập trung vào các đặc điểm và giới hạn độc đáo của chúng." +lang: vi +--- + +## Hợp đồng thông minh là gì? {#what-is-a-smart-contract} + +Một "hợp đồng thông minh" đơn giản chỉ là một chương trình hoạt động trên chuỗi khối Ethereum. Đó là một bộ mã (các hàm của nó) và dữ liệu (trạng thái của nó) tồn tại tại một địa chỉ cụ thể trên chuỗi khối Ethereum. + +Hợp đồng thông minh là một loại [tài khoản Ethereum](/developers/docs/accounts/). Điều này có nghĩa là họ có một số dư và có thể trở thành đối tượng của các giao dịch. Tuy nhiên, chúng không được điều khiển bởi người dùng, mà được triển khai vào mạng và hoạt động theo chương trình đã được lập. Các tài khoản người dùng sau đó có thể tương tác với một hợp đồng thông minh bằng cách gửi các giao dịch thực thi một chức năng được xác định trong hợp đồng thông minh. Hợp đồng thông minh có thể xác định các quy tắc, giống như một hợp đồng thông thường, và tự động thực thi chúng qua mã. Hợp đồng thông minh không thể bị xóa theo mặc định, và các tương tác với chúng là không thể đảo ngược. + +## Điều kiện tiên quyết {#prerequisites} + +Nếu bạn mới bắt đầu hoặc đang tìm kiếm một phần giới thiệu ít kỹ thuật hơn, chúng tôi khuyên bạn nên xem [phần giới thiệu về hợp đồng thông minh](/smart-contracts/) của chúng tôi. + +Hãy chắc chắn rằng bạn đã đọc về [tài khoản](/developers/docs/accounts/), [giao dịch](/developers/docs/transactions/) và [máy ảo Ethereum](/developers/docs/evm/) trước khi bước vào thế giới hợp đồng thông minh. + +## Máy bán hàng tự động kỹ thuật số {#a-digital-vending-machine} + +Có lẽ phép ẩn dụ tốt nhất cho một hợp đồng thông minh là một máy bán hàng tự động, như được mô tả bởi [Nick Szabo](https://unenumerated.blogspot.com/). Với những đầu vào đúng, một đầu ra nhất định được đảm bảo. + +Để lấy một món ăn nhẹ từ máy bán hàng tự động: + +``` +tiền + lựa chọn đồ ăn nhẹ = nhả đồ ăn nhẹ +``` + +Lô-gic này được lập trình vào trong máy bán hàng tự động. + +Một hợp đồng thông minh, giống như một máy bán hàng tự động, có logic được lập trình sẵn. Dưới đây là một ví dụ đơn giản về cách máy bán hàng này sẽ trông như thế nào nếu nó được viết dưới dạng hợp đồng thông minh bằng ngôn ngữ Solidity: + +```solidity +pragma solidity 0.8.7; + +contract VendingMachine { + + // Khai báo các biến trạng thái của hợp đồng + address public owner; + mapping (address => uint) public cupcakeBalances; + + // Khi hợp đồng 'VendingMachine' được triển khai: + // 1. đặt địa chỉ triển khai làm chủ sở hữu hợp đồng + // 2. đặt số dư cupcake của hợp đồng thông minh đã triển khai thành 100 + constructor() { + owner = msg.sender; + cupcakeBalances[address(this)] = 100; + } + + // Cho phép chủ sở hữu tăng số dư cupcake của hợp đồng thông minh + function refill(uint amount) public { + require(msg.sender == owner, "Chỉ chủ sở hữu mới có thể nạp thêm."); + cupcakeBalances[address(this)] += amount; + } + + // Cho phép bất kỳ ai mua cupcake + function purchase(uint amount) public payable { + require(msg.value >= amount * 1 ether, "Bạn phải trả ít nhất 1 ETH cho mỗi cupcake"); + require(cupcakeBalances[address(this)] >= amount, "Không đủ cupcake trong kho để hoàn tất giao dịch mua này"); + cupcakeBalances[address(this)] -= amount; + cupcakeBalances[msg.sender] += amount; + } +} +``` + +Giống như cách mà máy bán hàng tự động loại bỏ nhu cầu về một nhân viên bán hàng, hợp đồng thông minh có thể thay thế các trung gian trong nhiều ngành công nghiệp. + +## Không cần cấp phép {#permissionless} + +Bất kỳ ai cũng có thể viết một hợp đồng thông minh và triển khai nó lên mạng. Bạn chỉ cần học cách viết mã bằng [ngôn ngữ hợp đồng thông minh](/developers/docs/smart-contracts/languages/) và có đủ ETH để triển khai hợp đồng của mình. Việc triển khai một hợp đồng thông minh về mặt kỹ thuật là một giao dịch, vì vậy bạn cần phải trả [gas](/developers/docs/gas/) giống như cách bạn trả gas cho một lần chuyển ETH đơn giản. Tuy nhiên, chi phí gas cho việc triển khai hợp đồng cao hơn nhiều. + +Ethereum có các ngôn ngữ thân thiện với nhà phát triển để viết các hợp đồng thông minh: + +- Solidity +- Vyper + +[Thêm về các ngôn ngữ](/developers/docs/smart-contracts/languages/) + +Tuy nhiên, chúng phải được biên soạn trước khi có thể triển khai để máy ảo của Ethereum có thể hiểu và lưu trữ hợp đồng. [Thêm về việc biên dịch](/developers/docs/smart-contracts/compiling/) + +## Tính kết hợp {#composability} + +Hợp đồng thông minh trên Ethereum là công khai và có thể xem như là các API mở. Điều này có nghĩa là bạn có thể gọi các hợp đồng thông minh khác trong hợp đồng thông minh của riêng bạn để mở rộng đáng kể những gì có thể thực hiện. Các hợp đồng có thể triển khai các hợp đồng khác. + +Tìm hiểu thêm về [tính kết hợp của hợp đồng thông minh](/developers/docs/smart-contracts/composability/). + +## Các hạn chế {#limitations} + +Các hợp đồng thông minh đơn thuần không thể lấy thông tin về các sự kiện "thế giới thực" vì chúng không thể truy cập dữ liệu từ các nguồn ngoài chuỗi. Điều này có nghĩa là họ không thể phản ứng với các sự kiện trong thế giới thực. Điều này là do thiết kế. Việc phụ thuộc vào thông tin bên ngoài có thể gây tổn hại đến sự đồng thuận, điều này rất quan trọng cho bảo mật và tính phi tập trung. + +Tuy nhiên, điều quan trọng là các ứng dụng blockchain phải có khả năng sử dụng dữ liệu ngoài chuỗi. Giải pháp là các [oracle](/developers/docs/oracles/), là những công cụ thu thập dữ liệu ngoài chuỗi và cung cấp cho các hợp đồng thông minh. + +Một hạn chế khác của hợp đồng thông minh là kích thước tối đa của hợp đồng. Một hợp đồng thông minh có thể tối đa là 24KB, nếu không thì sẽ hết gas. Vấn đề này có thể được giải quyết bằng cách sử dụng [The Diamond Pattern](https://eips.ethereum.org/EIPS/eip-2535). + +## Hợp đồng đa chữ ký {#multisig} + +Hợp đồng nhiều chữ ký (Multisig) là các tài khoản hợp đồng thông minh yêu cầu nhiều chữ ký hợp lệ để thực hiện một giao dịch. Điều này rất hữu ích để tránh các điểm thất bại đơn lẻ cho các hợp đồng nắm giữ số tiền đáng kể ether hoặc các token khác. Multisig cũng phân chia trách nhiệm trong việc thực hiện hợp đồng và quản lý khóa giữa nhiều bên, ngăn chặn việc mất một khóa riêng lẻ dẫn đến việc mất tiền không thể khôi phục. Vì những lý do này, các hợp đồng đa chữ ký có thể được sử dụng cho việc quản trị DAO đơn giản. Hợp đồng đa chữ ký yêu cầu N chữ ký trong số M chữ ký được chấp nhận (trong đó N ≤ M và M > 1) để thực thi. `N = 3, M = 5` và `N = 4, M = 7` thường được sử dụng. Một multisig 4/7 cần bốn trong bảy chữ ký hợp lệ. Điều này có nghĩa là các quỹ vẫn có thể được thu hồi ngay cả khi ba chữ ký bị mất. Trong trường hợp này, điều đó cũng có nghĩa là phần lớn những người nắm giữ khóa phải đồng ý và ký tên thì hợp đồng mới có hiệu lực. + +## Các tài nguyên về hợp đồng thông minh {#smart-contract-resources} + +**Hợp đồng OpenZeppelin -** **_Thư viện để phát triển hợp đồng thông minh an toàn._** + +- [openzeppelin.com/contracts/](https://openzeppelin.com/contracts/) +- [GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts) +- [Diễn đàn cộng đồng](https://forum.openzeppelin.com/c/general/16) + +## Đọc thêm {#further-reading} + +- [Coinbase: Hợp đồng thông minh là gì?](https://www.coinbase.com/learn/crypto-basics/what-is-a-smart-contract) +- [Chainlink: Hợp đồng thông minh là gì?](https://chain.link/education/smart-contracts) +- [Video: Giải thích đơn giản - Hợp đồng thông minh](https://youtu.be/ZE2HxTmxfrI) +- [Cyfrin Updraft: Nền tảng học và kiểm toán Web3](https://updraft.cyfrin.io) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/languages/index.md b/public/content/translations/vi/developers/docs/smart-contracts/languages/index.md new file mode 100644 index 00000000000..459dc4a049f --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/languages/index.md @@ -0,0 +1,342 @@ +--- +title: "Ngôn ngữ hợp đồng thông minh" +description: "Tổng quan và so sánh hai ngôn ngữ chính dùng để xây dựng hợp đồng thông minh - Solidity và Vyper." +lang: vi +--- + +Một khía cạnh tuyệt vời của Ethereum đó chính là những hợp đồng thông minh có thể được viết nên bởi các ngôn ngữ lập trình tương đối thân thiện. Nếu bạn đã có kinh nghiệm với Python hoặc bất kỳ [ngôn ngữ dấu ngoặc nhọn nào](https://wikipedia.org/wiki/List_of_programming_languages_by_type#Curly-bracket_languages), bạn có thể tìm thấy một ngôn ngữ có cú pháp quen thuộc. + +Hai ngôn ngữ hoạt động và được duy trì phổ biến nhất là: + +- Solidity +- Vyper + +Remix IDE cung cấp một môi trường phát triển toàn diện cho việc tạo và kiểm tra hợp đồng bằng cả Solidity và Vyper. [Hãy thử Remix IDE trong trình duyệt](https://remix.ethereum.org) để bắt đầu lập trình. + +Các nhà phát triển có kinh nghiệm hơn cũng có thể muốn sử dụng Yul, một ngôn ngữ trung gian cho [Máy ảo Ethereum](/developers/docs/evm/), hoặc Yul+, một phần mở rộng của Yul. + +Nếu bạn muốn tìm hiểu thêm và thử nghiệm các ngôn ngữ mới vẫn đang được phát triển mạnh mẽ, bạn có thể thử Fe, một ngôn ngữ hợp đồng thông minh mới nổi hiện nay còn trong giai đoạn sơ khai. + +## Điều kiện tiên quyết {#prerequisites} + +Những kiến thức trước đây về các ngôn ngữ lập trình, đặc biệt là JavaScript hoặc Python, có thể giúp bạn hiểu được sự khác biệt trong những ngôn ngữ hợp đồng thông minh. Chúng tôi cũng khuyến nghị bạn nắm rõ hợp đồng thông minh như một khái niệm trước khi đi sâu vào sự so sánh giữa các ngôn ngữ. [Giới thiệu về hợp đồng thông minh](/developers/docs/smart-contracts/). + +## Solidity {#solidity} + +- Là ngôn ngữ bậc cao và hướng đối tượng để triển khai các hợp đồng thông minh. +- Ngôn ngữ ngoặc nhọn, chịu sự ảnh hưởng mạnh mẽ bởi C++. +- Nhập tĩnh (kiểu dữ liệu của biến sẽ được xác định ở thời điểm biên dịch). +- Hỗ Trợ: + - Kế thừa (để bạn có thể mở rộng các hợp đồng khác). + - Các thư viện (bạn có thể tạo ra những đoạn mã có thể tái sử dụng để gọi chúng vào các hợp đồng khác - tương tựng như hàm tĩnh trong một lớp tĩnh ở các ngôn ngữ lập trình hướng đối tượng khác). + - Các kiểu dữ liệu phức tạp do người dùng tự định nghĩa. + +### Các liên kết quan trọng {#important-links} + +- [Tài liệu tham khảo](https://docs.soliditylang.org/en/latest/) +- [Cổng thông tin ngôn ngữ Solidity](https://soliditylang.org/) +- [Solidity qua ví dụ](https://docs.soliditylang.org/en/latest/solidity-by-example.html) +- [GitHub](https://github.com/ethereum/solidity/) +- [Phòng trò chuyện Solidity Gitter](https://gitter.im/ethereum/solidity) được bắc cầu đến [Phòng trò chuyện Solidity Matrix](https://matrix.to/#/#ethereum_solidity:gitter.im) +- [Bảng tính nhanh](https://reference.auditless.com/cheatsheet) +- [Blog Solidity](https://blog.soliditylang.org/) +- [Twitter của Solidity](https://twitter.com/solidity_lang) + +### Hợp đồng mẫu {#example-contract} + +```solidity +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >= 0.7.0; + +contract Coin { + // Từ khóa "public" giúp các biến + // có thể truy cập được từ các hợp đồng khác + address public minter; + mapping (address => uint) public balances; + + // Các sự kiện cho phép các ứng dụng + // phản ứng với các thay đổi hợp đồng cụ thể mà bạn khai báo + event Sent(address from, address to, uint amount); + + // Mã hàm khởi tạo chỉ được chạy khi hợp đồng + // được tạo + constructor() { + minter = msg.sender; + } + + // Gửi một lượng coin mới được tạo tới một địa chỉ + // Chỉ có thể được gọi bởi người tạo hợp đồng + function mint(address receiver, uint amount) public { + require(msg.sender == minter); + require(amount < 1e60); + balances[receiver] += amount; + } + + // Gửi một lượng coin hiện có + // từ bất kỳ người gọi nào đến một địa chỉ + function send(address receiver, uint amount) public { + require(amount <= balances[msg.sender], "Số dư không đủ."); + balances[msg.sender] -= amount; + balances[receiver] += amount; + emit Sent(msg.sender, receiver, amount); + } +} +``` + +Ví dụ trên sẽ cho bạn biết cú pháp của hợp đồng được viết bằng Solidity là như thế nào. Để có mô tả chi tiết hơn về các hàm và biến, [xem tài liệu](https://docs.soliditylang.org/en/latest/contracts.html). + +## Vyper {#vyper} + +- Ngôn ngữ lập trình Python +- Strong typing (kiểu dữ liệu của một đối tượng không thay đổi đột ngột, không tường minh) +- Mã biên dịch gọn và dễ hiểu +- Tạo mã bytecode hiệu quả +- Được tạo ra với mục đích là it tính năng hơn Solidity để tăng sự an toàn của hợp đồng và dễ kiểm tra hơn. Vyper không hỗ trợ: + - Modifiers + - Tính kế thừa + - Mã assembly nội dòng + - Nạp chồng hàm + - Nạp chồng toán tử + - Đệ quy + - Vòng lặp vô hạn + - Các fixed points nhị phân + +Để biết thêm thông tin, [đọc cơ sở lý luận của Vyper](https://vyper.readthedocs.io/en/latest/index.html). + +### Các liên kết quan trọng {#important-links-1} + +- [Tài liệu tham khảo](https://vyper.readthedocs.io) +- [Vyper qua ví dụ](https://vyper.readthedocs.io/en/latest/vyper-by-example.html) +- [Thêm ví dụ về Vyper](https://vyper-by-example.org/) +- [GitHub](https://github.com/vyperlang/vyper) +- [Trò chuyện cộng đồng Vyper trên Discord](https://discord.gg/SdvKC79cJk) +- [Bảng tính nhanh](https://reference.auditless.com/cheatsheet) +- [Các bộ khung và công cụ phát triển hợp đồng thông minh cho Vyper](/developers/docs/programming-languages/python/) +- [VyperPunk - học cách bảo mật và hack các hợp đồng thông minh Vyper](https://github.com/SupremacyTeam/VyperPunk) +- [Vyper Hub để phát triển](https://github.com/zcor/vyper-dev) +- [Các ví dụ hợp đồng thông minh Vyper hay nhất](https://github.com/pynchmeister/vyper-greatest-hits/tree/main/contracts) +- [Các tài nguyên chọn lọc tuyệt vời về Vyper](https://github.com/spadebuilders/awesome-vyper) + +### Ví dụ {#example} + +```python +# Đấu giá mở + +# Tham số đấu giá + +# Người thụ hưởng nhận tiền từ người trả giá cao nhất + +beneficiary: public(address) +auctionStart: public(uint256) +auctionEnd: public(uint256) + +# Trạng thái hiện tại của phiên đấu giá + +highestBidder: public(address) +highestBid: public(uint256) + +# Đặt thành true ở cuối, không cho phép bất kỳ thay đổi nào + +ended: public(bool) + +# Theo dõi các giá thầu được hoàn lại để chúng ta có thể tuân theo mẫu rút tiền + +pendingReturns: public(HashMap[address, uint256]) + +# Tạo một phiên đấu giá đơn giản với `_bidding_time` + +# giây thời gian đấu giá thay mặt cho + +# địa chỉ người thụ hưởng `_beneficiary`. + +@external +def __init__(_beneficiary: address, _bidding_time: uint256): + self.beneficiary = _beneficiary + self.auctionStart = block.timestamp + self.auctionEnd = self.auctionStart + _bidding_time + +# Đặt giá cho phiên đấu giá với giá trị được gửi + +# cùng với giao dịch này. + +# Giá trị sẽ chỉ được hoàn lại nếu + +# không thắng phiên đấu giá. + +@external +@payable +def bid(): + # Kiểm tra xem thời gian đặt giá đã kết thúc chưa. + assert block.timestamp < self.auctionEnd + # Kiểm tra xem giá thầu có đủ cao không + assert msg.value > self.highestBid + # Theo dõi khoản tiền hoàn lại cho người trả giá cao trước đó + self.pendingReturns[self.highestBidder] += self.highestBid + # Theo dõi giá thầu cao mới + self.highestBidder = msg.sender + self.highestBid = msg.value + +# Rút lại một giá thầu đã được hoàn lại trước đó. Mẫu rút tiền được + +# sử dụng ở đây để tránh một vấn đề bảo mật. Nếu các khoản hoàn trả được gửi trực tiếp + +# như một phần của bid(), một hợp đồng đặt giá độc hại có thể chặn + +# các khoản hoàn trả đó và do đó chặn các giá thầu cao hơn mới được đưa vào. + +@external +def withdraw(): + pending_amount: uint256 = self.pendingReturns[msg.sender] + self.pendingReturns[msg.sender] = 0 + send(msg.sender, pending_amount) + +# Kết thúc phiên đấu giá và gửi giá thầu cao nhất + +# cho người thụ hưởng. + +@external +def endAuction(): + # Một nguyên tắc hay là cấu trúc các hàm tương tác + # với các hợp đồng khác (tức là chúng gọi các hàm hoặc gửi ether) + # thành ba giai đoạn: + # 1. kiểm tra các điều kiện + # 2. thực hiện các hành động (có khả năng thay đổi các điều kiện) + # 3. tương tác với các hợp đồng khác + # Nếu các giai đoạn này bị trộn lẫn, hợp đồng khác có thể gọi + # lại vào hợp đồng hiện tại và sửa đổi trạng thái hoặc gây ra + # các hiệu ứng (thanh toán ether) được thực hiện nhiều lần. + # Nếu các hàm được gọi trong nội bộ bao gồm tương tác với các hợp đồng + # bên ngoài, chúng cũng phải được coi là tương tác với + # các hợp đồng bên ngoài. + + # 1. Điều kiện + # Kiểm tra xem thời gian kết thúc đấu giá đã đến chưa + assert block.timestamp >= self.auctionEnd + # Kiểm tra xem hàm này đã được gọi chưa + assert not self.ended + + # 2. Tác động + self.ended = True + + # 3. Tương tác + send(self.beneficiary, self.highestBid) +``` + +Ví dụ trên sẽ cho bạn biết cú pháp của hợp đồng được viết bằng Vyper là như thế nào. Để có mô tả chi tiết hơn về các hàm và biến, [xem tài liệu](https://vyper.readthedocs.io/en/latest/vyper-by-example.html#simple-open-auction). + +## Yul và Yul+ {#yul} + +Nếu bạn mới tiếp cận Ethereum và chưa thực hiện bất kỳ đoạn mã nào với các ngôn ngữ lập trình hợp đồng thông minh, chúng tôi khuyên bạn nên bắt đầu với Solidity hoặc Vyper. Bạn chỉ nên tìm hiểu Yul hoặc Yul+ khi bạn đã quen thuộc với các kỹ thuật tốt nhất về bảo mật hợp đồng thông minh và các chi tiết công việc với Máy ảo Ethereum. + +**Yul** + +- Là ngôn ngữ trung gian cho Ethereum. +- Hỗ trợ [Máy ảo Ethereum (EVM)](/developers/docs/evm) và [Ewasm](https://github.com/ewasm), một WebAssembly đặc trưng của Ethereum, và được thiết kế để trở thành một mẫu số chung có thể sử dụng được của cả hai nền tảng. +- Mục tiêu tốt cho các giai đoạn tối ưu hóa cấp cao, có thể mang lại lợi ích ngang nhau cho cả hai nền tảng Máy ảo Ethereum và Ewasm. + +**Yul+** + +- Ngôn ngữ bậc thấp, có các tiện ích mở rộng hiệu quả hơn Yul. +- Ban đầu được thiết kế cho một hợp đồng [gộp giao dịch lạc quan](/developers/docs/scaling/optimistic-rollups/). +- Yul+ có thể được xem là một đề xuất nâng cấp thử nghiệm cho Yul với việc bổ sung các tính năng mới. + +### Các liên kết quan trọng {#important-links-2} + +- [Tài liệu Yul](https://docs.soliditylang.org/en/latest/yul.html) +- [Tài liệu Yul+](https://github.com/fuellabs/yulp) +- [Bài viết giới thiệu Yul+](https://medium.com/@fuellabs/introducing-yul-a-new-low-level-language-for-ethereum-aa64ce89512f) + +### Hợp đồng mẫu {#example-contract-2} + +Ví dụ đơn giản sau đây thực hiện một hàm lũy thừa. Nó có thể được biên dịch bằng `solc --strict-assembly --bin input.yul`. Ví dụ này nên được đặt trong thư mục input.yul. + +``` +{ + function power(base, exponent) -> result + { + switch exponent + case 0 { result := 1 } + case 1 { result := base } + default + { + result := power(mul(base, base), div(exponent, 2)) + if mod(exponent, 2) { result := mul(base, result) } + } + } + let res := power(calldataload(0), calldataload(32)) + mstore(0, res) + return(0, 32) +} +``` + +Nếu bạn đã có nhiều kinh nghiệm với các hợp đồng thông minh, bạn có thể tìm thấy một bản triển khai ERC20 đầy đủ bằng Yul [tại đây](https://solidity.readthedocs.io/en/latest/yul.html#complete-erc20-example). + +## Fe {#fe} + +- Là ngôn ngữ nhập tĩnh cho Máy ảo Ethereum (EVM). +- Được lấy cảm hứng từ Python và Rust. +- Dễ học - kể cả với những lập trình viên mới tiếp cận hệ sinh thái Ethereum. +- Quá trình phát triển Fe vẫn đang ở giai đoạn đầu với bản phát hành alpha được công bố vào 01/2021. + +### Các liên kết quan trọng {#important-links-3} + +- [GitHub](https://github.com/ethereum/fe) +- [Thông báo về Fe](https://snakecharmers.ethereum.org/fe-a-new-language-for-the-ethereum-ecosystem/) +- [Lộ trình Fe 2021](https://notes.ethereum.org/LVhaTF30SJOpkbG1iVw1jg) +- [Trò chuyện Fe trên Discord](https://discord.com/invite/ywpkAXFjZH) +- [Twitter của Fe](https://twitter.com/official_fe) + +### Hợp đồng mẫu {#example-contract-3} + +Dưới đây là một hợp đồng đơn giản được triển khai bằng Fe. + +``` +type BookMsg = bytes[100] + +contract GuestBook: + pub guest_book: map + + event Signed: + book_msg: BookMsg + + pub def sign(book_msg: BookMsg): + self.guest_book[msg.sender] = book_msg + + emit Signed(book_msg=book_msg) + + pub def get_msg(addr: address) -> BookMsg: + return self.guest_book[addr].to_mem() + +``` + +## Cách lựa chọn {#how-to-choose} + +Như những ngôn ngữ lập trình khác, điều này tùy thuộc vào sở thích cá nhân cũng như việc chọn đúng ngôn ngữ để phù hợp với nhu cầu công việc đó. + +Dưới đây là một vài gợi ý mà bạn có thể cân nhắc nếu bạn chưa từng thử lập trình một ngôn ngữ nào trước đây: + +### Thế mạnh của Solidity? {#solidity-advantages} + +- Có nhiều tài liệu hướng dẫn và các bộ công cụ học tập dành cho người mới bắt đầu. Xem thêm về điều đó trong phần [Học bằng cách viết mã](/developers/learning-tools/). +- Có sẵn các công cụ phát triển ổn định. +- Solidity có một cộng đồng các nhà phát triển lớp mạnh, điều đó có nghĩa là bạn sẽ luôn tìm được hầu hết các câu trả lời về những vấn đề của bạn một cách nhanh chóng. + +### Thế mạnh của Vyper? {#vyper-advatages} + +- Một cách tuyệt vời để bắt đầu cho những lập trình viên Python muốn xây dựng hợp đồng thông minh. +- Vyper có ít tính năng hơn vì thế phù hợp cho việc phác thảo nhanh các mẫu ý tưởng. +- Vyper nhắm đến việc đơn giản hóa việc kiểm định và giúp con người có thể hiểu được ở mức tối đa. + +### Thế mạnh của Yul và Yul+? {#yul-advantages} + +- Ngôn ngữ cấp thấp đơn giản. +- Cho phép tiếp cận gần hơn đến phần gốc Máy ảo Ethereum, giúp tối ưu hóa việc sử dụng gas trong các hợp đồng của bạn. + +## So sánh các ngôn ngữ {#language-comparisons} + +Để so sánh cú pháp cơ bản, vòng đời hợp đồng, giao diện, toán tử, cấu trúc dữ liệu, hàm, luồng điều khiển và hơn thế nữa, hãy xem [bảng tính nhanh của Auditless](https://reference.auditless.com/cheatsheet/). + +## Đọc thêm {#further-reading} + +- [Thư viện Hợp đồng Solidity của OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/) +- [Solidity qua ví dụ](https://solidity-by-example.org) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/libraries/index.md b/public/content/translations/vi/developers/docs/smart-contracts/libraries/index.md new file mode 100644 index 00000000000..52a79506f1a --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/libraries/index.md @@ -0,0 +1,117 @@ +--- +title: "Các thư viện hợp đồng thông minh" +description: "Khám phá các thư viện hợp đồng thông minh có thể tái sử dụng và phát triển khối để tăng tốc độ phát triển dự án Ethereum của bạn." +lang: vi +--- + +Bạn không cần phải viết mọi hợp đồng thông minh trong dự án của mình ngay từ đầu. Có rất nhiều thư viện hợp đồng thông minh mã nguồn mở cung cấp các khối xây dựng có thể tái sử dụng cho dự án của bạn, điều này sẽ giúp bạn không cần phải tạo lại những thứ sẵn có. + +## Điều kiện tiên quyết {#prerequisites} + +Trước khi đến với các thư viện hợp đồng thông minh, tốt hơn là bạn nên hiểu rõ cấu trúc của một hợp đồng thông minh. Hãy chuyển đến [cấu trúc hợp đồng thông minh](/developers/docs/smart-contracts/anatomy/) nếu bạn chưa thực hiện. + +## Thư viện có những gì {#whats-in-a-library} + +Bạn có thể thường tìm kiếm hai loại khối xây dựng trong thư viện hợp đồng thông minh: các hành vi tái sử dụng (các hàm được định nghĩa trong một lớp) mà bạn có thể thêm vào hợp đồng, và triển khai nhiều tiêu chuẩn khác nhau. + +### Các hành vi {#behaviors} + +Khi viết hợp đồng thông minh, rất có thể bạn sẽ thấy mình viết đi viết lại các mẫu tương tự, như chỉ định một địa chỉ _admin_ để thực hiện các hoạt động được bảo vệ trong một hợp đồng, hoặc thêm nút _tạm dừng_ khẩn cấp trong trường hợp xảy ra sự cố không mong muốn. + +Các thư viện hợp đồng thông minh thường cung cấp các triển khai có thể tái sử dụng của các hành vi này dưới dạng [thư viện](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#libraries) hoặc thông qua [kế thừa](https://solidity.readthedocs.io/en/v0.7.2/contracts.html#inheritance) trong Solidity. + +Ví dụ: sau đây là phiên bản đơn giản hóa của [hợp đồng `Ownable`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.2.0/contracts/access/Ownable.sol) từ [thư viện Hợp đồng OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts), hợp đồng này chỉ định một địa chỉ làm chủ sở hữu hợp đồng và cung cấp một bổ từ để hạn chế quyền truy cập vào một phương thức chỉ dành cho chủ sở hữu đó. + +```solidity +contract Ownable { + address public owner; + + constructor() internal { + owner = msg.sender; + } + + modifier onlyOwner() { + require(owner == msg.sender, "Ownable: người gọi không phải là chủ sở hữu"); + _; + } +} +``` + +Để sử dụng một khối xây dựng như thế này trong hợp đồng của bạn, bạn sẽ cần khai báo khối đó trước tiên, và sau đó mở rộng nó trong hợp đồng của chính bạn. Điều này sẽ cho phép bạn sử dụng bổ từ do hợp đồng `Ownable` cơ sở cung cấp để bảo mật các hàm của riêng bạn. + +```solidity +import ".../Ownable.sol"; // Đường dẫn đến thư viện đã nhập + +contract MyContract is Ownable { + // Hàm sau chỉ có thể được gọi bởi chủ sở hữu + function secured() onlyOwner public { + msg.sender.transfer(1 ether); + } +} +``` + +Một ví dụ phổ biến khác là [SafeMath](https://docs.openzeppelin.com/contracts/3.x/utilities#math) hoặc [DsMath](https://dappsys.readthedocs.io/en/latest/ds_math.html). Đây là những thư viện (trái ngược lại với các hợp đồng gốc) cung cấp các hàm toán học với với kiểm tra Overflow, không được cung cấp bằng ngôn ngữ. Đây là một cách tốt để thực hành khi sử dụng một trong hai thư viện này thay vì các toán tử cơ bản để bảo vệ hợp đồng của bạn khỏi Overflow, điều này có thể gây ra những hậu quả khó lường! + +### Các tiêu chuẩn {#standards} + +Để tạo điều kiện thuận lợi cho [tính khả hợp và khả năng tương tác](/developers/docs/smart-contracts/composability/), cộng đồng Ethereum đã xác định một số tiêu chuẩn dưới dạng **ERCs**. Bạn có thể đọc thêm về chúng trong phần [tiêu chuẩn](/developers/docs/standards/). + +Khi bao gồm ERC như một phần của các hợp đồng của bạn, tốt hơn là bạn nên tìm kiếm các triển khai tiêu chuẩn thay vì cố gắng tự tạo của riêng mình. Nhiều thư viện hợp đồng thông minh bao gồm các triển khai cho các ERC phổ biến nhất. Ví dụ: [tiêu chuẩn token có thể thay thế ERC20](/developers/tutorials/understand-the-erc-20-token-smart-contract/) phổ biến có thể được tìm thấy trong [HQ20](https://github.com/HQ20/contracts/blob/master/contracts/token/README.md), [DappSys](https://github.com/dapphub/ds-token/) và [OpenZeppelin](https://docs.openzeppelin.com/contracts/3.x/erc20). Ngoài ra, một vài ERC cũng cung cấp các triển khai chuẩn như một phần của chính bản thân ERC. + +Một điều đáng chú ý đó là một vài ERC không độc lập mà nó là phần bổ sung của các ERC khác. Ví dụ: [ERC2612](https://eips.ethereum.org/EIPS/eip-2612) thêm một tiện ích mở rộng vào ERC20 để cải thiện khả năng sử dụng của nó. + +## Cách thêm thư viện {#how-to} + +Hãy luôn tham khảo tài liệu của thư viện mà bạn đang sử dụng để đọc những hướng dẫn cụ thể về cách đưa thư viện đó vào dự án của bạn. Một số thư viện hợp đồng Solidity được đóng gói bằng `npm`, vì vậy bạn chỉ cần `npm install` chúng. Hầu hết các công cụ để [biên dịch](/developers/docs/smart-contracts/compiling/) hợp đồng sẽ tìm trong `node_modules` của bạn để tìm các thư viện hợp đồng thông minh, vì vậy bạn có thể làm như sau: + +```solidity +// Thao tác này sẽ tải thư viện @openzeppelin/contracts từ node_modules của bạn +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; + +contract MyNFT is ERC721 { + constructor() ERC721("MyNFT", "MNFT") public { } +} +``` + +Bất kể bạn sử dụng phương pháp nào, khi đưa vào một thư viện, hãy luôn để mắt đến phiên bản [ngôn ngữ](/developers/docs/smart-contracts/languages/). Ví dụ, bạn có thể không sử dụng được một thư viện cho Solidity 0.6 nếu bạn đang lập trình hợp đồng của bạn bằng Solidity 0.5. + +## Khi nào nên sử dụng {#when-to-use} + +Sử dụng một thư viện hợp đồng thông minh cho dự án của bạn sẽ mang đến nhiều lợi ích. Đầu tiên và quan trọng nhất, nó sẽ tiết kiệm thời gian cho bạn bằng việc cung cấp các khối xây dựng sẵn sàng sử dụng mà bạn có thể sử dụng trong hệ thống của bạn hơn là tự viết mã cho chúng. + +Bảo mật cũng là một điểm cộng lớn. Các thư viện hợp đồng thông minh mã nguồn mở thường được kiểm tra rất kỹ. Với nhiều dự án phụ thuộc vào chúng, cộng đồng có động lực mạnh mẽ để giữ cho các thư viện ấy luôn được kiểm tra liên tục. Việc tìm các lỗi trong đoạn mã của ứng dụng phổ biến hơn là tìm trong các thư viện hợp đồng tái sử dụng. Một số thư viện cũng trải qua [kiểm toán bên ngoài](https://github.com/OpenZeppelin/openzeppelin-contracts/tree/master/audits) để tăng cường bảo mật. + +Tuy nhiên, sử dụng các thư viện hợp đồng thông minh mang đến rủi ro khi chúng sẽ đưa các đoạn mã mà bạn không quen thuộc vào dự án của bạn. Sẽ rất tuyệt khi thêm một hợp đồng và sử dụng nó trực tiếp vào trong dự án của bạn, nhưng nếu không rõ chức năng của hợp đồng đó, bạn có thể vô tình gây ra sự cố trong hệ thống của mình do một hành vi mà bạn không ngờ đến. Hãy luôn chắc chắn là mình đã đọc các tài liệu tham khảo của những đoạn mã mà bạn thêm vào, và sau đó xem xét đoạn mã đó trước khi biến nó thành một phần của dự án! + +Cuối cùng, khi quyết định có sử dụng một thư viện hay không, hãy cân nhắc đến tổng thể sử dụng của nó. Một thư viện được áp dụng rộng rãi có lợi ích là sở hữu một cộng đồng lớn mạnh và có nhiều lập trình viên luôn kiểm tra các vấn đề của nó. Bảo mật nên là trọng tâm chính của bạn khi xây dựng hợp đồng thông minh! + +## Các công cụ liên quan {#related-tools} + +**OpenZeppelin Contracts -** **_Thư viện phổ biến nhất để phát triển hợp đồng thông minh bảo mật._** + +- [Tài liệu](https://docs.openzeppelin.com/contracts/) +- [GitHub](https://github.com/OpenZeppelin/openzeppelin-contracts) +- [Diễn đàn cộng đồng](https://forum.openzeppelin.com/c/general/16) + +**DappSys -** **_Các khối xây dựng an toàn, đơn giản, linh hoạt cho các hợp đồng thông minh._** + +- [Tài liệu](https://dappsys.readthedocs.io/) +- [GitHub](https://github.com/dapphub/dappsys) + +**HQ20 -** **_Một dự án Solidity với các hợp đồng, thư viện và ví dụ để giúp bạn xây dựng các ứng dụng phân tán đầy đủ tính năng cho thế giới thực._** + +- [GitHub](https://github.com/HQ20/contracts) + +**thirdweb Solidity SDK -** **_Cung cấp các công cụ cần thiết để xây dựng các hợp đồng thông minh tùy chỉnh một cách hiệu quả._** + +- [Tài liệu](https://portal.thirdweb.com/contracts/build/overview) +- [GitHub](https://github.com/thirdweb-dev/contracts) + +## Các hướng dẫn liên quan {#related-tutorials} + +- [Những lưu ý về bảo mật cho các nhà phát triển Ethereum](/developers/docs/smart-contracts/security/) _– Hướng dẫn về các lưu ý bảo mật khi xây dựng hợp đồng thông minh, bao gồm cả việc sử dụng thư viện._ +- [Tìm hiểu về hợp đồng thông minh token ERC-20](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _-Hướng dẫn về tiêu chuẩn ERC20, được cung cấp bởi nhiều thư viện._ + +## Đọc thêm {#further-reading} + +_Biết về nguồn lực cộng đồng đã giúp đỡ bạn? Chỉnh sửa trang này và bổ sung!_ diff --git a/public/content/translations/vi/developers/docs/smart-contracts/naming/index.md b/public/content/translations/vi/developers/docs/smart-contracts/naming/index.md new file mode 100644 index 00000000000..f93a2f68a73 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/naming/index.md @@ -0,0 +1,101 @@ +--- +title: "Đặt tên cho hợp đồng thông minh" +description: "Các phương pháp hay nhất để đặt tên cho hợp đồng thông minh Ethereum bằng ENS" +lang: vi +--- + +Hợp đồng thông minh là nền tảng của cơ sở hạ tầng phi tập trung của Ethereum, cho phép các ứng dụng và giao thức tự trị. Nhưng ngay cả khi các khả năng của hợp đồng phát triển, người dùng và nhà phát triển vẫn dựa vào các địa chỉ thập lục phân thô để xác định và tham chiếu các hợp đồng này. + +Việc đặt tên cho các hợp đồng thông minh bằng [Dịch vụ Định danh Ethereum (ENS)](https://ens.domains/) giúp cải thiện trải nghiệm người dùng bằng cách loại bỏ các địa chỉ hợp đồng thập lục phân và giảm rủi ro từ các cuộc tấn công như đầu độc địa chỉ và tấn công giả mạo. Hướng dẫn này giải thích tại sao việc đặt tên cho hợp đồng thông minh lại quan trọng, cách thức thực hiện và các công cụ có sẵn như [Enscribe](https://www.enscribe.xyz) để đơn giản hóa quy trình và giúp các nhà phát triển áp dụng phương pháp này. + +## Tại sao nên đặt tên cho hợp đồng thông minh? {#why-name-contracts} + +### Các định danh mà con người có thể đọc được {#human-readable-identifiers} + +Thay vì tương tác với các địa chỉ hợp đồng không rõ ràng như `0x8f8e...f9e3`, các nhà phát triển và người dùng có thể sử dụng các tên mà con người có thể đọc được như `v2.myapp.eth`. Điều này giúp đơn giản hóa các tương tác với hợp đồng thông minh. + +Điều này có thể thực hiện được nhờ [Dịch vụ Định danh Ethereum](https://ens.domains/) cung cấp dịch vụ đặt tên phi tập trung cho các địa chỉ Ethereum. Điều này tương tự như cách Dịch vụ Tên Miền (DNS) cho phép người dùng internet truy cập các địa chỉ mạng bằng một tên như ethereum.org thay vì thông qua một địa chỉ IP như `104.18.176.152`. + +### Cải thiện bảo mật và độ tin cậy {#improved-security-and-trust} + +Các hợp đồng được đặt tên giúp giảm thiểu các giao dịch vô tình đến sai địa chỉ. Chúng cũng giúp người dùng xác định các hợp đồng gắn với các ứng dụng hoặc thương hiệu cụ thể. Điều này bổ sung một lớp tin cậy về mặt danh tiếng, đặc biệt khi các tên được gắn vào các tên miền mẹ nổi tiếng như `uniswap.eth`. + +Do độ dài 42 ký tự của địa chỉ Ethereum, người dùng rất khó xác định những thay đổi nhỏ trong địa chỉ, nơi một vài ký tự đã bị sửa đổi. Ví dụ: một địa chỉ như `0x58068646C148E313CB414E85d2Fe89dDc3426870` thường sẽ bị các ứng dụng dành cho người dùng như ví rút gọn thành `0x580...870`. Người dùng khó có thể nhận thấy một địa chỉ độc hại khi một vài ký tự đã bị thay đổi. + +Loại kỹ thuật này được sử dụng trong các cuộc tấn công giả mạo và đầu độc địa chỉ, nơi người dùng bị lừa tin rằng họ đang tương tác hoặc gửi tiền đến đúng địa chỉ, trong khi thực tế địa chỉ đó chỉ giống với địa chỉ chính xác nhưng không phải là một. + +Tên ENS cho ví và hợp đồng giúp bảo vệ khỏi các loại tấn công này. Giống như các cuộc tấn công giả mạo DNS, các cuộc tấn công giả mạo ENS cũng có thể được che giấu, tuy nhiên, người dùng có nhiều khả năng nhận thấy một lỗi chính tả trong tên ENS hơn là một sửa đổi nhỏ đối với một địa chỉ thập lục phân. + +### UX tốt hơn cho ví và trình khám phá {#better-ux} + +Khi một hợp đồng thông minh đã được định cấu hình bằng tên ENS, các ứng dụng như ví và trình khám phá chuỗi khối có thể hiển thị tên ENS cho các hợp đồng thông minh, thay vì các địa chỉ thập lục phân. Điều này mang lại sự nâng cao đáng kể về trải nghiệm người dùng (UX) cho người dùng. + +Ví dụ: khi tương tác với một ứng dụng như Uniswap, người dùng thường sẽ thấy rằng ứng dụng họ đang tương tác được lưu trữ trên trang web `uniswap.org`, nhưng họ sẽ được hiển thị một địa chỉ hợp đồng thập lục phân nếu Uniswap chưa đặt tên cho các hợp đồng thông minh của họ bằng ENS. Nếu hợp đồng được đặt tên, thay vào đó, họ có thể thấy `v4.contracts.uniswap.eth` hữu ích hơn nhiều. + +## Đặt tên tại thời điểm triển khai so với sau khi triển khai {#when-to-name} + +Có hai thời điểm có thể đặt tên cho hợp đồng thông minh: + +- **Tại thời điểm triển khai**: gán một tên ENS cho hợp đồng khi nó được triển khai. +- **Sau khi triển khai**: ánh xạ một địa chỉ hợp đồng hiện có với một tên ENS mới. + +Cả hai phương pháp đều dựa vào việc có quyền sở hữu hoặc quản lý quyền truy cập vào một tên miền ENS để họ có thể tạo và thiết lập các bản ghi ENS. + +## Cách hoạt động của việc đặt tên ENS cho các hợp đồng {#how-ens-naming-works} + +Các tên ENS được lưu trữ trên chuỗi và phân giải thành các địa chỉ Ethereum thông qua các trình phân giải ENS. Để đặt tên cho một hợp đồng thông minh: + +1. Đăng ký hoặc kiểm soát một tên miền ENS mẹ (ví dụ: `myapp.eth`) +2. Tạo một tên miền phụ (ví dụ: `v1.myapp.eth`) +3. Thiết lập bản ghi `địa chỉ` của tên miền phụ thành địa chỉ hợp đồng +4. Thiết lập bản ghi ngược của hợp đồng thành ENS để cho phép tìm thấy tên thông qua địa chỉ của nó + +Các tên ENS có cấu trúc phân cấp và hỗ trợ không giới hạn tên phụ. Việc thiết lập các bản ghi này thường bao gồm việc tương tác với sổ đăng ký ENS và các hợp đồng trình phân giải công khai. + +## Công cụ để đặt tên cho hợp đồng {#tools} + +Có hai phương pháp để đặt tên cho hợp đồng thông minh. Sử dụng [Ứng dụng ENS](https://app.ens.domains) với một số bước thủ công hoặc sử dụng [Enscribe](https://www.enscribe.xyz). Những điều này được nêu dưới đây. + +### Thiết lập ENS thủ công {#manual-ens-setup} + +Sử dụng [Ứng dụng ENS](https://app.ens.domains/), các nhà phát triển có thể tạo các tên phụ theo cách thủ công và thiết lập các bản ghi địa chỉ chuyển tiếp. Tuy nhiên, họ không thể thiết lập một tên chính cho một hợp đồng thông minh bằng cách thiết lập bản ghi ngược cho tên đó thông qua ứng dụng ENS. Phải thực hiện các bước thủ công được đề cập trong [tài liệu ENS](https://docs.ens.domains/web/naming-contracts/). + +### Enscribe {#enscribe} + +[Enscribe](https://www.enscribe.xyz) đơn giản hóa việc đặt tên hợp đồng thông minh bằng ENS và nâng cao niềm tin của người dùng vào các hợp đồng thông minh. Nó cung cấp: + +- **Triển khai và đặt tên nguyên tử**: Gán một tên ENS khi triển khai một hợp đồng mới +- **Đặt tên sau triển khai**: Gắn tên cho các hợp đồng đã được triển khai +- **Hỗ trợ đa chuỗi**: Hoạt động trên Ethereum và các mạng L2 nơi ENS được hỗ trợ +- **Dữ liệu xác minh hợp đồng**: Bao gồm dữ liệu xác minh hợp đồng được lấy từ nhiều nguồn để tăng cường niềm tin cho người dùng + +Enscribe hỗ trợ các tên ENS do người dùng cung cấp hoặc các tên miền riêng của nó nếu người dùng không có tên ENS. + +Bạn có thể truy cập [Ứng dụng Enscribe](https://app.enscribe.xyz) để bắt đầu đặt tên và xem các hợp đồng thông minh. + +## Các phương pháp tốt nhất {#best-practices} + +- **Sử dụng các tên rõ ràng, có phiên bản** như `v1.myapp.eth` để làm cho việc nâng cấp hợp đồng trở nên minh bạch +- **Thiết lập bản ghi ngược** để liên kết hợp đồng với tên ENS nhằm đảm bảo khả năng hiển thị trong các ứng dụng như ví và trình khám phá chuỗi khối. +- **Theo dõi ngày hết hạn một cách chặt chẽ** nếu bạn muốn ngăn chặn những thay đổi vô tình về quyền sở hữu +- **Xác minh nguồn hợp đồng** để người dùng có thể tin tưởng rằng hợp đồng được đặt tên hoạt động như mong đợi + +## Rủi ro {#risks} + +Việc đặt tên cho các hợp đồng thông minh mang lại những lợi ích đáng kể cho người dùng Ethereum, tuy nhiên, chủ sở hữu các tên miền ENS phải cảnh giác trong việc quản lý chúng. Các rủi ro đáng chú ý bao gồm: + +- **Hết hạn**: Giống như tên DNS, việc đăng ký tên ENS có thời hạn hữu hạn. Do đó, điều quan trọng là chủ sở hữu phải theo dõi ngày hết hạn của tên miền và gia hạn chúng trước khi hết hạn. Cả Ứng dụng ENS và Enscribe đều cung cấp các chỉ báo trực quan cho chủ sở hữu tên miền khi sắp đến ngày hết hạn. +- **Thay đổi quyền sở hữu**: Các bản ghi ENS được biểu thị dưới dạng NFT trên Ethereum, trong đó chủ sở hữu của một tên miền `.eth` cụ thể sở hữu NFT được liên kết. Do đó, nếu một tài khoản khác nắm quyền sở hữu NFT này, chủ sở hữu mới có thể sửa đổi bất kỳ bản ghi ENS nào mà họ thấy phù hợp. + +Để giảm thiểu những rủi ro đó, tài khoản chủ sở hữu cho các tên miền cấp 2 (2LD) `.eth` nên được bảo mật thông qua ví đa chữ ký với các tên miền phụ được tạo để quản lý việc đặt tên hợp đồng. Bằng cách đó, trong trường hợp có bất kỳ thay đổi quyền sở hữu nào do vô tình hoặc độc hại ở cấp tên miền phụ, chúng có thể bị chủ sở hữu 2LD ghi đè. + +## Tương lai của việc đặt tên hợp đồng {#future} + +Việc đặt tên hợp đồng đang trở thành một phương pháp hay nhất cho việc phát triển dapp, tương tự như cách tên miền thay thế địa chỉ IP trên web. Khi nhiều cơ sở hạ tầng hơn như ví, trình khám phá và bảng điều khiển tích hợp phân giải ENS cho các hợp đồng, các hợp đồng được đặt tên sẽ cải thiện sự an toàn và giảm lỗi trên toàn hệ sinh thái. + +Bằng cách làm cho các hợp đồng thông minh dễ nhận biết và suy luận hơn, việc đặt tên giúp thu hẹp khoảng cách giữa người dùng và ứng dụng trên Ethereum, cải thiện cả sự an toàn và UX cho người dùng. + +## Đọc thêm {#further-reading} + +- [Đặt tên cho Hợp đồng thông minh bằng ENS](https://docs.ens.domains/web/naming-contracts/) +- [Đặt tên cho Hợp đồng thông minh bằng Enscribe](https://www.enscribe.xyz/docs). diff --git a/public/content/translations/vi/developers/docs/smart-contracts/security/index.md b/public/content/translations/vi/developers/docs/smart-contracts/security/index.md new file mode 100644 index 00000000000..ce14a7e0814 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/security/index.md @@ -0,0 +1,576 @@ +--- +title: "Bảo mật hợp đồng thông minh" +description: "Một tổng hợp về hướng dẫn xây dựng hợp đồng để xây dựng nên hợp đồng Ethereum thông minh và an toàn" +lang: vi +--- + +Hợp đồng thông minh cực kỳ linh hoạt và có khả năng điều khiển được một lượng lớn giá trị và số liệu, trong khi đang chạy logic bất biến dựa trên mã được triển khai trên blockchain. Cái này đã tạo ra một hệ sinh thái sôi động gồm các ứng dụng phi tập trung và đáng tin cậy, điều này mang lại rất nhiều lợi thế so với các hệ thống cũ. Chúng còn đại diện cho những cơ hội cho những kẻ tấn công ngắm đến lợi nhuận bằng cách khai thác các lỗ hổng trong hợp đồng thông minh. + +Các chuỗi khối công khai, như Ethereum, càng làm phức tạp thêm vấn đề bảo mật của các hợp đồng thông minh. Mã hợp đồng đã triển khai _thường_ không thể thay đổi để vá các lỗ hổng bảo mật, trong khi tài sản bị đánh cắp từ các hợp đồng thông minh cực kỳ khó theo dõi và hầu như không thể phục hồi do tính bất biến. + +Mặc dù các con số khác nhau, người ta ước tính rằng tổng giá trị bị đánh cắp hoặc mất mát do các khiếm khuyết bảo mật trong hợp đồng thông minh đã dễ dàng vượt qua 1 tỷ đô la. Điều này bao gồm các sự cố nổi tiếng, chẳng hạn như [vụ hack DAO](https://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/) (3,6 triệu ETH bị đánh cắp, trị giá hơn 1 tỷ đô la theo giá ngày nay), [vụ hack ví đa chữ ký Parity](https://www.coindesk.com/markets/2017/07/19/30-million-ether-reported-stolen-due-to-parity-wallet-breach) (mất 30 triệu đô la cho hacker) và [sự cố ví Parity bị đóng băng](https://www.theguardian.com/technology/2017/nov/08/cryptocurrency-300m-dollars-stolen-bug-ether) (hơn 300 triệu đô la ETH bị khóa vĩnh viễn). + +Các vấn đề nói trên khiến các nhà phát triển bắt buộc phải đầu tư nỗ lực vào việc xây dựng các hợp đồng thông minh an toàn, mạnh mẽ và có khả năng phục hồi. Bảo mật hợp đồng thông minh là một vấn đề nghiêm túc và mọi nhà phát triển nên học hỏi. Hướng dẫn này sẽ đề cập đến các cân nhắc về bảo mật cho các nhà phát triển Ethereum và khám phá các tài nguyên để cải thiện bảo mật hợp đồng thông minh. + +## Điều kiện tiên quyết {#prerequisites} + +Hãy chắc chắn rằng bạn đã quen thuộc với [các nguyên tắc cơ bản về phát triển hợp đồng thông minh](/developers/docs/smart-contracts/) trước khi giải quyết vấn đề bảo mật. + +## Hướng dẫn xây dựng hợp đồng thông minh Ethereum an toàn {#smart-contract-security-guidelines} + +### 1. Thiết kế các biện pháp kiểm soát truy cập phù hợp {#design-proper-access-controls} + +Trong các hợp đồng thông minh, các hàm được đánh dấu là `public` hoặc `external` có thể được gọi bởi bất kỳ tài khoản sở hữu bên ngoài (EOA) hoặc tài khoản hợp đồng nào. Việc chỉ định khả năng hiển thị công khai cho các hàm là cần thiết nếu bạn muốn người khác tương tác với hợp đồng của mình. Tuy nhiên, các hàm được đánh dấu là `private` chỉ có thể được gọi bởi các hàm trong hợp đồng thông minh, chứ không phải các tài khoản bên ngoài. Việc cấp cho mọi người tham gia mạng quyền truy cập vào các chức năng của hợp đồng có thể gây ra sự cố, đặc biệt nếu điều đó có nghĩa là bất kỳ ai cũng có thể thực hiện các hoạt động nhạy cảm (ví dụ: đúc token mới). + +Để ngăn chặn việc sử dụng trái phép các chức năng của hợp đồng thông minh, cần phải thực hiện các biện pháp kiểm soát truy cập an toàn. Cơ chế kiểm soát truy cập hạn chế khả năng sử dụng các chức năng nhất định trong hợp đồng thông minh đối với các thực thể được phê duyệt, chẳng hạn như các tài khoản chịu trách nhiệm quản lý hợp đồng. **Mô hình có thể sở hữu** và **kiểm soát dựa trên vai trò** là hai mô hình hữu ích để triển khai kiểm soát truy cập trong các hợp đồng thông minh: + +#### Mô hình có thể sở hữu {#ownable-pattern} + +Trong mô hình Có thể sở hữu, một địa chỉ được đặt làm "chủ sở hữu" của hợp đồng trong quá trình tạo hợp đồng. Các hàm được bảo vệ được gán một công cụ sửa đổi `OnlyOwner`, đảm bảo hợp đồng xác thực danh tính của địa chỉ gọi trước khi thực thi hàm. Các lệnh gọi đến các chức năng được bảo vệ từ các địa chỉ khác ngoài chủ sở hữu hợp đồng luôn được hoàn nguyên, ngăn chặn truy cập không mong muốn. + +#### Kiểm soát truy cập dựa trên vai trò {#role-based-access-control} + +Việc đăng ký một địa chỉ duy nhất với tư cách là `Owner` trong một hợp đồng thông minh sẽ có nguy cơ tập trung hóa và là một điểm lỗi duy nhất. Nếu khóa tài khoản của chủ sở hữu bị xâm phạm, kẻ tấn công có thể tấn công hợp đồng sở hữu. Đây là lý do tại sao việc sử dụng mô hình kiểm soát truy cập dựa trên vai trò với nhiều tài khoản quản trị có thể là một lựa chọn tốt hơn. + +Trong kiểm soát truy cập dựa trên vai trò, quyền truy cập vào các chức năng nhạy cảm được phân phối giữa một nhóm người tham gia đáng tin cậy. Ví dụ: một tài khoản có thể chịu trách nhiệm đúc token, trong khi một tài khoản khác thực hiện nâng cấp hoặc tạm dừng hợp đồng. Việc phân cấp quyền kiểm soát truy cập theo cách này giúp loại bỏ các điểm lỗi duy nhất và giảm các giả định về sự tin cậy cho người dùng. + +##### Sử dụng ví đa chữ ký + +Một cách tiếp cận khác để triển khai kiểm soát truy cập an toàn là sử dụng [tài khoản đa chữ ký](/developers/docs/smart-contracts/#multisig) để quản lý hợp đồng. Không giống như EOA thông thường, tài khoản đa chữ ký thuộc sở hữu của nhiều thực thể và yêu cầu chữ ký từ một số lượng tài khoản tối thiểu—ví dụ như 3 trên 5—để thực hiện giao dịch. + +Sử dụng đa chữ ký để kiểm soát truy cập sẽ tạo ra một lớp bảo mật bổ sung vì các hành động trên hợp đồng mục tiêu yêu cầu sự đồng ý của nhiều bên. Điều này đặc biệt hữu ích nếu cần sử dụng mẫu Có thể sở hữu, vì nó khiến kẻ tấn công hoặc người trong cuộc lừa đảo khó thao túng các chức năng hợp đồng nhạy cảm cho các mục đích xấu. + +### 2. Sử dụng các câu lệnh require(), assert() và revert() để bảo vệ các hoạt động của hợp đồng {#use-require-assert-revert} + +Như đã đề cập, bất kỳ ai cũng có thể gọi các chức năng công khai trong hợp đồng thông minh của bạn sau khi nó được triển khai trên chuỗi khối. Vì bạn không thể biết trước các tài khoản bên ngoài sẽ tương tác với một hợp đồng như thế nào, lý tưởng nhất là triển khai các biện pháp bảo vệ nội bộ chống lại các hoạt động có vấn đề trước khi triển khai. Bạn có thể thực thi hành vi chính xác trong các hợp đồng thông minh bằng cách sử dụng các câu lệnh `require()`, `assert()` và `revert()` để kích hoạt các ngoại lệ và hoàn nguyên các thay đổi trạng thái nếu việc thực thi không đáp ứng các yêu cầu nhất định. + +**`require()`**: `require` được định nghĩa ở đầu các hàm và đảm bảo các điều kiện được xác định trước được đáp ứng trước khi hàm được gọi được thực thi. Câu lệnh `require` có thể được sử dụng để xác thực đầu vào của người dùng, kiểm tra các biến trạng thái hoặc xác thực danh tính của tài khoản gọi trước khi tiếp tục với một hàm. + +**`assert()`**: `assert()` được sử dụng để phát hiện các lỗi nội bộ và kiểm tra các vi phạm "bất biến" trong mã của bạn. Một bất biến là một khẳng định logic về trạng thái của một hợp đồng phải luôn đúng cho tất cả các lần thực thi hàm. Một ví dụ về bất biến là tổng cung tối đa hoặc số dư của một hợp đồng token. Việc sử dụng `assert()` đảm bảo rằng hợp đồng của bạn không bao giờ đạt đến trạng thái dễ bị tấn công và nếu có, tất cả các thay đổi đối với các biến trạng thái sẽ được khôi phục. + +**`revert()`**: `revert()` có thể được sử dụng trong câu lệnh if-else để kích hoạt một ngoại lệ nếu điều kiện yêu cầu không được thỏa mãn. Hợp đồng mẫu bên dưới sử dụng `revert()` để bảo vệ việc thực thi các hàm: + +``` +pragma solidity ^0.8.4; + +contract VendingMachine { + address owner; + error Unauthorized(); + function buy(uint amount) public payable { + if (amount > msg.value / 2 ether) + revert("Không cung cấp đủ Ether."); + // Thực hiện giao dịch mua. + } + function withdraw() public { + if (msg.sender != owner) + revert Unauthorized(); + + payable(msg.sender).transfer(address(this).balance); + } +} +``` + +### 3. Kiểm tra hợp đồng thông minh và xác minh tính đúng đắn của mã {#test-smart-contracts-and-verify-code-correctness} + +Tính bất biến của mã chạy trong [Máy ảo Ethereum](/developers/docs/evm/) có nghĩa là các hợp đồng thông minh đòi hỏi mức độ đánh giá chất lượng cao hơn trong giai đoạn phát triển. Kiểm tra hợp đồng của bạn một cách rộng rãi và quan sát nó để tìm bất kỳ kết quả không mong muốn nào sẽ cải thiện đáng kể tính bảo mật và bảo vệ người dùng của bạn về lâu dài. + +Phương pháp thông thường là viết các bài kiểm tra đơn vị nhỏ bằng cách sử dụng dữ liệu giả mà hợp đồng dự kiến sẽ nhận được từ người dùng. [Kiểm tra đơn vị](/developers/docs/smart-contracts/testing/#unit-testing) rất tốt để kiểm tra chức năng của một số hàm nhất định và đảm bảo hợp đồng thông minh hoạt động như mong đợi. + +Thật không may, kiểm tra đơn vị có hiệu quả tối thiểu trong việc cải thiện bảo mật hợp đồng thông minh khi được sử dụng một cách riêng lẻ. Một bài kiểm tra đơn vị có thể chứng minh một hàm thực thi đúng với dữ liệu giả, nhưng các bài kiểm tra đơn vị chỉ hiệu quả khi các bài kiểm tra đó được viết ra. Điều này gây khó khăn cho việc phát hiện các trường hợp đặc biệt bị bỏ sót và các lỗ hổng có thể phá vỡ tính an toàn của hợp đồng thông minh của bạn. + +Một cách tiếp cận tốt hơn là kết hợp kiểm tra đơn vị với kiểm tra dựa trên thuộc tính được thực hiện bằng cách sử dụng [phân tích tĩnh và động](/developers/docs/smart-contracts/testing/#static-dynamic-analysis). Phân tích tĩnh dựa trên các biểu diễn cấp thấp, chẳng hạn như [biểu đồ luồng điều khiển](https://en.wikipedia.org/wiki/Control-flow_graph) và [cây cú pháp trừu tượng](https://deepsource.io/glossary/ast/) để phân tích các trạng thái chương trình có thể đạt được và các đường thực thi. Trong khi đó, các kỹ thuật phân tích động, chẳng hạn như [kiểm tra mờ hợp đồng thông minh](https://www.cyfrin.io/blog/smart-contract-fuzzing-and-invariants-testing-foundry), thực thi mã hợp đồng với các giá trị đầu vào ngẫu nhiên để phát hiện các hoạt động vi phạm các thuộc tính bảo mật. + +[Xác minh chính thức](/developers/docs/smart-contracts/formal-verification) là một kỹ thuật khác để xác minh các thuộc tính bảo mật trong hợp đồng thông minh. Không giống như kiểm thử thông thường, xác minh chính thức có thể chứng minh một cách thuyết phục sự không có lỗi trong một hợp đồng thông minh. Điều này đạt được bằng cách tạo một đặc tả chính thức nắm bắt các thuộc tính bảo mật mong muốn và chứng minh rằng một mô hình chính thức của các hợp đồng tuân thủ đặc tả này. + +### 4. Yêu cầu đánh giá độc lập về mã của bạn {#get-independent-code-reviews} + +Sau khi thử nghiệm hợp đồng của bạn, tốt nhất là nhờ người khác kiểm tra mã nguồn để tìm bất kỳ vấn đề bảo mật nào. Thử nghiệm sẽ không phát hiện ra mọi sai sót trong hợp đồng thông minh, nhưng việc có được một đánh giá độc lập sẽ làm tăng khả năng phát hiện các lỗ hổng. + +#### Kiểm toán {#audits} + +Việc ủy thác kiểm toán hợp đồng thông minh là một cách để tiến hành đánh giá mã độc lập. Các kiểm toán viên đóng một vai trò quan trọng trong việc đảm bảo rằng các hợp đồng thông minh được bảo mật và không có các khiếm khuyết về chất lượng cũng như lỗi thiết kế. + +Điều đó nói rằng, bạn nên tránh coi kiểm toán là một viên đạn bạc. Các cuộc kiểm toán hợp đồng thông minh sẽ không phát hiện ra mọi lỗi và chủ yếu được thiết kế để cung cấp một vòng đánh giá bổ sung, có thể giúp phát hiện các vấn đề mà các nhà phát triển bỏ sót trong quá trình phát triển và thử nghiệm ban đầu. Bạn cũng nên tuân theo các phương pháp hay nhất để làm việc với các kiểm toán viên, chẳng hạn như ghi lại mã đúng cách và thêm nhận xét nội tuyến, để tối đa hóa lợi ích của việc kiểm toán hợp đồng thông minh. + +- [Mẹo và thủ thuật kiểm toán hợp đồng thông minh](https://twitter.com/tinchoabbate/status/1400170232904400897) - _@tinchoabbate_ +- [Tận dụng tối đa cuộc kiểm toán của bạn](https://inference.ag/blog/2023-08-14-tips/) - _Inference_ + +#### Tiền thưởng săn lỗi {#bug-bounties} + +Thiết lập một chương trình tiền thưởng săn lỗi là một cách tiếp cận khác để thực hiện các bài đánh giá mã bên ngoài. Tiền thưởng săn lỗi là một phần thưởng tài chính dành cho các cá nhân (thường là hacker mũ trắng) phát hiện ra các lỗ hổng trong một ứng dụng. + +Khi được sử dụng đúng cách, tiền thưởng săn lỗi sẽ khuyến khích các thành viên của cộng đồng hacker kiểm tra mã của bạn để tìm các sai sót nghiêm trọng. Một ví dụ thực tế là "lỗi tiền vô hạn" có thể cho phép kẻ tấn công tạo ra một lượng ether không giới hạn trên [Optimism](https://www.optimism.io/), một giao thức [Lớp 2](/layer-2/) chạy trên Ethereum. May mắn thay, một hacker mũ trắng đã [phát hiện ra lỗ hổng](https://www.saurik.com/optimism.html) và thông báo cho đội ngũ, [kiếm được một khoản thanh toán lớn trong quá trình này](https://cryptoslate.com/critical-bug-in-ethereum-l2-optimism-2m-bounty-paid/). + +Một chiến lược hữu ích là đặt khoản thanh toán của chương trình tiền thưởng săn lỗi tương ứng với số tiền đang bị đe dọa. Được mô tả là “[tiền thưởng săn lỗi có thể mở rộng](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7)”, cách tiếp cận này cung cấp các ưu đãi tài chính để các cá nhân tiết lộ các lỗ hổng một cách có trách nhiệm thay vì khai thác chúng. + +### 5. Tuân thủ các phương pháp hay nhất trong quá trình phát triển hợp đồng thông minh {#follow-smart-contract-development-best-practices} + +Sự tồn tại của các cuộc kiểm toán và tiền thưởng săn lỗi không miễn trừ trách nhiệm của bạn trong việc viết mã chất lượng cao. Bảo mật hợp đồng thông minh tốt bắt đầu bằng việc tuân theo các quy trình thiết kế và phát triển phù hợp: + +- Lưu trữ tất cả mã trong một hệ thống kiểm soát phiên bản, chẳng hạn như git + +- Thực hiện tất cả các sửa đổi mã thông qua các yêu cầu kéo + +- Đảm bảo các yêu cầu kéo có ít nhất một người đánh giá độc lập—nếu bạn đang làm việc một mình trong một dự án, hãy cân nhắc tìm các nhà phát triển khác và trao đổi đánh giá mã + +- Sử dụng một [môi trường phát triển](/developers/docs/frameworks/) để kiểm tra, biên dịch, triển khai các hợp đồng thông minh + +- Chạy mã của bạn qua các công cụ phân tích mã cơ bản, chẳng hạn như, [Cyfrin Aderyn](https://github.com/Cyfrin/aderyn), Mythril và Slither. Lý tưởng nhất là bạn nên làm điều này trước khi mỗi yêu cầu kéo được hợp nhất và so sánh sự khác biệt trong đầu ra + +- Đảm bảo mã của bạn biên dịch không có lỗi và trình biên dịch Solidity không phát ra cảnh báo nào + +- Ghi lại tài liệu mã của bạn đúng cách (sử dụng [NatSpec](https://solidity.readthedocs.io/en/develop/natspec-format.html)) và mô tả chi tiết về kiến trúc hợp đồng bằng ngôn ngữ dễ hiểu. Điều này sẽ giúp người khác kiểm toán và xem xét mã của bạn dễ dàng hơn. + +### 6. Thực hiện các kế hoạch phục hồi sau thảm họa mạnh mẽ {#implement-disaster-recovery-plans} + +Việc thiết kế các biện pháp kiểm soát truy cập an toàn, triển khai các công cụ sửa đổi chức năng và các đề xuất khác có thể cải thiện tính bảo mật của hợp đồng thông minh, nhưng chúng không thể loại trừ khả năng bị khai thác độc hại. Xây dựng các hợp đồng thông minh an toàn đòi hỏi phải “chuẩn bị cho thất bại” và có một kế hoạch dự phòng để ứng phó hiệu quả với các cuộc tấn công. Một kế hoạch phục hồi sau thảm họa phù hợp sẽ kết hợp một số hoặc tất cả các thành phần sau: + +#### Nâng cấp hợp đồng {#contract-upgrades} + +Mặc dù các hợp đồng thông minh của Ethereum mặc định là bất biến, nhưng có thể đạt được một mức độ biến đổi nhất định bằng cách sử dụng các mẫu nâng cấp. Việc nâng cấp hợp đồng là cần thiết trong trường hợp một sai sót nghiêm trọng khiến hợp đồng cũ của bạn không thể sử dụng được và việc triển khai logic mới là lựa chọn khả thi nhất. + +Các cơ chế nâng cấp hợp đồng hoạt động khác nhau, nhưng “mẫu ủy quyền” là một trong những phương pháp phổ biến hơn để nâng cấp các hợp đồng thông minh. [Các mẫu ủy quyền](https://www.cyfrin.io/blog/upgradeable-proxy-smart-contract-pattern) chia trạng thái và logic của một ứng dụng giữa _hai_ hợp đồng. Hợp đồng đầu tiên (được gọi là 'hợp đồng ủy quyền') lưu trữ các biến trạng thái (ví dụ: số dư của người dùng), trong khi hợp đồng thứ hai (được gọi là 'hợp đồng logic') giữ mã để thực thi các chức năng của hợp đồng. + +Các tài khoản tương tác với hợp đồng ủy quyền, hợp đồng này sẽ chuyển tất cả các lệnh gọi hàm đến hợp đồng logic bằng cách sử dụng lệnh gọi cấp thấp [`delegatecall()`](https://docs.soliditylang.org/en/v0.8.16/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries). Không giống như một lệnh gọi thông điệp thông thường, `delegatecall()` đảm bảo mã chạy tại địa chỉ của hợp đồng logic được thực thi trong ngữ cảnh của hợp đồng gọi. Điều này có nghĩa là hợp đồng logic sẽ luôn ghi vào bộ lưu trữ của proxy (thay vì bộ lưu trữ của chính nó) và các giá trị ban đầu của `msg.sender` và `msg.value` được bảo toàn. + +Việc ủy quyền các cuộc gọi đến hợp đồng logic yêu cầu lưu trữ địa chỉ của nó trong bộ nhớ của hợp đồng ủy quyền. Do đó, việc nâng cấp logic của hợp đồng chỉ là vấn đề triển khai một hợp đồng logic khác và lưu trữ địa chỉ mới trong hợp đồng ủy quyền. Vì các lệnh gọi tiếp theo đến hợp đồng proxy được tự động định tuyến đến hợp đồng logic mới, bạn sẽ “nâng cấp” hợp đồng mà không thực sự sửa đổi mã. + +[Thông tin thêm về nâng cấp hợp đồng](/developers/docs/smart-contracts/upgrading/). + +#### Dừng khẩn cấp {#emergency-stops} + +Như đã đề cập, việc kiểm toán và thử nghiệm rộng rãi không thể phát hiện ra tất cả các lỗi trong một hợp đồng thông minh. Nếu một lỗ hổng xuất hiện trong mã của bạn sau khi triển khai, việc vá nó là không thể vì bạn không thể thay đổi mã đang chạy tại địa chỉ hợp đồng. Ngoài ra, các cơ chế nâng cấp (ví dụ: các mẫu proxy) có thể mất thời gian để thực hiện (chúng thường yêu cầu sự chấp thuận từ các bên khác nhau), điều này chỉ mang lại cho kẻ tấn công nhiều thời gian hơn để gây ra nhiều thiệt hại hơn. + +Lựa chọn cuối cùng là triển khai một chức năng “dừng khẩn cấp” để chặn các cuộc gọi đến các chức năng dễ bị tấn công trong hợp đồng. Các điểm dừng khẩn cấp thường bao gồm các thành phần sau: + +1. Một biến Boolean toàn cục cho biết hợp đồng thông minh đang ở trạng thái dừng hay không. Biến này được đặt thành `false` khi thiết lập hợp đồng, nhưng sẽ trở về `true` sau khi hợp đồng bị dừng. + +2. Các hàm tham chiếu đến biến Boolean trong quá trình thực thi của chúng. Các hàm như vậy có thể truy cập được khi hợp đồng thông minh không bị dừng và trở nên không thể truy cập được khi tính năng dừng khẩn cấp được kích hoạt. + +3. Một thực thể có quyền truy cập vào chức năng dừng khẩn cấp, đặt biến Boolean thành `true`. Để ngăn chặn các hành động độc hại, các cuộc gọi đến chức năng này có thể bị hạn chế đối với một địa chỉ đáng tin cậy (ví dụ: chủ sở hữu hợp đồng). + +Khi hợp đồng kích hoạt dừng khẩn cấp, một số chức năng nhất định sẽ không thể gọi được. Điều này đạt được bằng cách bao bọc các chức năng chọn lọc trong một công cụ sửa đổi tham chiếu đến biến toàn cục. Dưới đây là [một ví dụ](https://github.com/fravoll/solidity-patterns/blob/master/EmergencyStop/EmergencyStop.sol) mô tả việc triển khai mẫu này trong các hợp đồng: + +```solidity +// Mã này chưa được kiểm toán chuyên nghiệp và không đảm bảo về tính an toàn hoặc tính đúng đắn. Tự chịu rủi ro khi sử dụng. + +contract EmergencyStop { + + bool isStopped = false; + + modifier stoppedInEmergency { + require(!isStopped); + _; + } + + modifier onlyWhenStopped { + require(isStopped); + _; + } + + modifier onlyAuthorized { + // Kiểm tra quyền của msg.sender tại đây + _; + } + + function stopContract() public onlyAuthorized { + isStopped = true; + } + + function resumeContract() public onlyAuthorized { + isStopped = false; + } + + function deposit() public payable stoppedInEmergency { + // Logic gửi tiền diễn ra ở đây + } + + function emergencyWithdraw() public onlyWhenStopped { + // Rút tiền khẩn cấp diễn ra ở đây + } +} +``` + +Ví dụ này cho thấy các tính năng cơ bản của các điểm dừng khẩn cấp: + +- `isStopped` là một Boolean đánh giá thành `false` ở đầu và `true` khi hợp đồng vào chế độ khẩn cấp. + +- Các công cụ sửa đổi chức năng `onlyWhenStopped` và `stoppedInEmergency` kiểm tra biến `isStopped`. `stoppedInEmergency` được sử dụng để kiểm soát các chức năng không thể truy cập được khi hợp đồng dễ bị tấn công (ví dụ: `deposit()`). Các cuộc gọi đến các chức năng này sẽ chỉ đơn giản là hoàn nguyên. + +`onlyWhenStopped` được sử dụng cho các chức năng có thể gọi được trong trường hợp khẩn cấp (ví dụ: `emergencyWithdraw()`). Các chức năng như vậy có thể giúp giải quyết tình huống, do đó chúng bị loại trừ khỏi danh sách “các chức năng bị hạn chế”. + +Sử dụng chức năng dừng khẩn cấp cung cấp một biện pháp ngăn chặn hiệu quả để đối phó với các lỗ hổng nghiêm trọng trong hợp đồng thông minh của bạn. Tuy nhiên, nó làm tăng nhu cầu người dùng phải tin tưởng các nhà phát triển không kích hoạt nó vì những lý do tự phục vụ. Để đạt được mục tiêu này, việc phân cấp quyền kiểm soát việc dừng khẩn cấp bằng cách tuân theo cơ chế bỏ phiếu trên chuỗi, khóa thời gian hoặc sự chấp thuận từ ví đa chữ ký là những giải pháp khả thi. + +#### Giám sát sự kiện {#event-monitoring} + +[Các sự kiện](https://docs.soliditylang.org/en/v0.8.15/contracts.html#events) cho phép bạn theo dõi các lệnh gọi đến các chức năng của hợp đồng thông minh và giám sát các thay đổi đối với các biến trạng thái. Lý tưởng nhất là lập trình hợp đồng thông minh của bạn để phát ra một sự kiện bất cứ khi nào một bên nào đó thực hiện một hành động quan trọng về mặt an toàn (ví dụ: rút tiền). + +Việc ghi nhật ký các sự kiện và giám sát chúng ngoài chuỗi cung cấp thông tin chi tiết về các hoạt động của hợp đồng và hỗ trợ phát hiện các hành động độc hại nhanh hơn. Điều này có nghĩa là nhóm của bạn có thể phản ứng nhanh hơn với các vụ tấn công và thực hiện hành động để giảm thiểu tác động đến người dùng, chẳng hạn như tạm dừng các chức năng hoặc thực hiện nâng cấp. + +Bạn cũng có thể chọn một công cụ giám sát có sẵn tự động chuyển tiếp cảnh báo bất cứ khi nào có người tương tác với hợp đồng của bạn. Các công cụ này sẽ cho phép bạn tạo các cảnh báo tùy chỉnh dựa trên các trình kích hoạt khác nhau, chẳng hạn như khối lượng giao dịch, tần suất gọi hàm hoặc các hàm cụ thể có liên quan. Ví dụ: bạn có thể lập trình một cảnh báo xuất hiện khi số tiền rút trong một giao dịch vượt qua một ngưỡng nhất định. + +### 7. Thiết kế hệ thống quản trị an toàn {#design-secure-governance-systems} + +Bạn có thể muốn phân cấp ứng dụng của mình bằng cách chuyển quyền kiểm soát các hợp đồng thông minh cốt lõi cho các thành viên cộng đồng. Trong trường hợp này, hệ thống hợp đồng thông minh sẽ bao gồm một mô-đun quản trị—một cơ chế cho phép các thành viên cộng đồng phê duyệt các hành động quản trị thông qua một hệ thống quản trị trên chuỗi. Ví dụ, một đề xuất nâng cấp hợp đồng ủy quyền lên một triển khai mới có thể được bỏ phiếu bởi những người nắm giữ token. + +Quản trị phi tập trung có thể có lợi, đặc biệt là vì nó dung hòa lợi ích của các nhà phát triển và người dùng cuối. Tuy nhiên, các cơ chế quản trị hợp đồng thông minh có thể gây ra những rủi ro mới nếu được triển khai không chính xác. Một kịch bản hợp lý là nếu một kẻ tấn công có được quyền biểu quyết khổng lồ (được đo bằng số lượng token nắm giữ) bằng cách vay [khoản vay nhanh](/defi/#flash-loans) và thông qua một đề xuất độc hại. + +Một cách để ngăn chặn các vấn đề liên quan đến quản trị trên chuỗi là [sử dụng khóa thời gian](https://blog.openzeppelin.com/protect-your-users-with-smart-contract-timelocks/). Khóa thời gian ngăn không cho hợp đồng thông minh thực hiện một số hành động nhất định cho đến khi một khoảng thời gian cụ thể trôi qua. Các chiến lược khác bao gồm gán “trọng số biểu quyết” cho mỗi token dựa trên thời gian nó đã được khóa, hoặc đo lường quyền biểu quyết của một địa chỉ tại một thời điểm lịch sử (ví dụ: 2-3 khối trong quá khứ) thay vì khối hiện tại. Cả hai phương pháp đều làm giảm khả năng nhanh chóng tích lũy quyền biểu quyết để thay đổi các cuộc bỏ phiếu trên chuỗi. + +Thêm về [thiết kế các hệ thống quản trị an toàn](https://blog.openzeppelin.com/smart-contract-security-guidelines-4-strategies-for-safer-governance-systems/), [các cơ chế bỏ phiếu khác nhau trong các DAO](https://hackernoon.com/governance-is-the-holy-grail-for-daos) và [các vectơ tấn công DAO phổ biến tận dụng DeFi](https://dacian.me/dao-governance-defi-attacks) trong các liên kết được chia sẻ. + +### 8. Giảm độ phức tạp trong mã đến mức tối thiểu {#reduce-code-complexity} + +Các nhà phát triển phần mềm truyền thống đã quen thuộc với nguyên tắc KISS (“giữ nó đơn giản, ngu ngốc”), khuyên không nên đưa sự phức tạp không cần thiết vào thiết kế phần mềm. Điều này tuân theo suy nghĩ lâu đời rằng “các hệ thống phức tạp thất bại theo những cách phức tạp” và dễ bị lỗi tốn kém hơn. + +Giữ mọi thứ đơn giản là điều đặc biệt quan trọng khi viết các hợp đồng thông minh, vì các hợp đồng thông minh có khả năng kiểm soát một lượng lớn giá trị. Một mẹo để đạt được sự đơn giản khi viết các hợp đồng thông minh là sử dụng lại các thư viện hiện có, chẳng hạn như [Hợp đồng OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/), nếu có thể. Bởi vì các thư viện này đã được các nhà phát triển kiểm toán và thử nghiệm rộng rãi, việc sử dụng chúng sẽ làm giảm khả năng gây ra lỗi bằng cách viết chức năng mới từ đầu. + +Một lời khuyên phổ biến khác là viết các hàm nhỏ và giữ cho các hợp đồng có tính mô-đun bằng cách chia logic kinh doanh thành nhiều hợp đồng. Việc viết mã đơn giản hơn không chỉ làm giảm bề mặt tấn công trong một hợp đồng thông minh, mà còn giúp dễ dàng suy luận về tính đúng đắn của toàn bộ hệ thống và phát hiện các lỗi thiết kế có thể xảy ra sớm. + +### 9. Phòng chống các lỗ hổng hợp đồng thông minh phổ biến {#mitigate-common-smart-contract-vulnerabilities} + +#### Tái nhập {#reentrancy} + +EVM không cho phép đồng thời, nghĩa là hai hợp đồng liên quan đến một lệnh gọi thông điệp không thể chạy đồng thời. Một lệnh gọi bên ngoài sẽ tạm dừng việc thực thi và bộ nhớ của hợp đồng đang gọi cho đến khi lệnh gọi trả về, tại thời điểm đó việc thực thi sẽ tiếp tục bình thường. Quá trình này có thể được mô tả chính thức là chuyển [luồng điều khiển](https://www.computerhope.com/jargon/c/contflow.htm) sang một hợp đồng khác. + +Mặc dù hầu như vô hại, việc chuyển luồng điều khiển đến các hợp đồng không đáng tin cậy có thể gây ra các vấn đề, chẳng hạn như tái nhập. Một cuộc tấn công tái nhập xảy ra khi một hợp đồng độc hại gọi lại một hợp đồng dễ bị tấn công trước khi lệnh gọi hàm ban đầu hoàn tất. Loại tấn công này được giải thích tốt nhất bằng một ví dụ. + +Hãy xem xét một hợp đồng thông minh đơn giản ('Nạn nhân') cho phép bất kỳ ai gửi và rút ether: + +```solidity +// Hợp đồng này dễ bị tấn công. Không sử dụng trong sản xuất + +contract Victim { + mapping (address => uint256) public balances; + + function deposit() external payable { + balances[msg.sender] += msg.value; + } + + function withdraw() external { + uint256 amount = balances[msg.sender]; + (bool success, ) = msg.sender.call.value(amount)(""); + require(success); + balances[msg.sender] = 0; + } +} +``` + +Hợp đồng này hiển thị hàm `withdraw()` để cho phép người dùng rút ETH đã gửi trước đó trong hợp đồng. Khi xử lý một yêu cầu rút tiền, hợp đồng thực hiện các hoạt động sau: + +1. Kiểm tra số dư ETH của người dùng +2. Gửi tiền đến địa chỉ gọi +3. Đặt lại số dư của họ về 0, ngăn người dùng rút thêm tiền + +Hàm `withdraw()` trong hợp đồng `Victim` tuân theo mẫu “kiểm tra-tương tác-hiệu ứng”. Nó _kiểm tra_ xem các điều kiện cần thiết cho việc thực thi có được thỏa mãn không (tức là người dùng có số dư ETH dương) và thực hiện _tương tác_ bằng cách gửi ETH đến địa chỉ của người gọi, trước khi áp dụng _hiệu ứng_ của giao dịch (tức là giảm số dư của người dùng). + +Nếu `withdraw()` được gọi từ một tài khoản sở hữu bên ngoài (EOA), hàm sẽ thực thi như mong đợi: `msg.sender.call.value()` gửi ETH cho người gọi. Tuy nhiên, nếu `msg.sender` là một tài khoản hợp đồng thông minh gọi `withdraw()`, việc gửi tiền bằng `msg.sender.call.value()` cũng sẽ kích hoạt mã được lưu trữ tại địa chỉ đó để chạy. + +Hãy tưởng tượng đây là mã được triển khai tại địa chỉ hợp đồng: + +```solidity + contract Attacker { + function beginAttack() external payable { + Victim(victim_address).deposit.value(1 ether)(); + Victim(victim_address).withdraw(); + } + + function() external payable { + if (gasleft() > 40000) { + Victim(victim_address).withdraw(); + } + } +} +``` + +Hợp đồng này được thiết kế để thực hiện ba việc: + +1. Chấp nhận tiền gửi từ một tài khoản khác (có thể là EOA của kẻ tấn công) +2. Gửi 1 ETH vào hợp đồng Nạn nhân +3. Rút 1 ETH được lưu trữ trong hợp đồng thông minh + +Không có gì sai ở đây, ngoại trừ việc `Attacker` có một hàm khác gọi lại `withdraw()` trong `Victim` nếu lượng gas còn lại từ `msg.sender.call.value` đến lớn hơn 40.000. Điều này cho phép `Attacker` có khả năng tái nhập `Victim` và rút thêm tiền _trước khi_ lần gọi `withdraw` đầu tiên hoàn tất. Chu trình trông như thế này: + +```solidity +- EOA của kẻ tấn công gọi `Attacker.beginAttack()` với 1 ETH +- `Attacker.beginAttack()` gửi 1 ETH vào `Victim` +- `Attacker` gọi `withdraw()` trong `Victim` +- `Victim` kiểm tra số dư của `Attacker` (1 ETH) +- `Victim` gửi 1 ETH cho `Attacker` (kích hoạt hàm mặc định) +- `Attacker` gọi lại `Victim.withdraw()` (lưu ý rằng `Victim` chưa giảm số dư của `Attacker` từ lần rút đầu tiên) +- `Victim` kiểm tra số dư của `Attacker` (vẫn là 1 ETH vì nó chưa áp dụng hiệu ứng của lần gọi đầu tiên) +- `Victim` gửi 1 ETH cho `Attacker` (kích hoạt hàm mặc định và cho phép `Attacker` tái nhập vào hàm `withdraw`) +- Quá trình này lặp lại cho đến khi `Attacker` hết gas, tại thời điểm đó `msg.sender.call.value` trả về mà không kích hoạt thêm các lần rút tiền +- `Victim` cuối cùng áp dụng kết quả của giao dịch đầu tiên (và các giao dịch tiếp theo) vào trạng thái của nó, do đó số dư của `Attacker` được đặt về 0 +``` + +Tóm lại là vì số dư của người gọi không được đặt về 0 cho đến khi việc thực thi hàm hoàn tất, các lần gọi tiếp theo sẽ thành công và cho phép người gọi rút số dư của họ nhiều lần. Loại tấn công này có thể được sử dụng để rút cạn tiền của một hợp đồng thông minh, giống như những gì đã xảy ra trong [vụ hack DAO năm 2016](https://www.coindesk.com/learn/understanding-the-dao-attack). Các cuộc tấn công tái nhập vẫn là một vấn đề nghiêm trọng đối với các hợp đồng thông minh ngày nay như [danh sách công khai về các khai thác tái nhập](https://github.com/pcaversaccio/reentrancy-attacks) cho thấy. + +##### Làm thế nào để ngăn chặn các cuộc tấn công tái nhập + +Một cách tiếp cận để đối phó với tái nhập là tuân theo [mô hình kiểm tra-hiệu ứng-tương tác](https://docs.soliditylang.org/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern). Mẫu này sắp xếp thứ tự thực thi các hàm theo cách mà mã thực hiện các kiểm tra cần thiết trước khi tiếp tục thực thi sẽ đứng đầu, theo sau là mã thao túng trạng thái hợp đồng, với mã tương tác với các hợp đồng khác hoặc EOA sẽ đến cuối cùng. + +Mô hình kiểm tra-hiệu ứng-tương tác được sử dụng trong phiên bản sửa đổi của hợp đồng `Victim` được hiển thị bên dưới: + +```solidity +contract NoLongerAVictim { + function withdraw() external { + uint256 amount = balances[msg.sender]; + balances[msg.sender] = 0; + (bool success, ) = msg.sender.call.value(amount)(""); + require(success); + } +} +``` + +Hợp đồng này thực hiện một _kiểm tra_ số dư của người dùng, áp dụng _hiệu ứng_ của hàm `withdraw()` (bằng cách đặt lại số dư của người dùng về 0), và tiến hành thực hiện _tương tác_ (gửi ETH đến địa chỉ của người dùng). Điều này đảm bảo hợp đồng cập nhật bộ nhớ của nó trước khi thực hiện lệnh gọi bên ngoài, loại bỏ điều kiện tái nhập đã cho phép cuộc tấn công đầu tiên. Hợp đồng `Attacker` vẫn có thể gọi lại vào `NoLongerAVictim`, nhưng vì `balances[msg.sender]` đã được đặt thành 0, các lần rút tiền bổ sung sẽ gây ra lỗi. + +Một lựa chọn khác là sử dụng khóa loại trừ lẫn nhau (thường được mô tả là "mutex") để khóa một phần trạng thái của hợp đồng cho đến khi một lệnh gọi hàm hoàn tất. Điều này được thực hiện bằng cách sử dụng một biến Boolean được đặt thành `true` trước khi hàm thực thi và trở về `false` sau khi lệnh gọi hoàn tất. Như đã thấy trong ví dụ bên dưới, việc sử dụng mutex bảo vệ một hàm khỏi các lệnh gọi đệ quy trong khi lệnh gọi ban đầu vẫn đang được xử lý, ngăn chặn hiệu quả việc tái nhập. + +```solidity +pragma solidity ^0.7.0; + +contract MutexPattern { + bool locked = false; + mapping(address => uint256) public balances; + + modifier noReentrancy() { + require(!locked, "Bị chặn do tái nhập."); + locked = true; + _; + locked = false; + } + // Hàm này được bảo vệ bởi một mutex, vì vậy các lệnh gọi tái nhập từ bên trong `msg.sender.call` không thể gọi lại `withdraw`. + // Câu lệnh `return` đánh giá thành `true` nhưng vẫn đánh giá câu lệnh `locked = false` trong công cụ sửa đổi + function withdraw(uint _amount) public payable noReentrancy returns(bool) { + require(balances[msg.sender] >= _amount, "Không có số dư để rút."); + + balances[msg.sender] -= _amount; + (bool success, ) = msg.sender.call{value: _amount}(""); + require(success); + + return true; + } +} +``` + +Bạn cũng có thể sử dụng hệ thống [thanh toán kéo](https://docs.openzeppelin.com/contracts/5.x/api/security#PullPayment) yêu cầu người dùng rút tiền từ các hợp đồng thông minh, thay vì hệ thống "thanh toán đẩy" gửi tiền đến các tài khoản. Điều này loại bỏ khả năng vô tình kích hoạt mã tại các địa chỉ không xác định (và cũng có thể ngăn chặn một số cuộc tấn công từ chối dịch vụ). + +#### Tràn số và thiếu số nguyên {#integer-underflows-and-overflows} + +Tràn số nguyên xảy ra khi kết quả của một phép toán số học nằm ngoài phạm vi giá trị chấp nhận được, khiến nó "lăn" về giá trị có thể biểu diễn thấp nhất. Ví dụ, một `uint8` chỉ có thể lưu trữ các giá trị lên tới 2^8-1=255. Các phép toán số học dẫn đến các giá trị cao hơn `255` sẽ tràn và đặt lại `uint` thành `0`, tương tự như cách đồng hồ đo quãng đường trên xe hơi đặt lại về 0 khi đạt đến quãng đường tối đa (999999). + +Tràn số nguyên xảy ra vì những lý do tương tự: kết quả của một phép toán số học nằm dưới phạm vi chấp nhận được. Giả sử bạn đã cố gắng giảm `0` trong một `uint8`, kết quả sẽ chỉ đơn giản là quay trở lại giá trị có thể biểu diễn tối đa (`255`). + +Cả tràn số nguyên và thiếu số đều có thể dẫn đến những thay đổi không mong muốn đối với các biến trạng thái của hợp đồng và dẫn đến việc thực thi không theo kế hoạch. Dưới đây là một ví dụ cho thấy cách kẻ tấn công có thể khai thác tràn số học trong một hợp đồng thông minh để thực hiện một hoạt động không hợp lệ: + +``` +pragma solidity ^0.7.6; + +// Hợp đồng này được thiết kế để hoạt động như một kho tiền thời gian. +// Người dùng có thể gửi tiền vào hợp đồng này nhưng không thể rút tiền trong ít nhất một tuần. +// Người dùng cũng có thể kéo dài thời gian chờ đợi vượt quá thời gian chờ 1 tuần. + +/* +1. Triển khai TimeLock +2. Triển khai Attack với địa chỉ của TimeLock +3. Gọi Attack.attack gửi 1 ether. Bạn sẽ có thể ngay lập tức + rút ether của mình. + +Chuyện gì đã xảy ra? +Attack đã làm cho TimeLock.lockTime bị tràn và có thể rút tiền +trước thời gian chờ 1 tuần. +*/ + +contract TimeLock { + mapping(address => uint) public balances; + mapping(address => uint) public lockTime; + + function deposit() external payable { + balances[msg.sender] += msg.value; + lockTime[msg.sender] = block.timestamp + 1 weeks; + } + + function increaseLockTime(uint _secondsToIncrease) public { + lockTime[msg.sender] += _secondsToIncrease; + } + + function withdraw() public { + require(balances[msg.sender] > 0, "Không đủ tiền"); + require(block.timestamp > lockTime[msg.sender], "Thời gian khóa chưa hết hạn"); + + uint amount = balances[msg.sender]; + balances[msg.sender] = 0; + + (bool sent, ) = msg.sender.call{value: amount}(""); + require(sent, "Không gửi được Ether"); + } +} + +contract Attack { + TimeLock timeLock; + + constructor(TimeLock _timeLock) { + timeLock = TimeLock(_timeLock); + } + + fallback() external payable {} + + function attack() public payable { + timeLock.deposit{value: msg.value}(); + /* + nếu t = thời gian khóa hiện tại thì chúng ta cần tìm x sao cho + x + t = 2**256 = 0 + vậy x = -t + 2**256 = type(uint).max + 1 + vậy x = type(uint).max + 1 - t + */ + timeLock.increaseLockTime( + type(uint).max + 1 - timeLock.lockTime(address(this)) + ); + timeLock.withdraw(); + } +} +``` + +##### Làm thế nào để ngăn chặn tràn số và thiếu số nguyên + +Kể từ phiên bản 0.8.0, trình biên dịch Solidity từ chối mã dẫn đến tràn số và thiếu số nguyên. Tuy nhiên, các hợp đồng được biên dịch với phiên bản trình biên dịch thấp hơn nên thực hiện kiểm tra các hàm liên quan đến các phép toán số học hoặc sử dụng một thư viện (ví dụ: [SafeMath](https://docs.openzeppelin.com/contracts/2.x/api/math)) để kiểm tra tràn/thiếu số. + +#### Thao tác Oracle {#oracle-manipulation} + +[Oracles](/developers/docs/oracles/) lấy thông tin ngoài chuỗi và gửi nó lên chuỗi để các hợp đồng thông minh sử dụng. Với các oracle, bạn có thể thiết kế các hợp đồng thông minh tương tác với các hệ thống ngoài chuỗi, chẳng hạn như thị trường vốn, mở rộng đáng kể ứng dụng của chúng. + +Nhưng nếu oracle bị hỏng và gửi thông tin không chính xác lên chuỗi, các hợp đồng thông minh sẽ thực thi dựa trên các đầu vào sai, điều này có thể gây ra sự cố. Đây là cơ sở của “vấn đề oracle”, liên quan đến nhiệm vụ đảm bảo thông tin từ một oracle blockchain là chính xác, cập nhật và kịp thời. + +Một mối quan tâm bảo mật liên quan là sử dụng một oracle trên chuỗi, chẳng hạn như một sàn giao dịch phi tập trung, để lấy giá giao ngay cho một tài sản. Các nền tảng cho vay trong ngành [tài chính phi tập trung (DeFi)](/defi/) thường làm điều này để xác định giá trị tài sản thế chấp của người dùng để xác định số tiền họ có thể vay. + +Giá DEX thường chính xác, phần lớn là do các nhà kinh doanh chênh lệch giá khôi phục sự cân bằng trên thị trường. Tuy nhiên, chúng có thể bị thao túng, đặc biệt nếu oracle trên chuỗi tính toán giá tài sản dựa trên các mẫu giao dịch lịch sử (như thường lệ). + +Ví dụ, một kẻ tấn công có thể tăng giá giao ngay của một tài sản một cách nhân tạo bằng cách vay một khoản vay nhanh ngay trước khi tương tác với hợp đồng cho vay của bạn. Việc truy vấn DEX để biết giá của tài sản sẽ trả về một giá trị cao hơn bình thường (do “lệnh mua” lớn của kẻ tấn công làm lệch nhu cầu đối với tài sản), cho phép họ vay nhiều hơn mức họ nên vay. Các "cuộc tấn công cho vay nhanh" như vậy đã được sử dụng để khai thác sự phụ thuộc vào các oracle giá giữa các ứng dụng DeFi, khiến các giao thức thiệt hại hàng triệu đô la tiền bị mất. + +##### Làm thế nào để ngăn chặn thao tác oracle + +Yêu cầu tối thiểu để [tránh thao túng oracle](https://www.cyfrin.io/blog/price-oracle-manipultion-attacks-with-examples) là sử dụng một mạng oracle phi tập trung truy vấn thông tin từ nhiều nguồn để tránh các điểm lỗi duy nhất. Trong hầu hết các trường hợp, các oracle phi tập trung có các ưu đãi kinh tế tiền mã hóa tích hợp để khuyến khích các nút oracle báo cáo thông tin chính xác, khiến chúng an toàn hơn các oracle tập trung. + +Nếu bạn dự định truy vấn một oracle trên chuỗi để biết giá tài sản, hãy cân nhắc sử dụng một oracle triển khai cơ chế giá trung bình theo thời gian (TWAP). Một [oracle TWAP](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles) truy vấn giá của một tài sản tại hai thời điểm khác nhau (mà bạn có thể sửa đổi) và tính toán giá giao ngay dựa trên mức trung bình thu được. Việc chọn các khoảng thời gian dài hơn sẽ bảo vệ giao thức của bạn khỏi thao túng giá vì các lệnh lớn được thực hiện gần đây không thể ảnh hưởng đến giá tài sản. + +## Tài nguyên bảo mật hợp đồng thông minh cho các nhà phát triển {#smart-contract-security-resources-for-developers} + +### Các công cụ để phân tích hợp đồng thông minh và xác minh tính đúng đắn của mã {#code-analysis-tools} + +- **[Các công cụ và thư viện kiểm thử](/developers/docs/smart-contracts/testing/#testing-tools-and-libraries)** - _Bộ sưu tập các công cụ và thư viện tiêu chuẩn ngành để thực hiện các bài kiểm thử đơn vị, phân tích tĩnh và phân tích động trên các hợp đồng thông minh._ + +- **[Các công cụ xác minh chính thức](/developers/docs/smart-contracts/formal-verification/#formal-verification-tools)** - _Các công cụ để xác minh tính đúng đắn về mặt chức năng trong các hợp đồng thông minh và kiểm tra các bất biến._ + +- **[Các dịch vụ kiểm toán hợp đồng thông minh](/developers/docs/smart-contracts/testing/#smart-contract-auditing-services)** - _Danh sách các tổ chức cung cấp dịch vụ kiểm toán hợp đồng thông minh cho các dự án phát triển Ethereum._ + +- **[Các nền tảng tiền thưởng săn lỗi](/developers/docs/smart-contracts/testing/#bug-bounty-platforms)** - _Các nền tảng để phối hợp các chương trình tiền thưởng săn lỗi và thưởng cho việc tiết lộ có trách nhiệm các lỗ hổng nghiêm trọng trong các hợp đồng thông minh._ + +- **[Fork Checker](https://forkchecker.hashex.org/)** - _Một công cụ trực tuyến miễn phí để kiểm tra tất cả thông tin có sẵn về một hợp đồng được phân nhánh._ + +- **[ABI Encoder](https://abi.hashex.org/)** - _Một dịch vụ trực tuyến miễn phí để mã hóa các hàm và đối số hàm tạo của hợp đồng Solidity của bạn._ + +- **[Aderyn](https://github.com/Cyfrin/aderyn)** - _Công cụ phân tích tĩnh Solidity, duyệt qua Cây cú pháp trừu tượng (AST) để xác định các lỗ hổng đáng ngờ và in ra các vấn đề ở định dạng markdown dễ sử dụng._ + +### Các công cụ để giám sát hợp đồng thông minh {#smart-contract-monitoring-tools} + +- **[Tenderly Real-Time Alerting](https://tenderly.co/monitoring)** - _Một công cụ để nhận thông báo theo thời gian thực khi các sự kiện bất thường hoặc không mong muốn xảy ra trên các hợp đồng thông minh hoặc ví của bạn._ + +### Các công cụ để quản trị an toàn các hợp đồng thông minh {#smart-contract-administration-tools} + +- **[Safe](https://safe.global/)** - _Ví hợp đồng thông minh chạy trên Ethereum yêu cầu một số lượng người tối thiểu phải phê duyệt một giao dịch trước khi nó có thể xảy ra (M-of-N)._ + +- **[OpenZeppelin Contracts](https://docs.openzeppelin.com/contracts/5.x/)** - _Thư viện hợp đồng để triển khai các tính năng quản trị, bao gồm quyền sở hữu hợp đồng, nâng cấp, kiểm soát truy cập, quản trị, khả năng tạm dừng và hơn thế nữa._ + +### Dịch vụ kiểm toán hợp đồng thông minh {#smart-contract-auditing-services} + +- **[ConsenSys Diligence](https://diligence.consensys.io/)** - _Dịch vụ kiểm toán hợp đồng thông minh giúp các dự án trên toàn hệ sinh thái chuỗi khối đảm bảo các giao thức của họ sẵn sàng ra mắt và được xây dựng để bảo vệ người dùng._ + +- **[CertiK](https://www.certik.com/)** - _Công ty bảo mật chuỗi khối tiên phong trong việc sử dụng công nghệ Xác minh chính thức tiên tiến trên các hợp đồng thông minh và mạng chuỗi khối._ + +- **[Trail of Bits](https://www.trailofbits.com/)** - _Công ty an ninh mạng kết hợp nghiên cứu bảo mật với tâm lý của kẻ tấn công để giảm thiểu rủi ro và củng cố mã._ + +- **[PeckShield](https://peckshield.com/)** - _Công ty bảo mật chuỗi khối cung cấp các sản phẩm và dịch vụ cho sự bảo mật, quyền riêng tư và khả năng sử dụng của toàn bộ hệ sinh thái chuỗi khối._ + +- **[QuantStamp](https://quantstamp.com/)** - _Dịch vụ kiểm toán tạo điều kiện cho việc áp dụng công nghệ chuỗi khối vào xu hướng chủ đạo thông qua các dịch vụ đánh giá bảo mật và rủi ro._ + +- **[OpenZeppelin](https://www.openzeppelin.com/security-audits)** - _Công ty bảo mật hợp đồng thông minh cung cấp các cuộc kiểm toán bảo mật cho các hệ thống phân tán._ + +- **[Runtime Verification](https://runtimeverification.com/)** - _Công ty bảo mật chuyên về mô hình hóa chính thức và xác minh các hợp đồng thông minh._ + +- **[Hacken](https://hacken.io)** - _Kiểm toán viên an ninh mạng Web3 mang lại phương pháp tiếp cận 360 độ cho bảo mật chuỗi khối._ + +- **[Nethermind](https://www.nethermind.io/smart-contract-audits)** - _Các dịch vụ kiểm toán Solidity và Cairo, đảm bảo tính toàn vẹn của các hợp đồng thông minh và sự an toàn của người dùng trên Ethereum và Starknet._ + +- **[HashEx](https://hashex.org/)** - _HashEx tập trung vào kiểm toán chuỗi khối và hợp đồng thông minh để đảm bảo an ninh cho tiền mã hóa, cung cấp các dịch vụ như phát triển hợp đồng thông minh, kiểm thử thâm nhập, tư vấn chuỗi khối._ + +- **[Code4rena](https://code4rena.com/)** - _Nền tảng kiểm toán cạnh tranh khuyến khích các chuyên gia bảo mật hợp đồng thông minh tìm ra các lỗ hổng và giúp web3 trở nên an toàn hơn._ + +- **[CodeHawks](https://codehawks.com/)** - _Nền tảng kiểm toán cạnh tranh tổ chức các cuộc thi kiểm toán hợp đồng thông minh cho các nhà nghiên cứu bảo mật._ + +- **[Cyfrin](https://cyfrin.io)** - _Công ty hàng đầu về bảo mật Web3, ươm mầm bảo mật tiền mã hóa thông qua các sản phẩm và dịch vụ kiểm toán hợp đồng thông minh._ + +- **[ImmuneBytes](https://immunebytes.com/smart-contract-audit/)** - _Công ty bảo mật Web3 cung cấp các dịch vụ kiểm toán bảo mật cho các hệ thống blockchain thông qua một đội ngũ kiểm toán viên giàu kinh nghiệm và các công cụ tốt nhất._ + +- **[Oxorio](https://oxor.io/)** - _Dịch vụ kiểm toán hợp đồng thông minh và bảo mật blockchain với chuyên môn về EVM, Solidity, ZK, công nghệ chuỗi chéo cho các công ty tiền mã hóa và các dự án DeFi._ + +- **[Inference](https://inference.ag/)** - _Công ty kiểm toán bảo mật, chuyên về kiểm toán hợp đồng thông minh cho các chuỗi khối dựa trên EVM. Nhờ các kiểm toán viên chuyên gia của mình, họ xác định các vấn đề tiềm ẩn và đề xuất các giải pháp khả thi để khắc phục chúng trước khi triển khai._ + +### Các nền tảng tiền thưởng săn lỗi {#bug-bounty-platforms} + +- **[Immunefi](https://immunefi.com/)** - _Nền tảng tiền thưởng săn lỗi cho các hợp đồng thông minh và các dự án DeFi, nơi các nhà nghiên cứu bảo mật xem xét mã, tiết lộ các lỗ hổng, được trả tiền và làm cho tiền mã hóa an toàn hơn._ + +- **[HackerOne](https://www.hackerone.com/)** - _Nền tảng điều phối lỗ hổng và tiền thưởng săn lỗi kết nối các doanh nghiệp với những người kiểm thử thâm nhập và các nhà nghiên cứu an ninh mạng._ + +- **[HackenProof](https://hackenproof.com/)** - _Nền tảng tiền thưởng săn lỗi chuyên nghiệp cho các dự án tiền mã hóa (DeFi, Hợp đồng thông minh, Ví, CEX và hơn thế nữa), nơi các chuyên gia bảo mật cung cấp dịch vụ phân loại và các nhà nghiên cứu được trả tiền cho các báo cáo lỗi có liên quan, đã được xác minh._ + +- **[Sherlock](https://www.sherlock.xyz/)** - _Bảo lãnh phát hành trong Web3 cho bảo mật hợp đồng thông minh, với các khoản thanh toán cho kiểm toán viên được quản lý thông qua các hợp đồng thông minh để đảm bảo rằng các lỗi có liên quan được thanh toán một cách công bằng._ + +- **[CodeHawks](https://www.codehawks.com/)** - _Nền tảng tiền thưởng săn lỗi cạnh tranh, nơi các kiểm toán viên tham gia các cuộc thi và thử thách bảo mật, và (sắp tới) trong các cuộc kiểm toán riêng của họ._ + +### Các ấn phẩm về các lỗ hổng và khai thác hợp đồng thông minh đã biết {#common-smart-contract-vulnerabilities-and-exploits} + +- **[ConsenSys: Các cuộc tấn công đã biết trong Hợp đồng thông minh](https://consensysdiligence.github.io/smart-contract-best-practices/attacks/)** - _Giải thích thân thiện với người mới bắt đầu về các lỗ hổng hợp đồng quan trọng nhất, với mã mẫu cho hầu hết các trường hợp._ + +- **[SWC Registry](https://swcregistry.io/)** - _Danh sách được tuyển chọn các mục Liệt kê Điểm yếu Chung (CWE) áp dụng cho các hợp đồng thông minh Ethereum._ + +- **[Rekt](https://rekt.news/)** - _Ấn phẩm được cập nhật thường xuyên về các vụ tấn công và khai thác tiền mã hóa nổi tiếng, cùng với các báo cáo khám nghiệm chi tiết._ + +### Các thử thách để học bảo mật hợp đồng thông minh {#challenges-for-learning-smart-contract-security} + +- **[Awesome BlockSec CTF](https://github.com/blockthreat/blocksec-ctfs)** - _Danh sách được tuyển chọn các trò chơi chiến tranh bảo mật blockchain, các thử thách, và các cuộc thi [Capture The Flag](https://www.webopedia.com/definitions/ctf-event/amp/) và các bài viết giải pháp._ + +- **[Damn Vulnerable DeFi](https://www.damnvulnerabledefi.xyz/)** - _Trò chơi chiến tranh để học bảo mật tấn công của các hợp đồng thông minh DeFi và xây dựng kỹ năng săn lỗi và kiểm toán bảo mật._ + +- **[Ethernaut](https://ethernaut.openzeppelin.com/)** - _Trò chơi chiến tranh dựa trên Web3/Solidity, trong đó mỗi cấp độ là một hợp đồng thông minh cần phải bị 'tấn công'._ + +- **[HackenProof x HackTheBox](https://app.hackthebox.com/tracks/HackenProof-Track)** - _Thử thách hack hợp đồng thông minh, lấy bối cảnh trong một cuộc phiêu lưu giả tưởng. Việc hoàn thành thành công thử thách cũng cho phép truy cập vào một chương trình tiền thưởng săn lỗi riêng tư._ + +### Các phương pháp hay nhất để bảo mật hợp đồng thông minh {#smart-contract-security-best-practices} + +- **[ConsenSys: Các phương pháp hay nhất về bảo mật hợp đồng thông minh Ethereum](https://consensys.github.io/smart-contract-best-practices/)** - _Danh sách toàn diện các hướng dẫn để bảo mật các hợp đồng thông minh Ethereum._ + +- **[Nascent: Bộ công cụ bảo mật đơn giản](https://github.com/nascentxyz/simple-security-toolkit)** - _Bộ sưu tập các hướng dẫn và danh sách kiểm tra tập trung vào bảo mật thực tế để phát triển hợp đồng thông minh._ + +- **[Solidity Patterns](https://fravoll.github.io/solidity-patterns/)** - _Tổng hợp hữu ích các mẫu bảo mật và các phương pháp hay nhất cho ngôn ngữ lập trình hợp đồng thông minh Solidity._ + +- **[Tài liệu Solidity: Các cân nhắc về bảo mật](https://docs.soliditylang.org/en/v0.8.16/security-considerations.html)** - _Hướng dẫn viết các hợp đồng thông minh an toàn với Solidity._ + +- **[Tiêu chuẩn xác minh bảo mật hợp đồng thông minh](https://github.com/securing/SCSVS)** - _Danh sách kiểm tra mười bốn phần được tạo ra để tiêu chuẩn hóa bảo mật của các hợp đồng thông minh cho các nhà phát triển, kiến trúc sư, người đánh giá bảo mật và các nhà cung cấp._ + +- **[Học bảo mật và kiểm toán hợp đồng thông minh](https://updraft.cyfrin.io/courses/security)** - _Khóa học bảo mật và kiểm toán hợp đồng thông minh tối ưu, được tạo ra cho các nhà phát triển hợp đồng thông minh muốn nâng cao các phương pháp hay nhất về bảo mật của họ và trở thành các nhà nghiên cứu bảo mật._ + +### Hướng dẫn về bảo mật hợp đồng thông minh {#tutorials-on-smart-contract-security} + +- [Cách viết các hợp đồng thông minh an toàn](/developers/tutorials/secure-development-workflow/) + +- [Cách sử dụng Slither để tìm lỗi hợp đồng thông minh](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) + +- [Cách sử dụng Manticore để tìm lỗi hợp đồng thông minh](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) + +- [Hướng dẫn bảo mật hợp đồng thông minh](/developers/tutorials/smart-contract-security-guidelines/) + +- [Cách tích hợp an toàn hợp đồng token của bạn với các token tùy ý](/developers/tutorials/token-integration-checklist/) + +- [Cyfrin Updraft - Khóa học đầy đủ về bảo mật và kiểm toán hợp đồng thông minh](https://updraft.cyfrin.io/courses/security) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/testing/index.md b/public/content/translations/vi/developers/docs/smart-contracts/testing/index.md new file mode 100644 index 00000000000..c99a3692465 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/testing/index.md @@ -0,0 +1,310 @@ +--- +title: "Thử nghiệm hợp đồng thông minh" +description: "Tổng quan về kỹ thuật và những điều cần cân nhắc khi kiểm tra hợp đồng thông minh Ethereum." +lang: vi +--- + +Các blockchain công khai như Ethereum không thể thay đổi, nên rất khó để sửa đổi mã hợp đồng thông minh sau khi đã triển khai. [Các mẫu nâng cấp hợp đồng](/developers/docs/smart-contracts/upgrading/) để thực hiện "nâng cấp ảo" có tồn tại, nhưng chúng rất khó thực hiện và đòi hỏi sự đồng thuận của xã hội. Hơn nữa, một bản nâng cấp chỉ có thể sửa lỗi _sau khi_ nó được phát hiện—nếu kẻ tấn công phát hiện ra lỗ hổng trước, hợp đồng thông minh của bạn có nguy cơ bị khai thác. + +Vì những lý do này, việc kiểm tra các hợp đồng thông minh trước khi [triển khai](/developers/docs/smart-contracts/deploying/) lên Mạng chính là một yêu cầu tối thiểu về [bảo mật](/developers/docs/smart-contracts/security/). Có nhiều cách để kiểm tra hợp đồng và đánh giá độ chính xác của mã; thứ bạn chọn sẽ phụ thuộc vào nhu cầu của bạn. Dù sao thì, một bộ kiểm thử bao gồm nhiều công cụ và phương pháp khác nhau là lựa chọn tuyệt vời để phát hiện cả những lỗ hổng bảo mật nhỏ và lớn trong mã hợp đồng. + +## Điều kiện tiên quyết {#prerequisites} + +Trang này giải thích cách kiểm tra hợp đồng thông minh trước khi triển khai trên mạng Ethereum. Điều này giả định rằng bạn đã quen thuộc với [các hợp đồng thông minh](/developers/docs/smart-contracts/). + +## Kiểm tra hợp đồng thông minh là gì? {#what-is-smart-contract-testing} + +Kiểm tra hợp đồng thông minh là quá trình xác nhận rằng mã của hợp đồng thông minh hoạt động như mong đợi. Việc kiểm tra là cần thiết để xác minh liệu một hợp đồng thông minh cụ thể có đáp ứng các yêu cầu về độ tin cậy, tính hữu dụng và an ninh hay không. + +Mặc dù có nhiều cách tiếp cận khác nhau, nhưng hầu hết các phương pháp kiểm tra đều cần thực hiện một hợp đồng thông minh với một mẫu nhỏ dữ liệu mà nó dự kiến sẽ xử lý. Nếu hợp đồng tạo ra kết quả đúng cho dữ liệu mẫu, nó được cho là hoạt động chính xác. Hầu hết các công cụ kiểm tra cung cấp tài nguyên để viết và thực thi các [trường hợp kiểm tra](https://en.m.wikipedia.org/wiki/Test_case) để kiểm tra xem việc thực thi hợp đồng có khớp với kết quả mong đợi hay không. + +### Tại sao việc kiểm tra hợp đồng thông minh lại quan trọng? Tầm quan trọng của việc kiểm tra các hợp đồng thông minh {#importance-of-testing-smart-contracts} + +Vì các hợp đồng thông minh thường quản lý các tài sản tài chính có giá trị cao, những lỗi lập trình nhỏ có thể và thường dẫn đến [những khoản thua lỗ lớn cho người dùng](https://rekt.news/leaderboard/). Việc kiểm tra kỹ lưỡng có thể giúp bạn tìm ra lỗi và vấn đề trong mã của hợp đồng thông minh sớm hơn, từ đó sửa chữa trước khi đưa lên Mainnet. + +Mặc dù có thể nâng cấp hợp đồng nếu phát hiện lỗi, nhưng việc nâng cấp thì khá phức tạp và có thể [gây ra lỗi](https://blog.trailofbits.com/2018/09/05/contract-upgrade-anti-patterns/) nếu không được xử lý đúng cách. Việc nâng cấp một hợp đồng càng làm trái nguyên tắc không biến đổi và đặt thêm gánh nặng về niềm tin lên người dùng. Ngược lại, một kế hoạch toàn diện để thử nghiệm hợp đồng của bạn giảm thiểu rủi ro bảo mật hợp đồng thông minh và giảm nhu cầu thực hiện các nâng cấp logic phức tạp sau khi triển khai. + +## Các phương pháp kiểm tra hợp đồng thông minh {#methods-for-testing-smart-contracts} + +Các phương pháp kiểm tra hợp đồng thông minh của Ethereum được chia thành hai loại chính: **kiểm tra tự động** và **kiểm tra thủ công**. Kiểm thử tự động và kiểm thử thủ công đều mang lại những lợi ích và hạn chế riêng, nhưng bạn có thể kết hợp cả hai để tạo ra một kế hoạch vững chắc trong việc phân tích các hợp đồng thông minh của mình. + +### Kiểm tra tự động {#automated-testing} + +Kiểm thử tự động sử dụng các công cụ để tự động kiểm tra mã hợp đồng thông minh nhằm phát hiện lỗi trong quá trình thực thi. Lợi ích của việc kiểm tra tự động đến từ việc sử dụng [các tập lệnh](https://www.techtarget.com/whatis/definition/script?amp=1) để hướng dẫn đánh giá các chức năng của hợp đồng. Các bài kiểm thử theo kịch bản có thể được lập lịch để chạy nhiều lần với sự can thiệp của con người tối thiểu, khiến kiểm thử tự động hiệu quả hơn so với các phương pháp kiểm thử thủ công. + +Kiểm thử tự động đặc biệt hữu ích khi các bài kiểm thử lặp đi lặp lại và tốn nhiều thời gian; khó thực hiện thủ công; dễ bị lỗi do con người; hoặc liên quan đến việc đánh giá các chức năng quan trọng của hợp đồng thông minh. Nhưng các công cụ kiểm tra tự động có thể có những nhược điểm—chúng có thể bỏ lỡ một số lỗi nhất định và tạo ra nhiều [kết quả dương tính giả](https://www.contrastsecurity.com/glossary/false-positive). Do đó, việc kết hợp kiểm thử tự động với kiểm thử thủ công cho hợp đồng thông minh là lý tưởng. + +### Kiểm tra thủ công {#manual-testing} + +Kiểm thử thủ công có sự hỗ trợ của con người và bao gồm việc thực hiện từng trường hợp kiểm thử trong bộ kiểm thử của bạn lần lượt, nhằm phân tích độ chính xác của hợp đồng thông minh. Điều này khác với kiểm thử tự động, nơi bạn có thể chạy đồng thời nhiều bài kiểm thử tách biệt trên một hợp đồng thông minh và nhận được báo cáo hiển thị tất cả các bài kiểm thử thành công và thất bại. + +Kiểm thử thủ công có thể được thực hiện bởi một cá nhân theo một kế hoạch kiểm thử đã được viết sẵn, bao quát các kịch bản kiểm thử khác nhau. Bạn cũng có thể để nhiều cá nhân hoặc nhóm tương tác với một hợp đồng thông minh trong một khoảng thời gian xác định như một phần của kiểm thử thủ công. Người kiểm thử sẽ so sánh hành vi thực tế của hợp đồng thông minh với hành vi dự kiến, và đánh dấu bất kỳ khác biệt nào là lỗi. + +Kiểm thử thủ công hiệu quả đòi hỏi nguồn lực đáng kể (kỹ năng, thời gian, tiền bạc và công sức), và do lỗi con người, việc bỏ sót một số lỗi trong quá trình thực hiện kiểm thử là điều có thể xảy ra. Nhưng việc kiểm tra thủ công cũng có lợi đó—ví dụ như một người kiểm tra (như một kiểm toán viên) có thể dùng trực giác để phát hiện những trường hợp đặc biệt mà công cụ kiểm tra tự động có thể bỏ lỡ. + +## Kiểm tra tự động cho các hợp đồng thông minh {#automated-testing-for-smart-contracts} + +### Kiểm tra đơn vị {#unit-testing-for-smart-contracts} + +Kiểm thử đơn vị đánh giá các hàm hợp đồng một cách riêng biệt và kiểm tra rằng từng thành phần hoạt động chính xác. Các bài kiểm thử đơn vị tốt nên đơn giản, nhanh chóng để chạy và cung cấp một ý tưởng rõ ràng về những gì đã sai nếu các bài kiểm tra không thành công. + +Các bài kiểm thử đơn vị rất hữu ích để kiểm tra rằng các hàm trả về giá trị như mong đợi và rằng việc lưu trữ hợp đồng được cập nhật đúng sau khi thực thi hàm hay không. Hơn nữa, việc chạy các bài kiểm thử đơn vị sau khi thực hiện thay đổi trong mã nguồn hợp đồng đảm bảo rằng việc thêm logic mới không gây ra lỗi. Dưới đây là một số hướng dẫn để thực hiện các bài kiểm thử đơn vị hiệu quả: + +#### Hướng dẫn kiểm tra đơn vị cho các hợp đồng thông minh {#unit-testing-guidelines} + +##### 1. Hiểu rõ quy trình và logic kinh doanh trong hợp đồng của bạn + +Trước khi viết bài kiểm tra đơn vị, nó sẽ giúp việc biết được hợp đồng thông minh cung cấp những chức năng gì và người dùng sẽ truy cập và sử dụng những chức năng đó như thế nào. Điều này đặc biệt hữu ích cho việc chạy [các bài kiểm tra luồng chính](https://en.m.wikipedia.org/wiki/Happy_path) nhằm xác định xem các hàm trong một hợp đồng có trả về đầu ra chính xác cho các đầu vào hợp lệ của người dùng hay không. Chúng tôi sẽ giải thích khái niệm này bằng cách sử dụng ví dụ (rút gọn) này về [một hợp đồng đấu giá](https://docs.soliditylang.org/en/v0.8.17/solidity-by-example.html?highlight=Auction%20contract#simple-open-auction) + +```solidity +constructor( + uint biddingTime, + address payable beneficiaryAddress + ) { + beneficiary = beneficiaryAddress; + auctionEndTime = block.timestamp + biddingTime; + } + +function bid() external payable { + + if (block.timestamp > auctionEndTime) + revert AuctionAlreadyEnded(); + + if (msg.value <= highestBid) + revert BidNotHighEnough(highestBid); + + if (highestBid != 0) { + pendingReturns[highestBidder] += highestBid; + } + highestBidder = msg.sender; + highestBid = msg.value; + emit HighestBidIncreased(msg.sender, msg.value); + } + + function withdraw() external returns (bool) { + uint amount = pendingReturns[msg.sender]; + if (amount > 0) { + pendingReturns[msg.sender] = 0; + + if (!payable(msg.sender).send(amount)) { + pendingReturns[msg.sender] = amount; + return false; + } + } + return true; + } + +function auctionEnd() external { + if (block.timestamp < auctionEndTime) + revert AuctionNotYetEnded(); + if (ended) + revert AuctionEndAlreadyCalled(); + + ended = true; + emit AuctionEnded(highestBidder, highestBid); + + beneficiary.transfer(highestBid); + } +} +``` + +Đây là một hợp đồng đấu giá đơn giản được thiết kế để nhận các giá thầu trong thời gian đấu giá. Nếu `highestBid` tăng lên, người đặt giá cao nhất trước đó sẽ nhận lại tiền của họ; khi thời gian đấu giá kết thúc, `beneficiary` sẽ gọi hợp đồng để nhận tiền. + +Các bài kiểm tra đơn vị cho một hợp đồng như thế này sẽ bao gồm các chức năng khác nhau mà người dùng có thể gọi khi tương tác với hợp đồng. Một ví dụ là một bài kiểm tra đơn vị để kiểm tra xem người dùng có thể đặt giá thầu khi phiên đấu giá đang diễn ra hay không (tức là, các lệnh gọi đến `bid()` thành công) hoặc một bài kiểm tra để kiểm tra xem người dùng có thể đặt giá thầu cao hơn `highestBid` hiện tại hay không. + +Hiểu quy trình hoạt động của hợp đồng cũng giúp dễ dàng hơn trong việc viết các bài kiểm tra đơn vị để kiểm tra xem việc thực hiện có đáp ứng yêu cầu hay không. Ví dụ: hợp đồng đấu giá quy định rằng người dùng không thể đặt giá thầu khi phiên đấu giá đã kết thúc (tức là, khi `auctionEndTime` thấp hơn `block.timestamp`). Do đó, một nhà phát triển có thể chạy một bài kiểm tra đơn vị để kiểm tra xem các lệnh gọi đến hàm `bid()` có thành công hay thất bại khi phiên đấu giá kết thúc hay không (tức là, khi `auctionEndTime` > `block.timestamp`). + +##### 2. Đánh giá tất cả các giả định liên quan đến việc thực hiện hợp đồng. + +Việc ghi lại mọi giả định về việc thực hiện hợp đồng và viết các bài kiểm tra đơn vị để xác minh tính hợp lệ của những giả định đó là rất quan trọng. Ngoài việc cung cấp bảo vệ chống lại việc thực hiện bất ngờ, việc kiểm tra các tuyên bố buộc bạn phải suy nghĩ về các hoạt động có thể làm hỏng mô hình an ninh của hợp đồng thông minh. Ngoài việc cung cấp bảo vệ chống lại việc thực hiện bất ngờ, việc kiểm tra các tuyên bố buộc bạn phải suy nghĩ về các hoạt động có thể làm hỏng mô hình an ninh của hợp đồng thông minh. + +Nhiều framework kiểm thử đơn vị cho phép bạn tạo ra các khẳng định—những câu đơn giản nói về những gì một hợp đồng có thể và không thể làm—và chạy thử nghiệm để xem những khẳng định đó có đúng khi thực thi hay không. Một lập trình viên làm việc trên hợp đồng đấu giá đã đề cập ở trên có thể đưa ra các khẳng định sau về hành vi của nó trước khi thực hiện các bài kiểm tra tiêu cực: + +- Người dùng không thể đặt giá khi buổi đấu giá đã kết thúc hoặc chưa bắt đầu. + +- Hợp đồng đấu giá sẽ trở lại trạng thái ban đầu nếu một khoản đấu giá thấp hơn ngưỡng chấp nhận. + +- Người dùng không thắng thầu sẽ được hoàn lại số tiền của họ. + +**Lưu ý**: Một cách khác để kiểm tra các giả định là viết các bài kiểm tra kích hoạt [các công cụ sửa đổi hàm](https://docs.soliditylang.org/en/v0.8.16/contracts.html#function-modifiers) trong một hợp đồng, đặc biệt là các câu lệnh `require`, `assert`, và `if…else`. + +##### 3. Đo lường mã phủ + +[Độ bao phủ của mã](https://en.m.wikipedia.org/wiki/Code_coverage) là một chỉ số kiểm tra dùng để theo dõi số lượng nhánh, dòng và câu lệnh trong mã của bạn được thực thi trong các bài kiểm tra. Các bài kiểm tra nên có độ phủ mã tốt để giảm thiểu rủi ro về các lỗ hổng chưa được kiểm tra. Nếu không có đủ độ bao phủ, bạn có thể giả định sai rằng hợp đồng của bạn là an toàn bởi vì tất cả các bài kiểm tra đều đạt yêu cầu, trong khi vẫn còn tồn tại những lỗ hổng trong các đoạn mã chưa được kiểm tra. Việc ghi nhận mức độ bao phủ mã cao, tuy nhiên, đảm bảo rằng tất cả các câu lệnh/hàm trong một hợp đồng thông minh đã được kiểm tra đầy đủ về tính chính xác. + +##### 4. Sử dụng các khung thử nghiệm phát triển tốt. + +Chất lượng của các công cụ được sử dụng trong việc chạy các bài kiểm tra đơn vị cho hợp đồng thông minh của bạn là rất quan trọng. Một khung thử nghiệm lý tưởng là khung thường xuyên được duy trì; cung cấp các tính năng hữu ích (ví dụ, khả năng ghi nhật ký và báo cáo); và phải được sử dụng rộng rãi và kiểm định bởi các nhà phát triển khác. + +Các framework kiểm thử đơn vị cho hợp đồng thông minh Solidity có ở nhiều ngôn ngữ khác nhau (chủ yếu là JavaScript, Python và Rust). Xem một số hướng dẫn dưới đây để biết thông tin về cách bắt đầu chạy các bài kiểm tra đơn với các framework kiểm tra khác nhau: + +- **[Chạy các bài kiểm tra đơn vị với Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** +- **[Chạy các bài kiểm tra đơn vị với Foundry](https://book.getfoundry.sh/forge/writing-tests)** +- **[Chạy các bài kiểm tra đơn vị với Waffle](https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#writing-tests)** +- **[Chạy các bài kiểm tra đơn vị với Remix](https://remix-ide.readthedocs.io/en/latest/unittesting.html#write-tests)** +- **[Chạy các bài kiểm tra đơn vị với Ape](https://docs.apeworx.io/ape/stable/userguides/testing.html)** +- **[Chạy các bài kiểm tra đơn vị với Hardhat](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** +- **[Chạy các bài kiểm tra đơn vị với Wake](https://ackeeblockchain.com/wake/docs/latest/testing-framework/overview/)** + +### Kiểm tra tích hợp {#integration-testing-for-smart-contracts} + +Trong khi kiểm thử đơn vị gỡ lỗi các hàm hợp đồng một cách độc lập, các bài kiểm tra tích hợp đánh giá các thành phần của một hợp đồng thông minh như một tổng thể. Kiểm thử tích hợp có thể phát hiện các vấn đề phát sinh từ việc gọi giữa các hợp đồng hoặc các tương tác giữa các hàm khác nhau trong cùng một hợp đồng thông minh. Ví dụ: các bài kiểm tra tích hợp có thể giúp kiểm tra xem những thứ như [kế thừa](https://docs.soliditylang.org/en/v0.8.12/contracts.html#inheritance) và tiêm phụ thuộc có hoạt động bình thường hay không. + +Kiểm thử tích hợp có ích nếu hợp đồng của bạn áp dụng kiến trúc mô-đun hoặc giao tiếp với các hợp đồng trên chuỗi khác trong quá trình thực thi. Một cách để chạy các bài kiểm tra tích hợp là [phân nhánh chuỗi khối](/glossary/#fork) ở một độ cao cụ thể (sử dụng một công cụ như [Forge](https://book.getfoundry.sh/forge/fork-testing) hoặc [Hardhat](https://hardhat.org/hardhat-network/docs/guides/forking-other-networks)) và mô phỏng các tương tác giữa hợp đồng của bạn và các hợp đồng đã triển khai. + +Blockchain phân nhánh sẽ hoạt động tương tự như Mainnet và có các tài khoản với trạng thái và số dư đi kèm. Nhưng nó chỉ hoạt động như một môi trường phát triển cục bộ được cách ly, có nghĩa là bạn sẽ không cần ETH thật cho các giao dịch, chẳng hạn như, và các thay đổi của bạn sẽ không ảnh hưởng đến giao thức Ethereum thực. + +### Kiểm tra dựa trên thuộc tính {#property-based-testing-for-smart-contracts} + +Kiểm thử dựa trên thuộc tính là quá trình kiểm tra xem một hợp đồng thông minh có thỏa mãn một số thuộc tính đã được định nghĩa hay không. Các thuộc tính đưa ra những điều kiện về cách thức hoạt động của hợp đồng mà người ta mong đợi sẽ giữ nguyên trong các tình huống khác nhau—một ví dụ về thuộc tính của hợp đồng thông minh có thể là "Các phép toán số học trong hợp đồng không bao giờ bị tràn hoặc thiếu." + +**Phân tích tĩnh** và **phân tích động** là hai kỹ thuật phổ biến để thực hiện kiểm tra dựa trên thuộc tính, và cả hai đều có thể xác minh rằng mã cho một chương trình (một hợp đồng thông minh trong trường hợp này) thỏa mãn một số thuộc tính được xác định trước. Một số công cụ kiểm tra dựa trên thuộc tính đi kèm với các quy tắc đã được định nghĩa trước về các thuộc tính hợp đồng mong đợi và kiểm tra mã theo các quy tắc đó, trong khi những công cụ khác cho phép bạn tạo các thuộc tính tùy chỉnh cho hợp đồng thông minh. + +#### Phân tích tĩnh {#static-analysis} + +Một trình phân tích tĩnh nhận mã nguồn của một hợp đồng thông minh và đưa ra kết quả xem liệu hợp đồng có đáp ứng một thuộc tính nào đó hay không. Khác với phân tích động, phân tích tĩnh không cần thực thi hợp đồng để phân tích tính chính xác của nó. Phân tích tĩnh thì sẽ xem xét tất cả các đường đi có thể có mà một hợp đồng thông minh có thể thực hiện trong quá trình chạy (tức là, bằng cách xem xét cấu trúc của mã nguồn để xác định điều gì sẽ xảy ra với hoạt động của hợp đồng trong thời gian thực). + +[Linting](https://www.perforce.com/blog/qac/what-is-linting) và [kiểm tra tĩnh](https://www.techtarget.com/whatis/definition/static-analysis-static-code-analysis) là các phương pháp phổ biến để chạy phân tích tĩnh trên các hợp đồng. Cả hai đều yêu cầu phân tích các biểu diễn cấp thấp của việc thực thi hợp đồng, chẳng hạn như [cây cú pháp trừu tượng](https://en.m.wikipedia.org/wiki/Abstract_syntax_tree) và [đồ thị luồng điều khiển](https://www.geeksforgeeks.org/software-engineering-control-flow-graph-cfg/amp/) do trình biên dịch xuất ra. + +Trong hầu hết các trường hợp, phân tích tĩnh hữu ích để phát hiện các vấn đề an toàn như việc sử dụng các cấu trúc không an toàn, lỗi cú pháp, hoặc vi phạm tiêu chuẩn lập trình trong mã hợp đồng. Tuy nhiên, các công cụ phân tích tĩnh thường không đáng tin cậy trong việc phát hiện những lỗ hổng sâu hơn, và có thể tạo ra quá nhiều cảnh báo sai. + +#### Phân tích động {#dynamic-analysis} + +Phân tích động tạo ra các đầu vào tượng trưng (ví dụ, trong [thực thi tượng trưng](https://en.m.wikipedia.org/wiki/Symbolic_execution)) hoặc các đầu vào cụ thể (ví dụ, trong [fuzzing](https://owasp.org/www-community/Fuzzing)) cho các hàm của hợp đồng thông minh để xem liệu có bất kỳ dấu vết thực thi nào vi phạm các thuộc tính cụ thể hay không. Hình thức kiểm thử dựa trên thuộc tính này khác với kiểm thử đơn vị ở chỗ các trường hợp test bao gồm nhiều tình huống và chương trình đảm nhận việc tạo ra các trường hợp kiểm thử. + +[Fuzzing](https://www.halborn.com/blog/post/what-is-fuzz-testing-fuzzing) là một ví dụ về một kỹ thuật phân tích động để xác minh các thuộc tính tùy ý trong các hợp đồng thông minh. Một bộ thử nghiệm (fuzzer) kích hoạt các hàm trong một hợp đồng mục tiêu với các biến thể ngẫu nhiên hoặc sai định dạng của một giá trị đầu vào đã định nghĩa. Nếu hợp đồng thông minh gặp lỗi (ví dụ, khi một điều kiện bị sai), vấn đề sẽ được đánh dấu và những đầu vào dẫn đến việc thực thi theo con đường dễ bị tổn thương sẽ được đưa vào báo cáo. + +Fuzzing rất hữu ích để kiểm tra cơ chế xác thực đầu vào của hợp đồng thông minh, vì việc xử lý không đúng các đầu vào không mong muốn có thể dẫn đến việc thực thi không mong muốn và tạo ra những tác động nguy hiểm. Cách kiểm tra dựa trên thuộc tính này có thể tuyệt vời vì nhiều lý do: + +1. **Việc viết các trường hợp kiểm tra để bao quát nhiều kịch bản là một điều khó khăn.** Một bài kiểm tra thuộc tính chỉ yêu cầu bạn xác định một hành vi và một phạm vi dữ liệu để kiểm tra hành vi đó—chương trình sẽ tự động tạo ra các trường hợp kiểm tra dựa trên thuộc tính đã được định nghĩa. + +2. **Bộ kiểm tra của bạn có thể không đủ để bao phủ tất cả các đường đi có thể trong chương trình.** Ngay cả khi đạt được 100% độ bao phủ, vẫn có thể bỏ lỡ các trường hợp biên. + +3. **Các bài kiểm tra đơn vị chứng minh rằng hợp đồng thực thi đúng với dữ liệu mẫu, nhưng liệu hợp đồng có thực thi đúng với các đầu vào ngoài mẫu hay không vẫn chưa rõ.** Các bài kiểm tra thuộc tính thực thi hợp đồng mục tiêu với nhiều biến thể của một giá trị đầu vào nhất định để tìm các dấu vết thực thi gây ra sự thất bại trong xác nhận. Do đó, một bài kiểm tra thuộc tính cung cấp nhiều đảm bảo hơn rằng hợp đồng thực thi đúng đắn cho một lớp rộng các dữ liệu đầu vào. + +### Hướng dẫn chạy kiểm tra dựa trên thuộc tính cho các hợp đồng thông minh {#running-property-based-tests} + +Việc chạy kiểm tra dựa trên thuộc tính thường bắt đầu bằng việc xác định một thuộc tính (ví dụ: không có [tràn số nguyên](https://github.com/ConsenSys/mythril/wiki/Integer-Overflow)) hoặc một tập hợp các thuộc tính mà bạn muốn xác minh trong một hợp đồng thông minh. Có thể bạn cũng cần xác định một khoảng giá trị mà chương trình có thể tạo dữ liệu cho đầu vào giao dịch khi viết các bài kiểm tra thuộc tính. + +Khi được cấu hình đúng cách, công cụ kiểm tra tài sản sẽ thực thi các chức năng hợp đồng thông minh của bạn với các đầu vào được tạo ra ngẫu nhiên. Nếu có bất kỳ khẳng định vi phạm nào, bạn nên nhận được một báo cáo với dữ liệu đầu vào cụ thể vi phạm thuộc tính đang được đánh giá. Xem một số hướng dẫn dưới đây để bắt đầu với việc chạy thử nghiệm dựa trên thuộc tính với các công cụ khác nhau: + +- **[Phân tích tĩnh các hợp đồng thông minh với Slither](https://github.com/crytic/slither)** +- **[Phân tích tĩnh các hợp đồng thông minh với Wake](https://ackeeblockchain.com/wake/docs/latest/static-analysis/using-detectors/)** +- **[Kiểm tra dựa trên thuộc tính với Brownie](https://eth-brownie.readthedocs.io/en/stable/tests-hypothesis-property.html)** +- **[Fuzzing hợp đồng với Foundry](https://book.getfoundry.sh/forge/fuzz-testing)** +- **[Fuzzing hợp đồng với Echidna](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/echidna#echidna-tutorial)** +- **[Fuzzing hợp đồng với Wake](https://ackeeblockchain.com/wake/docs/latest/testing-framework/fuzzing/)** +- **[Thực thi tượng trưng các hợp đồng thông minh với Manticore](https://github.com/crytic/building-secure-contracts/tree/master/program-analysis/manticore#manticore-tutorial)** +- **[Thực thi tượng trưng các hợp đồng thông minh với Mythril](https://mythril-classic.readthedocs.io/en/master/tutorial.html)** + +## Kiểm tra thủ công cho các hợp đồng thông minh {#manual-testing-for-smart-contracts} + +Kiểm tra thủ công các hợp đồng thông minh thường diễn ra sau trong chu trình phát triển, sau khi đã chạy các bài kiểm tra tự động. Hình thức kiểm tra này đánh giá hợp đồng thông minh như một sản phẩm đã được tích hợp hoàn chỉnh để xem nó có hoạt động như đã được chỉ định trong các yêu cầu kỹ thuật hay không. + +### Kiểm tra hợp đồng trên chuỗi khối cục bộ {#testing-on-local-blockchain} + +Mặc dù việc kiểm thử tự động ở môi trường cục bộ có thể cung cấp thông tin hữu ích để gỡ lỗi, nhưng bạn sẽ muốn biết cách hợp đồng thông minh của bạn hoạt động trong môi trường sản xuất. Nhưng mà, triển khai lên chuỗi chính của Ethereum sẽ tốn phí gas - chưa kể rằng bạn hoặc người dùng của bạn có thể mất tiền thật nếu hợp đồng thông minh của bạn vẫn còn lỗi. + +Kiểm tra hợp đồng của bạn trên một chuỗi khối cục bộ (còn được gọi là [mạng phát triển](/developers/docs/development-networks/)) là một giải pháp thay thế được đề xuất cho việc kiểm tra trên Mạng chính. Một blockchain cục bộ là bản sao của blockchain Ethereum chạy trực tiếp trên máy tính của bạn, mô phỏng hành vi của lớp thực thi của Ethereum. Vì vậy, bạn có thể lập trình các giao dịch để tương tác với một hợp đồng mà không bị chịu chi phí lớn. + +Chạy hợp đồng trên một blockchain cục bộ có thể hữu ích như một hình thức kiểm thử tích hợp thủ công. [Các hợp đồng thông minh có tính kết hợp cao](/developers/docs/smart-contracts/composability/), cho phép bạn tích hợp với các giao thức hiện có—nhưng bạn vẫn cần đảm bảo rằng các tương tác trên chuỗi phức tạp như vậy tạo ra kết quả chính xác. + +[Thông tin thêm về các mạng phát triển.](/developers/docs/development-networks/) + +### Kiểm tra hợp đồng trên các mạng thử nghiệm {#testing-contracts-on-testnets} + +Mạng thử nghiệm hoặc testnet hoạt động giống như Ethereum Mainnet, ngoại trừ việc nó sử dụng ether (ETH) không có giá trị thực tế. Triển khai hợp đồng của bạn trên [mạng thử nghiệm](/developers/docs/networks/#ethereum-testnets) có nghĩa là bất kỳ ai cũng có thể tương tác với nó (ví dụ: thông qua giao diện người dùng của ứng dụng phi tập trung) mà không gặp rủi ro về tiền bạc. + +Cách kiểm tra thủ công này rất hữu ích để đánh giá quy trình hoạt động của ứng dụng từ góc nhìn của người dùng. Tại đây, những người thử nghiệm beta cũng có thể thực hiện các thử nghiệm và báo cáo bất kỳ vấn đề nào liên quan đến logic kinh doanh của hợp đồng và chức năng tổng thể. + +Triển khai trên testnet sau khi thử nghiệm trên một blockchain nội bộ thật sự là lựa chọn tuyệt vời vì cái đó giống với cách hoạt động của Ethereum Virtual Machine hơn. Do đó, việc nhiều dự án gốc Ethereum triển khai các dapp trên mạng thử nghiệm để đánh giá hoạt động của hợp đồng thông minh trong điều kiện thực tế là điều phổ biến. + +[Thông tin thêm về các mạng thử nghiệm Ethereum.](/developers/docs/development-networks/#public-beacon-testchains) + +## Kiểm tra và xác minh chính thức {#testing-vs-formal-verification} + +Trong khi việc kiểm tra giúp xác nhận rằng một hợp đồng trả về kết quả mong đợi cho một số đầu vào dữ liệu, nó không thể chứng minh một cách kết luận rằng điều tương tự cũng đúng cho các đầu vào không được sử dụng trong quá trình kiểm tra. Do đó, việc kiểm tra một hợp đồng thông minh không thể đảm bảo "tính đúng đắn về chức năng" (tức là, nó không thể cho thấy một chương trình hoạt động như yêu cầu đối với _tất cả_ các bộ giá trị đầu vào). + +Xác minh hình thức là một phương pháp đánh giá tính đúng đắn của phần mềm bằng cách kiểm tra xem mô hình chính thức của chương trình có khớp với đặc tả chính thức hay không. Một mô hình hình thức là một biểu diễn toán học trừu tượng của một chương trình, trong khi một đặc tả hình thức định nghĩa các thuộc tính của chương trình (tức là, các khẳng định logic về việc thực thi của chương trình). + +Bởi vì các thuộc tính được viết bằng các thuật ngữ toán học, điều này giúp có thể xác minh rằng một mô hình hình thức (toán học) của hệ thống thỏa mãn một đặc tả bằng cách sử dụng các quy tắc suy diễn logic. Vậy nên, các công cụ xác minh chính thức được cho là tạo ra ‘bằng chứng toán học’ về tính đúng đắn của hệ thống. + +Không giống như kiểm tra, xác minh chính thức có thể được sử dụng để xác minh việc thực thi một hợp đồng thông minh thỏa mãn một đặc tả chính thức cho _tất cả_ các lần thực thi (tức là, nó không có lỗi) mà không cần thực thi nó với dữ liệu mẫu. Không chỉ giúp tiết kiệm thời gian cho việc chạy hàng tá bài kiểm tra đơn vị, mà nó còn hiệu quả hơn trong việc phát hiện các lỗ hổng ẩn. Nói như vậy, các kỹ thuật xác minh chính thức nằm trên một phổ tùy thuộc vào độ khó thực hiện và tính hữu ích của chúng. + +[Thông tin thêm về xác minh chính thức cho các hợp đồng thông minh.](/developers/docs/smart-contracts/formal-verification) + +## Kiểm tra và kiểm toán và tiền thưởng săn lỗi {#testing-vs-audits-bug-bounties} + +Như đã đề cập, việc kiểm tra kỹ lưỡng hiếm khi đảm bảo hoàn toàn không có lỗi trong một hợp đồng; các phương pháp xác minh hình thức có thể cung cấp sự đảm bảo mạnh mẽ hơn về độ chính xác nhưng hiện tại thì khó sử dụng và tốn kém. + +Dù sao, bạn có thể tăng khả năng phát hiện lỗ hổng hợp đồng bằng cách nhờ xem xét mã độc lập. [Kiểm toán hợp đồng thông minh](https://www.immunebytes.com/blog/what-is-a-smart-contract-audit/) và [tiền thưởng săn lỗi](https://medium.com/immunefi/a-defi-security-standard-the-scaling-bug-bounty-9b83dfdc1ba7) là hai cách để người khác phân tích hợp đồng của bạn. + +Các buổi kiểm toán được thực hiện bởi những kiểm toán viên có kinh nghiệm trong việc tìm ra các lỗ hổng bảo mật và các thực hành phát triển kém trong hợp đồng thông minh. Một cuộc kiểm toán thường sẽ bao gồm việc kiểm tra (và có thể là xác minh chính thức) cũng như một đánh giá thủ công về toàn bộ mã nguồn. + +Ngược lại, một chương trình tiền thưởng săn lỗi thường bao gồm việc cung cấp một phần thưởng tài chính cho một cá nhân (thường được mô tả là [tin tặc mũ trắng](https://en.wikipedia.org/wiki/White_hat_\(computer_security\))) phát hiện ra một lỗ hổng trong một hợp đồng thông minh và tiết lộ nó cho các nhà phát triển. Giải thưởng lỗi tương tự như các cuộc kiểm toán vì nó liên quan đến việc yêu cầu người khác giúp tìm ra các lỗi trong hợp đồng thông minh. + +Sự khác biệt chính là các chương trình bug bounty mở cửa cho cộng đồng lập trình viên/ hacker rộng rãi và thu hút một lớp các hacker mũ trắng và các chuyên gia an ninh độc lập với những kỹ năng và kinh nghiệm độc đáo. Điều này có thể là một lợi thế so với việc kiểm toán hợp đồng thông minh chủ yếu dựa vào các đội ngũ có thể chỉ sở hữu kiến thức hạn hẹp hoặc chuyên môn hạn chế. + +## Các công cụ và thư viện kiểm tra {#testing-tools-and-libraries} + +### Các công cụ kiểm tra đơn vị {#unit-testing-tools} + +- **[solidity-coverage](https://github.com/sc-forks/solidity-coverage)** - _Công cụ đo độ bao phủ mã cho các hợp đồng thông minh được viết bằng Solidity._ + +- **[Waffle](https://ethereum-waffle.readthedocs.io/en/latest/)** - _Framework để phát triển và kiểm tra hợp đồng thông minh nâng cao (dựa trên ethers.js)_. + +- **[Remix Tests](https://github.com/ethereum/remix-project/tree/master/libs/remix-tests)** - _Công cụ để kiểm tra các hợp đồng thông minh Solidity. Làm việc dưới Remix IDE với plugin "Kiểm thử Solidity" được sử dụng để viết và chạy các trường hợp test cho một hợp đồng._ + +- **[OpenZeppelin Test Helpers](https://github.com/OpenZeppelin/openzeppelin-test-helpers)** - _Thư viện xác nhận để kiểm tra hợp đồng thông minh Ethereum. Hãy đảm bảo rằng các hợp đồng của bạn hoạt động như mong đợi!_ + +- **[Framework kiểm tra đơn vị Brownie](https://eth-brownie.readthedocs.io/en/v1.0.0_a/tests.html)** - _Brownie sử dụng Pytest, một framework kiểm tra giàu tính năng cho phép bạn viết các bài kiểm tra nhỏ với mã tối thiểu, có khả năng mở rộng tốt cho các dự án lớn và có khả năng mở rộng cao._ + +- **[Foundry Tests](https://github.com/foundry-rs/foundry/tree/master/crates/forge)** - _Foundry cung cấp Forge, một framework kiểm tra Ethereum nhanh và linh hoạt có khả năng thực hiện các bài kiểm tra đơn vị đơn giản, kiểm tra tối ưu hóa gas và fuzzing hợp đồng._ + +- **[Hardhat Tests](https://hardhat.org/hardhat-runner/docs/guides/test-contracts)** - _Framework để kiểm tra các hợp đồng thông minh dựa trên ethers.js, Mocha và Chai._ + +- **[ApeWorx](https://docs.apeworx.io/ape/stable/userguides/testing.html)** - _Framework phát triển và kiểm tra dựa trên Python cho các hợp đồng thông minh nhắm vào Máy ảo Ethereum._ + +- **[Wake](https://ackeeblockchain.com/wake/docs/latest/testing-framework/overview/)** - _Framework dựa trên Python để kiểm tra đơn vị và fuzzing với khả năng gỡ lỗi mạnh mẽ và hỗ trợ kiểm tra chuỗi chéo, sử dụng pytest và Anvil để có trải nghiệm người dùng và hiệu suất tốt nhất._ + +### Các công cụ kiểm tra dựa trên thuộc tính {#property-based-testing-tools} + +#### Các công cụ phân tích tĩnh {#static-analysis-tools} + +- **[Slither](https://github.com/crytic/slither)** - _Framework phân tích tĩnh Solidity dựa trên Python để tìm các lỗ hổng, nâng cao khả năng hiểu mã và viết các phân tích tùy chỉnh cho các hợp đồng thông minh._ + +- **[Ethlint](https://ethlint.readthedocs.io/en/latest/)** - _Công cụ linter để thực thi các phương pháp hay nhất về văn phong và bảo mật cho ngôn ngữ lập trình hợp đồng thông minh Solidity._ + +- **[Cyfrin Aderyn](https://cyfrin.io/tools/aderyn)** - _Trình phân tích tĩnh dựa trên Rust được thiết kế đặc biệt cho bảo mật và phát triển hợp đồng thông minh Web3._ + +- **[Wake](https://ackeeblockchain.com/wake/docs/latest/static-analysis/using-detectors/)** - _Framework phân tích tĩnh dựa trên Python với các công cụ phát hiện lỗ hổng và chất lượng mã, các máy in để trích xuất thông tin hữu ích từ mã và hỗ trợ viết các mô-đun con tùy chỉnh._ + +- **[Slippy](https://github.com/fvictorio/slippy)** - _Một linter đơn giản và mạnh mẽ cho Solidity._ + +#### Các công cụ phân tích động {#dynamic-analysis-tools} + +- **[Echidna](https://github.com/crytic/echidna/)** - _Công cụ fuzzer hợp đồng nhanh để phát hiện các lỗ hổng trong các hợp đồng thông minh thông qua kiểm tra dựa trên thuộc tính._ + +- **[Diligence Fuzzing](https://consensys.net/diligence/fuzzing/)** - _Công cụ fuzzing tự động hữu ích để phát hiện các vi phạm thuộc tính trong mã hợp đồng thông minh._ + +- **[Manticore](https://manticore.readthedocs.io/en/latest/index.html)** - _Framework thực thi tượng trưng động để phân tích mã byte EVM._ + +- **[Mythril](https://github.com/ConsenSys/mythril-classic)** - _Công cụ đánh giá mã byte EVM để phát hiện các lỗ hổng hợp đồng bằng cách sử dụng phân tích vết, phân tích kết hợp và kiểm tra luồng điều khiển._ + +- **[Diligence Scribble](https://consensys.net/diligence/scribble/)** - _Scribble là một ngôn ngữ đặc tả và công cụ xác minh thời gian chạy cho phép bạn chú thích các hợp đồng thông minh với các thuộc tính cho phép bạn tự động kiểm tra các hợp đồng bằng các công cụ như Diligence Fuzzing hoặc MythX._ + +## Các hướng dẫn liên quan {#related-tutorials} + +- [Tổng quan và so sánh các sản phẩm kiểm tra khác nhau](/developers/tutorials/guide-to-smart-contract-security-tools/) \_ +- [Cách sử dụng Echidna để kiểm tra các hợp đồng thông minh](/developers/tutorials/how-to-use-echidna-to-test-smart-contracts/) +- [Cách sử dụng Manticore để tìm lỗi hợp đồng thông minh](/developers/tutorials/how-to-use-manticore-to-find-smart-contract-bugs/) +- [Cách sử dụng Slither để tìm lỗi hợp đồng thông minh](/developers/tutorials/how-to-use-slither-to-find-smart-contract-bugs/) +- [Cách mô phỏng các hợp đồng Solidity để kiểm tra](/developers/tutorials/how-to-mock-solidity-contracts-for-testing/) +- [Cách chạy các bài kiểm tra đơn vị trong Solidity bằng Foundry](https://www.rareskills.io/post/foundry-testing-solidity) + +## Đọc thêm {#further-reading} + +- [Hướng dẫn chuyên sâu về kiểm tra các hợp đồng thông minh Ethereum](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297) +- [Cách kiểm tra các hợp đồng thông minh Ethereum](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d) +- [Hướng dẫn kiểm tra đơn vị của MolochDAO cho các nhà phát triển](https://github.com/MolochVentures/moloch/tree/4e786db8a4aa3158287e0935dcbc7b1e43416e38/test#moloch-testing-guide) +- [Cách kiểm tra các hợp đồng thông minh như một ngôi sao nhạc rock](https://forum.openzeppelin.com/t/test-smart-contracts-like-a-rockstar/1001) diff --git a/public/content/translations/vi/developers/docs/smart-contracts/upgrading/index.md b/public/content/translations/vi/developers/docs/smart-contracts/upgrading/index.md new file mode 100644 index 00000000000..d30a1be4778 --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/upgrading/index.md @@ -0,0 +1,165 @@ +--- +title: "Nâng cấp hợp đồng thông minh" +description: "Tổng quan về các mẫu nâng cấp cho hợp đồng thông minh Ethereum" +lang: vi +--- + +Hợp đồng thông minh trên Ethereum là các chương trình tự thực thi chạy trong Máy ảo Ethereum (EVM). Các chương trình này được thiết kế bất biến, giúp ngăn chặn mọi cập nhật đối với logic nghiệp vụ sau khi hợp đồng được triển khai. + +Mặc dù tính bất biến là cần thiết cho tính không cần tin cậy, tính phi tập trung và tính bảo mật của các hợp đồng thông minh, nhưng nó có thể là một nhược điểm trong một số trường hợp nhất định. Ví dụ: mã bất biến có thể khiến các nhà phát triển không thể sửa các hợp đồng dễ bị tấn công. + +Tuy nhiên, việc tăng cường nghiên cứu nhằm cải thiện các hợp đồng thông minh đã dẫn đến sự ra đời của một số mẫu nâng cấp. Các mẫu nâng cấp này cho phép các nhà phát triển nâng cấp các hợp đồng thông minh (trong khi vẫn duy trì tính bất biến) bằng cách đặt logic nghiệp vụ vào các hợp đồng khác nhau. + +## Điều kiện tiên quyết {#prerequisites} + +Bạn nên có hiểu biết tốt về [hợp đồng thông minh](/developers/docs/smart-contracts/), [cấu trúc của hợp đồng thông minh](/developers/docs/smart-contracts/anatomy/) và [Máy ảo Ethereum (EVM)](/developers/docs/evm/). Hướng dẫn này cũng giả định rằng người đọc đã nắm được kiến thức lập trình hợp đồng thông minh. + +## Nâng cấp hợp đồng thông minh là gì? {#what-is-a-smart-contract-upgrade} + +Nâng cấp hợp đồng thông minh bao gồm việc thay đổi logic nghiệp vụ của hợp đồng thông minh trong khi vẫn giữ nguyên trạng thái của hợp đồng. Điều quan trọng là phải làm rõ rằng khả năng nâng cấp và khả năng thay đổi là không giống nhau, đặc biệt là trong bối cảnh hợp đồng thông minh. + +Bạn vẫn không thể thay đổi một chương trình đã được triển khai đến một địa chỉ trên mạng Ethereum. Nhưng bạn có thể thay đổi mã được thực thi khi người dùng tương tác với hợp đồng thông minh. + +Điều này có thể được thực hiện thông qua các phương pháp sau: + +1. Tạo nhiều phiên bản của một hợp đồng thông minh và di chuyển trạng thái (tức là dữ liệu) từ hợp đồng cũ sang một phiên bản mới của hợp đồng. + +2. Tạo các hợp đồng riêng biệt để lưu trữ logic nghiệp vụ và trạng thái. + +3. Sử dụng các mẫu proxy để ủy quyền các lệnh gọi hàm từ một hợp đồng proxy bất biến đến một hợp đồng logic có thể sửa đổi. + +4. Tạo một hợp đồng chính bất biến giao tiếp với và dựa vào các hợp đồng vệ tinh linh hoạt để thực hiện các chức năng cụ thể. + +5. Sử dụng mẫu kim cương để ủy quyền các lệnh gọi hàm từ hợp đồng proxy đến các hợp đồng logic. + +### Cơ chế nâng cấp số 1: Di chuyển hợp đồng {#contract-migration} + +Di chuyển hợp đồng dựa trên việc tạo phiên bản—ý tưởng tạo và quản lý các trạng thái duy nhất của cùng một phần mềm. Việc di chuyển hợp đồng bao gồm việc triển khai một phiên bản mới của một hợp đồng thông minh hiện có và chuyển lưu trữ và số dư sang hợp đồng mới. + +Hợp đồng mới được triển khai sẽ có một bộ nhớ trống, cho phép bạn khôi phục dữ liệu từ hợp đồng cũ và ghi nó vào bản triển khai mới. Sau đó, bạn sẽ cần cập nhật tất cả các hợp đồng đã tương tác với hợp đồng cũ để phản ánh địa chỉ mới. + +Bước cuối cùng trong việc di chuyển hợp đồng là thuyết phục người dùng chuyển sang sử dụng hợp đồng mới. Phiên bản hợp đồng mới sẽ giữ lại số dư và địa chỉ của người dùng, điều này giúp duy trì tính bất biến. Nếu đó là hợp đồng dựa trên token, bạn cũng sẽ cần liên hệ với các sàn giao dịch để loại bỏ hợp đồng cũ và sử dụng hợp đồng mới. + +Di chuyển hợp đồng là một biện pháp tương đối đơn giản và an toàn để nâng cấp các hợp đồng thông minh mà không làm gián đoạn các tương tác của người dùng. Tuy nhiên, việc di chuyển thủ công bộ nhớ và số dư của người dùng sang hợp đồng mới tốn nhiều thời gian và có thể phát sinh chi phí gas cao. + +[Thông tin thêm về di chuyển hợp đồng.](https://blog.trailofbits.com/2018/10/29/how-contract-migration-works/) + +### Cơ chế nâng cấp số 2: Tách dữ liệu {#data-separation} + +Một phương pháp khác để nâng cấp hợp đồng thông minh là tách logic nghiệp vụ và lưu trữ dữ liệu thành các hợp đồng riêng biệt. Điều này có nghĩa là người dùng tương tác với hợp đồng logic, trong khi dữ liệu được lưu trữ trong hợp đồng lưu trữ. + +Hợp đồng logic chứa mã được thực thi khi người dùng tương tác với ứng dụng. Nó cũng giữ địa chỉ của hợp đồng lưu trữ và tương tác với nó để lấy và thiết lập dữ liệu. + +Trong khi đó, hợp đồng lưu trữ giữ trạng thái liên quan đến hợp đồng thông minh, chẳng hạn như số dư và địa chỉ của người dùng. Lưu ý rằng hợp đồng lưu trữ thuộc sở hữu của hợp đồng logic và được cấu hình với địa chỉ của hợp đồng logic tại thời điểm triển khai. Điều này ngăn các hợp đồng không được ủy quyền gọi hợp đồng lưu trữ hoặc cập nhật dữ liệu của nó. + +Theo mặc định, hợp đồng lưu trữ là bất biến—nhưng bạn có thể thay thế hợp đồng logic mà nó trỏ đến bằng một bản triển khai mới. Điều này sẽ thay đổi mã chạy trong EVM, trong khi vẫn giữ nguyên bộ nhớ và số dư. + +Sử dụng phương pháp nâng cấp này yêu cầu cập nhật địa chỉ của hợp đồng logic trong hợp đồng lưu trữ. Bạn cũng phải cấu hình hợp đồng logic mới với địa chỉ của hợp đồng lưu trữ vì những lý do đã giải thích trước đó. + +Mẫu tách dữ liệu được cho là dễ triển khai hơn so với di chuyển hợp đồng. Tuy nhiên, bạn sẽ phải quản lý nhiều hợp đồng và triển khai các lược đồ ủy quyền phức tạp để bảo vệ các hợp đồng thông minh khỏi các nâng cấp độc hại. + +### Cơ chế nâng cấp số 3: Các mẫu proxy {#proxy-patterns} + +Mẫu proxy cũng sử dụng phương pháp tách dữ liệu để giữ logic nghiệp vụ và dữ liệu trong các hợp đồng riêng biệt. Tuy nhiên, trong một mẫu proxy, hợp đồng lưu trữ (được gọi là proxy) sẽ gọi hợp đồng logic trong quá trình thực thi mã. Đây là phương pháp đảo ngược của phương pháp tách dữ liệu, trong đó hợp đồng logic gọi hợp đồng lưu trữ. + +Đây là những gì xảy ra trong một mẫu proxy: + +1. Người dùng tương tác với hợp đồng proxy, nơi lưu trữ dữ liệu nhưng không giữ logic nghiệp vụ. + +2. Hợp đồng proxy lưu trữ địa chỉ của hợp đồng logic và ủy quyền tất cả các lệnh gọi hàm cho hợp đồng logic (nơi chứa logic nghiệp vụ) bằng hàm `delegatecall`. + +3. Sau khi lệnh gọi được chuyển tiếp đến hợp đồng logic, dữ liệu trả về từ hợp đồng logic sẽ được truy xuất và trả lại cho người dùng. + +Sử dụng các mẫu proxy đòi hỏi sự hiểu biết về hàm **delegatecall**. Về cơ bản, `delegatecall` là một mã vận hành cho phép một hợp đồng gọi một hợp đồng khác, trong khi việc thực thi mã thực tế diễn ra trong ngữ cảnh của hợp đồng gọi. Một hệ quả của việc sử dụng `delegatecall` trong các mẫu proxy là hợp đồng proxy đọc và ghi vào bộ nhớ của nó và thực thi logic được lưu trữ tại hợp đồng logic như thể đang gọi một hàm nội bộ. + +Từ [tài liệu tham khảo Solidity](https://docs.soliditylang.org/en/latest/introduction-to-smart-contracts.html#delegatecall-callcode-and-libraries): + +> _Tồn tại một biến thể đặc biệt của một lệnh gọi hàm nhắn tin, có tên là **delegatecall**, giống hệt với một lệnh gọi hàm nhắn tin ngoại trừ việc mã tại địa chỉ đích được thực thi trong ngữ cảnh (tức là tại địa chỉ) của hợp đồng gọi và `msg.sender` cùng `msg.value` không thay đổi giá trị của chúng._ _Điều này có nghĩa là một hợp đồng có thể tải động mã từ một địa chỉ khác trong thời gian chạy. Lưu trữ, địa chỉ hiện tại và số dư vẫn tham chiếu đến hợp đồng gọi, chỉ có mã được lấy từ địa chỉ được gọi._ + +Hợp đồng proxy biết cách gọi `delegatecall` bất cứ khi nào người dùng gọi một hàm vì nó có một hàm `fallback` được tích hợp sẵn. Trong lập trình Solidity, [hàm dự phòng](https://docs.soliditylang.org/en/latest/contracts.html#fallback-function) được thực thi khi một lệnh gọi hàm không khớp với các hàm được chỉ định trong hợp đồng. + +Để mẫu proxy hoạt động, cần phải viết một hàm dự phòng tùy chỉnh chỉ định cách hợp đồng proxy xử lý các lệnh gọi hàm mà nó không hỗ trợ. Trong trường hợp này, hàm dự phòng của proxy được lập trình để khởi tạo một delegatecall và định tuyến lại yêu cầu của người dùng đến bản triển khai hợp đồng logic hiện tại. + +Hợp đồng proxy là bất biến theo mặc định, nhưng các hợp đồng logic mới với logic nghiệp vụ được cập nhật có thể được tạo. Việc thực hiện nâng cấp sau đó là vấn đề thay đổi địa chỉ của hợp đồng logic được tham chiếu trong hợp đồng proxy. + +Bằng cách trỏ hợp đồng proxy đến một hợp đồng logic mới, mã được thực thi khi người dùng gọi hàm của hợp đồng proxy sẽ thay đổi. Điều này cho phép chúng tôi nâng cấp logic của hợp đồng mà không cần yêu cầu người dùng tương tác với hợp đồng mới. + +Các mẫu proxy là một phương pháp phổ biến để nâng cấp các hợp đồng thông minh vì chúng loại bỏ những khó khăn liên quan đến việc di chuyển hợp đồng. Tuy nhiên, các mẫu proxy phức tạp hơn khi sử dụng và có thể gây ra các lỗi nghiêm trọng, chẳng hạn như [xung đột bộ chọn hàm](https://medium.com/nomic-foundation-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357), nếu được sử dụng không đúng cách. + +[Thông tin thêm về các mẫu proxy](https://blog.openzeppelin.com/proxy-patterns/). + +### Cơ chế nâng cấp số 4: Mẫu chiến lược {#strategy-pattern} + +Kỹ thuật này bị ảnh hưởng bởi [mẫu chiến lược](https://en.wikipedia.org/wiki/Strategy_pattern), khuyến khích việc tạo ra các chương trình phần mềm giao tiếp với các chương trình khác để triển khai các tính năng cụ thể. Áp dụng mẫu chiến lược cho việc phát triển Ethereum có nghĩa là xây dựng một hợp đồng thông minh gọi các hàm từ các hợp đồng khác. + +Hợp đồng chính trong trường hợp này chứa logic nghiệp vụ cốt lõi, nhưng giao tiếp với các hợp đồng thông minh khác ("hợp đồng vệ tinh") để thực hiện các chức năng nhất định. Hợp đồng chính này cũng lưu trữ địa chỉ cho mỗi hợp đồng vệ tinh và có thể chuyển đổi giữa các bản triển khai khác nhau của hợp đồng vệ tinh. + +Bạn có thể xây dựng một hợp đồng vệ tinh mới và cấu hình hợp đồng chính với địa chỉ mới. Điều này cho phép bạn thay đổi _chiến lược_ (tức là triển khai logic mới) cho một hợp đồng thông minh. + +Mặc dù tương tự như mẫu proxy đã được thảo luận trước đó, mẫu chiến lược lại khác biệt vì hợp đồng chính, nơi người dùng tương tác, nắm giữ logic nghiệp vụ. Sử dụng mẫu này mang lại cho bạn cơ hội để giới thiệu những thay đổi hạn chế đối với hợp đồng thông minh mà không ảnh hưởng đến cơ sở hạ tầng cốt lõi. + +Nhược điểm chính là mẫu này chủ yếu hữu ích cho việc triển khai các nâng cấp nhỏ. Ngoài ra, nếu hợp đồng chính bị xâm phạm (ví dụ, thông qua một vụ hack), bạn không thể sử dụng phương pháp nâng cấp này. + +### Cơ chế nâng cấp số 5: Mẫu kim cương {#diamond-pattern} + +Mẫu kim cương có thể được coi là một cải tiến so với mẫu proxy. Các mẫu kim cương khác với các mẫu proxy vì hợp đồng proxy kim cương có thể ủy quyền các lệnh gọi hàm cho nhiều hơn một hợp đồng logic. + +Các hợp đồng logic trong mẫu kim cương được gọi là _facet_. Để làm cho mẫu kim cương hoạt động, bạn cần tạo một ánh xạ trong hợp đồng proxy để ánh xạ [các bộ chọn hàm](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector) đến các địa chỉ facet khác nhau. + +Khi người dùng thực hiện một lệnh gọi hàm, hợp đồng proxy sẽ kiểm tra ánh xạ để tìm facet chịu trách nhiệm thực thi hàm đó. Sau đó, nó gọi `delegatecall` (sử dụng hàm dự phòng) và chuyển hướng lệnh gọi đến hợp đồng logic thích hợp. + +Mẫu nâng cấp kim cương có một số ưu điểm so với các mẫu nâng cấp proxy truyền thống: + +1. Nó cho phép bạn nâng cấp một phần nhỏ của hợp đồng mà không cần thay đổi toàn bộ mã. Sử dụng mẫu proxy để nâng cấp đòi hỏi phải tạo một hợp đồng logic hoàn toàn mới, ngay cả đối với các nâng cấp nhỏ. + +2. Tất cả các hợp đồng thông minh (bao gồm cả các hợp đồng logic được sử dụng trong các mẫu proxy) đều có giới hạn kích thước 24KB, đây có thể là một hạn chế—đặc biệt đối với các hợp đồng phức tạp đòi hỏi nhiều chức năng hơn. Mẫu kim cương giúp giải quyết vấn đề này dễ dàng bằng cách chia các chức năng trên nhiều hợp đồng logic. + +3. Các mẫu proxy áp dụng phương pháp tiếp cận toàn diện để kiểm soát truy cập. Một thực thể có quyền truy cập vào các chức năng nâng cấp có thể thay đổi _toàn bộ_ hợp đồng. Nhưng mẫu kim cương cho phép một cách tiếp cận cấp phép theo mô-đun, nơi bạn có thể hạn chế các thực thể nâng cấp một số chức năng nhất định trong một hợp đồng thông minh. + +[Thông tin thêm về mẫu kim cương](https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard?s=w). + +## Ưu và nhược điểm của việc nâng cấp hợp đồng thông minh {#pros-and-cons-of-upgrading-smart-contracts} + +| Ưu điểm | Nhược điểm | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Việc nâng cấp hợp đồng thông minh có thể giúp dễ dàng sửa các lỗ hổng được phát hiện trong giai đoạn sau triển khai. | Việc nâng cấp các hợp đồng thông minh phủ nhận ý tưởng về tính bất biến của mã, điều này có ý nghĩa đối với tính phi tập trung và bảo mật. | +| Các nhà phát triển có thể sử dụng các nâng cấp logic để thêm các tính năng mới cho các ứng dụng phi tập trung. | Người dùng phải tin tưởng các nhà phát triển sẽ không sửa đổi các hợp đồng thông minh một cách tùy tiện. | +| Việc nâng cấp hợp đồng thông minh có thể cải thiện sự an toàn cho người dùng cuối vì các lỗi có thể được sửa chữa nhanh chóng. | Việc lập trình chức năng nâng cấp vào các hợp đồng thông minh sẽ thêm một lớp phức tạp khác và làm tăng khả năng xảy ra các lỗi nghiêm trọng. | +| Các nâng cấp hợp đồng giúp các nhà phát triển có nhiều không gian hơn để thử nghiệm các tính năng khác nhau và cải thiện các ứng dụng phi tập trung theo thời gian. | Cơ hội nâng cấp các hợp đồng thông minh có thể khuyến khích các nhà phát triển khởi chạy dự án nhanh hơn mà không cần thực hiện thẩm định trong giai đoạn phát triển. | +| | Việc kiểm soát truy cập không an toàn hoặc tập trung hóa trong các hợp đồng thông minh có thể giúp các tác nhân độc hại thực hiện các nâng cấp trái phép dễ dàng hơn. | + +## Những lưu ý khi nâng cấp hợp đồng thông minh {#considerations-for-upgrading-smart-contracts} + +1. Sử dụng các cơ chế kiểm soát/ủy quyền truy cập an toàn để ngăn chặn các nâng cấp hợp đồng thông minh trái phép, đặc biệt nếu sử dụng các mẫu proxy, mẫu chiến lược hoặc tách dữ liệu. Một ví dụ là hạn chế quyền truy cập vào chức năng nâng cấp, để chỉ chủ sở hữu của hợp đồng mới có thể gọi nó. + +2. Nâng cấp hợp đồng thông minh là một hoạt động phức tạp và đòi hỏi sự cẩn trọng cao độ để ngăn chặn việc phát sinh các lỗ hổng bảo mật. + +3. Giảm các giả định về sự tin cậy bằng cách phi tập trung hóa quy trình thực hiện các nâng cấp. Các chiến lược khả thi bao gồm việc sử dụng [hợp đồng ví đa chữ ký](/developers/docs/smart-contracts/#multisig) để kiểm soát các nâng cấp, hoặc yêu cầu [các thành viên của một DAO](/dao/) bỏ phiếu để phê duyệt việc nâng cấp. + +4. Hãy lưu ý đến các chi phí liên quan đến việc nâng cấp hợp đồng. Ví dụ, việc sao chép trạng thái (ví dụ: số dư của người dùng) từ hợp đồng cũ sang hợp đồng mới trong quá trình di chuyển hợp đồng có thể yêu cầu nhiều hơn một giao dịch, nghĩa là sẽ tốn nhiều phí gas hơn. + +5. Hãy cân nhắc việc triển khai **khóa thời gian** để bảo vệ người dùng. Khóa thời gian đề cập đến một sự chậm trễ được áp dụng đối với các thay đổi của một hệ thống. Khóa thời gian có thể được kết hợp với một hệ thống quản trị đa chữ ký để kiểm soát các nâng cấp: nếu một hành động được đề xuất đạt đến ngưỡng phê duyệt yêu cầu, nó sẽ không được thực thi cho đến khi khoảng thời gian trì hoãn được xác định trước trôi qua. + +Khóa thời gian cho người dùng một khoảng thời gian để thoát khỏi hệ thống nếu họ không đồng ý với một thay đổi được đề xuất (ví dụ: nâng cấp logic hoặc các lược đồ phí mới). Nếu không có khóa thời gian, người dùng cần phải tin tưởng các nhà phát triển sẽ không thực hiện các thay đổi tùy tiện trong một hợp đồng thông minh mà không có thông báo trước. Nhược điểm ở đây là khóa thời gian hạn chế khả năng vá nhanh các lỗ hổng bảo mật. + +## Tài nguyên {#resources} + +**Plugin Nâng cấp OpenZeppelin - _Một bộ công cụ để triển khai và bảo mật các hợp đồng thông minh có thể nâng cấp._** + +- [GitHub](https://github.com/OpenZeppelin/openzeppelin-upgrades) +- [Tài liệu tham khảo](https://docs.openzeppelin.com/upgrades) + +## Hướng dẫn {#tutorials} + +- [Nâng cấp các Hợp đồng thông minh của bạn | Hướng dẫn trên YouTube](https://www.youtube.com/watch?v=bdXJmWajZRY) của Patrick Collins +- [Hướng dẫn Di chuyển Hợp đồng thông minh Ethereum](https://medium.com/coinmonks/ethereum-smart-contract-migration-13f6f12539bd) của Austin Griffith +- [Sử dụng mẫu proxy UUPS để nâng cấp hợp đồng thông minh](https://blog.logrocket.com/author/praneshas/) của Pranesh A.S +- [Hướng dẫn Web3: Viết hợp đồng thông minh có thể nâng cấp (proxy) bằng OpenZeppelin](https://dev.to/yakult/tutorial-write-upgradeable-smart-contract-proxy-contract-with-openzeppelin-1916) của fangjun.eth + +## Đọc thêm {#further-reading} + +- [Thực trạng Nâng cấp Hợp đồng thông minh](https://blog.openzeppelin.com/the-state-of-smart-contract-upgrades/) của Santiago Palladino +- [Nhiều cách để nâng cấp một hợp đồng thông minh Solidity](https://cryptomarketpool.com/multiple-ways-to-upgrade-a-solidity-smart-contract/) - blog của Crypto Market Pool +- [Tìm hiểu: Nâng cấp Hợp đồng thông minh](https://docs.openzeppelin.com/learn/upgrading-smart-contracts) - Tài liệu OpenZeppelin +- [Các Mẫu Proxy cho Khả năng Nâng cấp của Hợp đồng Solidity: Proxy Transparent so với UUPS](https://mirror.xyz/0xB38709B8198d147cc9Ff9C133838a044d78B064B/M7oTptQkBGXxox-tk9VJjL66E1V8BUF0GF79MMK4YG0) của Naveen Sahu +- [Cách thức hoạt động của các bản nâng cấp Diamond](https://dev.to/mudgen/how-diamond-upgrades-work-417j) của Nick Mudge diff --git a/public/content/translations/vi/developers/docs/smart-contracts/verifying/index.md b/public/content/translations/vi/developers/docs/smart-contracts/verifying/index.md new file mode 100644 index 00000000000..554bd8130bd --- /dev/null +++ b/public/content/translations/vi/developers/docs/smart-contracts/verifying/index.md @@ -0,0 +1,113 @@ +--- +title: "Xác minh hợp đồng thông minh" +description: "Tổng quan về xác minh mã nguồn cho hợp đồng thông minh Ethereum" +lang: vi +--- + +[Hợp đồng thông minh](/developers/docs/smart-contracts/) được thiết kế để "không cần tin cậy", có nghĩa là người dùng không cần phải tin tưởng các bên thứ ba (ví dụ: nhà phát triển và công ty) trước khi tương tác với một hợp đồng. Là một điều kiện tiên quyết cho việc không cần tin cậy, người dùng và các nhà phát triển khác phải có khả năng xác minh mã nguồn của một hợp đồng thông minh. Việc xác minh mã nguồn đảm bảo cho người dùng và nhà phát triển rằng mã hợp đồng đã công bố giống với mã đang chạy tại địa chỉ hợp đồng trên chuỗi khối Ethereum. + +Điều quan trọng là phải phân biệt giữa "xác minh mã nguồn" và "[xác minh chính thức](/developers/docs/smart-contracts/formal-verification/)". Xác minh mã nguồn, sẽ được giải thích chi tiết bên dưới, đề cập đến việc xác minh rằng mã nguồn đã cho của một hợp đồng thông minh bằng ngôn ngữ cấp cao (ví dụ: Solidity) biên dịch thành cùng một chỉ thị biên dịch để được thực thi tại địa chỉ hợp đồng. Tuy nhiên, xác minh chính thức mô tả việc xác minh tính đúng đắn của một hợp đồng thông minh, có nghĩa là hợp đồng hoạt động như mong đợi. Mặc dù phụ thuộc vào ngữ cảnh, việc xác minh hợp đồng thường đề cập đến việc xác minh mã nguồn. + +## Xác minh mã nguồn là gì? {#what-is-source-code-verification} + +Trước khi triển khai một hợp đồng thông minh trong [Máy ảo Ethereum (EVM)](/developers/docs/evm/), các nhà phát triển [biên dịch](/developers/docs/smart-contracts/compiling/) mã nguồn của hợp đồng — các hướng dẫn [được viết bằng Solidity](/developers/docs/smart-contracts/languages/) hoặc một ngôn ngữ lập trình cấp cao khác — thành chỉ thị biên dịch. Vì EVM không thể diễn giải các hướng dẫn cấp cao, việc biên dịch mã nguồn thành chỉ thị biên dịch (tức là các hướng dẫn máy cấp thấp) là cần thiết để thực thi logic hợp đồng trong EVM. + +Xác minh mã nguồn là so sánh mã nguồn của một hợp đồng thông minh và chỉ thị biên dịch đã biên dịch được sử dụng trong quá trình tạo hợp đồng để phát hiện bất kỳ sự khác biệt nào. Việc xác minh hợp đồng thông minh là quan trọng vì mã hợp đồng được quảng cáo có thể khác với mã chạy trên chuỗi khối. + +Việc xác minh hợp đồng thông minh cho phép điều tra những gì một hợp đồng thực hiện thông qua ngôn ngữ cấp cao hơn mà nó được viết, mà không cần phải đọc mã máy. Các hàm, giá trị và thường là tên biến và nhận xét vẫn giống với mã nguồn gốc được biên dịch và triển khai. Điều này làm cho việc đọc mã dễ dàng hơn nhiều. Xác minh nguồn cũng cung cấp tài liệu tham khảo mã, để người dùng cuối biết hợp đồng thông minh được thiết kế để làm gì. + +### Xác minh đầy đủ là gì? {#full-verification} + +Có một số phần của mã nguồn không ảnh hưởng đến chỉ thị biên dịch đã biên dịch, chẳng hạn như nhận xét hoặc tên biến. Điều đó có nghĩa là hai mã nguồn có tên biến khác nhau và nhận xét khác nhau đều có thể xác minh cùng một hợp đồng. Với điều đó, một tác nhân độc hại có thể thêm các nhận xét lừa đảo hoặc đặt tên biến gây hiểu lầm bên trong mã nguồn và được xác minh hợp đồng với một mã nguồn khác với mã nguồn gốc. + +Có thể tránh điều này bằng cách nối thêm dữ liệu bổ sung vào chỉ thị biên dịch để làm _đảm bảo mật mã_ cho tính chính xác của mã nguồn và làm _dấu vân tay_ của thông tin biên dịch. Thông tin cần thiết được tìm thấy trong [siêu dữ liệu hợp đồng của Solidity](https://docs.soliditylang.org/en/v0.8.15/metadata.html), và hàm băm của tệp này được nối vào chỉ thị biên dịch của một hợp đồng. Bạn có thể thấy nó hoạt động trong [sân chơi siêu dữ liệu](https://playground.sourcify.dev) + +Tệp siêu dữ liệu chứa thông tin về việc biên dịch hợp đồng bao gồm các tệp nguồn và hàm băm của chúng. Nghĩa là, nếu bất kỳ cài đặt biên dịch nào hoặc thậm chí một byte trong một trong các tệp nguồn thay đổi, tệp siêu dữ liệu sẽ thay đổi. Do đó, hàm băm của tệp siêu dữ liệu, được nối vào chỉ thị biên dịch, cũng thay đổi. Điều đó có nghĩa là nếu chỉ thị biên dịch của hợp đồng + hàm băm siêu dữ liệu được nối vào khớp với mã nguồn và cài đặt biên dịch đã cho, chúng ta có thể chắc chắn rằng đây chính xác là cùng một mã nguồn được sử dụng trong quá trình biên dịch ban đầu, không có một byte nào khác. + +Loại xác minh này tận dụng hàm băm siêu dữ liệu được gọi là **"[xác minh đầy đủ](https://docs.sourcify.dev/docs/full-vs-partial-match/)"** (cũng là "xác minh hoàn hảo"). Nếu các hàm băm siêu dữ liệu không khớp hoặc không được xem xét trong quá trình xác minh, đó sẽ là một "kết quả khớp một phần", hiện là cách phổ biến hơn để xác minh hợp đồng. Có thể [chèn mã độc hại](https://samczsun.com/hiding-in-plain-sight/) mà sẽ không được phản ánh trong mã nguồn đã xác minh nếu không có xác minh đầy đủ. Hầu hết các nhà phát triển không biết về xác minh đầy đủ và không giữ tệp siêu dữ liệu của quá trình biên dịch của họ, do đó xác minh một phần đã là phương pháp trên thực tế để xác minh hợp đồng cho đến nay. + +## Tại sao việc xác minh mã nguồn lại quan trọng? {#importance-of-source-code-verification} + +### Tính không cần tin cậy {#trustlessness} + +Tính không cần tin cậy được cho là tiền đề lớn nhất cho các hợp đồng thông minh và [các ứng dụng phi tập trung (dapps)](/developers/docs/dapps/). Các hợp đồng thông minh là "bất biến" và không thể thay đổi; một hợp đồng sẽ chỉ thực thi logic kinh doanh được xác định trong mã tại thời điểm triển khai. Điều này có nghĩa là các nhà phát triển và doanh nghiệp không thể can thiệp vào mã của hợp đồng sau khi triển khai trên Ethereum. + +Để một hợp đồng thông minh không cần tin cậy, mã hợp đồng phải có sẵn để xác minh độc lập. Mặc dù chỉ thị biên dịch đã biên dịch cho mọi hợp đồng thông minh đều có sẵn công khai trên chuỗi khối, nhưng ngôn ngữ cấp thấp rất khó hiểu — đối với cả nhà phát triển và người dùng. + +Các dự án giảm bớt các giả định về sự tin cậy bằng cách công bố mã nguồn của các hợp đồng của họ. Nhưng điều này dẫn đến một vấn đề khác: rất khó để xác minh rằng mã nguồn đã xuất bản khớp với chỉ thị biên dịch của hợp đồng. Trong trường hợp này, giá trị của tính không cần tin cậy bị mất đi vì người dùng phải tin tưởng các nhà phát triển sẽ không thay đổi logic kinh doanh của hợp đồng (tức là bằng cách thay đổi chỉ thị biên dịch) trước khi triển khai nó trên chuỗi khối. + +Các công cụ xác minh mã nguồn cung cấp sự đảm bảo rằng các tệp mã nguồn của hợp đồng thông minh khớp với mã hợp ngữ. Kết quả là một hệ sinh thái không cần tin cậy, nơi người dùng không tin tưởng một cách mù quáng vào các bên thứ ba mà thay vào đó xác minh mã trước khi gửi tiền vào hợp đồng. + +### An toàn cho Người dùng {#user-safety} + +Với các hợp đồng thông minh, thường có rất nhiều tiền bị đe dọa. Điều này đòi hỏi sự đảm bảo an ninh cao hơn và xác minh logic của một hợp đồng thông minh trước khi sử dụng nó. Vấn đề là các nhà phát triển vô đạo đức có thể lừa dối người dùng bằng cách chèn mã độc hại vào một hợp đồng thông minh. Nếu không có xác minh, các hợp đồng thông minh độc hại có thể có [cửa hậu](https://www.trustnodes.com/2018/11/10/concerns-rise-over-backdoored-smart-contracts), các cơ chế kiểm soát truy cập gây tranh cãi, các lỗ hổng có thể bị khai thác và những thứ khác gây nguy hiểm cho sự an toàn của người dùng mà không bị phát hiện. + +Việc công bố các tệp mã nguồn của một hợp đồng thông minh giúp những người quan tâm, chẳng hạn như kiểm toán viên, đánh giá hợp đồng để tìm các véc-tơ tấn công tiềm ẩn dễ dàng hơn. Với nhiều bên độc lập xác minh một hợp đồng thông minh, người dùng có sự đảm bảo mạnh mẽ hơn về tính bảo mật của nó. + +## Cách xác minh mã nguồn cho các hợp đồng thông minh Ethereum {#source-code-verification-for-ethereum-smart-contracts} + +[Việc triển khai một hợp đồng thông minh trên Ethereum](/developers/docs/smart-contracts/deploying/) yêu cầu gửi một giao dịch có tải trọng dữ liệu (chỉ thị biên dịch đã biên dịch) đến một địa chỉ đặc biệt. Tải trọng dữ liệu được tạo bằng cách biên dịch mã nguồn, cộng với các [đối số hàm khởi tạo](https://docs.soliditylang.org/en/v0.8.14/contracts.html#constructor) của phiên bản hợp đồng được nối vào tải trọng dữ liệu trong giao dịch. Biên dịch có tính xác định, có nghĩa là nó luôn tạo ra cùng một đầu ra (tức là chỉ thị biên dịch hợp đồng) nếu cùng một tệp nguồn và cài đặt biên dịch (ví dụ: phiên bản trình biên dịch, trình tối ưu hóa) được sử dụng. + +![Sơ đồ hiển thị việc xác minh mã nguồn hợp đồng thông minh](./source-code-verification.png) + +Việc xác minh một hợp đồng thông minh về cơ bản bao gồm các bước sau: + +1. Nhập các tệp nguồn và cài đặt biên dịch vào trình biên dịch. + +2. Trình biên dịch xuất ra chỉ thị biên dịch của hợp đồng + +3. Lấy chỉ thị biên dịch của hợp đồng đã triển khai tại một địa chỉ nhất định + +4. So sánh chỉ thị biên dịch đã triển khai với chỉ thị biên dịch đã biên dịch lại. Nếu các mã khớp nhau, hợp đồng sẽ được xác minh với mã nguồn và cài đặt biên dịch đã cho. + +5. Ngoài ra, nếu các hàm băm siêu dữ liệu ở cuối chỉ thị biên dịch khớp nhau, đó sẽ là một kết quả khớp hoàn toàn. + +Lưu ý rằng đây là một mô tả đơn giản về xác minh và có nhiều ngoại lệ sẽ không hoạt động với điều này, chẳng hạn như có [các biến bất biến](https://docs.sourcify.dev/docs/immutables/). + +## Các công cụ xác minh mã nguồn {#source-code-verification-tools} + +Quy trình xác minh hợp đồng truyền thống có thể phức tạp. Đây là lý do tại sao chúng tôi có các công cụ để xác minh mã nguồn cho các hợp đồng thông minh được triển khai trên Ethereum. Các công cụ này tự động hóa phần lớn quá trình xác minh mã nguồn và cũng quản lý các hợp đồng đã xác minh vì lợi ích của người dùng. + +### Etherscan {#etherscan} + +Mặc dù chủ yếu được biết đến như một [trình khám phá chuỗi khối Ethereum](/developers/docs/data-and-analytics/block-explorers/), Etherscan cũng cung cấp [dịch vụ xác minh mã nguồn](https://etherscan.io/verifyContract) cho các nhà phát triển và người dùng hợp đồng thông minh. + +Etherscan cho phép bạn biên dịch lại chỉ thị biên dịch của hợp đồng từ tải trọng dữ liệu gốc (mã nguồn, địa chỉ thư viện, cài đặt trình biên dịch, địa chỉ hợp đồng, v.v.) Nếu chỉ thị biên dịch được biên dịch lại được liên kết với chỉ thị biên dịch (và các tham số của hàm tạo) của hợp đồng trên chuỗi, thì [hợp đồng được xác minh](https://info.etherscan.com/types-of-contract-verification/). + +Sau khi được xác minh, mã nguồn của hợp đồng của bạn sẽ nhận được nhãn "Đã xác minh" và được xuất bản trên Etherscan để những người khác kiểm tra. Nó cũng được thêm vào phần [Hợp đồng đã xác minh](https://etherscan.io/contractsVerified/) — một kho lưu trữ các hợp đồng thông minh có mã nguồn đã được xác minh. + +Etherscan là công cụ được sử dụng nhiều nhất để xác minh hợp đồng. Tuy nhiên, việc xác minh hợp đồng của Etherscan có một nhược điểm: nó không thể so sánh **hàm băm siêu dữ liệu** của chỉ thị biên dịch trên chuỗi và chỉ thị biên dịch đã được biên dịch lại. Do đó, các kết quả trùng khớp trong Etherscan là các kết quả khớp một phần. + +[Tìm hiểu thêm về xác minh hợp đồng trên Etherscan](https://medium.com/etherscan-blog/verifying-contracts-on-etherscan-f995ab772327). + +### Blockscout {#blockscout} + +[Blockscout](https://blockscout.com/) là một trình khám phá chuỗi khối mã nguồn mở cũng cung cấp [dịch vụ xác minh hợp đồng](https://eth.blockscout.com/contract-verification) cho các nhà phát triển và người dùng hợp đồng thông minh. Là một giải pháp thay thế mã nguồn mở, Blockscout cung cấp sự minh bạch trong cách thực hiện xác minh và cho phép cộng đồng đóng góp để cải thiện quy trình xác minh. + +Tương tự như các dịch vụ xác minh khác, Blockscout cho phép bạn xác minh mã nguồn hợp đồng của mình bằng cách biên dịch lại chỉ thị biên dịch và so sánh nó với hợp đồng đã triển khai. Sau khi được xác minh, hợp đồng của bạn sẽ nhận được trạng thái xác minh và mã nguồn sẽ được công khai để kiểm tra và tương tác. Các hợp đồng đã xác minh cũng được liệt kê trong [kho lưu trữ hợp đồng đã xác minh](https://eth.blockscout.com/verified-contracts) của Blockscout để dễ dàng duyệt và khám phá. + +### Sourcify {#sourcify} + +[Sourcify](https://sourcify.dev/#/verifier) là một công cụ khác để xác minh các hợp đồng có mã nguồn mở và phi tập trung. Nó không phải là một trình khám phá khối và chỉ xác minh các hợp đồng trên [các mạng dựa trên EVM khác nhau](https://docs.sourcify.dev/docs/chains). Nó hoạt động như một cơ sở hạ tầng công cộng để các công cụ khác xây dựng trên đó, và nhằm mục đích cho phép các tương tác hợp đồng thân thiện với con người hơn bằng cách sử dụng [ABI](/developers/docs/smart-contracts/compiling/#web-applications) và các nhận xét [NatSpec](https://docs.soliditylang.org/en/v0.8.15/natspec-format.html) được tìm thấy trong tệp siêu dữ liệu. + +Không giống như Etherscan, Sourcify hỗ trợ các kết quả khớp hoàn toàn với hàm băm siêu dữ liệu. Các hợp đồng đã xác minh được phục vụ trong [kho lưu trữ công khai](https://docs.sourcify.dev/docs/repository/) của nó trên HTTP và [IPFS](https://docs.ipfs.io/concepts/what-is-ipfs/#what-is-ipfs), đây là một bộ lưu trữ phi tập trung, [có thể định địa chỉ nội dung](https://docs.storacha.network/concepts/content-addressing/). Điều này cho phép tìm nạp tệp siêu dữ liệu của hợp đồng qua IPFS vì hàm băm siêu dữ liệu được nối vào là một hàm băm IPFS. + +Ngoài ra, người ta cũng có thể truy xuất các tệp mã nguồn qua IPFS, vì các hàm băm IPFS của các tệp này cũng được tìm thấy trong siêu dữ liệu. Một hợp đồng có thể được xác minh bằng cách cung cấp tệp siêu dữ liệu và các tệp nguồn qua Giao diện Lập trình Ứng dụng của nó hoặc [Giao diện Người dùng](https://sourcify.dev/#/verifier), hoặc sử dụng các plugin. Công cụ giám sát của Sourcify cũng lắng nghe việc tạo hợp đồng trên các khối mới và cố gắng xác minh các hợp đồng nếu siêu dữ liệu và tệp nguồn của chúng được xuất bản trên IPFS. + +[Thông tin thêm về việc xác minh hợp đồng trên Sourcify](https://soliditylang.org/blog/2020/06/25/sourcify-faq/). + +### Tenderly {#tenderly} + +[Nền tảng Tenderly](https://tenderly.co/) cho phép các nhà phát triển Web3 xây dựng, kiểm tra, giám sát và vận hành các hợp đồng thông minh. Kết hợp các công cụ gỡ lỗi với khả năng quan sát và các khối xây dựng cơ sở hạ tầng, Tenderly giúp các nhà phát triển tăng tốc phát triển hợp đồng thông minh. Để kích hoạt đầy đủ các tính năng của Tenderly, các nhà phát triển cần [thực hiện xác minh mã nguồn](https://docs.tenderly.co/monitoring/contract-verification) bằng một số phương pháp. + +Có thể xác minh hợp đồng một cách riêng tư hoặc công khai. Nếu được xác minh riêng tư, hợp đồng thông minh chỉ hiển thị với bạn (và các thành viên khác trong dự án của bạn). Việc xác minh một hợp đồng công khai sẽ làm cho nó hiển thị với mọi người sử dụng nền tảng Tenderly. + +Bạn có thể xác minh các hợp đồng của mình bằng [Bảng điều khiển](https://docs.tenderly.co/contract-verification), [plugin Tenderly Hardhat](https://docs.tenderly.co/contract-verification/hardhat), hoặc [CLI](https://docs.tenderly.co/monitoring/smart-contract-verification/verifying-contracts-using-cli). + +Khi xác minh hợp đồng thông qua Bảng điều khiển, bạn cần nhập tệp nguồn hoặc tệp siêu dữ liệu được tạo bởi trình biên dịch Solidity, địa chỉ/mạng và cài đặt trình biên dịch. + +Sử dụng plugin Tenderly Hardhat cho phép kiểm soát nhiều hơn đối với quá trình xác minh với ít nỗ lực hơn, cho phép bạn lựa chọn giữa xác minh tự động (không cần mã) và thủ công (dựa trên mã). + +## Đọc thêm {#further-reading} + +- [Xác minh mã nguồn hợp đồng](https://programtheblockchain.com/posts/2018/01/16/verifying-contract-source-code/) diff --git a/public/content/translations/vi/developers/docs/standards/index.md b/public/content/translations/vi/developers/docs/standards/index.md new file mode 100644 index 00000000000..5927ed03271 --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/index.md @@ -0,0 +1,59 @@ +--- +title: "Tiêu chuẩn phát triển Ethereum" +description: "Tìm hiểu về các tiêu chuẩn Ethereum, bao gồm EIPs, các tiêu chuẩn token như ERC-20 và ERC-721, cùng với các quy ước phát triển." +lang: vi +incomplete: true +--- + +## Tổng quan về các tiêu chuẩn {#standards-overview} + +Cộng đồng Ethereum đã áp dụng nhiều tiêu chuẩn giúp giữ cho các dự án (chẳng hạn như [máy khách Ethereum](/developers/docs/nodes-and-clients/) và ví) có thể tương tác giữa các lần triển khai và đảm bảo các hợp đồng thông minh và các ứng dụng phi tập trung vẫn có thể kết hợp được. + +Thông thường, các tiêu chuẩn được giới thiệu dưới dạng [Đề xuất Cải tiến Ethereum](/eips/) (EIP), được các thành viên cộng đồng thảo luận thông qua một [quy trình tiêu chuẩn](https://eips.ethereum.org/EIPS/eip-1). + +- [Giới thiệu về EIP](/eips/) +- [Danh sách các EIP](https://eips.ethereum.org/) +- [Kho lưu trữ GitHub của EIP](https://github.com/ethereum/EIPs) +- [Bảng thảo luận EIP](https://ethereum-magicians.org/c/eips) +- [Giới thiệu về Quản trị Ethereum](/governance/) +- [Tổng quan về Quản trị Ethereum](https://web.archive.org/web/20201107234050/https://blog.bmannconsulting.com/ethereum-governance/) _Ngày 31 tháng 3 năm 2019 - Boris Mann_ +- [Quản trị Phát triển Giao thức Ethereum và Điều phối Nâng cấp Mạng lưới](https://hudsonjameson.com/posts/2020-03-23-ethereum-protocol-development-governance-and-network-upgrade-coordination/) _Ngày 23 tháng 3 năm 2020 - Hudson Jameson_ +- [Danh sách phát tất cả các cuộc họp của Nhà phát triển cốt lõi Ethereum](https://www.youtube.com/@EthereumProtocol) _(Danh sách phát trên YouTube)_ + +## Các loại tiêu chuẩn {#types-of-standards} + +Có 3 loại EIPs: + +- Standards Track: mô tả bất kỳ thay đổi nào ảnh hưởng đến hầu hết hoặc tất cả các khai triển Ethereum +- [Lộ trình meta](https://eips.ethereum.org/meta): mô tả một quy trình xung quanh Ethereum hoặc đề xuất thay đổi một quy trình +- [Lộ trình thông tin](https://eips.ethereum.org/informational): mô tả một vấn đề thiết kế của Ethereum hoặc cung cấp các hướng dẫn chung hoặc thông tin cho cộng đồng Ethereum + +Hơn nữa, Lộ trình Chuẩn được chia thành 4 loại: + +- [Cốt lõi](https://eips.ethereum.org/core): các cải tiến yêu cầu phân nhánh đồng thuận +- [Mạng lưới](https://eips.ethereum.org/networking): các cải tiến xung quanh devp2p và Giao thức phụ Ethereum nhẹ, cũng như các cải tiến được đề xuất cho các thông số kỹ thuật giao thức mạng của whisper và swarm. +- [Giao diện](https://eips.ethereum.org/interface): các cải tiến xung quanh các tiêu chuẩn và thông số kỹ thuật API/RPC của máy khách, và các tiêu chuẩn cấp ngôn ngữ nhất định như tên phương thức và ABI hợp đồng. +- [ERC](https://eips.ethereum.org/erc): các tiêu chuẩn và quy ước cấp ứng dụng + +Thông tin chi tiết hơn về các loại và danh mục khác nhau này có thể được tìm thấy trong [EIP-1](https://eips.ethereum.org/EIPS/eip-1#eip-types) + +### Các tiêu chuẩn token {#token-standards} + +- [ERC-20](/developers/docs/standards/tokens/erc-20/) - Một giao diện tiêu chuẩn cho các token có thể thay thế (có thể hoán đổi cho nhau), như token biểu quyết, token cổ phần hoặc tiền ảo. + - [ERC-223](/developers/docs/standards/tokens/erc-223/) - Một tiêu chuẩn token có thể thay thế giúp các token hoạt động giống hệt như ether và hỗ trợ xử lý việc chuyển token ở phía người nhận. + - [ERC-1363](/developers/docs/standards/tokens/erc-1363/) - Một giao diện mở rộng cho các token ERC-20 hỗ trợ thực thi lệnh gọi lại trên các hợp đồng của người nhận trong một giao dịch duy nhất. +- [ERC-721](/developers/docs/standards/tokens/erc-721/) - Một giao diện tiêu chuẩn cho các token không thể thay thế, như một chứng từ cho một tác phẩm nghệ thuật hoặc một bài hát. + - [ERC-2309](https://eips.ethereum.org/EIPS/eip-2309) - Một sự kiện được tiêu chuẩn hóa được phát ra khi tạo/chuyển một hoặc nhiều token không thể thay thế sử dụng các mã định danh token liên tiếp. + - [ERC-4400](https://eips.ethereum.org/EIPS/eip-4400) - Phần mở rộng giao diện cho vai trò người tiêu dùng EIP-721. + - [ERC-4907](https://eips.ethereum.org/EIPS/eip-4907) - Thêm một vai trò có giới hạn thời gian với các quyền hạn bị hạn chế cho các token ERC-721. +- [ERC-777](/developers/docs/standards/tokens/erc-777/) - **(KHÔNG ĐƯỢC KHUYẾN NGHỊ)** Một tiêu chuẩn token cải tiến so với ERC-20. +- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - Một tiêu chuẩn token có thể chứa cả tài sản có thể thay thế và không thể thay thế. +- [ERC-4626](/developers/docs/standards/tokens/erc-4626/) - Một tiêu chuẩn kho vault được token hóa được thiết kế để tối ưu hóa và thống nhất các thông số kỹ thuật của các kho vault sinh lời. + +Tìm hiểu thêm về [các tiêu chuẩn token](/developers/docs/standards/tokens/). + +## Đọc thêm {#further-reading} + +- [Đề xuất Cải tiến Ethereum (EIP)](/eips/) + +_Biết về nguồn lực cộng đồng đã giúp đỡ bạn? Chỉnh sửa trang này và bổ sung!_ diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-1155/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-1155/index.md new file mode 100644 index 00000000000..80ba366e510 --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-1155/index.md @@ -0,0 +1,146 @@ +--- +title: "Tiêu chuẩn Đa Token ERC-1155" +description: "Tìm hiểu về ERC-1155, một tiêu chuẩn đa token kết hợp các token có thể thay thế và không thể thay thế trong một hợp đồng duy nhất." +lang: vi +--- + +## Giới thiệu {#introduction} + +Một giao diện tiêu chuẩn cho các hợp đồng quản lý nhiều loại token. Một hợp đồng được triển khai duy nhất có thể bao gồm bất kỳ sự kết hợp nào của token có thể thay thế, token không thể thay thế hoặc các cấu hình khác (ví dụ: token bán thay thế). + +**Tiêu chuẩn Đa Token có nghĩa là gì?** + +Ý tưởng này rất đơn giản và tìm cách tạo ra một giao diện hợp đồng thông minh có thể đại diện và kiểm soát bất kỳ số lượng loại token có thể thay thế và không thể thay thế nào. Theo cách này, token ERC-1155 có thể thực hiện các chức năng tương tự như token [ERC-20](/developers/docs/standards/tokens/erc-20/) và [ERC-721](/developers/docs/standards/tokens/erc-721/), và thậm chí cả hai cùng một lúc. Nó cải thiện chức năng của cả hai tiêu chuẩn ERC-20 và ERC-721, giúp nó hiệu quả hơn và sửa chữa các lỗi triển khai rõ ràng. + +Token ERC-1155 được mô tả đầy đủ trong [EIP-1155](https://eips.ethereum.org/EIPS/eip-1155). + +## Điều kiện tiên quyết {#prerequisites} + +Để hiểu rõ hơn về trang này, chúng tôi khuyên bạn nên đọc trước về [các tiêu chuẩn token](/developers/docs/standards/tokens/), [ERC-20](/developers/docs/standards/tokens/erc-20/) và [ERC-721](/developers/docs/standards/tokens/erc-721/). + +## Các chức năng và tính năng của ERC-1155: {#body} + +- [Chuyển hàng loạt](#batch_transfers): Chuyển nhiều tài sản trong một lệnh gọi duy nhất. +- [Số dư hàng loạt](#batch_balance): Lấy số dư của nhiều tài sản trong một lệnh gọi duy nhất. +- [Phê duyệt hàng loạt](#batch_approval): Phê duyệt tất cả các token cho một địa chỉ. +- [Hook](#receive_hook): Hook nhận token. +- [Hỗ trợ NFT](#nft_support): Nếu nguồn cung chỉ là 1, hãy coi nó như một NFT. +- [Quy tắc chuyển an toàn](#safe_transfer_rule): Bộ quy tắc để chuyển an toàn. + +### Chuyển hàng loạt {#batch-transfers} + +Việc chuyển hàng loạt hoạt động rất giống với các giao dịch chuyển ERC-20 thông thường. Hãy xem hàm `transferFrom` ERC-20 thông thường: + +```solidity +// ERC-20 +function transferFrom(address from, address to, uint256 value) external returns (bool); + +// ERC-1155 +function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data +) external; +``` + +Sự khác biệt duy nhất trong ERC-1155 là chúng ta chuyển các giá trị dưới dạng một mảng và chúng ta cũng chuyển một mảng các id. Ví dụ với `ids=[3, 6, 13]` và `values=[100, 200, 5]`, các giao dịch chuyển kết quả sẽ là + +1. Chuyển 100 token có id 3 từ `_from` đến `_to`. +2. Chuyển 200 token có id 6 từ `_from` đến `_to`. +3. Chuyển 5 token có id 13 từ `_from` đến `_to`. + +Trong ERC-1155, chúng ta chỉ có `transferFrom`, không có `transfer`. Để sử dụng nó như một `transfer` thông thường, chỉ cần đặt địa chỉ người gửi thành địa chỉ đang gọi hàm. + +### Số dư hàng loạt {#batch-balance} + +Lệnh gọi `balanceOf` ERC-20 tương ứng cũng có hàm đối tác với sự hỗ trợ hàng loạt. Xin nhắc lại, đây là phiên bản ERC-20: + +```solidity +// ERC-20 +function balanceOf(address owner) external view returns (uint256); + +// ERC-1155 +function balanceOfBatch( + address[] calldata _owners, + uint256[] calldata _ids +) external view returns (uint256[] memory); +``` + +Thậm chí còn đơn giản hơn đối với lệnh gọi số dư, chúng ta có thể truy xuất nhiều số dư trong một lệnh gọi duy nhất. Chúng ta chuyển mảng chủ sở hữu, tiếp theo là mảng id token. + +Ví dụ với `_ids=[3, 6, 13]` và `_owners=[0xbeef..., 0x1337..., 0x1111...]`, giá trị trả về sẽ là + +```solidity +[ + balanceOf(0xbeef...), + balanceOf(0x1337...), + balanceOf(0x1111...) +] +``` + +### Phê duyệt hàng loạt {#batch-approval} + +```solidity +// ERC-1155 +function setApprovalForAll( + address _operator, + bool _approved +) external; + +function isApprovedForAll( + address _owner, + address _operator +) external view returns (bool); +``` + +Việc phê duyệt hơi khác so với ERC-20. Thay vì phê duyệt các số lượng cụ thể, bạn đặt một nhà điều hành thành được phê duyệt hoặc không được phê duyệt thông qua `setApprovalForAll`. + +Việc đọc trạng thái hiện tại có thể được thực hiện thông qua `isApprovedForAll`. Như bạn có thể thấy, đó là một hoạt động tất cả hoặc không có gì. Bạn không thể xác định số lượng token cần phê duyệt hoặc thậm chí là lớp token nào. + +Điều này được thiết kế có chủ ý với mục tiêu đơn giản. Bạn chỉ có thể phê duyệt mọi thứ cho một địa chỉ. + +### Hook nhận {#receive-hook} + +```solidity +function onERC1155BatchReceived( + address _operator, + address _from, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data +) external returns(bytes4); +``` + +Với sự hỗ trợ của [EIP-165](https://eips.ethereum.org/EIPS/eip-165), ERC-1155 hỗ trợ các hook nhận chỉ dành cho các hợp đồng thông minh. Hàm hook phải trả về một giá trị bytes4 kỳ diệu được xác định trước, được đưa ra như sau: + +```solidity +bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)")) +``` + +Khi hợp đồng nhận trả về giá trị này, nghĩa là hợp đồng chấp nhận việc chuyển giao và biết cách xử lý các token ERC-1155. Tuyệt vời, không còn token bị kẹt trong hợp đồng nữa! + +### Hỗ trợ NFT {#nft-support} + +Khi nguồn cung chỉ là một, token về cơ bản là một token không thể thay thế (NFT). Và theo tiêu chuẩn của ERC-721, bạn có thể xác định một URL siêu dữ liệu. URL có thể được đọc và sửa đổi bởi các ứng dụng, xem [tại đây](https://eips.ethereum.org/EIPS/eip-1155#metadata). + +### Quy tắc chuyển an toàn {#safe-transfer-rule} + +Chúng ta đã đề cập đến một vài quy tắc chuyển an toàn trong các giải thích trước đó. Nhưng hãy xem xét các quy tắc quan trọng nhất: + +1. Người gọi phải được phê duyệt để chi tiêu các token cho địa chỉ `_from` hoặc người gọi phải bằng `_from`. +2. Lệnh gọi chuyển phải hoàn nguyên nếu + 1. địa chỉ `_to` là 0. + 2. độ dài của `_ids` không giống với độ dài của `_values`. + 3. bất kỳ số dư nào của người nắm giữ đối với các token trong `_ids` thấp hơn số lượng tương ứng trong `_values` được gửi cho người nhận. + 4. bất kỳ lỗi nào khác xảy ra. + +_Lưu ý_: Tất cả các hàm hàng loạt bao gồm cả hook cũng tồn tại dưới dạng các phiên bản không có hàng loạt. Điều này được thực hiện để tiết kiệm gas, vì việc chuyển chỉ một tài sản có thể vẫn sẽ là cách được sử dụng phổ biến nhất. Chúng tôi đã bỏ qua chúng để cho đơn giản trong các giải thích, bao gồm cả các quy tắc chuyển an toàn. Tên giống hệt nhau, chỉ cần xóa 'Batch'. + +## Đọc thêm {#further-reading} + +- [EIP-1155: Tiêu chuẩn Đa Token](https://eips.ethereum.org/EIPS/eip-1155) +- [ERC-1155: Tài liệu Openzeppelin](https://docs.openzeppelin.com/contracts/5.x/erc1155) +- [ERC-1155: Repo GitHub](https://github.com/enjin/erc-1155) +- [API NFT của Alchemy](https://www.alchemy.com/docs/reference/nft-api-quickstart) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-1363/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-1363/index.md new file mode 100644 index 00000000000..fee34915438 --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-1363/index.md @@ -0,0 +1,213 @@ +--- +title: "Tiêu chuẩn Token có thể thanh toán ERC-1363" +description: "ERC-1363 là một giao diện mở rộng cho các token ERC-20, hỗ trợ thực thi logic tùy chỉnh trên hợp đồng của người nhận sau khi chuyển token hoặc trên hợp đồng của người chi tiêu sau khi phê duyệt, tất cả chỉ trong một giao dịch duy nhất." +lang: vi +--- + +## Giới thiệu {#introduction} + +### ERC-1363 là gì? {#what-is-erc1363} + +ERC-1363 là một giao diện mở rộng cho các token ERC-20, hỗ trợ thực thi logic tùy chỉnh trên hợp đồng của người nhận sau khi chuyển token hoặc trên hợp đồng của người chi tiêu sau khi phê duyệt, tất cả chỉ trong một giao dịch duy nhất. + +### Sự khác biệt so với ERC-20 {#erc20-differences} + +Các hoạt động ERC-20 tiêu chuẩn như `transfer`, `transferFrom` và `approve` không cho phép thực thi mã trên hợp đồng của người nhận hoặc người chi tiêu mà không cần một giao dịch riêng biệt. +Điều này tạo ra sự phức tạp trong quá trình phát triển giao diện người dùng và rào cản trong việc áp dụng vì người dùng phải đợi giao dịch đầu tiên được thực thi rồi mới gửi giao dịch thứ hai. +Họ cũng phải trả GAS hai lần. + +ERC-1363 giúp các token có thể thay thế thực hiện các hành động dễ dàng hơn và hoạt động mà không cần sử dụng bất kỳ trình lắng nghe ngoài chuỗi nào. +Nó cho phép thực hiện một lệnh gọi lại trên hợp đồng của người nhận hoặc người chi tiêu, sau một lần chuyển hoặc một lần phê duyệt, trong một giao dịch duy nhất. + +## Điều kiện tiên quyết {#prerequisites} + +Để hiểu rõ hơn về trang này, chúng tôi khuyên bạn nên đọc trước về: + +- [Các tiêu chuẩn của token](/developers/docs/standards/tokens/) +- [ERC-20](/developers/docs/standards/tokens/erc-20/) + +## Nội dung {#body} + +ERC-1363 giới thiệu một Giao diện Lập trình Ứng dụng tiêu chuẩn cho các token ERC-20 để tương tác với các hợp đồng thông minh sau khi `transfer`, `transferFrom` hoặc `approve`. + +Tiêu chuẩn này cung cấp chức năng cơ bản để chuyển token, cũng như cho phép token được phê duyệt để chúng có thể được chi tiêu bởi một bên thứ ba khác trên chuỗi, và sau đó thực hiện một lệnh gọi lại trên hợp đồng của người nhận hoặc người chi tiêu. + +Có nhiều mục đích sử dụng được đề xuất của các hợp đồng thông minh có thể chấp nhận các lệnh gọi lại ERC-20. + +Các ví dụ có thể là: + +- **Bán token huy động vốn**: token được gửi đi sẽ kích hoạt việc phân bổ phần thưởng ngay lập tức. +- **Dịch vụ**: thanh toán kích hoạt quyền truy cập dịch vụ trong một bước. +- **Hóa đơn**: token tự động thanh toán hóa đơn. +- **Đăng ký**: việc phê duyệt mức phí hàng năm sẽ kích hoạt đăng ký trong khoản thanh toán của tháng đầu tiên. + +Vì những lý do này, nó ban đầu được đặt tên là **"Token có thể thanh toán"**. + +Hành vi gọi lại còn mở rộng hơn nữa tiện ích của nó, cho phép các tương tác liền mạch như: + +- **Góp cổ phần**: token được chuyển sẽ kích hoạt việc khóa tự động trong một hợp đồng góp cổ phần. +- **Bỏ phiếu**: token nhận được sẽ ghi nhận phiếu bầu trong một hệ thống quản trị. +- **Hoán đổi**: việc phê duyệt token sẽ kích hoạt logic hoán đổi trong một bước duy nhất. + +Các token ERC-1363 có thể được sử dụng cho các tiện ích cụ thể trong mọi trường hợp yêu cầu thực thi một lệnh gọi lại sau khi nhận được một lần chuyển hoặc một lần phê duyệt. +ERC-1363 cũng hữu ích để tránh mất token hoặc khóa token trong các hợp đồng thông minh bằng cách xác minh khả năng xử lý token của người nhận. + +Không giống như các đề xuất mở rộng ERC-20 khác, ERC-1363 không ghi đè các phương thức `transfer` và `transferFrom` của ERC-20 và xác định các ID giao diện cần được triển khai để duy trì khả năng tương thích ngược với ERC-20. + +Từ [EIP-1363](https://eips.ethereum.org/EIPS/eip-1363): + +### Các phương thức {#methods} + +Các hợp đồng thông minh triển khai tiêu chuẩn ERC-1363 **PHẢI** triển khai tất cả các hàm trong giao diện `ERC1363`, cũng như các giao diện `ERC20` và `ERC165`. + +```solidity +pragma solidity ^0.8.0; + +/** + * @title ERC1363 + * @dev Một giao diện mở rộng cho các token ERC-20 hỗ trợ thực thi mã trên hợp đồng của người nhận + * sau `transfer` hoặc `transferFrom`, hoặc mã trên hợp đồng của người chi tiêu sau `approve`, trong một giao dịch duy nhất. + */ +interface ERC1363 is ERC20, ERC165 { + /* + * LƯU Ý: mã định danh ERC-165 cho giao diện này là 0xb0202a11. + * 0xb0202a11 === + * bytes4(keccak256('transferAndCall(address,uint256)')) ^ + * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ + * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ + * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ + * bytes4(keccak256('approveAndCall(address,uint256)')) ^ + * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) + */ + + /** + * @dev Di chuyển một lượng token `value` từ tài khoản của người gọi đến `to` + * và sau đó gọi `ERC1363Receiver::onTransferReceived` trên `to`. + * @param to Địa chỉ mà token đang được chuyển đến. + * @param value Số lượng token sẽ được chuyển. + * @return Một giá trị boolean cho biết hoạt động đã thành công trừ khi có lỗi. + */ + function transferAndCall(address to, uint256 value) external returns (bool); + + /** + * @dev Di chuyển một lượng token `value` từ tài khoản của người gọi đến `to` + * và sau đó gọi `ERC1363Receiver::onTransferReceived` trên `to`. + * @param to Địa chỉ mà token đang được chuyển đến. + * @param value Số lượng token sẽ được chuyển. + * @param data Dữ liệu bổ sung không có định dạng cụ thể, được gửi trong lệnh gọi đến `to`. + * @return Một giá trị boolean cho biết hoạt động đã thành công trừ khi có lỗi. + */ + function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); + + /** + * @dev Di chuyển một lượng token `value` từ `from` đến `to` bằng cơ chế cho phép + * và sau đó gọi `ERC1363Receiver::onTransferReceived` trên `to`. + * @param from Địa chỉ gửi token. + * @param to Địa chỉ mà token đang được chuyển đến. + * @param value Số lượng token sẽ được chuyển. + * @return Một giá trị boolean cho biết hoạt động đã thành công trừ khi có lỗi. + */ + function transferFromAndCall(address from, address to, uint256 value) external returns (bool); + + /** + * @dev Di chuyển một lượng token `value` từ `from` đến `to` bằng cơ chế cho phép + * và sau đó gọi `ERC1363Receiver::onTransferReceived` trên `to`. + * @param from Địa chỉ gửi token. + * @param to Địa chỉ mà token đang được chuyển đến. + * @param value Số lượng token sẽ được chuyển. + * @param data Dữ liệu bổ sung không có định dạng cụ thể, được gửi trong lệnh gọi đến `to`. + * @return Một giá trị boolean cho biết hoạt động đã thành công trừ khi có lỗi. + */ + function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); + + /** + * @dev Đặt một lượng token `value` làm mức cho phép của `spender` đối với token của người gọi + * và sau đó gọi `ERC1363Spender::onApprovalReceived` trên `spender`. + * @param spender Địa chỉ sẽ chi tiêu số tiền. + * @param value Số lượng token sẽ được chi tiêu. + * @return Một giá trị boolean cho biết hoạt động đã thành công trừ khi có lỗi. + */ + function approveAndCall(address spender, uint256 value) external returns (bool); + + /** + * @dev Đặt một lượng token `value` làm mức cho phép của `spender` đối với token của người gọi + * và sau đó gọi `ERC1363Spender::onApprovalReceived` trên `spender`. + * @param spender Địa chỉ sẽ chi tiêu số tiền. + * @param value Số lượng token sẽ được chi tiêu. + * @param data Dữ liệu bổ sung không có định dạng cụ thể, được gửi trong lệnh gọi đến `spender`. + * @return Một giá trị boolean cho biết hoạt động đã thành công trừ khi có lỗi. + */ + function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); +} + +interface ERC20 { + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + function transfer(address to, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 value) external returns (bool); + function approve(address spender, uint256 value) external returns (bool); + function totalSupply() external view returns (uint256); + function balanceOf(address account) external view returns (uint256); + function allowance(address owner, address spender) external view returns (uint256); +} + +interface ERC165 { + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} +``` + +Một hợp đồng thông minh muốn chấp nhận token ERC-1363 thông qua `transferAndCall` hoặc `transferFromAndCall` **PHẢI** triển khai giao diện `ERC1363Receiver`: + +```solidity +/** + * @title ERC1363Receiver + * @dev Giao diện cho bất kỳ hợp đồng nào muốn hỗ trợ `transferAndCall` hoặc `transferFromAndCall` từ các hợp đồng token ERC-1363. + */ +interface ERC1363Receiver { + /** + * @dev Bất cứ khi nào token ERC-1363 được chuyển đến hợp đồng này qua `ERC1363::transferAndCall` hoặc `ERC1363::transferFromAndCall` + * bởi `operator` từ `from`, hàm này sẽ được gọi. + * + * LƯU Ý: Để chấp nhận việc chuyển, hàm này phải trả về + * `bytes4(keccak256(\"onTransferReceived(address,address,uint256,bytes)\"))` + * (tức là 0x88a7ca5c, hoặc bộ chọn hàm của chính nó). + * + * @param operator Địa chỉ đã gọi hàm `transferAndCall` hoặc `transferFromAndCall`. + * @param from Địa chỉ mà từ đó token được chuyển đi. + * @param value Số lượng token được chuyển. + * @param data Dữ liệu bổ sung không có định dạng cụ thể. + * @return `bytes4(keccak256(\"onTransferReceived(address,address,uint256,bytes)\"))` nếu việc chuyển được cho phép trừ khi có lỗi. + */ + function onTransferReceived(address operator, address from, uint256 value, bytes calldata data) external returns (bytes4); +} +``` + +Một hợp đồng thông minh muốn chấp nhận token ERC-1363 thông qua `approveAndCall` **PHẢI** triển khai giao diện `ERC1363Spender`: + +```solidity +/** + * @title ERC1363Spender + * @dev Giao diện cho bất kỳ hợp đồng nào muốn hỗ trợ `approveAndCall` từ các hợp đồng token ERC-1363. + */ +interface ERC1363Spender { + /** + * @dev Bất cứ khi nào một `owner` token ERC-1363 phê duyệt hợp đồng này qua `ERC1363::approveAndCall` + * để chi tiêu token của họ, hàm này sẽ được gọi. + * + * LƯU Ý: Để chấp nhận việc phê duyệt, hàm này phải trả về + * `bytes4(keccak256(\"onApprovalReceived(address,uint256,bytes)\"))` + * (tức là 0x7b04a2d0, hoặc bộ chọn hàm của chính nó). + * + * @param owner Địa chỉ đã gọi hàm `approveAndCall` và trước đây đã sở hữu các token. + * @param value Số lượng token sẽ được chi tiêu. + * @param data Dữ liệu bổ sung không có định dạng cụ thể. + * @return `bytes4(keccak256(\"onApprovalReceived(address,uint256,bytes)\"))` nếu việc phê duyệt được cho phép trừ khi có lỗi. + */ + function onApprovalReceived(address owner, uint256 value, bytes calldata data) external returns (bytes4); +} +``` + +## Đọc thêm {#further-reading} + +- [ERC-1363: Tiêu chuẩn Token có thể thanh toán](https://eips.ethereum.org/EIPS/eip-1363) +- [ERC-1363: Kho lưu trữ GitHub](https://github.com/vittominacori/erc1363-payable-token) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-20/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-20/index.md new file mode 100644 index 00000000000..17cd883c680 --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-20/index.md @@ -0,0 +1,187 @@ +--- +title: "Tiêu chuẩn token ERC-20" +description: "Tìm hiểu về ERC-20, tiêu chuẩn cho các token có thể thay thế trên Ethereum, cho phép các ứng dụng token tương thích với nhau." +lang: vi +--- + +## Giới thiệu {#introduction} + +**Token là gì?** + +Token đại diện cho bất kỳ thứ gì trên Ethereum: + +- Điểm danh tiếng trên nền tảng online +- Kỹ năng của nhân vật trong game +- Tài sản tài chính như cổ phần của một công ty +- Tiền pháp định như USD chẳng hạn +- Một ounce vàng (khoảng 31 gram) +- và nhiều thứ khác + +Một tính năng mạnh mẽ như vậy của Ethereum chắc chắn phải được quản lý bằng một tiêu chuẩn vững chắc, đúng chứ? Đó chính xác là những gì ERC-20 đang thực hiện. Tiêu chuẩn này cho phép các nhà phát triển xây dựng các ứng dụng token có khả năng tương tác với các sản phẩm và dịch vụ khác. Tiêu chuẩn ERC-20 cũng được sử dụng để cung cấp chức năng bổ sung cho [ether](/glossary/#ether). + +**ERC-20 là gì?** + +ERC-20 đặt ra một tiêu chuẩn cho các token có thể thay thế, nghĩa là mỗi token +giống hệt nhau về loại và giá trị. Ví dụ, một Token ERC-20 hoạt động giống như ETH, có nghĩa là 1 Token luôn và sẽ luôn bằng tất cả các Token khác. + +## Điều kiện tiên quyết {#prerequisites} + +- [Tài khoản](/developers/docs/accounts) +- [Hợp đồng thông minh](/developers/docs/smart-contracts/) +- [Các tiêu chuẩn của token](/developers/docs/standards/tokens/) + +## Nội dung {#body} + +ERC-20 (Ethereum Requests for Comments 20), được dự thảo bởi Fabian Vogelsteller vào tháng 11/2015, là một tiêu chuẩn token thực thi API cho token trong Hợp đồng Thông minh. + +Ví dụ một số chức năng ERC-20 cung cấp: + +- gửi các token từ một tài khoản này đến một tài khoản khác +- lấy thông tin số lượng token của tài khoản +- lấy tổng cung của token đang có trên mạng +- phê duyệt xem tài khoản của bên thứ ba có thể sử dụng token từ tài khoản hay không + +Nếu một Hợp đồng Thông minh có thể thực thi các phương thức và sự kiện bên dưới, chúng được gọi là Hợp đồng Token ERC-20, khi triển khai, chúng sẽ có trách nhiệm duy trì các token được tạo trên Ethereum. + +Từ [EIP-20](https://eips.ethereum.org/EIPS/eip-20): + +### Các phương thức {#methods} + +```solidity +function name() public view returns (string) +function symbol() public view returns (string) +function decimals() public view returns (uint8) +function totalSupply() public view returns (uint256) +function balanceOf(address _owner) public view returns (uint256 balance) +function transfer(address _to, uint256 _value) public returns (bool success) +function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) +function approve(address _spender, uint256 _value) public returns (bool success) +function allowance(address _owner, address _spender) public view returns (uint256 remaining) +``` + +### Sự kiện {#events} + +```solidity +event Transfer(address indexed _from, address indexed _to, uint256 _value) +event Approval(address indexed _owner, address indexed _spender, uint256 _value) +``` + +### Ví dụ {#web3py-example} + +Hãy xem Tiêu chuẩn quan trọng như thế nào để giúp mọi thứ trở nên đơn giản với chúng ta khi kiểm tra Hợp đồng Token ERC-20 trên Ethereum. +Chúng ta chỉ cần Contract Application Binary Interface (ABI), để tạo ra giao diện một token ERC-20 bất kỳ. Như bạn cũng thấy ở dưới, chúng ta sẽ dùng một ABI đơn giản, khiến nó trở thành một ví dụ có tính ma sát thấp. + +#### Ví dụ về Web3.py {#web3py-example} + +Đầu tiên, hãy đảm bảo rằng bạn đã cài đặt thư viện Python [Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation): + +``` +pip install web3 +``` + +```python +from web3 import Web3 + + +w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com")) + +dai_token_addr = "0x6B175474E89094C44Da98b954EedeAC495271d0F" # DAI +weth_token_addr = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" # Ether được bọc (WETH) + +acc_address = "0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11" # Uniswap V2: DAI 2 + +# Đây là Giao diện nhị phân ứng dụng (ABI) hợp đồng được đơn giản hóa của một Hợp đồng Token ERC-20. +# Nó sẽ chỉ hiển thị các phương thức: balanceOf(address), decimals(), symbol() và totalSupply() +simplified_abi = [ + { + 'inputs': [{'internalType': 'address', 'name': 'account', 'type': 'address'}], + 'name': 'balanceOf', + 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [], + 'name': 'decimals', + 'outputs': [{'internalType': 'uint8', 'name': '', 'type': 'uint8'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [], + 'name': 'symbol', + 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [], + 'name': 'totalSupply', + 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + } +] + +dai_contract = w3.eth.contract(address=w3.to_checksum_address(dai_token_addr), abi=simplified_abi) +symbol = dai_contract.functions.symbol().call() +decimals = dai_contract.functions.decimals().call() +totalSupply = dai_contract.functions.totalSupply().call() / 10**decimals +addr_balance = dai_contract.functions.balanceOf(acc_address).call() / 10**decimals + +# DAI +print("===== %s =====" % symbol) +print("Total Supply:", totalSupply) +print("Addr Balance:", addr_balance) + +weth_contract = w3.eth.contract(address=w3.to_checksum_address(weth_token_addr), abi=simplified_abi) +symbol = weth_contract.functions.symbol().call() +decimals = weth_contract.functions.decimals().call() +totalSupply = weth_contract.functions.totalSupply().call() / 10**decimals +addr_balance = weth_contract.functions.balanceOf(acc_address).call() / 10**decimals + +# WETH +print("===== %s =====" % symbol) +print("Total Supply:", totalSupply) +print("Addr Balance:", addr_balance) +``` + +## Các vấn đề đã biết {#erc20-issues} + +### Sự cố nhận token ERC-20 {#reception-issue} + +**Tính đến ngày 20/06/2024, ít nhất 83.656.418 USD giá trị token ERC-20 đã bị mất do sự cố này. Lưu ý rằng việc triển khai ERC-20 thuần túy dễ gặp phải vấn đề này trừ khi bạn triển khai một tập hợp các hạn chế bổ sung bên trên tiêu chuẩn như được liệt kê dưới đây.** + +Khi các token ERC-20 được gửi đến một hợp đồng thông minh không được thiết kế để xử lý các token ERC-20, những token đó có thể bị mất vĩnh viễn. Điều này xảy ra bởi vì hợp đồng nhận không có chức năng nhận diện hoặc phản hồi với các token đến, và không có cơ chế nào trong tiêu chuẩn ERC-20 để thông báo cho hợp đồng nhận về các token được gửi đến. Lý do chính mà vấn đề này thể hiện là qua: + +1. Cơ chế chuyển đổi token + +- Các token ERC-20 được chuyển đổi bằng cách sử dụng các hàm transfer hoặc transferFrom. + - Khi một người dùng gửi token đến địa chỉ hợp đồng bằng cách sử dụng những hàm này, token sẽ được chuyển giao bất kể hợp đồng nhận có được thiết kế để xử lý chúng hay không. + +2. Thất thoát thông báo + - Hợp đồng nhận không nhận thông báo hoặc cuộc gọi lại rằng các token đã được gửi đến nó. + - Nếu hợp đồng nhận thiếu cơ chế để xử lý token (ví dụ: một hàm fallback hoặc một hàm chuyên dụng để quản lý việc nhận token), các token sẽ bị mắc kẹt trong địa chỉ của hợp đồng. +3. Không tích hợp xử lý sẵn + - Chuẩn ERC-20 không có một hàm bắt buộc nào cho các hợp đồng nhận tiền phải thực hiện, dẫn đến việc nhiều hợp đồng không thể quản lý các token đến một cách đúng đắn. + +**Các giải pháp khả thi** + +Mặc dù không thể ngăn chặn hoàn toàn vấn đề này với ERC-20, nhưng có vài cách cho phép giảm đáng kể khả năng mất tokens cho người dùng: + +- Vấn đề phổ biến nhất là khi người dùng gửi token đến chính địa chỉ hợp đồng token (ví dụ: USDT được gửi vào địa chỉ của hợp đồng token USDT). Khuyến nghị hạn chế hàm `transfer(...)` để hoàn tác các nỗ lực chuyển tiền như vậy. Cân nhắc thêm kiểm tra `require(_to != address(this));` trong quá trình triển khai hàm `transfer(...)`. +- Nhìn chung, hàm `transfer(...)` không được thiết kế để gửi token vào các hợp đồng. Thay vào đó, mẫu `approve(..) & transferFrom(...)` được sử dụng để gửi token ERC-20 vào các hợp đồng. Có thể hạn chế hàm `transfer(...)` để không cho phép gửi token vào bất kỳ hợp đồng nào bằng hàm đó, tuy nhiên, điều này có thể phá vỡ tính tương thích với các hợp đồng giả định rằng token có thể được gửi vào các hợp đồng bằng hàm `transfer(...)` (ví dụ: các bể thanh khoản Uniswap). +- Luôn luôn giả định rằng các token ERC-20 có thể xuất hiện trong hợp đồng của bạn, ngay cả khi hợp đồng của bạn không được thiết kế để nhận bất kỳ token nào. Không thể ngăn chặn hoặc từ chối các khoản tiền gửi không mong muốn từ phía người nhận. Nên thực hiện một chức năng cho phép trích xuất các token ERC-20 được gửi nhầm. +- Hãy xem xét việc sử dụng các chuẩn token khác. + +Một số tiêu chuẩn thay thế đã ra đời từ vấn đề này, chẳng hạn như [ERC-223](/developers/docs/standards/tokens/erc-223) hoặc [ERC-1363](/developers/docs/standards/tokens/erc-1363). + +## Đọc thêm {#further-reading} + +- [EIP-20: Tiêu chuẩn Token ERC-20](https://eips.ethereum.org/EIPS/eip-20) +- [OpenZeppelin - Token](https://docs.openzeppelin.com/contracts/3.x/tokens#ERC20) +- [OpenZeppelin - Triển khai ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol) +- [Alchemy - Hướng dẫn về Token ERC20 trong Solidity](https://www.alchemy.com/overviews/erc20-solidity) + +## Các tiêu chuẩn token có thể thay thế khác {#fungible-token-standards} + +- [ERC-223](/developers/docs/standards/tokens/erc-223) +- [ERC-1363](/developers/docs/standards/tokens/erc-1363) +- [ERC-777](/developers/docs/standards/tokens/erc-777) +- [ERC-4626 - Kho tiền được token hóa](/developers/docs/standards/tokens/erc-4626) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-223/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-223/index.md new file mode 100644 index 00000000000..1138120b71f --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-223/index.md @@ -0,0 +1,198 @@ +--- +title: "Tiêu chuẩn token ERC-223" +description: "Tổng quan về tiêu chuẩn token có thể thay thế ERC-223, cách hoạt động của nó và so sánh với ERC-20." +lang: vi +--- + +## Giới thiệu {#introduction} + +### ERC-223 là gì? {#what-is-erc223} + +ERC-223 là một tiêu chuẩn cho các token có thể thay thế, tương tự như tiêu chuẩn ERC-20. Sự khác biệt chính là ERC-223 không chỉ xác định API của token mà còn cả logic để chuyển token từ người gửi đến người nhận. Nó giới thiệu một mô hình giao tiếp cho phép các lần chuyển token được xử lý ở phía người nhận. + +### Sự khác biệt so với ERC-20 {#erc20-differences} + +ERC-223 giải quyết một số hạn chế của ERC-20 và giới thiệu một phương thức tương tác mới giữa hợp đồng token và hợp đồng có thể nhận các token. Có một vài điều có thể thực hiện với ERC-223 nhưng không thể với ERC-20: + +- Xử lý việc chuyển token ở phía người nhận: Người nhận có thể phát hiện rằng một token ERC-223 đang được gửi vào. +- Từ chối các token được gửi không đúng cách: Nếu người dùng gửi token ERC-223 đến một hợp đồng không được cho là sẽ nhận token, hợp đồng có thể từ chối giao dịch, ngăn chặn việc mất token. +- Siêu dữ liệu trong các lần chuyển: Các token ERC-223 có thể bao gồm siêu dữ liệu, cho phép đính kèm thông tin tùy ý vào các giao dịch token. + +## Điều kiện tiên quyết {#prerequisites} + +- [Tài khoản](/developers/docs/accounts) +- [Hợp đồng thông minh](/developers/docs/smart-contracts/) +- [Các tiêu chuẩn của token](/developers/docs/standards/tokens/) +- [ERC-20](/developers/docs/standards/tokens/erc-20/) + +## Nội dung {#body} + +ERC-223 là một tiêu chuẩn token triển khai một API cho các token trong các hợp đồng thông minh. Nó cũng khai báo một API cho các hợp đồng được cho là sẽ nhận token ERC-223. Các hợp đồng không hỗ trợ API Người nhận ERC-223 không thể nhận các token ERC-223, ngăn ngừa lỗi từ người dùng. + +Nếu một hợp đồng thông minh triển khai các phương thức và sự kiện sau đây, nó có thể được gọi là một hợp đồng token tương thích với ERC-223. Sau khi được triển khai, nó +sẽ chịu trách nhiệm theo dõi các token được tạo trên Ethereum. + +Hợp đồng không bắt buộc chỉ có các hàm này và một nhà phát triển có thể thêm bất kỳ tính năng nào khác từ các tiêu chuẩn token khác vào hợp đồng này. Ví dụ: các hàm `approve` và `transferFrom` không phải là một phần của tiêu chuẩn ERC-223 nhưng các hàm này có thể được triển khai nếu cần thiết. + +Từ [EIP-223](https://eips.ethereum.org/EIPS/eip-223): + +### Các phương thức {#methods} + +Token ERC-223 phải triển khai các phương thức sau: + +```solidity +function name() public view returns (string) +function symbol() public view returns (string) +function decimals() public view returns (uint8) +function totalSupply() public view returns (uint256) +function balanceOf(address _owner) public view returns (uint256 balance) +function transfer(address _to, uint256 _value) public returns (bool success) +function transfer(address _to, uint256 _value, bytes calldata _data) public returns (bool success) +``` + +Một hợp đồng được cho là sẽ nhận token ERC-223 phải triển khai phương thức sau: + +```solidity +function tokenReceived(address _from, uint _value, bytes calldata _data) +``` + +Nếu các token ERC-223 được gửi đến một hợp đồng không triển khai hàm `tokenReceived(..)`, thì việc chuyển phải thất bại và các token không được di chuyển khỏi số dư của người gửi. + +### Sự kiện {#events} + +```solidity +event Transfer(address indexed _from, address indexed _to, uint256 _value, bytes calldata _data) +``` + +### Ví dụ {#examples} + +API của token ERC-223 tương tự như của ERC-20, vì vậy từ quan điểm phát triển giao diện người dùng (UI) thì không có sự khác biệt. Ngoại lệ duy nhất ở đây là các token ERC-223 có thể không có các hàm `approve` + `transferFrom` vì chúng là tùy chọn cho tiêu chuẩn này. + +#### Các ví dụ về Solidity {#solidity-example} + +Ví dụ sau đây minh họa cách hoạt động của một hợp đồng token ERC-223 cơ bản: + +```solidity +pragma solidity ^0.8.19; +abstract contract IERC223Recipient { + function tokenReceived(address _from, uint _value, bytes memory _data) public virtual; +} +contract VeryBasicERC223Token { + event Transfer(address indexed from, address indexed to, uint value, bytes data); + string private _name; + string private _symbol; + uint8 private _decimals; + uint256 private _totalSupply; + mapping(address => uint256) private balances; + function name() public view returns (string memory) { return _name; } + function symbol() public view returns (string memory) {return _symbol; } + function decimals() public view returns (uint8) { return _decimals; } + function totalSupply() public view returns (uint256) { return _totalSupply; } + function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } + function isContract(address account) internal view returns (bool) { + uint256 size; + assembly { size := extcodesize(account) } + return size > 0; + } + function transfer(address _to, uint _value, bytes calldata _data) public returns (bool success){ + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _data); + } + emit Transfer(msg.sender, _to, _value, _data); + return true; + } + function transfer(address _to, uint _value) public returns (bool success){ + bytes memory _empty = hex"00000000"; + balances[msg.sender] = balances[msg.sender] - _value; + balances[_to] = balances[_to] + _value; + if(isContract(_to)) { + IERC223Recipient(_to).tokenReceived(msg.sender, _value, _empty); + } + emit Transfer(msg.sender, _to, _value, _empty); + return true; + } +} +``` + +Bây giờ chúng ta muốn một hợp đồng khác chấp nhận các khoản tiền gửi `tokenA` giả sử rằng tokenA là một token ERC-223. Hợp đồng phải chỉ chấp nhận tokenA và từ chối mọi token khác. Khi hợp đồng nhận tokenA, nó phải phát ra một sự kiện `Deposit()` và tăng giá trị của biến nội bộ `deposits`. + +Đây là mã: + +```solidity +contract RecipientContract is IERC223Recipient { + event Deposit(address whoSentTheTokens); + uint256 deposits = 0; + address tokenA; // Token duy nhất mà chúng ta muốn chấp nhận. + function tokenReceived(address _from, uint _value, bytes memory _data) public override + { + // Điều quan trọng là phải hiểu rằng trong hàm này + // msg.sender là địa chỉ của token đang được nhận, + // msg.value luôn là 0 vì hợp đồng token không sở hữu hoặc gửi ether trong hầu hết các trường hợp, + // _from là người gửi của lần chuyển token, + // _value là số lượng token đã được gửi. + require(msg.sender == tokenA); + deposits += _value; + emit Deposit(_from); + } +} +``` + +## Những câu hỏi thường gặp {#faq} + +### Điều gì sẽ xảy ra nếu chúng ta gửi một số tokenB đến hợp đồng? {#sending-tokens} + +Giao dịch sẽ thất bại, và việc chuyển token sẽ không xảy ra. Các token sẽ được trả lại cho địa chỉ của người gửi. + +### Làm thế nào chúng ta có thể gửi tiền vào hợp đồng này? {#contract-deposits} + +Gọi hàm `transfer(address,uint256)` hoặc `transfer(address,uint256,bytes)` của token ERC-223, chỉ định địa chỉ của `RecipientContract`. + +### Điều gì sẽ xảy ra nếu chúng ta chuyển một token ERC-20 đến hợp đồng này? {#erc-20-transfers} + +Nếu một token ERC-20 được gửi đến `RecipientContract`, các token sẽ được chuyển, nhưng việc chuyển sẽ không được công nhận (không có sự kiện `Deposit()` nào được kích hoạt, và giá trị tiền gửi sẽ không thay đổi). Các khoản tiền gửi ERC-20 không mong muốn không thể được lọc hoặc ngăn chặn. + +### Điều gì sẽ xảy ra nếu chúng ta muốn thực thi một hàm nào đó sau khi việc gửi token hoàn tất? {#function-execution} + +Có nhiều cách để làm điều đó. Trong ví dụ này, chúng ta sẽ làm theo phương pháp khiến cho các lần chuyển ERC-223 giống hệt như các lần chuyển ether: + +```solidity +contract RecipientContract is IERC223Recipient { + event Foo(); + event Bar(uint256 someNumber); + address tokenA; // Token duy nhất mà chúng ta muốn chấp nhận. + function tokenReceived(address _from, uint _value, bytes memory _data) public override + { + require(msg.sender == tokenA); + address(this).call(_data); // Xử lý giao dịch đến và thực hiện một lệnh gọi hàm tiếp theo. + } + function foo() public + { + emit Foo(); + } + function bar(uint256 _someNumber) public + { + emit Bar(_someNumber); + } +} +``` + +Khi `RecipientContract` nhận được một token ERC-223, hợp đồng sẽ thực thi một hàm được mã hóa dưới dạng tham số `_data` của giao dịch token, giống hệt như cách các giao dịch ether mã hóa các lệnh gọi hàm dưới dạng `data` giao dịch. Đọc [trường dữ liệu](/developers/docs/transactions/#the-data-field) để biết thêm thông tin. + +Trong ví dụ trên, một token ERC-223 phải được chuyển đến địa chỉ của `RecipientContract` bằng hàm `transfer(address,uin256,bytes calldata _data)`. Nếu tham số dữ liệu là `0xc2985578` (chữ ký của hàm `foo()`), thì hàm foo() sẽ được gọi sau khi nhận được tiền gửi token và sự kiện Foo() sẽ được kích hoạt. + +Các tham số cũng có thể được mã hóa trong `data` của lần chuyển token, ví dụ: chúng ta có thể gọi hàm bar() với giá trị 12345 cho `_someNumber`. Trong trường hợp này, `data` phải là `0x0423a13200000000000000000000000000000000000000000000000000000000000004d2`, trong đó `0x0423a132` là chữ ký của hàm `bar(uint256)` và `00000000000000000000000000000000000000000000000000000000000004d2` là 12345 dưới dạng uint256. + +## Các hạn chế {#limitations} + +Mặc dù ERC-223 giải quyết một số vấn đề được tìm thấy trong tiêu chuẩn ERC-20, nó không phải là không có những hạn chế riêng: + +- Việc áp dụng và tính tương thích: ERC-223 vẫn chưa được áp dụng rộng rãi, điều này có thể hạn chế khả năng tương thích của nó với các công cụ và nền tảng hiện có. +- Khả năng tương thích ngược: ERC-223 không tương thích ngược với ERC-20, nghĩa là các hợp đồng và công cụ ERC-20 hiện có sẽ không hoạt động với các token ERC-223 nếu không có sửa đổi. +- Chi phí gas: Các kiểm tra và chức năng bổ sung trong các lần chuyển ERC-223 có thể dẫn đến chi phí gas cao hơn so với các giao dịch ERC-20. + +## Đọc thêm {#further-reading} + +- [EIP-223: Tiêu chuẩn token ERC-223](https://eips.ethereum.org/EIPS/eip-223) +- [Đề xuất ERC-223 ban đầu](https://github.com/ethereum/eips/issues/223) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-4626/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-4626/index.md new file mode 100644 index 00000000000..66243e824cd --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-4626/index.md @@ -0,0 +1,227 @@ +--- +title: "Tiêu chuẩn Kho lưu trữ Token hóa ERC-4626" +description: "Một tiêu chuẩn cho các kho lưu trữ sinh lợi." +lang: vi +--- + +## Giới thiệu {#introduction} + +ERC-4626 là một tiêu chuẩn để tối ưu hóa và thống nhất các thông số kỹ thuật của các kho lưu trữ sinh lợi. Nó cung cấp một API tiêu chuẩn cho các kho lưu trữ sinh lợi được token hóa, đại diện cho các phần của một token ERC-20 cơ sở duy nhất. ERC-4626 cũng nêu ra một phần mở rộng tùy chọn cho các kho lưu trữ được token hóa sử dụng ERC-20, cung cấp chức năng cơ bản để gửi, rút token và đọc số dư. + +**Vai trò của ERC-4626 trong các kho lưu trữ sinh lợi** + +Các thị trường cho vay, các công cụ tổng hợp và các token có lãi suất nội tại giúp người dùng tìm được lợi suất tốt nhất trên các token tiền mã hóa của họ bằng cách thực hiện các chiến lược khác nhau. Các chiến lược này được thực hiện với những biến thể nhỏ, có thể dễ bị lỗi hoặc lãng phí tài nguyên phát triển. + +ERC-4626 trong các kho lưu trữ sinh lợi sẽ giảm bớt công sức tích hợp và mở khóa quyền truy cập vào lợi suất trong các ứng dụng khác nhau với ít nỗ lực chuyên môn hóa từ các nhà phát triển bằng cách tạo ra các mẫu triển khai nhất quán và mạnh mẽ hơn. + +Token ERC-4626 được mô tả đầy đủ trong [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626). + +**Phần mở rộng kho lưu trữ không đồng bộ (ERC-7540)** + +ERC-4626 được tối ưu hóa cho các khoản tiền gửi và quy đổi nguyên tử lên đến một giới hạn. Nếu đạt đến giới hạn, không thể gửi thêm các khoản tiền gửi hoặc quy đổi mới. Hạn chế này không hoạt động tốt đối với bất kỳ hệ thống hợp đồng thông minh nào có các hành động không đồng bộ hoặc độ trễ là điều kiện tiên quyết để giao tiếp với Kho lưu trữ (ví dụ: các giao thức tài sản trong thế giới thực, các giao thức cho vay dưới thế chấp, các giao thức cho vay chuỗi chéo, các token staking thanh khoản hoặc các mô-đun an toàn bảo hiểm). + +ERC-7540 mở rộng tiện ích của Kho lưu trữ ERC-4626 cho các trường hợp sử dụng không đồng bộ. Giao diện Kho lưu trữ hiện có (`deposit`/`withdraw`/`mint`/`redeem`) được tận dụng hoàn toàn để yêu cầu các Yêu cầu không đồng bộ. + +Phần mở rộng ERC-7540 được mô tả đầy đủ trong [ERC-7540](https://eips.ethereum.org/EIPS/eip-7540). + +**Phần mở rộng kho lưu trữ đa tài sản (ERC-7575)** + +Một trường hợp sử dụng bị thiếu không được ERC-4626 hỗ trợ là các Kho lưu trữ có nhiều tài sản hoặc điểm vào chẳng hạn như token nhà cung cấp thanh khoản (LP). Chúng thường khó sử dụng hoặc không tuân thủ do yêu cầu của ERC-4626 phải là một ERC-20. + +ERC-7575 bổ sung hỗ trợ cho các Kho lưu trữ có nhiều tài sản bằng cách bên ngoài hóa việc triển khai token ERC-20 từ việc triển khai ERC-4626. + +Phần mở rộng ERC-7575 được mô tả đầy đủ trong [ERC-7575](https://eips.ethereum.org/EIPS/eip-7575). + +## Điều kiện tiên quyết {#prerequisites} + +Để hiểu rõ hơn về trang này, chúng tôi khuyên bạn nên đọc trước về [các tiêu chuẩn token](/developers/docs/standards/tokens/) và [ERC-20](/developers/docs/standards/tokens/erc-20/). + +## Các hàm và Tính năng của ERC-4626: {#body} + +### Các phương thức {#methods} + +#### tài sản {#asset} + +```solidity +function asset() public view returns (address assetTokenAddress) +``` + +Hàm này trả về địa chỉ của token cơ sở được sử dụng cho kho lưu trữ để hạch toán, gửi tiền, rút tiền. + +#### tổng tài sản {#totalassets} + +```solidity +function totalAssets() public view returns (uint256) +``` + +Hàm này trả về tổng số lượng tài sản cơ sở do kho lưu trữ nắm giữ. + +#### chuyển đổi thành cổ phần {#convertoshares} + +```solidity +function convertToShares(uint256 assets) public view returns (uint256 shares) +``` + +Hàm này trả về số lượng `cổ phần` sẽ được kho lưu trữ trao đổi cho số lượng `tài sản` được cung cấp. + +#### chuyển đổi thành tài sản {#convertoassets} + +```solidity +function convertToAssets(uint256 shares) public view returns (uint256 assets) +``` + +Hàm này trả về số lượng `tài sản` sẽ được kho lưu trữ trao đổi cho số lượng `cổ phần` được cung cấp. + +#### gửi tiền tối đa {#maxdeposit} + +```solidity +function maxDeposit(address receiver) public view returns (uint256 maxAssets) +``` + +Hàm này trả về số lượng tối đa tài sản cơ sở có thể được gửi trong một lệnh gọi [`gửi tiền`](#deposit) duy nhất, với các cổ phần được đúc cho `người nhận`. + +#### xem trước khi gửi tiền {#previewdeposit} + +```solidity +function previewDeposit(uint256 assets) public view returns (uint256 shares) +``` + +Hàm này cho phép người dùng mô phỏng các tác động của việc gửi tiền của họ tại khối hiện tại. + +#### gửi tiền {#deposit} + +```solidity +function deposit(uint256 assets, address receiver) public returns (uint256 shares) +``` + +Hàm này gửi `tài sản` của các token cơ sở vào kho lưu trữ và cấp quyền sở hữu `cổ phần` cho `người nhận`. + +#### đúc tối đa {#maxmint} + +```solidity +function maxMint(address receiver) public view returns (uint256 maxShares) +``` + +Hàm này trả về số lượng cổ phần tối đa có thể được đúc trong một lệnh gọi [`đúc`](#mint) duy nhất, với các cổ phần được đúc cho `người nhận`. + +#### xem trước khi đúc {#previewmint} + +```solidity +function previewMint(uint256 shares) public view returns (uint256 assets) +``` + +Hàm này cho phép người dùng mô phỏng các tác động của việc đúc của họ tại khối hiện tại. + +#### đúc {#mint} + +```solidity +function mint(uint256 shares, address receiver) public returns (uint256 assets) +``` + +Hàm này đúc chính xác `cổ phần` kho lưu trữ cho `người nhận` bằng cách gửi `tài sản` của các token cơ sở. + +#### rút tối đa {#maxwithdraw} + +```solidity +function maxWithdraw(address owner) public view returns (uint256 maxAssets) +``` + +Hàm này trả về số lượng tối đa tài sản cơ sở có thể được rút từ số dư của `chủ sở hữu` bằng một lệnh gọi [`rút`](#withdraw) duy nhất. + +#### xem trước khi rút {#previewwithdraw} + +```solidity +function previewWithdraw(uint256 assets) public view returns (uint256 shares) +``` + +Hàm này cho phép người dùng mô phỏng các tác động của việc rút tiền của họ tại khối hiện tại. + +#### rút {#withdraw} + +```solidity +function withdraw(uint256 assets, address receiver, address owner) public returns (uint256 shares) +``` + +Hàm này đốt `cổ phần` từ `chủ sở hữu` và gửi chính xác token `tài sản` từ kho lưu trữ đến `người nhận`. + +#### quy đổi tối đa {#maxredeem} + +```solidity +function maxRedeem(address owner) public view returns (uint256 maxShares) +``` + +Hàm này trả về số lượng cổ phần tối đa có thể được quy đổi từ số dư của `chủ sở hữu` thông qua một lệnh gọi [`quy đổi`](#redeem). + +#### xem trước khi quy đổi {#previewredeem} + +```solidity +function previewRedeem(uint256 shares) public view returns (uint256 assets) +``` + +Hàm này cho phép người dùng mô phỏng các tác động của việc quy đổi của họ tại khối hiện tại. + +#### quy đổi {#redeem} + +```solidity +function redeem(uint256 shares, address receiver, address owner) public returns (uint256 assets) +``` + +Hàm này quy đổi một số lượng `cổ phần` cụ thể từ `chủ sở hữu` và gửi `tài sản` của token cơ sở từ kho lưu trữ đến `người nhận`. + +#### tổng cung {#totalsupply} + +```solidity +function totalSupply() public view returns (uint256) +``` + +Trả về tổng số lượng cổ phần kho lưu trữ chưa được quy đổi đang lưu hành. + +#### số dư của {#balanceof} + +```solidity +function balanceOf(address owner) public view returns (uint256) +``` + +Trả về tổng số lượng cổ phần kho lưu trữ mà `chủ sở hữu` hiện có. + +### Sơ đồ giao diện {#mapOfTheInterface} + +![Sơ đồ giao diện ERC-4626](./map-of-erc-4626.png) + +### Sự kiện {#events} + +#### Sự kiện Gửi tiền + +**PHẢI** được phát ra khi các token được gửi vào kho lưu trữ thông qua các phương thức [`đúc`](#mint) và [`gửi tiền`](#deposit). + +```solidity +event Deposit( + address indexed sender, + address indexed owner, + uint256 assets, + uint256 shares +) +``` + +Trong đó `người gửi` là người dùng đã trao đổi `tài sản` lấy `cổ phần` và đã chuyển những `cổ phần` đó cho `chủ sở hữu`. + +#### Sự kiện Rút tiền + +**PHẢI** được phát ra khi cổ phần được rút từ kho lưu trữ bởi một người gửi tiền trong các phương thức [`quy đổi`](#redeem) hoặc [`rút`](#withdraw). + +```solidity +event Withdraw( + address indexed sender, + address indexed receiver, + address indexed owner, + uint256 assets, + uint256 shares +) +``` + +Trong đó `người gửi` là người dùng đã kích hoạt việc rút tiền và trao đổi `cổ phần` do `chủ sở hữu` sở hữu lấy `tài sản`. `người nhận` là người dùng đã nhận `tài sản` đã rút. + +## Đọc thêm {#further-reading} + +- [EIP-4626: Tiêu chuẩn kho lưu trữ được token hóa](https://eips.ethereum.org/EIPS/eip-4626) +- [ERC-4626: Kho lưu trữ GitHub](https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC4626.sol) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-721/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-721/index.md new file mode 100644 index 00000000000..d70aaca5ffd --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-721/index.md @@ -0,0 +1,254 @@ +--- +title: "Tiêu chuẩn Token Không Phân tách ERC-721" +description: "Tìm hiểu thêm về ERC-62, chuẩn NFT đại diện cho tài sản kỹ thuật số độc đáo trên Ethereum." +lang: vi +--- + +## Giới thiệu {#introduction} + +**NFT (Non-Fungible Token, hay Token không thể thay thế) là gì?** + +Token không thể thay thế (NFT) được dùng để xác định một thứ gì đó hoặc ai đó theo một cách độc nhất. Loại Token này rất phù hợp để sử dụng trên các nền tảng cung cấp các mặt hàng sưu tầm, chìa khóa truy cập, vé xổ số, chỗ ngồi có số cho các buổi hòa nhạc và các trận thể thao, v.v. Tiểu token đặc biệt này có khả năng kinh ngạc, và để tiêu chuẩn hóa tài sản, ERC-721 sẽ giúp chúng xử lý vấn đề này. + +**ERC-721 là gì?** + +ERC-721 trình bày các tiêu chuẩn NFT, nói cách khác, kiểu token này là duy nhất và có những giá trị khác nhau mà các token khác không có, dù chúng cùng Hợp đồng Thông Minh, có thể do tuổi tác, độ hiếm, hay thậm chí là thứ gì đó về bề ngoài. +Đợi đã, bề ngoài? + +Vâng! Tất cả các NFT đều có một biến `uint256` gọi là `tokenId`, vì vậy đối với bất kỳ Hợp đồng ERC-721 nào, cặp +`địa chỉ hợp đồng, uint256 tokenId` phải là duy nhất trên toàn cầu. Dù vậy, một ứng dụng phi tập trung có thể có một "bộ chuyển đổi" sử dụng `tokenId` làm đầu vào và cho ra hình ảnh của một thứ gì đó thú vị, như thây ma, vũ khí, kỹ năng hoặc những chú mèo tuyệt vời! + +## Điều kiện tiên quyết {#prerequisites} + +- [Tài khoản](/developers/docs/accounts/) +- [Hợp đồng thông minh](/developers/docs/smart-contracts/) +- [Các tiêu chuẩn của token](/developers/docs/standards/tokens/) + +## Nội dung {#body} + +ERC-721 (Ethereum Request for Comments 721) được đề xuất bởi William Entriken, Dieter Shirley, Jacod Evans, Nastassia Sachs vào tháng 1 năm 2018, là một Tiêu chuẩn Token Không phân tách, thực hiện API cho các tokens trong các Hợp đồng Thông minh. + +Nó cung cấp các chức năng như chuyển token từ tài khoản này sang tài khoản khác, lấy số dư token hiện tại của một +tài khoản, lấy chủ sở hữu của một token cụ thể và cả tổng cung của token có sẵn trên mạng. +Bên cạnh đó, nó cũng có một vài tính năng như chấp thuận lượng token từ tài khoản có thể di chuyển bởi tài khoản bên thứ 3. + +Nếu một Hợp đồng Thông minh có thể thực thi các phương thức và sự kiện bên dưới, chúng được gọi là Hợp đồng Token Không phân tách ERC-721, khi triển khai, chúng sẽ có trách nhiệm duy trì các token được tạo trên Ethereum. + +Từ [EIP-721](https://eips.ethereum.org/EIPS/eip-721): + +### Các phương thức {#methods} + +```solidity + function balanceOf(address _owner) external view returns (uint256); + function ownerOf(uint256 _tokenId) external view returns (address); + function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; + function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; + function transferFrom(address _from, address _to, uint256 _tokenId) external payable; + function approve(address _approved, uint256 _tokenId) external payable; + function setApprovalForAll(address _operator, bool _approved) external; + function getApproved(uint256 _tokenId) external view returns (address); + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +``` + +### Sự kiện {#events} + +```solidity + event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); + event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); +``` + +### Ví dụ {#web3py-example} + +Hãy xem Tiêu chuẩn quan trọng như thế nào để giúp mọi thứ trở nên đơn giản với chúng ta khi kiểm tra Hợp đồng Token Không phân tách ERC-721 trên Ethereum. +Chúng ta chỉ cần Contract Application Binary Interface (ABI), để tạo ra giao diện một token ERC-721 bất kỳ. Như bạn cũng thấy ở dưới, chúng ta sẽ dùng một ABI đơn giản, khiến nó trở thành một ví dụ có tính ma sát thấp. + +#### Ví dụ về Web3.py {#web3py-example} + +Đầu tiên, hãy đảm bảo rằng bạn đã cài đặt thư viện Python [Web3.py](https://web3py.readthedocs.io/en/stable/quickstart.html#installation): + +``` +pip install web3 +``` + +```python +from web3 import Web3 +from web3._utils.events import get_event_data + + +w3 = Web3(Web3.HTTPProvider("https://cloudflare-eth.com")) + +ck_token_addr = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d" # Hợp đồng CryptoKitties + +acc_address = "0xb1690C08E213a35Ed9bAb7B318DE14420FB57d8C" # Bán Đấu giá CryptoKitties + +# Đây là một Giao diện nhị phân ứng dụng (ABI) hợp đồng đơn giản hóa của một Hợp đồng NFT ERC-721. +# Nó sẽ chỉ hiển thị các phương thức: balanceOf(address), name(), ownerOf(tokenId), symbol(), totalSupply() +simplified_abi = [ + { + 'inputs': [{'internalType': 'address', 'name': 'owner', 'type': 'address'}], + 'name': 'balanceOf', + 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], + 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [], + 'name': 'name', + 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [{'internalType': 'uint256', 'name': 'tokenId', 'type': 'uint256'}], + 'name': 'ownerOf', + 'outputs': [{'internalType': 'address', 'name': '', 'type': 'address'}], + 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [], + 'name': 'symbol', + 'outputs': [{'internalType': 'string', 'name': '', 'type': 'string'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [], + 'name': 'totalSupply', + 'outputs': [{'internalType': 'uint256', 'name': '', 'type': 'uint256'}], + 'stateMutability': 'view', 'type': 'function', 'constant': True + }, +] + +ck_extra_abi = [ + { + 'inputs': [], + 'name': 'pregnantKitties', + 'outputs': [{'name': '', 'type': 'uint256'}], + 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True + }, + { + 'inputs': [{'name': '_kittyId', 'type': 'uint256'}], + 'name': 'isPregnant', + 'outputs': [{'name': '', 'type': 'bool'}], + 'payable': False, 'stateMutability': 'view', 'type': 'function', 'constant': True + } +] + +ck_contract = w3.eth.contract(address=w3.to_checksum_address(ck_token_addr), abi=simplified_abi+ck_extra_abi) +name = ck_contract.functions.name().call() +symbol = ck_contract.functions.symbol().call() +kitties_auctions = ck_contract.functions.balanceOf(acc_address).call() +print(f"{name} [{symbol}] NFTs in Auctions: {kitties_auctions}") + +pregnant_kitties = ck_contract.functions.pregnantKitties().call() +print(f"{name} [{symbol}] NFTs Pregnants: {pregnant_kitties}") + +# Sử dụng ABI Sự kiện Chuyển để nhận thông tin về các Kitty đã được chuyển. +tx_event_abi = { + 'anonymous': False, + 'inputs': [ + {'indexed': False, 'name': 'from', 'type': 'address'}, + {'indexed': False, 'name': 'to', 'type': 'address'}, + {'indexed': False, 'name': 'tokenId', 'type': 'uint256'}], + 'name': 'Transfer', + 'type': 'event' +} + +# Chúng ta cần chữ ký của sự kiện để lọc nhật ký +event_signature = w3.keccak(text="Transfer(address,address,uint256)").hex() + +logs = w3.eth.get_logs({ + "fromBlock": w3.eth.block_number - 120, + "address": w3.to_checksum_address(ck_token_addr), + "topics": [event_signature] +}) + +# Lưu ý: +# - Tăng số khối lên từ 120 nếu không có sự kiện Chuyển nào được trả về. +# - Nếu bạn không tìm thấy bất kỳ sự kiện Chuyển nào, bạn cũng có thể thử lấy tokenId tại: +# https://etherscan.io/address/0x06012c8cf97BEaD5deAe237070F9587f8E7A266d#events +# Nhấp để mở rộng nhật ký của sự kiện và sao chép đối số "tokenId" của nó +recent_tx = [get_event_data(w3.codec, tx_event_abi, log)["args"] for log in logs] + +if recent_tx: + kitty_id = recent_tx[0]['tokenId'] # Dán "tokenId" từ liên kết trên vào đây + is_pregnant = ck_contract.functions.isPregnant(kitty_id).call() + print(f"{name} [{symbol}] NFTs {kitty_id} is pregnant: {is_pregnant}") +``` + +Hợp đồng CryptoKitties có vài Sự kiện thú vị hơn các hợp đồng Tiêu chuẩn + +Hãy kiểm tra hai trong số chúng, `Pregnant` và `Birth`. + +```python +# Sử dụng ABI Sự kiện Mang thai và Sinh để nhận thông tin về các Kitty mới. +ck_extra_events_abi = [ + { + 'anonymous': False, + 'inputs': [ + {'indexed': False, 'name': 'owner', 'type': 'address'}, + {'indexed': False, 'name': 'matronId', 'type': 'uint256'}, + {'indexed': False, 'name': 'sireId', 'type': 'uint256'}, + {'indexed': False, 'name': 'cooldownEndBlock', 'type': 'uint256'}], + 'name': 'Pregnant', + 'type': 'event' + }, + { + 'anonymous': False, + 'inputs': [ + {'indexed': False, 'name': 'owner', 'type': 'address'}, + {'indexed': False, 'name': 'kittyId', 'type': 'uint256'}, + {'indexed': False, 'name': 'matronId', 'type': 'uint256'}, + {'indexed': False, 'name': 'sireId', 'type': 'uint256'}, + {'indexed': False, 'name': 'genes', 'type': 'uint256'}], + 'name': 'Birth', + 'type': 'event' + }] + +# Chúng ta cần chữ ký của sự kiện để lọc nhật ký +ck_event_signatures = [ + w3.keccak(text="Pregnant(address,uint256,uint256,uint256)").hex(), + w3.keccak(text="Birth(address,uint256,uint256,uint256,uint256)").hex(), +] + +# Đây là một Sự kiện Mang thai: +# - https://etherscan.io/tx/0xc97eb514a41004acc447ac9d0d6a27ea6da305ac8b877dff37e49db42e1f8cef#eventlog +pregnant_logs = w3.eth.get_logs({ + "fromBlock": w3.eth.block_number - 120, + "address": w3.to_checksum_address(ck_token_addr), + "topics": [ck_event_signatures[0]] +}) + +recent_pregnants = [get_event_data(w3.codec, ck_extra_events_abi[0], log)["args"] for log in pregnant_logs] + +# Đây là một Sự kiện Sinh: +# - https://etherscan.io/tx/0x3978028e08a25bb4c44f7877eb3573b9644309c044bf087e335397f16356340a +birth_logs = w3.eth.get_logs({ + "fromBlock": w3.eth.block_number - 120, + "address": w3.to_checksum_address(ck_token_addr), + "topics": [ck_event_signatures[1]] +}) + +recent_births = [get_event_data(w3.codec, ck_extra_events_abi[1], log)["args"] for log in birth_logs] +``` + +## Các NFT phổ biến {#popular-nfts} + +- [Etherscan NFT Tracker](https://etherscan.io/nft-top-contracts) liệt kê các NFT hàng đầu trên Ethereum theo khối lượng chuyển nhượng. +- [CryptoKitties](https://www.cryptokitties.co/) là một trò chơi tập trung vào các sinh vật có thể nhân giống, sưu tầm và vô cùng đáng yêu mà chúng ta gọi là CryptoKitties. +- [Sorare](https://sorare.com/) là một trò chơi bóng đá giả tưởng toàn cầu, nơi bạn có thể thu thập các vật phẩm sưu tầm phiên bản giới hạn, + quản lý đội của mình và thi đấu để giành giải thưởng. +- [Dịch vụ Định danh Ethereum (ENS)](https://ens.domains/) cung cấp một cách an toàn và phi tập trung để định địa chỉ các tài nguyên cả + trong và ngoài chuỗi khối bằng cách sử dụng các tên đơn giản, con người có thể đọc được. +- [POAP](https://poap.xyz) cung cấp NFT miễn phí cho những người tham dự sự kiện hoặc hoàn thành các hành động cụ thể. POAP có thể được tạo và phân phối miễn phí. +- [Unstoppable Domains](https://unstoppabledomains.com/) là một công ty có trụ sở tại San Francisco chuyên xây dựng các tên miền trên + chuỗi khối. Các tên miền chuỗi khối thay thế các địa chỉ tiền mã hóa bằng các tên mà con người có thể đọc được và có thể được sử dụng để cho phép các + trang web chống kiểm duyệt. +- [Gods Unchained Cards](https://godsunchained.com/) là một TCG (Trò chơi thẻ bài giao dịch) trên chuỗi khối Ethereum, sử dụng NFT để mang lại quyền sở hữu thực sự + cho các tài sản trong trò chơi. +- [Bored Ape Yacht Club](https://boredapeyachtclub.com) là một bộ sưu tập gồm 10.000 NFT độc nhất. Đây vừa là một tác phẩm nghệ thuật hiếm có thể chứng minh được, vừa hoạt động như một token thành viên của câu lạc bộ, cung cấp các đặc quyền và lợi ích cho thành viên, những lợi ích này sẽ tăng dần theo thời gian nhờ vào nỗ lực của cộng đồng. + +## Đọc thêm {#further-reading} + +- [EIP-721: Tiêu chuẩn Token không thể thay thế ERC-721](https://eips.ethereum.org/EIPS/eip-721) +- [OpenZeppelin - Tài liệu ERC-721](https://docs.openzeppelin.com/contracts/3.x/erc721) +- [OpenZeppelin - Triển khai ERC-721](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol) +- [API NFT của Alchemy](https://www.alchemy.com/docs/reference/nft-api-quickstart) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/erc-777/index.md b/public/content/translations/vi/developers/docs/standards/tokens/erc-777/index.md new file mode 100644 index 00000000000..d8bba91213a --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/erc-777/index.md @@ -0,0 +1,45 @@ +--- +title: "Tiêu chuẩn token ERC-777" +description: "Tìm hiểu về ERC-777, một tiêu chuẩn token có thể thay thế được cải tiến với các hook, mặc dù ERC-20 được khuyến nghị vì lý do bảo mật." +lang: vi +--- + +## Cảnh báo {#warning} + +**ERC-777 khó triển khai đúng cách, do tính dễ bị tổn thương trước [các hình thức tấn công khác nhau](https://github.com/OpenZeppelin/openzeppelin-contracts/issues/2620). Bạn nên sử dụng [ERC-20](/developers/docs/standards/tokens/erc-20/) thay thế.** Trang này được lưu giữ như một tài liệu lưu trữ lịch sử. + +## Giới thiệu? {#introduction} + +ERC-777 là một tiêu chuẩn token có thể thay thế nhằm cải tiến tiêu chuẩn [ERC-20](/developers/docs/standards/tokens/erc-20/) hiện có. + +## Điều kiện tiên quyết {#prerequisites} + +Để hiểu rõ hơn về trang này, chúng tôi khuyên bạn nên đọc trước về [ERC-20](/developers/docs/standards/tokens/erc-20/). + +## ERC-777 đề xuất những cải tiến nào so với ERC-20? {#-erc-777-vs-erc-20} + +ERC-777 cung cấp những cải tiến sau so với ERC-20. + +### Hook {#hooks} + +Hook là một hàm được mô tả trong mã của một hợp đồng thông minh. Các hook được gọi khi token được gửi hoặc nhận thông qua hợp đồng. Điều này cho phép một hợp đồng thông minh phản ứng với các token đến hoặc đi. + +Các hook được đăng ký và phát hiện bằng cách sử dụng tiêu chuẩn [ERC-1820](https://eips.ethereum.org/EIPS/eip-1820). + +#### Tại sao hook lại tuyệt vời? {#why-are-hooks-great} + +1. Hook cho phép gửi token đến một hợp đồng và thông báo cho hợp đồng đó trong một giao dịch duy nhất, không giống như [ERC-20](https://eips.ethereum.org/EIPS/eip-20), vốn yêu cầu một lệnh gọi kép (`approve`/`transferFrom`) để đạt được điều này. +2. Các hợp đồng chưa đăng ký hook sẽ không tương thích với ERC-777. Hợp đồng gửi sẽ hủy giao dịch khi hợp đồng nhận chưa đăng ký hook. Điều này ngăn chặn việc chuyển khoản vô tình đến các hợp đồng thông minh không phải ERC-777. +3. Hook có thể từ chối các giao dịch. + +### Số thập phân {#decimals} + +Tiêu chuẩn này cũng giải quyết sự nhầm lẫn xung quanh `decimals` gây ra trong ERC-20. Sự rõ ràng này cải thiện trải nghiệm của nhà phát triển. + +### Khả năng tương thích ngược với ERC-20 {#backwards-compatibility-with-erc-20} + +Các hợp đồng ERC-777 có thể được tương tác như thể chúng là các hợp đồng ERC-20. + +## Đọc thêm {#further-reading} + +[EIP-777: Tiêu chuẩn Token](https://eips.ethereum.org/EIPS/eip-777) diff --git a/public/content/translations/vi/developers/docs/standards/tokens/index.md b/public/content/translations/vi/developers/docs/standards/tokens/index.md new file mode 100644 index 00000000000..150bae6a5f1 --- /dev/null +++ b/public/content/translations/vi/developers/docs/standards/tokens/index.md @@ -0,0 +1,41 @@ +--- +title: "Tiêu chuẩn Token" +description: "Khám phá các tiêu chuẩn token của Ethereum như ERC-20, ERC-721 và ERC-1155 dành cho token có thể thay thế và không thể thay thế." +lang: vi +incomplete: true +--- + +## Giới thiệu {#introduction} + +Nhiều tiêu chuẩn phát triển Ethereum tập trung vào giao diện của token. Các tiêu chuẩn này giúp đảm bảo các hợp đồng thông minh vẫn có thể kết hợp được, vì vậy khi một dự án mới phát hành một token, nó sẽ vẫn tương thích với các sàn giao dịch phi tập trung và ứng dụng hiện có. + +Các tiêu chuẩn token xác định cách các token hoạt động và tương tác trên toàn hệ sinh thái Ethereum. Chúng giúp các nhà phát triển xây dựng dễ dàng hơn mà không cần phải phát minh lại bánh xe, đảm bảo rằng các token hoạt động liền mạch với các ví, sàn giao dịch và nền tảng DeFi. Dù là trong lĩnh vực trò chơi, quản trị hay các trường hợp sử dụng khác, các tiêu chuẩn này đều mang lại sự nhất quán và giúp Ethereum kết nối với nhau nhiều hơn. + +## Điều kiện tiên quyết {#prerequisites} + +- [Các tiêu chuẩn phát triển Ethereum](/developers/docs/standards/) +- [Hợp đồng thông minh](/developers/docs/smart-contracts/) + +## Các tiêu chuẩn token {#token-standards} + +Đây là vài tiêu chuẩn token phổ biến nhất trên Ethereum: + +- [ERC-20](/developers/docs/standards/tokens/erc-20/) - Một giao diện tiêu chuẩn cho các token có thể thay thế (có thể hoán đổi cho nhau), như token biểu quyết, token cổ phần hoặc tiền ảo. + +### Các tiêu chuẩn NFT {#nft-standards} + +- [ERC-721](/developers/docs/standards/tokens/erc-721/) - Một giao diện tiêu chuẩn cho các token không thể thay thế, như một chứng từ cho một tác phẩm nghệ thuật hoặc một bài hát. +- [ERC-1155](/developers/docs/standards/tokens/erc-1155/) - ERC-1155 cho phép giao dịch hiệu quả hơn và gộp các giao dịch lại với nhau – nhờ vậy mà tiết kiệm chi phí. Tiêu chuẩn token này cho phép tạo ra cả token tiện ích (như $BNB hay $BAT) và các NFT như CryptoPunks. + +Danh sách đầy đủ các đề xuất [ERC](https://eips.ethereum.org/erc). + +## Đọc thêm {#further-reading} + +_Biết về nguồn lực cộng đồng đã giúp đỡ bạn? Chỉnh sửa trang này và bổ sung!_ + +## Các hướng dẫn liên quan {#related-tutorials} + +- [Danh sách kiểm tra tích hợp token](/developers/tutorials/token-integration-checklist/) _– Một danh sách những điều cần cân nhắc khi tương tác với các token._ +- [Tìm hiểu về hợp đồng thông minh token ERC20](/developers/tutorials/understand-the-erc-20-token-smart-contract/) _– Giới thiệu về cách triển khai hợp đồng thông minh đầu tiên của bạn trên mạng thử nghiệm Ethereum._ +- [Chuyển và phê duyệt các token ERC20 từ một hợp đồng thông minh Solidity](/developers/tutorials/transfers-and-approval-of-erc-20-tokens-from-a-solidity-smart-contract/) _– Cách sử dụng một hợp đồng thông minh để tương tác với token bằng ngôn ngữ Solidity._ +- [Triển khai thị trường ERC721 [hướng dẫn cách thực hiện]](/developers/tutorials/how-to-implement-an-erc721-market/) _– Cách đưa các vật phẩm được token hóa ra bán trên một bảng rao vặt phi tập trung._