diff --git a/client/src/containers/Header.js b/client/src/containers/Header.js
index 7d2c4bcf0..7961b69b7 100644
--- a/client/src/containers/Header.js
+++ b/client/src/containers/Header.js
@@ -243,6 +243,7 @@ class Header extends React.Component {
tr: strings.turkish,
uk: strings.ukrainian,
ko: strings.korean,
+ vi: strings.vietnamese,
};
const ddOpen = Boolean(this.state.multiDDOpen);
diff --git a/client/src/gamedata/ar/strings.json b/client/src/gamedata/ar/strings.json
index 3461e9cd7..cf9ddab7c 100644
--- a/client/src/gamedata/ar/strings.json
+++ b/client/src/gamedata/ar/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "العب الان!",
"toggleNavigation": "تصفح",
@@ -32,9 +33,9 @@
"accountNotConnectedMessage": "لبدء مغامرتك، قم بتوصيل محفظة MetaMask الخاصة بك! تتفاعل لعبتنا بشكل مباشر مع عقود Ethernaut على السلسلة، مما يعني أن أفعالك في اللعبة مسجلة على blockchain. من خلال ربط حساب MetaMask الخاص بك، يمكنك التفاعل بأمان مع هذه العقود الذكية، مما يسمح لك بحل التحديات والتقدم في اللعبة.",
"connectAccount": "يتصل",
"deployMessageTitle": "لم يتم نشر اللعبة",
- "deployMessage": "تدُعم اللُعبة حاليًا هذه الشبكات فقط:",
"deprecatedNetwork": "شبكة عفا عليها الزمن",
"networkBeingDeprecated": "يتم إهمال الشبكة",
+ "deployMessage": "تدُعم اللُعبة حاليًا هذه الشبكات فقط:",
"deployConfirmation": "هل تريد نشر العقود على هذه الشبكة أم التبديل إلى شبكة Sepolia",
"deployNote": "ملاحظة: إذا قمت بنشر جميع المستويات ، فسنرشدك إلى إرسال اللعبة المنشورة بالكامل على هذه الشبكة.",
"deployGame": "نشر اللعبة",
diff --git a/client/src/gamedata/en/strings.json b/client/src/gamedata/en/strings.json
index 9e7498cc9..94accda9d 100644
--- a/client/src/gamedata/en/strings.json
+++ b/client/src/gamedata/en/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Play now!",
"toggleNavigation": "Toggle navigation",
diff --git a/client/src/gamedata/es/strings.json b/client/src/gamedata/es/strings.json
index b18142d46..e61ee610d 100644
--- a/client/src/gamedata/es/strings.json
+++ b/client/src/gamedata/es/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Juega ahora!",
"toggleNavigation": "Despliega la navegación",
@@ -75,7 +76,7 @@
"levelAddressMessage": "Dirección del nivel",
"instanceAddressMessage": "Dirección de la instancia",
"playerAddressMessage": "Dirección del jugador",
- "selectedNetworkMessage": "Current network: ",
+ "selectedNetworkMessage": "Red actual: ",
"ethernautAddressMessage": "Dirección de Ethernaut",
"noLevelsDataMessage": "No se encuentran los datos de los niveles",
"ethernautNotFoundMessage": "El contrato de Ethernaut no se ha encontrado en la red seleccionada. Por favor averigua que 1) Estás usando MetaMask, 2) Estas en una red soportada, 3) Que MetaMask esté desbloqueado, 4 opcional) Puedes habilitar y setear en ON el modo privado (desactivado por defecto) en los ajustes si no quieres que tus informaciones sean automáticamente expuestas. 5 opcional) Si el modo privado esta habilitado tienes que autorizar MetaMask a utilizar esta página web. 6) Actualiza la página.",
@@ -83,7 +84,7 @@
"unableToRetrieveLevelMessage": "No se puede obtener la instancia del nivel! Por favor, controle la cantidad de gas proporcionada e inténtelo de nuevo.",
"transactionNoLogsMessage": "La transacción no contiene logs",
"noPlayerAddressMessage": "Ninguna dirección encontrada para el jugador! Asegúrate de que 1) Tengas instalada la extensión MetaMask para tu navegador y 2) Que esté desbloqueada. 3 opcional) Puedes habilitar y setear en ON el modo privado (desactivado por defecto) en los ajustes si no quieres que tus informaciones sean automáticamente expuestas. 4 opcional) Si el modo privado esta habilitado tienes que autorizar MetaMask a utilizar esta página web. 5) Actualiza la página.",
- "noEthersMessage": "Yikes, you have no ether! Get some at valid faucet for your chosen network",
+ "noEthersMessage": "Vaya, no tienes ether. Consigue algo en un faucet válido para la red seleccionada",
"submitLevelMessage": "Enviando la instancia del nivel",
"wellDoneMessage": "Bien hecho",
"completedLevelMessage": "Has completado ese nivel!!!",
@@ -105,16 +106,16 @@
"helperFromWei": "convierte wei en ether",
"levelNotTranslated": "Este nivel no está traducido o la traducción es incompleta. ",
"contributeTranslation": "Haz clic aquí para contribuir en mejorar la traducción",
- "usingConsole": "Most game interaction is via the browser's console: `Dev Tools -> Console`. Open the console and enter the command: \n\n`help()`\n\n to see a list of objects and functions injected by the game to the console. Since most interactions are asynchronous, we recommend using Chrome v62 which enables the `async`/`await` keywords in the console, so instead of writting:\n\n`getBalance(player)> PROMISE`\n\nand opening the promise. With await/async, you can write:\n\n`await getBalance(player) > '1.11002387' `\n\n",
- "gameMechanics": "The game uses the main contract `Ethernaut.sol` to manage player progress and delegate interaction with `Level.sol` implementations. Each level contract emits instances for players to manipulate, break, destroy, fix, etc. The player requests an instance, manipulates it and returns it to the game for evaluation of level completion.\n\n Both requesting instances and submitting instances back to the game are done with the buttons in the user interface in each level. When this app retrieves an instance from `Ethernaut.sol`, it wraps it in a `TruffleContract` object and exposes it in the browser's console. See the first level for a full tutorial on how to play the game.",
- "beyondConsole": "Some levels will require working outside of the browser console. That is, writing solidity code and deploying it in the network to attack the level's instance contract with another contract. This can be done in multiple ways, for example: \n\n1) Use Remix to write the code and deploy it in the corresponding network See [Remix Solidity IDE](https://remix.ethereum.org/).\n\n 2) Setup a local truffle project to develop and deploy the attack contracts. See [Truffle Framework](https://trufflesuite.com/).",
- "troubleshooting": "Sometimes \n\n(a) the app state or (b) the MetaMask plugin state \n\ncan become a bit messed up, specially after switching networks, unlocking, etc. If what you're seeing doesn't make much sense, try refreshing the app, hard-refreshing it, disabling and re-enabling your metamask plugin or even restarting your browser. \n\nIf you find issues, please let us know at ethernaut@zeppelin.solutions",
- "poweredBy": "powered by ",
+ "usingConsole": "La mayoría de la interacción del juego se realiza mediante la consola del navegador: `Dev Tools -> Console`. Abre la consola e ingresa el comando:\n\n`help()`\n\n para ver una lista de objetos y funciones que el juego inyecta en la consola. Dado que la mayoría de las interacciones son asíncronas, recomendamos usar Chrome v62 o superior que habilita las palabras clave `async`/`await` en la consola, así en lugar de escribir:\n\n`getBalance(player) > PROMISE`\n\n y abrir la promesa. Con async/await puedes escribir:\n\n`await getBalance(player) > '1.11002387' `\n\n",
+ "gameMechanics": "El juego usa el contrato principal `Ethernaut.sol` para gestionar el progreso de los jugadores y delegar la interacción con las implementaciones de `Level.sol`. Cada contrato de nivel emite instancias para que los jugadores las manipulen, rompan, destruyan, arreglen, etc. El jugador solicita una instancia, la manipula y la devuelve al juego para evaluar la finalización del nivel.\n\n Tanto la solicitud de instancias como el envío de instancias de vuelta al juego se realizan con los botones en la interfaz de usuario de cada nivel. Cuando esta aplicación obtiene una instancia de `Ethernaut.sol`, la envuelve en un objeto `TruffleContract` y la expone en la consola del navegador. Consulta el primer nivel para un tutorial completo sobre cómo jugar.",
+ "beyondConsole": "Algunos niveles requerirán trabajar fuera de la consola del navegador. Es decir, escribir código Solidity y desplegarlo en la red para atacar el contrato de la instancia del nivel con otro contrato. Esto puede hacerse de varias maneras, por ejemplo: \n\n1) Usa Remix para escribir el código y desplegarlo en la red correspondiente. Ver [Remix Solidity IDE](https://remix.ethereum.org/).\n\n2) Configura un proyecto local de Truffle para desarrollar y desplegar los contratos de ataque. Ver [Truffle Framework](https://trufflesuite.com/).",
+ "troubleshooting": "A veces \n\n(a) el estado de la aplicación o (b) el estado del plugin MetaMask \n\npueden quedar un poco desordenados, especialmente después de cambiar de red, desbloquear, etc. Si lo que estás viendo no tiene mucho sentido, intenta recargar la aplicación, hacer una recarga forzada, desactivar y volver a activar la extensión de MetaMask o incluso reiniciar el navegador. \n\nSi encuentras problemas, avísanos en ethernaut@zeppelin.solutions",
+ "poweredBy": "impulsado por ",
"setupMetamask": "Si aún no lo tienes, instala la [extensión del navegador MetaMask](https://metamask.io/). \n\nConfigura la billetera de la extensión y usa el selector de red para apuntar a tu red preferida en la parte superior izquierda de la interfaz de la extensión. De forma alternativa, puedes usar el boton en la interfaz de usuario para cambiar entre diferentes redes. Si seleccionas una red no soportada, el juego te notificarà y llevarà a la red de test por defecto de Sepolia. \n\nUna vez hecho, vuelve aqui y vuelve a carga la pagin",
- "FifthyPercentMessage": "Awesome work! You’re halfway through Ethernaut and getting pretty good at breaking things. Working as a Blockchain Security Researcher at OpenZeppelin could be fun... https://grnh.se/fdbf1c043us",
- "SeventyFivePercentMessage": "75%: Good work anon…you’re deep down the rabbit hole now....who knows where it will take you... https://grnh.se/d4a786e43us",
- "NinetyPercentMessage": "90%: You’re almost there anon! Just a few more challenges left until you complete Ethernaut! Have you considered a career in Blockchain Security?https://grnh.se/cfcca8c83us",
- "HundredPercentMessage": "100%: Congratulations! Your journey down the web3 rabbit hole is impressive and should be celebrated! You now have the skills to break smart contracts! What’s next from here anon? Apply to be a Blockchain Security Researcher at OpenZeppelin, and contribute to securing the top protocols in web3! https://grnh.se/26c05aac3us",
+ "FifthyPercentMessage": "¡Excelente trabajo! Vas a mitad de camino en Ethernaut y te estás volviendo bastante bueno rompiendo cosas. Trabajar como Blockchain Security Researcher en OpenZeppelin podría ser divertido... https://grnh.se/fdbf1c043us",
+ "SeventyFivePercentMessage": "75%: Buen trabajo anon... ya estás muy dentro de la madriguera del conejo... quién sabe a dónde te llevará... https://grnh.se/d4a786e43us",
+ "NinetyPercentMessage": "90%: ¡Ya casi llegas anon! Solo unos pocos desafíos más hasta completar Ethernaut. ¿Has considerado una carrera en Seguridad Blockchain? https://grnh.se/cfcca8c83us",
+ "HundredPercentMessage": "100%: ¡Felicidades! Tu viaje por la madriguera de web3 es impresionante y merece celebrarse. ¡Ahora tienes las habilidades para romper smart contracts! ¿Qué sigue desde aquí anon? Postula para ser Blockchain Security Researcher en OpenZeppelin y contribuye a asegurar los principales protocolos en web3. https://grnh.se/26c05aac3us",
"Menu": "Menú",
"Networks": "Redes",
"Languages": "Idiomas",
diff --git a/client/src/gamedata/fr/strings.json b/client/src/gamedata/fr/strings.json
index 9bb952f54..a3c030d4c 100644
--- a/client/src/gamedata/fr/strings.json
+++ b/client/src/gamedata/fr/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Jouer maintenant!",
"toggleNavigation": "Basculer la navigation",
diff --git a/client/src/gamedata/ja/strings.json b/client/src/gamedata/ja/strings.json
index c967b2544..09f9b75e4 100644
--- a/client/src/gamedata/ja/strings.json
+++ b/client/src/gamedata/ja/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "プレイ!",
"toggleNavigation": "トグルナビゲーション",
@@ -32,9 +33,9 @@
"accountNotConnectedMessage": "冒険を始めるには、MetaMask ウォレットを接続してください。私たちのゲームは Ethernaut オンチェーン コントラクトと直接やり取りします。つまり、ゲーム内でのアクションはブロックチェーンに記録されます。MetaMask アカウントをリンクすることで、これらのスマート コントラクトに安全に関与し、課題を解決してゲームを進めることができます。",
"connectAccount": "接続する",
"deployMessageTitle": "ゲームが展開されていません",
- "deployMessage": "現在、ゲームはこれらのネットワークのみをサポートしています:",
"deprecatedNetwork": "ネットワークは放棄されています",
"networkBeingDeprecated": "将来的には、ネットワークは使用できなくなります。",
+ "deployMessage": "現在、ゲームはこれらのネットワークのみをサポートしています:",
"deployConfirmation": "コントラクトをこのネットワークに展開しますか、それとも Sepolia ネットワークに切り替えますか?",
"deployNote": "注: すべてのレベルを展開する場合は、展開されたゲーム全体をこのネットワークに送信するように案内されます。",
"deployGame": "ゲームを展開する",
diff --git a/client/src/gamedata/ko/strings.json b/client/src/gamedata/ko/strings.json
index 5b33d105a..4524b9ec1 100644
--- a/client/src/gamedata/ko/strings.json
+++ b/client/src/gamedata/ko/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "지금 플레이!",
"toggleNavigation": "내비게이션 전환",
@@ -31,10 +32,10 @@
"accountNotConnectedTitle": "MetaMask 계정 연결되지 않음",
"accountNotConnectedMessage": "모험을 시작하려면 MetaMask 지갑을 연결하세요! 게임은 Ethernaut의 온체인 계약과 직접 상호작용하며, 게임 내에서의 모든 행동은 블록체인에 기록됩니다. MetaMask 계정을 연결하면 이러한 스마트 계약과 안전하게 상호작용할 수 있습니다.",
"connectAccount": "연결",
- "deployMessageTitle": "게임이 배포되지 않음",
+ "deployMessage": "현재 게임은 다음 네트워크만 지원합니다:",
"deprecatedNetwork": "네트워크가 더 이상 지원되지 않음",
"networkBeingDeprecated": "네트워크가 더 이상 지원되지 않음",
- "deployMessage": "현재 게임은 다음 네트워크만 지원합니다:",
+ "deployMessageTitle": "게임이 배포되지 않음",
"deployConfirmation": "이 네트워크에 계약을 배포하시겠습니까, 아니면 Sepolia 네트워크로 전환하시겠습니까?",
"deployNote": "참고: 모든 레벨을 배포하면, 우리는 이 네트워크에서 전체 게임을 제출할 수 있도록 안내할 것입니다.",
"deployGame": "게임 배포",
diff --git a/client/src/gamedata/pt_br/strings.json b/client/src/gamedata/pt_br/strings.json
index 1a1477c7c..24a20ecda 100644
--- a/client/src/gamedata/pt_br/strings.json
+++ b/client/src/gamedata/pt_br/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Jogue agora!",
"toggleNavigation": "Exibir a navegação",
diff --git a/client/src/gamedata/ru/strings.json b/client/src/gamedata/ru/strings.json
index d7cfdacb5..5659ada7c 100644
--- a/client/src/gamedata/ru/strings.json
+++ b/client/src/gamedata/ru/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Играть!",
"toggleNavigation": "Показать или скрыть панель навигации",
diff --git a/client/src/gamedata/tr/strings.json b/client/src/gamedata/tr/strings.json
index cf3548ad3..5c65e4226 100644
--- a/client/src/gamedata/tr/strings.json
+++ b/client/src/gamedata/tr/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Şimdi oyna!",
"toggleNavigation": "Menüyü Aç/Kapat",
diff --git a/client/src/gamedata/uk/strings.json b/client/src/gamedata/uk/strings.json
index 608d35ad4..c6b16d0e2 100644
--- a/client/src/gamedata/uk/strings.json
+++ b/client/src/gamedata/uk/strings.json
@@ -2,6 +2,8 @@
"ethernaut": "Ethernaut",
"title": "Ethernaut",
"hiring": "Ми наймаємо",
+ "ctfRegister": "Register now!",
+ "ctfInfo": "We are hosting Ethernaut CTF: A 48-hour capture the flag event with prizes and blockchain challenges, starting 16/03.",
"info": "
Ethernaut це Web3/Solidity варгейм на базі Ethereum Virtual Machine, натхненний overthewire.org. Кожен рівень є смарт-контрактом, який потрібно 'зламати'. Вихідний код гри повністю відкритий, а всі рівні створені іншими гравцями. У тебе є цікава ідея для нового рівня?
",
"home": "Назад",
"help": "Допомога",
@@ -19,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "Грати!",
"toggleNavigation": "Показати або приховати панель навігації",
@@ -26,12 +29,18 @@
"sources": "Вихідний код",
"submitInstance": "Надіслати інстанс на перевірку",
"getNewInstance": "Створити новий інстанс",
+ "accountNotConnectedTitle": "Обліковий запис MetaMask не підключений",
+ "accountNotConnectedMessage": "Щоб розпочати свою пригоду, підключіть свій гаманець MetaMask! Наша гра взаємодіє безпосередньо з ончейн‑контрактами Ethernaut, тож ваші дії в грі записуються в блокчейн. Підключивши свій обліковий запис MetaMask, ви зможете безпечно взаємодіяти з цими смарт‑контрактами, розв’язувати завдання та просуватися у грі.",
+ "connectAccount": "Підключити",
"deployMessageTitle": "Гра не розгорнута",
+ "deprecatedNetwork": "Мережа застаріла",
+ "networkBeingDeprecated": "Мережа позначена як застаріла",
"deployMessage": "На даний момент гра підтримує тільки ці мережі:",
"deployConfirmation": "Ви хочете розгорнути контракти в цій мережі або переключитись на мережу Sepolia?",
"deployNote": "Примітка. Якщо ви розгорнете всі рівні, ми порадимо вам відправити всю розгорнуту гру в цю мережу.",
"deployGame": "Розгорнути гру",
"switchToSepolia": "Переключитись на Sepolia",
+ "continueAnyway": "Продовжити все одно",
"deployLevel": "Рівень розгортання",
"helperDeployAllContracts": "Розгорніть всі залишені контракти в поточній мережі.",
"confirmMainnetDeploy": "Ви перебуваєте в основній мережі, гра не має грошової вартості, вам не слід розгортати її в цій мережі.",
diff --git a/client/src/gamedata/vi/descriptions/levels/aliencodex.md b/client/src/gamedata/vi/descriptions/levels/aliencodex.md
new file mode 100644
index 000000000..48365b6de
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/aliencodex.md
@@ -0,0 +1,7 @@
+Bạn đã phát hiện ra một hợp đồng Alien. Hãy chiếm quyền sở hữu để hoàn thành cấp độ này.
+
+
+Những điều có thể hữu ích
+* Hiểu cách lưu trữ mảng hoạt động
+* Hiểu [đặc tả ABI](https://solidity.readthedocs.io/en/v0.4.21/abi-spec.html)
+* Sử dụng một cách tiếp cận rất `gian lận`
diff --git a/client/src/gamedata/vi/descriptions/levels/aliencodex_complete.md b/client/src/gamedata/vi/descriptions/levels/aliencodex_complete.md
new file mode 100644
index 000000000..e78884878
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/aliencodex_complete.md
@@ -0,0 +1,5 @@
+Cấp độ này khai thác thực tế rằng EVM không xác thực độ dài được mã hóa ABI của mảng so với payload thực tế của nó.
+
+Ngoài ra, nó khai thác underflow số học của độ dài mảng, bằng cách mở rộng giới hạn của mảng đến toàn bộ vùng lưu trữ của `2^256`. Người dùng sau đó có thể sửa đổi tất cả lưu trữ hợp đồng.
+
+Cả hai lỗ hổng đều được lấy cảm hứng từ [cuộc thi lập trình Underhanded 2017](https://medium.com/@weka/announcing-the-winners-of-the-first-underhanded-solidity-coding-contest-282563a87079)
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/coinflip.md b/client/src/gamedata/vi/descriptions/levels/coinflip.md
new file mode 100644
index 000000000..1b6540521
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/coinflip.md
@@ -0,0 +1,5 @@
+Đây là trò chơi tung đồng xu nơi bạn cần xây dựng chuỗi thắng bằng cách đoán kết quả của việc tung đồng xu. Để hoàn thành cấp độ này, bạn cần sử dụng khả năng tâm linh để đoán đúng kết quả 10 lần liên tiếp.
+
+
+Những điều có thể hữu ích
+* Xem trang ["?"](https://ethernaut.openzeppelin.com/help) ở trên trong menu góc trên bên phải, phần "Beyond the console"
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/coinflip_complete.md b/client/src/gamedata/vi/descriptions/levels/coinflip_complete.md
new file mode 100644
index 000000000..9424ad62f
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/coinflip_complete.md
@@ -0,0 +1,6 @@
+Tạo số ngẫu nhiên trong solidity có thể khó khăn. Hiện tại không có cách bản địa để tạo chúng, và mọi thứ bạn sử dụng trong hợp đồng thông minh đều có thể nhìn thấy công khai, bao gồm các biến cục bộ và biến trạng thái được đánh dấu là private. Các thợ mỏ cũng có quyền kiểm soát những thứ như blockhashes, timestamps, và việc có bao gồm các giao dịch nhất định hay không - điều này cho phép họ thiên vị các giá trị này có lợi cho họ.
+
+Để có được số ngẫu nhiên được chứng minh bằng mật mã, bạn có thể sử dụng [Chainlink VRF](https://docs.chain.link/docs/get-a-random-number), sử dụng oracle, token LINK, và hợp đồng on-chain để xác minh rằng số đó thực sự ngẫu nhiên.
+
+Một số tùy chọn khác bao gồm sử dụng Bitcoin block headers (được xác minh thông qua [BTC Relay](http://btcrelay.org)), [RANDAO](https://github.com/randao/randao), hoặc [Oraclize](http://www.oraclize.it/)).
+
diff --git a/client/src/gamedata/vi/descriptions/levels/delegate.md b/client/src/gamedata/vi/descriptions/levels/delegate.md
new file mode 100644
index 000000000..f849d1bc9
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/delegate.md
@@ -0,0 +1,7 @@
+Mục tiêu của cấp độ này là bạn phải chiếm quyền sở hữu của phiên bản được cung cấp.
+
+
+Những điều có thể hữu ích
+* Tìm hiểu tài liệu Solidity về hàm cấp thấp `delegatecall`, cách nó hoạt động, cách sử dụng để ủy quyền các thao tác cho thư viện on-chain, và những tác động của nó đến phạm vi thực thi.
+* Phương thức fallback
+* ID phương thức
diff --git a/client/src/gamedata/vi/descriptions/levels/delegate_complete.md b/client/src/gamedata/vi/descriptions/levels/delegate_complete.md
new file mode 100644
index 000000000..ba3a0a63a
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/delegate_complete.md
@@ -0,0 +1,5 @@
+Việc sử dụng `delegatecall` đặc biệt rủi ro và đã được sử dụng làm vector tấn công trong nhiều vụ hack lịch sử. Với nó, hợp đồng của bạn thực tế đang nói "đây, -hợp đồng khác- hoặc -thư viện khác-, làm bất cứ điều gì bạn muốn với trạng thái của tôi". Các delegate có quyền truy cập hoàn toàn vào trạng thái hợp đồng của bạn. Hàm `delegatecall` là một tính năng mạnh mẽ, nhưng nguy hiểm, và phải được sử dụng với sự cẩn thận tối đa.
+
+
+Vui lòng tham khảo bài viết [The Parity Wallet Hack Explained](https://blog.openzeppelin.com/on-the-parity-wallet-multisig-hack-405a8c12e8f7) để có giải thích chính xác về cách ý tưởng này được sử dụng để đánh cắp 30M USD.
+
diff --git a/client/src/gamedata/vi/descriptions/levels/denial.md b/client/src/gamedata/vi/descriptions/levels/denial.md
new file mode 100644
index 000000000..99b8777cc
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/denial.md
@@ -0,0 +1,5 @@
+Đây là một ví đơn giản nhỏ giọt tiền theo thời gian. Bạn có thể rút tiền
+từ từ bằng cách trở thành đối tác rút tiền.
+
+Nếu bạn có thể ngăn chủ sở hữu rút tiền khi họ gọi `withdraw()`
+(trong khi hợp đồng vẫn còn tiền, và giao dịch có gas 1M hoặc ít hơn) bạn sẽ thắng cấp độ này.
diff --git a/client/src/gamedata/vi/descriptions/levels/denial_complete.md b/client/src/gamedata/vi/descriptions/levels/denial_complete.md
new file mode 100644
index 000000000..4a3df7ad2
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/denial_complete.md
@@ -0,0 +1,11 @@
+Cấp độ này chứng minh rằng các lệnh gọi bên ngoài đến các hợp đồng không xác định vẫn có thể
+tạo ra các vector tấn công từ chối dịch vụ nếu không chỉ định một lượng gas cố định.
+
+Nếu bạn đang sử dụng `call` cấp thấp để tiếp tục thực thi trong trường hợp lệnh gọi bên ngoài revert, hãy đảm bảo rằng bạn chỉ định một khoản gas cố định. Ví dụ `call.gas(100000).value()`.
+
+Thông thường người ta nên tuân theo mẫu [checks-effects-interactions](http://solidity.readthedocs.io/en/latest/security-considerations.html#use-the-checks-effects-interactions-pattern) để tránh các cuộc tấn công reentrancy, có thể có các trường hợp khác (như nhiều lệnh gọi bên ngoài ở cuối hàm) nơi các vấn đề như vậy có thể phát sinh.
+
+*Lưu ý*: Một `CALL` bên ngoài có thể sử dụng tối đa 63/64 gas hiện có
+tại thời điểm `CALL`. Do đó, tùy thuộc vào lượng gas cần thiết để
+hoàn thành một giao dịch, một giao dịch có gas đủ cao (tức là một giao dịch như vậy
+mà 1/64 gas có khả năng hoàn thành các opcode còn lại trong lệnh gọi cha) có thể được sử dụng để giảm thiểu cuộc tấn công cụ thể này.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/dex.md b/client/src/gamedata/vi/descriptions/levels/dex.md
new file mode 100644
index 000000000..a0d3c8292
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/dex.md
@@ -0,0 +1,18 @@
+Mục tiêu của cấp độ này là bạn phải hack hợp đồng [DEX](https://en.wikipedia.org/wiki/Decentralized_exchange) cơ bản bên dưới và đánh cắp tiền bằng cách thao túng giá.
+
+Bạn sẽ bắt đầu với 10 token của `token1` và 10 của `token2`. Hợp đồng DEX bắt đầu với 100 của mỗi token.
+
+Bạn sẽ thành công trong cấp độ này nếu bạn quản lý để rút hết ít nhất 1 trong 2 token từ hợp đồng, và cho phép hợp đồng báo cáo giá "xấu" của tài sản.
+
+
+### Lưu ý nhanh
+Thông thường, khi bạn thực hiện swap với token ERC20, bạn phải `approve` hợp đồng để chi tiêu token của bạn. Để phù hợp với cú pháp của trò chơi, chúng tôi đã thêm phương thức `approve` vào chính hợp đồng. Vì vậy hãy thoải mái sử dụng `contract.approve(contract.address, )` thay vì gọi token trực tiếp, và nó sẽ tự động phê duyệt chi tiêu hai token với số lượng mong muốn. Hãy thoải mái bỏ qua hợp đồng `SwappableToken` nếu không.
+
+
+Những điều có thể hữu ích:
+* Giá của token được tính như thế nào?
+* Phương thức `swap` hoạt động như thế nào?
+* Làm thế nào để `approve` một giao dịch của ERC20?
+* Có nhiều hơn một cách để tương tác với hợp đồng!
+* Remix có thể hữu ích
+* "At Address" làm gì?
diff --git a/client/src/gamedata/vi/descriptions/levels/dex2.md b/client/src/gamedata/vi/descriptions/levels/dex2.md
new file mode 100644
index 000000000..b41e579a4
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/dex2.md
@@ -0,0 +1,9 @@
+Cấp độ này sẽ yêu cầu bạn phá vỡ `DexTwo`, một hợp đồng `Dex` được sửa đổi tinh tế từ cấp độ trước, theo một cách khác.
+
+Bạn cần rút hết số dư của token1 và token2 từ hợp đồng `DexTwo` để thành công trong cấp độ này.
+
+Bạn vẫn sẽ bắt đầu với 10 token của `token1` và 10 của `token2`. Hợp đồng DEX vẫn bắt đầu với 100 của mỗi token.
+
+
+Những điều có thể hữu ích:
+* Phương thức `swap` đã được sửa đổi như thế nào?
diff --git a/client/src/gamedata/vi/descriptions/levels/dex2_complete.md b/client/src/gamedata/vi/descriptions/levels/dex2_complete.md
new file mode 100644
index 000000000..4c3135ec1
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/dex2_complete.md
@@ -0,0 +1,9 @@
+Như chúng ta đã thấy nhiều lần, tương tác giữa các hợp đồng có thể là nguồn gốc của hành vi không mong đợi.
+
+Chỉ vì một hợp đồng tuyên bố triển khai [đặc tả ERC20](https://eips.ethereum.org/EIPS/eip-20) không có nghĩa là nó đáng tin cậy.
+
+Một số token lệch khỏi đặc tả ERC20 bằng cách không trả về giá trị boolean từ các phương thức `transfer` của chúng. Xem [Lỗi thiếu giá trị trả về - Ít nhất 130 token bị ảnh hưởng](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca).
+
+Các token ERC20 khác, đặc biệt là những token được thiết kế bởi kẻ thù có thể hành xử độc hại hơn.
+
+Nếu bạn thiết kế một DEX nơi bất kỳ ai cũng có thể liệt kê token của riêng họ mà không cần sự cho phép của cơ quan trung ương, thì tính đúng đắn của DEX có thể phụ thuộc vào tương tác của hợp đồng DEX và các hợp đồng token được giao dịch.
diff --git a/client/src/gamedata/vi/descriptions/levels/dex_complete.md b/client/src/gamedata/vi/descriptions/levels/dex_complete.md
new file mode 100644
index 000000000..46a37daa3
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/dex_complete.md
@@ -0,0 +1,58 @@
+Bỏ qua phần toán học số nguyên, việc lấy giá hoặc bất kỳ loại dữ liệu nào từ một nguồn duy nhất là một vector tấn công lớn trong hợp đồng thông minh.
+
+Bạn có thể thấy rõ từ ví dụ này, rằng ai đó có nhiều vốn có thể thao túng giá trong một cú đánh, và khiến bất kỳ ứng dụng nào dựa vào nó sử dụng giá sai.
+
+Bản thân sàn giao dịch là phi tập trung, nhưng giá của tài sản lại tập trung, vì nó đến từ 1 dex. Tuy nhiên, nếu chúng ta xem xét các token đại diện cho tài sản thực tế thay vì tài sản hư cấu, hầu hết chúng sẽ có các cặp trao đổi trong nhiều dex và mạng. Điều này sẽ giảm tác động đến giá tài sản trong trường hợp một dex cụ thể bị tấn công như vậy.
+
+[Oracles](https://betterprogramming.pub/what-is-a-blockchain-oracle-f5ccab8dbd72?source=friends_link&sk=d921a38466df8a9176ed8dd767d8c77d) được sử dụng để lấy dữ liệu vào và ra khỏi hợp đồng thông minh.
+
+[Chainlink Data Feeds](https://docs.chain.link/docs/get-the-latest-price) là một cách an toàn, đáng tin cậy để lấy dữ liệu phi tập trung vào hợp đồng thông minh của bạn. Chúng có một thư viện rộng lớn với nhiều nguồn khác nhau, và cũng cung cấp [tính ngẫu nhiên an toàn](https://docs.chain.link/docs/chainlink-vrf), khả năng thực hiện [bất kỳ lệnh gọi API nào](https://docs.chain.link/docs/make-a-http-get-request), [tạo mạng oracle mô-đun](https://docs.chain.link/docs/architecture-decentralized-model), [bảo trì, hành động và duy trì](https://docs.chain.link/docs/kovan-keeper-network-beta), và tùy chỉnh không giới hạn.
+
+[Uniswap TWAP Oracles](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles) dựa vào mô hình giá trọng số thời gian gọi là [TWAP](https://en.wikipedia.org/wiki/Time-weighted_average_price#). Mặc dù thiết kế có thể hấp dẫn, giao thức này phụ thuộc nhiều vào tính thanh khoản của giao thức DEX, và nếu điều này quá thấp, giá có thể dễ dàng bị thao túng.
+
+
+Đây là một ví dụ về việc lấy giá Bitcoin bằng USD từ Chainlink data feed (trên Sepolia testnet):
+
+```
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.7;
+
+import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
+
+contract PriceConsumerV3 {
+ AggregatorV3Interface internal priceFeed;
+
+ /**
+ * Network: Sepolia
+ * Aggregator: BTC/USD
+ * Address: 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
+ */
+ constructor() {
+ priceFeed = AggregatorV3Interface(
+ 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43
+ );
+ }
+
+ /**
+ * Returns the latest price.
+ */
+ function getLatestPrice() public view returns (int) {
+ // prettier-ignore
+ (
+ /* uint80 roundID */,
+ int price,
+ /*uint startedAt*/,
+ /*uint timeStamp*/,
+ /*uint80 answeredInRound*/
+ ) = priceFeed.latestRoundData();
+ return price;
+ }
+}
+
+```
+[Thử trên Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/PriceFeeds/PriceConsumerV3.sol)
+
+Kiểm tra [trang](https://data.chain.link/ethereum/mainnet/crypto-usd/btc-usd) Chainlink feed để xem rằng giá Bitcoin được truy vấn từ tối đa 31 nguồn khác nhau.
+
+Bạn cũng có thể kiểm tra [danh sách](https://docs.chain.link/data-feeds/price-feeds/addresses/) tất cả địa chỉ Chainlink price feeds.
+
diff --git a/client/src/gamedata/vi/descriptions/levels/doubleentrypoint.md b/client/src/gamedata/vi/descriptions/levels/doubleentrypoint.md
new file mode 100644
index 000000000..98324cfe8
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/doubleentrypoint.md
@@ -0,0 +1,10 @@
+Cấp độ này có một `CryptoVault` với chức năng đặc biệt, hàm `sweepToken`. Đây là một hàm phổ biến được sử dụng để lấy lại token bị kẹt trong hợp đồng. `CryptoVault` hoạt động với một token `underlying` không thể bị quét, vì nó là thành phần logic cốt lõi quan trọng của `CryptoVault`. Bất kỳ token nào khác đều có thể bị quét.
+
+Token underlying là một phiên bản của token DET được triển khai trong định nghĩa hợp đồng `DoubleEntryPoint` và `CryptoVault` nắm giữ 100 đơn vị của nó. Ngoài ra `CryptoVault` cũng nắm giữ 100 `LegacyToken LGT`.
+
+Trong cấp độ này bạn nên tìm ra lỗi ở đâu trong `CryptoVault` và bảo vệ nó khỏi bị rút hết token.
+
+Hợp đồng có một hợp đồng `Forta` nơi bất kỳ người dùng nào cũng có thể đăng ký hợp đồng `detection bot` của riêng mình. Forta là một mạng giám sát phi tập trung, dựa trên cộng đồng để phát hiện các mối đe dọa và bất thường trên DeFi, NFT, quản trị, cầu nối và các hệ thống Web3 khác một cách nhanh chóng nhất có thể. Nhiệm vụ của bạn là triển khai một `detection bot` và đăng ký nó trong hợp đồng `Forta`. Việc triển khai bot sẽ cần đưa ra cảnh báo chính xác để ngăn chặn các cuộc tấn công tiềm ẩn hoặc khai thác lỗi.
+
+Những điều có thể hữu ích:
+- Double entry point hoạt động như thế nào cho hợp đồng token?
diff --git a/client/src/gamedata/vi/descriptions/levels/doubleentrypoint_complete.md b/client/src/gamedata/vi/descriptions/levels/doubleentrypoint_complete.md
new file mode 100644
index 000000000..50e0d4bca
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/doubleentrypoint_complete.md
@@ -0,0 +1,13 @@
+Chúc mừng!
+
+Đây là trải nghiệm đầu tiên của bạn với [Forta bot](https://docs.forta.network/en/latest/).
+
+Forta bao gồm một mạng phi tập trung của các nhà điều hành nút độc lập quét tất cả các giao dịch và thay đổi trạng thái theo từng khối để tìm các giao dịch bất thường và mối đe dọa. Khi phát hiện vấn đề, các nhà điều hành nút gửi cảnh báo cho người đăng ký về các rủi ro tiềm ẩn, cho phép họ hành động.
+
+Ví dụ được trình bày chỉ dành cho mục đích giáo dục vì Forta bot không được mô hình hóa thành hợp đồng thông minh. Trong Forta, bot là một script mã để phát hiện các điều kiện hoặc sự kiện cụ thể, nhưng khi cảnh báo được phát ra, nó không kích hoạt các hành động tự động - ít nhất là chưa. Trong cấp độ này, cảnh báo của bot hiệu quả kích hoạt revert trong giao dịch, lệch khỏi thiết kế bot dự định của Forta.
+
+Detection bot phụ thuộc nhiều vào triển khai cuối cùng của hợp đồng và một số có thể nâng cấp và phá vỡ tích hợp bot, nhưng để giảm thiểu điều đó, bạn thậm chí có thể tạo một bot cụ thể để tìm kiếm nâng cấp hợp đồng và phản ứng với nó. Tìm hiểu cách làm điều đó [tại đây](https://docs.forta.network/en/latest/quickstart/).
+
+Bạn cũng đã trải qua một vấn đề bảo mật gần đây đã được phát hiện trong [hợp tác mới nhất của OpenZeppelin với giao thức Compound](https://compound.finance/governance/proposals/76).
+
+Có token trình bày double entry point là một mẫu không tầm thường có thể ảnh hưởng đến nhiều giao thức. Điều này là do người ta thường giả định có một hợp đồng cho mỗi token. Nhưng lần này không phải vậy :) Bạn có thể đọc toàn bộ chi tiết về những gì đã xảy ra [tại đây](https://blog.openzeppelin.com/compound-tusd-integration-issue-retrospective/).
diff --git a/client/src/gamedata/vi/descriptions/levels/elevator.md b/client/src/gamedata/vi/descriptions/levels/elevator.md
new file mode 100644
index 000000000..8e633b6cc
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/elevator.md
@@ -0,0 +1,5 @@
+Thang máy này sẽ không cho phép bạn lên đến đỉnh tòa nhà. Đúng không?
+
+##### Những điều có thể hữu ích:
+* Đôi khi solidity không giỏi giữ lời hứa.
+* `Elevator` này mong đợi được sử dụng từ một `Building`.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/elevator_complete.md b/client/src/gamedata/vi/descriptions/levels/elevator_complete.md
new file mode 100644
index 000000000..7072188e4
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/elevator_complete.md
@@ -0,0 +1,4 @@
+Bạn có thể sử dụng modifier hàm `view` trên một interface để ngăn chặn các thay đổi trạng thái. Modifier `pure` cũng ngăn các hàm thay đổi trạng thái.
+Hãy đảm bảo bạn đọc [tài liệu Solidity](http://solidity.readthedocs.io/en/develop/contracts.html#view-functions) và tìm hiểu các lưu ý của nó.
+
+Một cách khác để giải cấp độ này là xây dựng một hàm view trả về kết quả khác nhau tùy thuộc vào dữ liệu đầu vào nhưng không thay đổi trạng thái, ví dụ `gasleft()`.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/fallback.md b/client/src/gamedata/vi/descriptions/levels/fallback.md
new file mode 100644
index 000000000..b6a57db34
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/fallback.md
@@ -0,0 +1,12 @@
+Hãy xem kỹ mã hợp đồng bên dưới.
+
+Bạn sẽ thắng cấp độ này nếu
+1) bạn chiếm quyền sở hữu của hợp đồng
+2) bạn giảm số dư của nó xuống 0
+
+
+Những điều có thể hữu ích
+* Cách gửi ether khi tương tác với ABI
+* Cách gửi ether bên ngoài ABI
+* Chuyển đổi từ và sang đơn vị wei/ether (xem lệnh `help()`)
+* Phương thức fallback
diff --git a/client/src/gamedata/vi/descriptions/levels/fallback_complete.md b/client/src/gamedata/vi/descriptions/levels/fallback_complete.md
new file mode 100644
index 000000000..8ed52713f
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/fallback_complete.md
@@ -0,0 +1,5 @@
+Bạn biết những điều cơ bản về cách ether vào và ra khỏi hợp đồng, bao gồm việc sử dụng phương thức fallback.
+
+Bạn cũng đã học về hợp đồng Ownable của OpenZeppelin, và cách nó có thể được sử dụng để hạn chế việc sử dụng một số phương thức cho một địa chỉ đặc quyền.
+
+Chuyển sang cấp độ tiếp theo khi bạn sẵn sàng!
diff --git a/client/src/gamedata/vi/descriptions/levels/fallout.md b/client/src/gamedata/vi/descriptions/levels/fallout.md
new file mode 100644
index 000000000..4354ed8a4
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/fallout.md
@@ -0,0 +1,5 @@
+Chiếm quyền sở hữu của hợp đồng bên dưới để hoàn thành cấp độ này.
+
+
+Những điều có thể hữu ích
+* Solidity Remix IDE
diff --git a/client/src/gamedata/vi/descriptions/levels/fallout_complete.md b/client/src/gamedata/vi/descriptions/levels/fallout_complete.md
new file mode 100644
index 000000000..44576011b
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/fallout_complete.md
@@ -0,0 +1,15 @@
+Điều đó thật ngớ ngẩn phải không? Các hợp đồng thực tế phải an toàn hơn nhiều so với điều này và vì vậy phải khó hack hơn nhiều phải không?
+
+Chà... Không hẳn vậy.
+
+Câu chuyện của Rubixi là một trường hợp rất nổi tiếng trong hệ sinh thái Ethereum. Công ty đã đổi tên từ 'Dynamic Pyramid' thành 'Rubixi' nhưng bằng cách nào đó họ không đổi tên phương thức constructor của hợp đồng:
+
+```
+contract Rubixi {
+ address private owner;
+ function DynamicPyramid() { owner = msg.sender; }
+ function collectAllFees() { owner.transfer(this.balance) }
+ ...
+```
+
+Điều này cho phép kẻ tấn công gọi constructor cũ và chiếm quyền sở hữu hợp đồng, và đánh cắp một số tiền. Vâng. Những sai lầm lớn có thể được thực hiện trong smartcontractland.
diff --git a/client/src/gamedata/vi/descriptions/levels/force.md b/client/src/gamedata/vi/descriptions/levels/force.md
new file mode 100644
index 000000000..3aa4bb5d8
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/force.md
@@ -0,0 +1,9 @@
+Một số hợp đồng sẽ đơn giản không nhận tiền của bạn `¯\_(ツ)_/¯`
+
+Mục tiêu của cấp độ này là làm cho số dư của hợp đồng lớn hơn không.
+
+
+Những điều có thể hữu ích:
+* Phương thức fallback
+* Đôi khi cách tốt nhất để tấn công một hợp đồng là với một hợp đồng khác.
+* Xem trang ["?"](https://ethernaut.openzeppelin.com/help) ở trên, phần "Beyond the console"
diff --git a/client/src/gamedata/vi/descriptions/levels/force_complete.md b/client/src/gamedata/vi/descriptions/levels/force_complete.md
new file mode 100644
index 000000000..177095e86
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/force_complete.md
@@ -0,0 +1,3 @@
+Trong solidity, để một hợp đồng có thể nhận ether, hàm fallback phải được đánh dấu `payable`.
+
+Tuy nhiên, không có cách nào để ngăn kẻ tấn công gửi ether đến hợp đồng bằng cách tự hủy. Do đó, điều quan trọng là không dựa vào bất biến `address(this).balance == 0` cho bất kỳ logic hợp đồng nào.
diff --git a/client/src/gamedata/vi/descriptions/levels/gatekeeper1.md b/client/src/gamedata/vi/descriptions/levels/gatekeeper1.md
new file mode 100644
index 000000000..47fd77ca9
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/gatekeeper1.md
@@ -0,0 +1,5 @@
+Vượt qua người gác cổng và đăng ký như một người tham gia để vượt qua cấp độ này.
+
+##### Những điều có thể hữu ích:
+* Hãy nhớ những gì bạn đã học từ các cấp độ Telephone và Token.
+* Bạn có thể tìm hiểu thêm về hàm đặc biệt `gasleft()`, trong tài liệu Solidity (xem [đây](https://docs.soliditylang.org/en/v0.8.3/units-and-global-variables.html) và [đây](https://docs.soliditylang.org/en/v0.8.3/control-structures.html#external-function-calls)).
diff --git a/client/src/gamedata/vi/descriptions/levels/gatekeeper1_complete.md b/client/src/gamedata/vi/descriptions/levels/gatekeeper1_complete.md
new file mode 100644
index 000000000..d501b07f8
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/gatekeeper1_complete.md
@@ -0,0 +1 @@
+Làm tốt lắm! Tiếp theo, hãy thử sức với người gác cổng thứ hai...
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/gatekeeper2.md b/client/src/gamedata/vi/descriptions/levels/gatekeeper2.md
new file mode 100644
index 000000000..883745dd3
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/gatekeeper2.md
@@ -0,0 +1,6 @@
+Người gác cổng này giới thiệu một vài thử thách mới. Đăng ký như một người tham gia để vượt qua cấp độ này.
+
+##### Những điều có thể hữu ích:
+* Hãy nhớ những gì bạn đã học từ việc vượt qua người gác cổng đầu tiên - cánh cổng đầu tiên là giống nhau.
+* Từ khóa `assembly` trong cánh cổng thứ hai cho phép hợp đồng truy cập chức năng không có sẵn trong vanilla Solidity. Xem [đây](http://solidity.readthedocs.io/en/v0.4.23/assembly.html) để biết thêm thông tin. Lệnh gọi `extcodesize` trong cánh cổng này sẽ lấy kích thước mã của hợp đồng tại một địa chỉ nhất định - bạn có thể tìm hiểu thêm về cách và khi nào điều này được thiết lập trong phần 7 của [yellow paper](https://ethereum.github.io/yellowpaper/paper.pdf).
+* Ký tự `^` trong cánh cổng thứ ba là một phép toán bitwise (XOR), và được sử dụng ở đây để áp dụng một phép toán bitwise phổ biến khác (xem [đây](http://solidity.readthedocs.io/en/v0.4.23/miscellaneous.html#cheatsheet)). Cấp độ Coin Flip cũng là một nơi tốt để bắt đầu khi tiếp cận thử thách này.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/gatekeeper2_complete.md b/client/src/gamedata/vi/descriptions/levels/gatekeeper2_complete.md
new file mode 100644
index 000000000..40de03481
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/gatekeeper2_complete.md
@@ -0,0 +1 @@
+Tuyệt vời! Bây giờ bạn có thể vượt qua người gác cổng, bạn có những gì cần thiết để tham gia [theCyber](https://etherscan.io/address/thecyber.eth#code), một câu lạc bộ phi tập trung trên Ethereum mainnet. Lấy mật khẩu bằng cách liên hệ với người tạo trên [reddit](https://www.reddit.com/user/0age) hoặc qua [email](mailto:0age@protonmail.com) và sử dụng nó để đăng ký với hợp đồng tại [gatekeepertwo.thecyber.eth](https://etherscan.io/address/gatekeepertwo.thecyber.eth#code) (lưu ý rằng chỉ 128 người tham gia đầu tiên sẽ được hợp đồng chấp nhận).
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/gatekeeper3.md b/client/src/gamedata/vi/descriptions/levels/gatekeeper3.md
new file mode 100644
index 000000000..32c124e1a
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/gatekeeper3.md
@@ -0,0 +1,6 @@
+Đối phó với các cánh cổng và trở thành người tham gia.
+
+##### Những điều có thể hữu ích:
+* Nhớ lại giá trị trả về của các hàm cấp thấp.
+* Chú ý đến ngữ nghĩa.
+* Làm mới cách lưu trữ hoạt động trong Ethereum.
diff --git a/client/src/gamedata/vi/descriptions/levels/gatekeeper3_complete.md b/client/src/gamedata/vi/descriptions/levels/gatekeeper3_complete.md
new file mode 100644
index 000000000..9b2de3c61
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/gatekeeper3_complete.md
@@ -0,0 +1 @@
+Làm tốt lắm! Để biết thêm thông tin hãy đọc [này](https://web3js.readthedocs.io/en/v1.2.9/web3-eth.html?highlight=getStorageAt#getstorageat) và [này](https://medium.com/loom-network/ethereum-solidity-memory-vs-storage-how-to-initialize-an-array-inside-a-struct-184baf6aa2eb).
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/goodsamaritan.md b/client/src/gamedata/vi/descriptions/levels/goodsamaritan.md
new file mode 100644
index 000000000..14d3cc95c
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/goodsamaritan.md
@@ -0,0 +1,7 @@
+Phiên bản này đại diện cho một Người Samaritan Tốt Bụng giàu có và sẵn sàng quyên góp một số coin cho bất kỳ ai yêu cầu.
+
+Bạn có thể rút hết số dư từ Ví của anh ấy không?
+
+Những điều có thể hữu ích:
+
+- [Solidity Custom Errors](https://blog.soliditylang.org/2021/04/21/custom-errors/)
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/goodsamaritan_complete.md b/client/src/gamedata/vi/descriptions/levels/goodsamaritan_complete.md
new file mode 100644
index 000000000..f53c2bd54
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/goodsamaritan_complete.md
@@ -0,0 +1,3 @@
+Chúc mừng!
+
+Custom errors trong Solidity được xác định bởi 'selector' 4-byte của chúng, giống như lệnh gọi hàm. Chúng được nổi bọt lên qua chuỗi lệnh gọi cho đến khi được bắt bởi câu lệnh catch trong khối try-catch, như được thấy trong hàm `requestDonation()` của GoodSamaritan. Vì những lý do này, không an toàn khi giả định rằng lỗi được ném bởi mục tiêu trực tiếp của lệnh gọi hợp đồng (tức là Wallet trong trường hợp này). Bất kỳ hợp đồng nào khác xa hơn trong chuỗi lệnh gọi có thể khai báo cùng một lỗi và ném nó ở một vị trí không mong đợi, chẳng hạn như trong hàm `notify(uint256 amount)` trong hợp đồng tấn công của bạn.
diff --git a/client/src/gamedata/vi/descriptions/levels/instances.md b/client/src/gamedata/vi/descriptions/levels/instances.md
new file mode 100644
index 000000000..796a20877
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/instances.md
@@ -0,0 +1,69 @@
+Cấp độ này sẽ hướng dẫn bạn những điều cơ bản về cách chơi trò chơi.
+
+
+#### 1. Thiết lập MetaMask
+Nếu bạn chưa có thì hãy cài đặt [tiện ích mở rộng trình duyệt MetaMask](https://metamask.io/) (trong Chrome, Firefox, Brave hoặc Opera trên máy tính để bàn của bạn).
+Thiết lập ví của tiện ích mở rộng và sử dụng bộ chọn mạng để trỏ đến mạng ưa thích ở phía trên bên trái giao diện của tiện ích mở rộng. Ngoài ra, bạn có thể sử dụng nút UI để chuyển đổi giữa các mạng. Nếu bạn chọn mạng không được hỗ trợ, trò chơi sẽ thông báo cho bạn và đưa bạn đến mạng thử nghiệm Sepolia mặc định.
+
+#### 2. Mở bảng điều khiển của trình duyệt
+Mở bảng điều khiển của trình duyệt của bạn: `Tools > Developer Tools`.
+
+Bạn sẽ thấy một vài thông báo từ trò chơi. Một trong số họ sẽ nêu địa chỉ người chơi của bạn. Điều này sẽ rất quan trọng trong trò chơi! Bạn luôn có thể xem địa chỉ người chơi của mình bằng cách nhập lệnh sau:
+
+`player`
+
+Hãy để ý đến các cảnh báo và lỗi vì chúng có thể cung cấp thông tin quan trọng trong quá trình chơi trò chơi.
+
+#### 3. Sử dụng trợ giúp của bảng điều khiển
+
+Bạn cũng có thể xem số dư ether hiện tại của mình bằng cách nhập:
+
+`getBalance(player)`
+
+###### LƯU Ý: Mở rộng lời hứa để xem giá trị thực tế, ngay cả khi nó ghi "đang chờ xử lý". Nếu đang sử dụng Chrome v62, bạn có thể sử dụng `await getBalance(player)` để có trải nghiệm bảng điều khiển rõ ràng hơn.
+
+Tuyệt vời! Để xem bạn có những chức năng tiện ích nào khác trong loại bảng điều khiển:
+
+`help()`
+
+Những thứ này sẽ cực kỳ tiện dụng trong quá trình chơi game.
+
+#### 4. Hợp đồng ethernaut
+Nhập lệnh sau vào bảng điều khiển:
+
+`ethernaut`
+
+Đây là hợp đồng thông minh chính của trò chơi. Bạn không cần phải tương tác trực tiếp với nó thông qua bảng điều khiển (vì ứng dụng này sẽ làm điều đó cho bạn) nhưng bạn có thể làm điều đó nếu muốn. Chơi đùa với đối tượng này bây giờ là một cách tuyệt vời để tìm hiểu cách tương tác với các hợp đồng thông minh khác của trò chơi.
+
+Hãy tiếp tục và mở rộng đối tượng ethernaut để xem có gì bên trong.
+
+#### 5. Tương tác với ABI
+`ethernaut` là một đối tượng `TruffleContract` bao bọc hợp đồng `Ethernaut.sol` đã được triển khai trên blockchain.
+
+Trong số những thứ khác, ABI của hợp đồng tiết lộ tất cả các phương thức công khai của `Ethernaut.sol`, chẳng hạn như `chủ sở hữu`. Nhập lệnh sau đây chẳng hạn:
+
+`ethernaut.owner()` hoặc `await ethernaut.owner()` nếu bạn đang sử dụng Chrome v62.
+
+Bạn có thể xem chủ sở hữu của hợp đồng ethernaut là ai.
+
+#### 6. Nhận ether thử nghiệm
+Để chơi trò chơi, bạn sẽ cần ether thử nghiệm. Cách dễ nhất để nhận một số ether testnet là thông qua một vòi hợp lệ cho mạng bạn đã chọn.
+
+Khi bạn thấy một số xu trong số dư của mình, hãy chuyển sang bước tiếp theo.
+
+#### 7. Lấy một phiên bản cấp độ
+Khi chơi một cấp độ, bạn không tương tác trực tiếp với hợp đồng ethernaut. Thay vào đó, bạn yêu cầu nó tạo một **phiên bản cấp độ** cho bạn. Để làm như vậy, hãy nhấp vào nút "Nhận phiên bản mới" ở cuối trang. Hãy làm điều đó ngay bây giờ và quay lại!
+
+Bạn sẽ được MetaMask nhắc nhở ủy quyền giao dịch. Làm như vậy và bạn sẽ thấy một số thông báo trong bảng điều khiển. Lưu ý rằng quá trình này đang triển khai một hợp đồng mới trong chuỗi khối và có thể mất vài giây, vì vậy hãy kiên nhẫn khi yêu cầu các phiên bản cấp mới!
+
+#### 8. Kiểm tra hợp đồng
+Giống như bạn đã làm với hợp đồng ethernaut, bạn có thể kiểm tra ABI của hợp đồng này thông qua bảng điều khiển bằng cách sử dụng biến `hợp đồng`.
+
+#### 9. Tương tác với hợp đồng để hoàn thành cấp độ
+Hãy xem phương thức thông tin của cấp độ `contract.info()` hoặc `await Contract.info()` nếu bạn đang sử dụng Chrome v62.
+Bạn nên có tất cả những gì bạn cần để hoàn thành cấp độ trong hợp đồng.
+Khi bạn biết mình đã hoàn thành cấp độ, hãy gửi hợp đồng bằng nút gửi ở cuối trang.
+Thao tác này sẽ gửi phiên bản của bạn trở lại ethernaut, điều này sẽ xác định xem bạn đã hoàn thành nó chưa.
+
+
+##### Mẹo: Đừng quên rằng bạn luôn có thể xem ABI của hợp đồng!
diff --git a/client/src/gamedata/vi/descriptions/levels/instances_complete.md b/client/src/gamedata/vi/descriptions/levels/instances_complete.md
new file mode 100644
index 000000000..d65b9d350
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/instances_complete.md
@@ -0,0 +1,6 @@
+Chúc mừng! Bạn đã hoàn thành phần hướng dẫn.
+Hãy xem mã Solidity cho hợp đồng bạn vừa tương tác bên dưới.
+
+Bây giờ bạn đã sẵn sàng để hoàn thành trò chơi và tiếp theo, bạn sẽ phải tự làm một mình.
+
+Chúc may mắn!!
diff --git a/client/src/gamedata/vi/descriptions/levels/king.md b/client/src/gamedata/vi/descriptions/levels/king.md
new file mode 100644
index 000000000..5b8a3c4bf
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/king.md
@@ -0,0 +1,5 @@
+Hợp đồng bên dưới đại diện cho một trò chơi rất đơn giản: bất kỳ ai gửi cho nó một lượng ether lớn hơn giải thưởng hiện tại sẽ trở thành vua mới. Trong sự kiện như vậy, vua bị lật đổ sẽ được trả giải thưởng mới, kiếm được một chút ether trong quá trình! Ponzi như nó có thể xD
+
+Một trò chơi thú vị như vậy. Mục tiêu của bạn là phá vỡ nó.
+
+Khi bạn gửi phiên bản trở lại cấp độ, cấp độ sẽ tái chiếm vương quyền. Bạn sẽ thắng cấp độ nếu bạn có thể tránh được sự tự tuyên bố như vậy.
diff --git a/client/src/gamedata/vi/descriptions/levels/king_complete.md b/client/src/gamedata/vi/descriptions/levels/king_complete.md
new file mode 100644
index 000000000..c5f9a8f05
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/king_complete.md
@@ -0,0 +1,3 @@
+Hầu hết các cấp độ của Ethernaut cố gắng phơi bày (dưới dạng đơn giản hóa quá mức tất nhiên) một cái gì đó thực sự đã xảy ra — một vụ hack thực sự hoặc một lỗi thực sự.
+
+Trong trường hợp này, xem: [King of the Ether](https://www.kingoftheether.com/thrones/kingoftheether/index.html) và [King of the Ether Postmortem](http://www.kingoftheether.com/postmortem.html).
diff --git a/client/src/gamedata/vi/descriptions/levels/magicnum.md b/client/src/gamedata/vi/descriptions/levels/magicnum.md
new file mode 100644
index 000000000..6c75ca2ed
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/magicnum.md
@@ -0,0 +1,11 @@
+Để giải cấp độ này, bạn chỉ cần cung cấp cho Ethernaut một `Solver`, một hợp đồng phản hồi `whatIsTheMeaningOfLife()` với số đúng.
+
+Dễ phải không?
+Chà... có một cái bẫy.
+
+Mã của solver cần phải thực sự nhỏ. Thực sự rất nhỏ. Như thực sự thực sự rất nhỏ: tối đa 10 opcode.
+
+Gợi ý: Có lẽ đã đến lúc rời khỏi sự thoải mái của trình biên dịch Solidity trong chốc lát, và xây dựng cái này bằng tay O_o.
+Đúng vậy: Raw EVM bytecode.
+
+Chúc may mắn!
diff --git a/client/src/gamedata/vi/descriptions/levels/magicnum_complete.md b/client/src/gamedata/vi/descriptions/levels/magicnum_complete.md
new file mode 100644
index 000000000..dc63315f6
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/magicnum_complete.md
@@ -0,0 +1,3 @@
+Chúc mừng! Nếu bạn đã giải cấp độ này, hãy coi mình là Bậc thầy của Vũ trụ.
+
+Hãy tiếp tục và đâm một vật ngẫu nhiên trong phòng với vẻ ngoài Magnum của bạn. Bây giờ, hãy thử di chuyển nó từ xa; Khả năng thần giao cách cảm của bạn có thể vừa bắt đầu hoạt động.
diff --git a/client/src/gamedata/vi/descriptions/levels/motorbike.md b/client/src/gamedata/vi/descriptions/levels/motorbike.md
new file mode 100644
index 000000000..55193ab30
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/motorbike.md
@@ -0,0 +1,9 @@
+Xe máy của Ethernaut có thiết kế động cơ có thể nâng cấp hoàn toàn mới.
+
+Bạn có thể `selfdestruct` động cơ của nó và làm cho xe máy không sử dụng được không?
+
+Những điều có thể hữu ích:
+
+- [EIP-1967](https://eips.ethereum.org/EIPS/eip-1967)
+- [UUPS](https://forum.openzeppelin.com/t/uups-proxies-tutorial-solidity-javascript/7786) upgradeable pattern
+- [Initializable](https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol) contract
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/motorbike_complete.md b/client/src/gamedata/vi/descriptions/levels/motorbike_complete.md
new file mode 100644
index 000000000..4ab42a94e
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/motorbike_complete.md
@@ -0,0 +1,9 @@
+Ưu điểm của việc tuân theo mẫu UUPS là có proxy tối thiểu để triển khai. Proxy hoạt động như lớp lưu trữ nên bất kỳ thay đổi trạng thái nào trong hợp đồng triển khai thường không tạo ra tác dụng phụ cho các hệ thống sử dụng nó, vì chỉ logic được sử dụng thông qua delegatecalls.
+
+Điều này không có nghĩa là bạn không nên đề phòng các lỗ hổng có thể bị khai thác nếu chúng ta để hợp đồng triển khai không được khởi tạo.
+
+Đây là phiên bản đơn giản hóa một chút của những gì thực sự đã được phát hiện sau nhiều tháng phát hành mẫu UUPS.
+
+Bài học: không bao giờ để hợp đồng triển khai không được khởi tạo ;)
+
+Nếu bạn quan tâm đến những gì đã xảy ra, hãy đọc thêm [tại đây](https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680).
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/naughtcoin.md b/client/src/gamedata/vi/descriptions/levels/naughtcoin.md
new file mode 100644
index 000000000..c12521140
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/naughtcoin.md
@@ -0,0 +1,6 @@
+NaughtCoin là một token ERC20 và bạn đã nắm giữ tất cả chúng. Cái bẫy là bạn chỉ có thể chuyển chúng sau thời gian khóa 10 năm. Bạn có thể tìm ra cách để chuyển chúng ra địa chỉ khác để bạn có thể chuyển chúng tự do không? Hoàn thành cấp độ này bằng cách đưa số dư token của bạn về 0.
+
+
+Những điều có thể hữu ích
+* [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) Spec
+* [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/tree/master/contracts) codebase
diff --git a/client/src/gamedata/vi/descriptions/levels/naughtcoin_complete.md b/client/src/gamedata/vi/descriptions/levels/naughtcoin_complete.md
new file mode 100644
index 000000000..625d41456
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/naughtcoin_complete.md
@@ -0,0 +1 @@
+Khi sử dụng mã không phải của bạn, nên làm quen với nó để hiểu rõ cách mọi thứ kết hợp với nhau. Điều này có thể đặc biệt quan trọng khi có nhiều cấp độ import (import của bạn có import) hoặc khi bạn đang triển khai kiểm soát ủy quyền, ví dụ khi bạn cho phép hoặc không cho phép mọi người làm những việc. Trong ví dụ này, một nhà phát triển có thể quét qua mã và nghĩ rằng `transfer` là cách duy nhất để di chuyển token xung quanh, thấp và kìa có những cách khác để thực hiện cùng một thao tác với một triển khai khác.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/preservation.md b/client/src/gamedata/vi/descriptions/levels/preservation.md
new file mode 100644
index 000000000..3e2673cd0
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/preservation.md
@@ -0,0 +1,11 @@
+Hợp đồng này sử dụng một thư viện để lưu trữ hai thời gian khác nhau cho hai múi giờ khác nhau. Constructor tạo hai phiên bản của thư viện cho mỗi thời gian cần được lưu trữ.
+
+Mục tiêu của cấp độ này là bạn phải chiếm quyền sở hữu của phiên bản được cung cấp.
+
+ Những điều có thể hữu ích
+* Tìm hiểu tài liệu Solidity về hàm cấp thấp `delegatecall`,
+ cách nó hoạt động, cách sử dụng để ủy quyền các thao tác cho
+ thư viện on-chain, và những tác động của nó đến phạm vi thực thi.
+* Hiểu ý nghĩa của việc `delegatecall` bảo toàn ngữ cảnh.
+* Hiểu cách các biến lưu trữ được lưu trữ và truy cập.
+* Hiểu cách casting hoạt động giữa các kiểu dữ liệu khác nhau.
diff --git a/client/src/gamedata/vi/descriptions/levels/preservation_complete.md b/client/src/gamedata/vi/descriptions/levels/preservation_complete.md
new file mode 100644
index 000000000..c45fd15da
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/preservation_complete.md
@@ -0,0 +1,6 @@
+Như cấp độ trước, `delegate` đề cập, việc sử dụng `delegatecall` để gọi
+thư viện có thể rủi ro. Điều này đặc biệt đúng với các thư viện hợp đồng có
+trạng thái riêng của chúng. Ví dụ này chứng minh tại sao từ khóa `library`
+nên được sử dụng để xây dựng thư viện, vì nó ngăn các thư viện
+lưu trữ và truy cập các biến trạng thái.
+
diff --git a/client/src/gamedata/vi/descriptions/levels/privacy.md b/client/src/gamedata/vi/descriptions/levels/privacy.md
new file mode 100644
index 000000000..74a2123b6
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/privacy.md
@@ -0,0 +1,11 @@
+Người tạo hợp đồng này đã cẩn thận đủ để bảo vệ các khu vực nhạy cảm của bộ nhớ của nó.
+
+Mở khóa hợp đồng này để thắng cấp độ.
+
+Những điều có thể hữu ích:
+* Hiểu cách lưu trữ hoạt động
+* Hiểu cách phân tích tham số hoạt động
+* Hiểu cách casting hoạt động
+
+Mẹo:
+* Hãy nhớ rằng metamask chỉ là một hàng hóa. Sử dụng công cụ khác nếu nó gây ra vấn đề. Gameplay nâng cao có thể liên quan đến việc sử dụng remix, hoặc web3 provider của riêng bạn.
diff --git a/client/src/gamedata/vi/descriptions/levels/privacy_complete.md b/client/src/gamedata/vi/descriptions/levels/privacy_complete.md
new file mode 100644
index 000000000..ea8e6521a
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/privacy_complete.md
@@ -0,0 +1,3 @@
+Không có gì trong blockchain ethereum là riêng tư. Từ khóa private chỉ là một cấu trúc nhân tạo của ngôn ngữ Solidity. `getStorageAt(...)` của Web3 có thể được sử dụng để đọc bất cứ thứ gì từ lưu trữ. Tuy nhiên, có thể khó khăn để đọc những gì bạn muốn, vì một số quy tắc tối ưu hóa và kỹ thuật được sử dụng để nén lưu trữ càng nhiều càng tốt.
+
+Nó không thể phức tạp hơn nhiều so với những gì được phơi bày trong cấp độ này. Để biết thêm, hãy xem bài viết tuyệt vời này của "Darius": [Cách đọc lưu trữ hợp đồng Ethereum](https://medium.com/aigang-network/how-to-read-ethereum-contract-storage-44252c8af925)
diff --git a/client/src/gamedata/vi/descriptions/levels/puzzle_wallet.md b/client/src/gamedata/vi/descriptions/levels/puzzle_wallet.md
new file mode 100644
index 000000000..24cb6f3d4
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/puzzle_wallet.md
@@ -0,0 +1,18 @@
+Ngày nay, việc thanh toán cho các hoạt động DeFi là không thể, thực tế.
+
+Một nhóm bạn đã khám phá ra cách giảm nhẹ chi phí thực hiện nhiều giao dịch bằng cách gộp chúng thành một giao dịch, vì vậy họ đã phát triển một hợp đồng thông minh để làm điều này.
+
+Họ cần hợp đồng này có thể nâng cấp trong trường hợp mã chứa lỗi, và họ cũng muốn ngăn những người bên ngoài nhóm sử dụng nó. Để làm điều này, họ đã bỏ phiếu và chỉ định hai người với vai trò đặc biệt trong hệ thống:
+Admin, người có quyền cập nhật logic của hợp đồng thông minh.
+Owner, người kiểm soát whitelist các địa chỉ được phép sử dụng hợp đồng.
+Các hợp đồng đã được triển khai, và nhóm đã được whitelist. Mọi người đều vui mừng vì thành tích của họ chống lại các thợ mỏ xấu.
+
+Họ không biết rằng, tiền ăn trưa của họ đang gặp rủi ro...
+
+
+Bạn sẽ cần cướp ví này để trở thành admin của proxy.
+
+
+Những điều có thể hữu ích:
+* Hiểu cách `delegatecall` hoạt động và cách `msg.sender` và `msg.value` hoạt động khi thực hiện một.
+* Biết về các mẫu proxy và cách chúng xử lý các biến lưu trữ.
diff --git a/client/src/gamedata/vi/descriptions/levels/puzzle_wallet_complete.md b/client/src/gamedata/vi/descriptions/levels/puzzle_wallet_complete.md
new file mode 100644
index 000000000..a23443271
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/puzzle_wallet_complete.md
@@ -0,0 +1,7 @@
+Lần sau, những người bạn đó sẽ yêu cầu kiểm toán trước khi gửi tiền vào hợp đồng. Chúc mừng!
+
+Thường xuyên, việc sử dụng hợp đồng proxy được khuyến nghị cao để mang lại tính năng nâng cấp và giảm chi phí gas triển khai. Tuy nhiên, các nhà phát triển phải cẩn thận không để xảy ra va chạm lưu trữ, như được thấy trong cấp độ này.
+
+Hơn nữa, lặp qua các thao tác tiêu thụ ETH có thể dẫn đến vấn đề nếu không được xử lý đúng cách. Ngay cả khi ETH được chi tiêu, `msg.value` sẽ vẫn giữ nguyên, vì vậy nhà phát triển phải theo dõi thủ công số tiền còn lại thực tế trong mỗi lần lặp. Điều này cũng có thể dẫn đến vấn đề khi sử dụng mẫu multi-call, vì thực hiện nhiều `delegatecall` đến một hàm trông an toàn có thể dẫn đến chuyển ETH không mong muốn, vì `delegatecall` giữ nguyên `msg.value` gốc được gửi đến hợp đồng.
+
+Chuyển sang cấp độ tiếp theo khi bạn sẵn sàng!
diff --git a/client/src/gamedata/vi/descriptions/levels/recovery.md b/client/src/gamedata/vi/descriptions/levels/recovery.md
new file mode 100644
index 000000000..339260251
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/recovery.md
@@ -0,0 +1,4 @@
+
+Một người tạo hợp đồng đã xây dựng một hợp đồng nhà máy token rất đơn giản. Bất kỳ ai cũng có thể tạo token mới một cách dễ dàng. Sau khi triển khai hợp đồng token đầu tiên, người tạo đã gửi `0.001` ether để có thêm token. Họ đã mất địa chỉ hợp đồng.
+
+Cấp độ này sẽ được hoàn thành nếu bạn có thể khôi phục (hoặc xóa) `0.001` ether từ địa chỉ hợp đồng bị mất.
diff --git a/client/src/gamedata/vi/descriptions/levels/recovery_complete.md b/client/src/gamedata/vi/descriptions/levels/recovery_complete.md
new file mode 100644
index 000000000..5d76086aa
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/recovery_complete.md
@@ -0,0 +1,10 @@
+
+Địa chỉ hợp đồng là xác định và được tính bằng `keccak256(address, nonce)` trong đó `address` là địa chỉ của hợp đồng (hoặc địa chỉ ethereum đã tạo giao dịch) và `nonce` là số lượng hợp đồng mà hợp đồng tạo ra đã tạo (hoặc nonce giao dịch, cho các giao dịch thông thường).
+
+Vì điều này, người ta có thể gửi ether đến một địa chỉ được xác định trước (không có khóa riêng) và sau đó tạo hợp đồng tại địa chỉ đó để khôi phục ether. Đây là một cách không trực quan và phần nào bí mật để (nguy hiểm) lưu trữ ether mà không cần giữ khóa riêng.
+
+Một [bài đăng blog](https://swende.se/blog/Ethereum_quirks_and_vulns.html) thú vị của Martin Swende mô tả chi tiết các trường hợp sử dụng tiềm năng của điều này.
+
+Nếu bạn sẽ triển khai kỹ thuật này, hãy đảm bảo bạn không bỏ lỡ nonce, hoặc tiền của bạn sẽ bị mất mãi mãi.
+
+
diff --git a/client/src/gamedata/vi/descriptions/levels/reentrancy.md b/client/src/gamedata/vi/descriptions/levels/reentrancy.md
new file mode 100644
index 000000000..747431586
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/reentrancy.md
@@ -0,0 +1,9 @@
+Mục tiêu của cấp độ này là bạn phải đánh cắp tất cả tiền từ hợp đồng.
+
+
+Những điều có thể hữu ích:
+* Các hợp đồng không đáng tin cậy có thể thực thi mã ở nơi bạn ít mong đợi nhất.
+* Phương thức fallback
+* Throw/revert bubbling
+* Đôi khi cách tốt nhất để tấn công một hợp đồng là với một hợp đồng khác.
+* Xem trang ["?"](https://ethernaut.openzeppelin.com/help) ở trên, phần "Beyond the console"
diff --git a/client/src/gamedata/vi/descriptions/levels/reentrancy_complete.md b/client/src/gamedata/vi/descriptions/levels/reentrancy_complete.md
new file mode 100644
index 000000000..42038bd8c
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/reentrancy_complete.md
@@ -0,0 +1,12 @@
+Để ngăn chặn các cuộc tấn công re-entrancy khi di chuyển tiền ra khỏi hợp đồng của bạn, hãy sử dụng mẫu [Checks-Effects-Interactions](https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern) biết rằng `call` sẽ chỉ trả về false mà không làm gián đoạn luồng thực thi. Các giải pháp như [ReentrancyGuard](https://docs.openzeppelin.com/contracts/2.x/api/utils#ReentrancyGuard) hoặc [PullPayment](https://docs.openzeppelin.com/contracts/2.x/api/payment#PullPayment) cũng có thể được sử dụng.
+
+`transfer` và `send` không còn là giải pháp được khuyến nghị vì chúng có thể phá vỡ hợp đồng sau hard fork Istanbul [Nguồn 1](https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/) [Nguồn 2](https://forum.openzeppelin.com/t/reentrancy-after-istanbul/1742).
+
+Luôn giả định rằng người nhận tiền bạn đang gửi có thể là một hợp đồng khác, không chỉ là địa chỉ thông thường. Do đó, nó có thể thực thi mã trong phương thức fallback payable của nó và *tái nhập* hợp đồng của bạn, có thể làm rối tung trạng thái/logic của bạn.
+
+Re-entrancy là một cuộc tấn công phổ biến. Bạn nên luôn chuẩn bị sẵn sàng cho nó!
+
+
+#### Vụ hack DAO
+
+Vụ hack DAO nổi tiếng đã sử dụng reentrancy để trích xuất một lượng ether khổng lồ từ hợp đồng nạn nhân. Xem [15 dòng mã có thể ngăn chặn vụ hack DAO](https://blog.openzeppelin.com/15-lines-of-code-that-could-have-prevented-thedao-hack-782499e00942).
diff --git a/client/src/gamedata/vi/descriptions/levels/shop.md b/client/src/gamedata/vi/descriptions/levels/shop.md
new file mode 100644
index 000000000..8b1622da2
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/shop.md
@@ -0,0 +1,5 @@
+Bạn có thể lấy mặt hàng từ cửa hàng với giá thấp hơn giá được yêu cầu không?
+
+##### Những điều có thể hữu ích:
+* `Shop` mong đợi được sử dụng từ một `Buyer`
+* Hiểu các hạn chế của hàm view
diff --git a/client/src/gamedata/vi/descriptions/levels/shop_complete.md b/client/src/gamedata/vi/descriptions/levels/shop_complete.md
new file mode 100644
index 000000000..aafdb9032
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/shop_complete.md
@@ -0,0 +1,3 @@
+Hợp đồng có thể thao túng dữ liệu được nhìn thấy bởi các hợp đồng khác theo bất kỳ cách nào chúng muốn.
+
+Không an toàn khi thay đổi trạng thái dựa trên logic của các hợp đồng bên ngoài và không đáng tin cậy.
diff --git a/client/src/gamedata/vi/descriptions/levels/switch.md b/client/src/gamedata/vi/descriptions/levels/switch.md
new file mode 100644
index 000000000..162c091e3
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/switch.md
@@ -0,0 +1,4 @@
+Chỉ cần bật công tắc. Không thể khó đến vậy, phải không?
+
+##### Những điều có thể hữu ích:
+Hiểu cách `CALLDATA` được mã hóa.
diff --git a/client/src/gamedata/vi/descriptions/levels/switch_complete.md b/client/src/gamedata/vi/descriptions/levels/switch_complete.md
new file mode 100644
index 000000000..c81841afa
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/switch_complete.md
@@ -0,0 +1 @@
+Giả định các vị trí trong `CALLDATA` với các kiểu động có thể sai, đặc biệt khi sử dụng các vị trí `CALLDATA` được mã hóa cứng.
diff --git a/client/src/gamedata/vi/descriptions/levels/telephone.md b/client/src/gamedata/vi/descriptions/levels/telephone.md
new file mode 100644
index 000000000..6568cbd3c
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/telephone.md
@@ -0,0 +1,5 @@
+Chiếm quyền sở hữu của hợp đồng bên dưới để hoàn thành cấp độ này.
+
+
+Những điều có thể hữu ích
+* Xem trang ["?"](https://ethernaut.openzeppelin.com/help) ở trên, phần "Beyond the console"
diff --git a/client/src/gamedata/vi/descriptions/levels/telephone_complete.md b/client/src/gamedata/vi/descriptions/levels/telephone_complete.md
new file mode 100644
index 000000000..a8108ba3e
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/telephone_complete.md
@@ -0,0 +1,21 @@
+Mặc dù ví dụ này có thể đơn giản, việc nhầm lẫn `tx.origin` với `msg.sender` có thể dẫn đến các cuộc tấn công kiểu phishing, chẳng hạn như [này](https://blog.ethereum.org/2016/06/24/security-alert-smart-contract-wallets-created-in-frontier-are-vulnerable-to-phishing-attacks/).
+
+Một ví dụ về cuộc tấn công có thể được mô tả dưới đây.
+
+1) Sử dụng `tx.origin` để xác định token của ai để chuyển, ví dụ:
+
+```
+function transfer(address _to, uint _value) {
+ tokens[tx.origin] -= _value;
+ tokens[_to] += _value;
+}
+```
+2) Kẻ tấn công khiến nạn nhân gửi tiền đến một hợp đồng độc hại gọi hàm transfer của hợp đồng token, ví dụ:
+
+```
+function () payable {
+ token.transfer(attackerAddress, 10000);
+}
+```
+
+3) Trong trường hợp này, `tx.origin` sẽ là địa chỉ của nạn nhân (trong khi `msg.sender` sẽ là địa chỉ của hợp đồng độc hại), dẫn đến việc chuyển tiền từ nạn nhân sang kẻ tấn công.
diff --git a/client/src/gamedata/vi/descriptions/levels/token.md b/client/src/gamedata/vi/descriptions/levels/token.md
new file mode 100644
index 000000000..4f2f59c78
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/token.md
@@ -0,0 +1,7 @@
+Mục tiêu của cấp độ này là bạn phải hack hợp đồng token cơ bản bên dưới.
+
+Bạn được cung cấp 20 token để bắt đầu và bạn sẽ thắng cấp độ nếu bạn bằng cách nào đó quản lý để có thêm bất kỳ token nào. Tốt nhất là một lượng token rất lớn.
+
+
+Những điều có thể hữu ích:
+* Đồng hồ đo quãng đường là gì?
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/token_complete.md b/client/src/gamedata/vi/descriptions/levels/token_complete.md
new file mode 100644
index 000000000..86e928a28
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/token_complete.md
@@ -0,0 +1,12 @@
+Overflow rất phổ biến trong solidity và phải được kiểm tra bằng các câu lệnh điều khiển như:
+```
+if(a + c > a) {
+ a = a + c;
+}
+```
+
+Một lựa chọn dễ dàng hơn là sử dụng thư viện SafeMath của OpenZeppelin tự động kiểm tra overflow trong tất cả các toán tử toán học. Mã kết quả trông như thế này:
+```
+a = a.add(c);
+```
+Nếu có overflow, mã sẽ revert.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/unstoppable.md b/client/src/gamedata/vi/descriptions/levels/unstoppable.md
new file mode 100644
index 000000000..4942fe346
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/unstoppable.md
@@ -0,0 +1,5 @@
+Có một pool cho vay với một triệu token trong số dư, cung cấp flash loan miễn phí.
+
+Nếu chỉ có cách để tấn công và ngăn pool cung cấp flash loan...
+
+Bạn bắt đầu với 100 token trong số dư.
diff --git a/client/src/gamedata/vi/descriptions/levels/vault.md b/client/src/gamedata/vi/descriptions/levels/vault.md
new file mode 100644
index 000000000..4ec2d8832
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/vault.md
@@ -0,0 +1 @@
+Mở khóa kho bạc để vượt qua cấp độ!
\ No newline at end of file
diff --git a/client/src/gamedata/vi/descriptions/levels/vault_complete.md b/client/src/gamedata/vi/descriptions/levels/vault_complete.md
new file mode 100644
index 000000000..d771d463e
--- /dev/null
+++ b/client/src/gamedata/vi/descriptions/levels/vault_complete.md
@@ -0,0 +1,3 @@
+Điều quan trọng cần nhớ là việc đánh dấu một biến là private chỉ ngăn các hợp đồng khác truy cập nó. Các biến trạng thái được đánh dấu là private và các biến cục bộ vẫn có thể truy cập công khai.
+
+Để đảm bảo rằng dữ liệu là riêng tư, nó cần được mã hóa trước khi được đưa lên blockchain. Trong trường hợp này, khóa giải mã không bao giờ nên được gửi on-chain, vì nó sẽ có thể nhìn thấy bởi bất kỳ ai tìm kiếm nó. [zk-SNARKs](https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell/) cung cấp một cách để xác định xem ai đó có sở hữu một tham số bí mật hay không, mà không bao giờ phải tiết lộ tham số đó.
\ No newline at end of file
diff --git a/client/src/gamedata/vi/strings.json b/client/src/gamedata/vi/strings.json
new file mode 100644
index 000000000..575ff6f91
--- /dev/null
+++ b/client/src/gamedata/vi/strings.json
@@ -0,0 +1,124 @@
+{
+ "ethernaut": "Ethernaut",
+ "title": "Ethernaut",
+ "hiring": "Chung tôi đang cần tuyển dụng!",
+ "ctfRegister": "Đăng ký ngay!",
+ "ctfInfo": "Chúng tôi đang tổ chức Ethernaut CTF: Sự kiện bắt cờ 48 giờ với giải thưởng và thử thách blockchain, bắt đầu từ 16/03.",
+ "info": "
Ethernaut là một trò chơi lập trình sử dụng Web3/Solidity lấy cảm hứng từ overthewire.org, được chơi trong Máy ảo Ethereum. Mỗi cấp độ là một hợp đồng thông minh cần được “hack”. 100% trò chơi là mã nguồn mở và tất cả các cấp độ đều được đóng góp bởi những người chơi khác. Bạn có ý tưởng muốn đóng góp? Mọi PR đều được
",
+ "home": "Trang chủ",
+ "help": "Trợ giúp",
+ "stats": "Thống kê",
+ "ethernautHelp": "Trợ giúp",
+ "footer": "được phát triển với và bởi đội ngũ OpenZeppelin",
+ "english": "English",
+ "arabic": "عربي",
+ "spanish": "Español",
+ "ukrainian": "Українська",
+ "portuguese": "Português",
+ "japanese": "日本語",
+ "turkish": "Türkçe",
+ "chinese_simplified": "簡體中文",
+ "chinese_traditional": "正體中文",
+ "french": "Français",
+ "russian": "Русский",
+ "vietnamese": "tiếng Việt",
+ "korean": "한국어",
+ "playNow": "Bắt đầu!",
+ "toggleNavigation": "Bật tắt điều hướng",
+ "levelCompleted": "Hoàn thành!",
+ "sources": "Nguồn",
+ "submitInstance": "Nộp bài",
+ "getNewInstance": "Tạo phiên bản mới",
+ "accountNotConnectedTitle": "Tài khoản MetaMask chưa được kết nối",
+ "accountNotConnectedMessage": "Để bắt đầu hành trình, hãy kết nối ví MetaMask của bạn! Trò chơi tương tác trực tiếp với các hợp đồng Ethernaut on-chain, nghĩa là mọi hành động của bạn trong game đều được ghi lại trên blockchain. Bằng cách liên kết tài khoản MetaMask, bạn có thể tương tác an toàn với các hợp đồng thông minh này, giải các thử thách và tiến bộ trong trò chơi.",
+ "connectAccount": "Kết nối",
+ "deployMessageTitle": "Trò chơi chưa được triển khai",
+ "deprecatedNetwork": "Mạng đã bị ngừng hỗ trợ",
+ "networkBeingDeprecated": "Mạng đang bị ngừng hỗ trợ",
+ "deployMessage": "Hiện tại game chỉ hỗ trợ các mạng này:",
+ "deployConfirmation": "Bạn muốn triển khai các hợp đồng trên mạng này hay chuyển sang mạng Sepolia?",
+ "deployNote": "Lưu ý: Nếu bạn triển khai tất cả các cấp độ, chúng tôi sẽ hướng dẫn bạn gửi toàn bộ trò chơi đã triển khai trên mạng này.",
+ "deployGame": "Triển khai trò chơi",
+ "switchToSepolia": "Chuyển sang Sepolia",
+ "continueAnyway": "Vẫn tiếp tục",
+ "deployLevel": "Triển khai cấp độ",
+ "helperDeployAllContracts": "Triển khai tất cả các hợp đồng còn lại trên mạng hiện tại.",
+ "confirmMainnetDeploy": "Bạn đang ở trên mạng chính, trò chơi không có giá trị tiền tệ, bạn không nên triển khai trên mạng này.",
+ "submitLevelFooter": "Triển khai tất cả các cấp độ (deployAllContracts() in console) để thêm mạng hiện tại vào Github repository dưới dạng mạng được hỗ trợ mới.",
+ "submitGameFooter": "Tuyệt vời! Toàn bộ trò chơi được triển khai trên mạng này. Nhấp vào đây để tạo vấn đề GitHub và gửi cho chúng tôi :)",
+ "nextLevel": "Đi đến cấp độ tiếp theo",
+ "uLevels": "Cấp độ",
+ "lLevels": "cấp độ",
+ "refresh": "Làm mới",
+ "uCompleted": "Hoàn thành",
+ "lCompleted": "hoàn thành",
+ "players": "người chơi",
+ "player": "Người chơi",
+ "levelName": "Tên cấp độ",
+ "levelAddress": "Địa chỉ của cấp độ",
+ "blockNum": "Số khối",
+ "uCreated": "Tạo",
+ "lCreated": "tạo",
+ "instance": "Phiên bản",
+ "numberOf": "Số lượng",
+ "warning": "Cảnh báo",
+ "warningMessage": "Không có nhà cung cấp Web3 và trò chơi ở chế độ chỉ đọc",
+ "levelAuthor": "Cấp độ tác giả:",
+ "pleaseWait": "VUI LÒNG CHỜ",
+ "donate": "Bài tập này có dạy cho bạn điều gì hữu ích không? Đóng góp cho tác giả của bài tập (trên mainnet):",
+ "openConsole": "MỞ CONSOLE CỦA BẠN ĐỂ CHƠI",
+ "difficulty": "Độ khó",
+ "error": "Lỗi",
+ "retrying": "thử lại...",
+ "typeHelpMessage": "Nhập help() để có danh sách các tiện ích bổ sung web3 tùy chỉnh",
+ "slowNetworkMessage": "Thông báo 'Phát hiện mạng chậm' gây khó chịu? Hãy thử cài đặt Công cụ dành cho nhà phát triển -> Chỉ tin nhắn của người dùng hoặc tắt 'chrome://flags/#enable-webfonts-intervention-v2",
+ "notContractSetMessage": "Không có hợp đồng nào được sử dụng, hãy chuyển đến một cấp độ và nhấp vào 'Tạo phiên bản mới'",
+ "levelAddressMessage": "Địa chỉ cấp độ",
+ "instanceAddressMessage": "Địa chỉ phiên bản",
+ "playerAddressMessage": "Địa chỉ người chơi",
+ "selectedNetworkMessage": "Mạng hiện tại: ",
+ "ethernautAddressMessage": "Địa chỉ Ethernaut",
+ "noLevelsDataMessage": "Không thể tìm thấy dữ liệu cấp độ",
+ "ethernautNotFoundMessage": "Hợp đồng Ethernaut không được tìm thấy trong mạng hiện tại. Vui lòng đảm bảo (1) rằng bạn đang sử dụng metamask, (2) nó nằm trên mạng được hỗ trợ, (3) nó đã được mở khóa, (4 tùy chọn) Từ ngày 2 tháng 11, bạn có thể BẬT chế độ bảo mật (TẮT theo mặc định) trong Metamask cài đặt nếu bạn không muốn hiển thị thông tin của mình theo mặc định. (5 tùy chọn) Nếu chế độ bảo mật được BẬT, bạn phải ủy quyền cho siêu mặt nạ để sử dụng trang này. và (6) sau đó làm mới.",
+ "requestingNewInstanceMessage": "Yêu cầu hợp đồng mới từ bài tập...",
+ "unableToRetrieveLevelMessage": "Không thể tạo được hợp đồng mới cho bài tập! Hãy kiểm tra gas và thử lại lần nữa.",
+ "transactionNoLogsMessage": "Giao dịch không được lưu lại",
+ "noPlayerAddressMessage": "Không có địa chỉ người chơi được phát hiện! Đảm bảo rằng 1) Bạn đã cài đặt tiện ích mở rộng trình duyệt metamask và 2) nó đã được mở khóa. 3 tùy chọn) Từ ngày 2 tháng 11, bạn có thể BẬT chế độ bảo mật (TẮT theo mặc định) trong cài đặt nếu bạn không muốn tiết lộ thông tin của mình theo mặc định. 4 tùy chọn) Nếu chế độ riêng tư được BẬT, bạn phải ủy quyền cho Metamask sử dụng trang này. 5) sau đó làm mới",
+ "noEthersMessage": "Ôi, bạn không có ether! Hãy nhận một ít từ faucet hợp lệ cho mạng bạn chọn",
+ "submitLevelMessage": "Nộp bài...",
+ "wellDoneMessage": "Rất tốt",
+ "completedLevelMessage": "Bạn đã hoàn thành cấp độ này!!!",
+ "uncompletedLevelMessage": "Ối! Có vẻ như bạn chưa vượt qua được cấp độ này",
+ "metamaskKnownIssue": "Ôi! Có vẻ như bạn đã gặp phải sự cố Metamask đã biết. Hãy thử tắt và bật lại plugin metamask của bạn. Nếu cách đó không hiệu quả, tôi e rằng bạn cần phải đóng tất cả các quy trình của Chrome và khởi động lại để xử lý plugin cho đến khi bản sửa lỗi được đưa ra. Đừng lo lắng, sau khi khởi động lại, bạn sẽ không thấy thông báo này nữa.",
+ "eventsCompletionMessage": "Lỗi khi xem sự kiện hoàn thành:",
+ "unexpectedAddressMessage": "Địa chỉ không mong đợi trong sự kiện LevelCompletedLog (bỏ qua):",
+ "helperPlayer": "địa chỉ người chơi hiện tại",
+ "helperEthernaut": "hợp đồng trò chơi chính",
+ "helperLevel": "địa chỉ hợp đồng cấp hiện tại",
+ "helperContract": "phiên bản hợp đồng cấp hiện tại (nếu được tạo)",
+ "helperInstance": "địa chỉ hợp đồng cấp hiện tại (nếu được tạo)",
+ "helperVersion": "phiên bản trò chơi hiện tại",
+ "helperGetBalance": "lấy số dư địa chỉ trong ether",
+ "helperGetBlockNumber": "lấy số khối mạng hiện tại",
+ "helperSendTransaction": "gửi giao dịch",
+ "helperGetNetworkId": "lấy id mạng ethereum",
+ "helperToWei": "chuyển đổi đơn vị ether sang wei",
+ "helperFromWei": "chuyển đổi đơn vị wei sang ether",
+ "levelNotTranslated": "Cấp độ này chưa được dịch hoặc bản dịch chưa đầy đủ.",
+ "contributeTranslation": "Bấm vào đây để cải thiện bản dịch",
+ "usingConsole": "Hầu hết tương tác trò chơi đều thông qua bảng điều khiển của trình duyệt: `Dev Tools -> Console`. Mở bảng điều khiển và nhập lệnh: \n\n`help()`\n\n để xem danh sách các đối tượng và chức năng được trò chơi đưa vào bảng điều khiển. Vì hầu hết các tương tác đều không đồng bộ, chúng tôi khuyên bạn nên sử dụng Chrome v62 để bật từ khóa `async/await` trong bảng điều khiển, thay vì viết: \n\n`getBalance(player)> PROMISE`\n\n và mở lời hứa. Với chờ đợi/không đồng bộ, bạn có thể viết:\n\n`await getBalance(player) > '1.11002387' `\n\n",
+ "gameMechanics": "Trò chơi sử dụng hợp đồng chính `Ethernaut.sol` để quản lý tiến trình của người chơi và ủy quyền tương tác với việc triển khai `Level.sol`. Mỗi hợp đồng cấp độ sẽ tạo ra các phiên bản để người chơi thao tác, phá vỡ, phá hủy, sửa chữa, v.v. Người chơi yêu cầu một phiên bản, thao túng nó và trả lại nó cho trò chơi để đánh giá mức độ hoàn thành cấp độ.\n\n Cả hai yêu cầu phiên bản và gửi lại phiên bản vào trò chơi được thực hiện bằng các nút trong giao diện người dùng ở mỗi cấp độ. Khi ứng dụng này truy xuất một phiên bản từ `Ethernaut.sol`, nó sẽ gói phiên bản đó trong một đối tượng `TruffleContract` và hiển thị phiên bản đó trong bảng điều khiển của trình duyệt. Xem cấp độ đầu tiên để có hướng dẫn đầy đủ về cách chơi trò chơi.",
+ "beyondConsole": "Một số cấp độ sẽ yêu cầu làm việc bên ngoài bảng điều khiển trình duyệt. Tức là viết mã vững chắc và triển khai nó trong mạng để tấn công hợp đồng cá thể của cấp độ đó với một hợp đồng khác. Việc này có thể được thực hiện theo nhiều cách, ví dụ: \n\n1) Sử dụng Remix để viết mã và triển khai mã đó trong mạng tương ứng Xem [Remix Solidity IDE](https://remix.ethereum.org/). \n\n2) Thiết lập dự án truffle cục bộ để phát triển và triển khai các hợp đồng tấn công. Xem [Truffle Framework](http://truffleframework.com/).",
+ "troubleshooting": "Đôi khi \n\n(a) trạng thái ứng dụng hoặc (b) trạng thái plugin MetaMask \n\ncó thể hơi rối, đặc biệt là sau khi chuyển mạng, mở khóa, v.v. Nếu những gì bạn đang thấy không có nhiều ý nghĩa , hãy thử làm mới ứng dụng, làm mới ứng dụng, tắt và bật lại plugin metamask hoặc thậm chí khởi động lại trình duyệt của bạn. \n\nNếu bạn gặp vấn đề, vui lòng cho chúng tôi biết theo địa chỉ ethernaut@zeppelin.solutions",
+ "poweredBy": "được cung cấp bởi ",
+ "setupMetamask": "Nếu bạn chưa có nó, hãy cài đặt [MetaMask browser extension](https://metamask.io/) (trong Chrome, Firefox, Brave hoặc Opera trên máy tính để bàn của bạn). \n\nThiết lập ví của tiện ích mở rộng và sử dụng bộ chọn mạng để trỏ đến mạng ưa thích ở phía trên bên trái giao diện của tiện ích mở rộng. Ngoài ra bạn có thể sử dụng nút UI để chuyển đổi giữa các mạng. Nếu bạn chọn mạng không được hỗ trợ, trò chơi sẽ thông báo cho bạn và đưa bạn đến mạng thử nghiệm Sepolia mặc định. \n\nSau khi hoàn tất, hãy quay lại đây và tải lại trang web",
+ "FifthyPercentMessage": "Công việc tuyệt vời! Bạn đã đi được nửa chặng đường của Ethernaut và đang khá giỏi trong việc phá vỡ mọi thứ. Làm việc với tư cách là Nhà nghiên cứu bảo mật Blockchain tại OpenZeppelin có thể rất thú vị... https://grnh.se/fdbf1c043us",
+ "SeventyFivePercentMessage": "75%: Làm tốt lắm…bây giờ bạn đang ở sâu trong hố thỏ…ai biết nó sẽ đưa bạn đến đâu… https://grnh.se/d4a786e43us",
+ "NinetyPercentMessage": "90%: Bạn sắp đến đích rồi! Chỉ còn một vài thử thách nữa là bạn sẽ hoàn thành Ethernaut! Bạn đã cân nhắc sự nghiệp trong lĩnh vực Bảo mật Blockchain chưa?https://grnh.se/cfcca8c83us",
+ "HundredPercentMessage": "100%: Xin chúc mừng! Cuộc hành trình của bạn xuống hố thỏ Web3 thật ấn tượng và đáng được tôn vinh! Bây giờ bạn có kỹ năng để phá vỡ hợp đồng thông minh! Điều gì tiếp theo từ đây? Đăng ký làm Nhà nghiên cứu bảo mật Blockchain tại OpenZeppelin và góp phần bảo mật các giao thức hàng đầu trong Web3! https://grnh.se/26c05aac3us",
+ "Menu": "Menu",
+ "Networks": "Mạng",
+ "Languages": "Ngôn ngữ",
+ "PageNotFoundTitle": "404 Lỗi - Không tìm thấy trang",
+ "PageNotFoundText": "Ối! Trang bạn đang tìm kiếm không thể được tìm thấy."
+}
\ No newline at end of file
diff --git a/client/src/gamedata/zh_cn/strings.json b/client/src/gamedata/zh_cn/strings.json
index 4bea0faed..988f18a34 100644
--- a/client/src/gamedata/zh_cn/strings.json
+++ b/client/src/gamedata/zh_cn/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "开始!",
"toggleNavigation": "切换导航",
diff --git a/client/src/gamedata/zh_tw/strings.json b/client/src/gamedata/zh_tw/strings.json
index 61afe8065..1a3f14812 100644
--- a/client/src/gamedata/zh_tw/strings.json
+++ b/client/src/gamedata/zh_tw/strings.json
@@ -21,6 +21,7 @@
"chinese_traditional": "正體中文",
"french": "Français",
"russian": "Русский",
+ "vietnamese": "tiếng Việt",
"korean": "한국어",
"playNow": "開始!",
"toggleNavigation": "切換導覽",