diff --git a/README.md b/README.md index 0d76d69a..ee2dc976 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,27 @@ All the Markdown files **MUST** be edited in english. To work locally in english - Open a PR with your changes. +##### Work locally (translations) + +To work with translations, those are the steps to update the translated content: + +- Run a local server for the language you want to edit: `./translations.sh zh-cn` for instance. If no language is provided, the script will only extract translations from english. + +- Open the translation file you are interested in `po/zh-cn.po` for instance. You can also use editors like [poedit](https://poedit.net/) to help you on this task. + +- When you are done, you should only have changes into the `po/xx.po` file. Commit them and open a PR. + The PR must stars with `i18n` to let the maintainers know that the PR is only changing translation. + +The translation work is inspired from [Comprehensive Rust repository](https://github.com/google/comprehensive-rust/blob/main/TRANSLATIONS.md). + +##### Initiate a new translation for your language + +If you wish to initiate a new translation for your language without running a local server, consider the following tips: + +- Execute the command `./translations.sh new xx` (replace `xx` with your language code). This method can generate the `xx.po` file of your language for you. +- To update your `xx.po` file, execute the command `./translations.sh xx` (replace `xx` with your language code), as mentioned in the previous chapter. +- If the `xx.po` file already exists (which means you are not initiating a new translation), you should not run this command. + #### Cairo programs The current book has script that verifies the compilation of all Cairo programs in the book. diff --git a/po/zh-cn.po b/po/zh-cn.po index 8fdef775..54728fa8 100644 --- a/po/zh-cn.po +++ b/po/zh-cn.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: Starknet by Example\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2023-12-01 22:05+0900\n" +"PO-Revision-Date: 2023-12-02 16:18+0900\n" "Last-Translator: StarknetAstro \n" "Language-Team: Language zh-cn\n" "Language: zh_CN\n" @@ -142,35 +142,35 @@ msgstr "ERC20 代币" #: src/SUMMARY.md:40 msgid "Constant Product AMM" -msgstr "" +msgstr "恒定产品 AMM" #: src/SUMMARY.md:43 msgid "Advanced concepts" -msgstr "" +msgstr "高级概念" #: src/SUMMARY.md:44 msgid "Writing to any storage slot" -msgstr "" +msgstr "写入任何存储槽" #: src/SUMMARY.md:45 msgid "Storing Arrays" -msgstr "" +msgstr "存储数组" #: src/SUMMARY.md:46 msgid "Struct as mapping key" -msgstr "" +msgstr "结构体作为映射键" #: src/SUMMARY.md:47 msgid "Hash Solidity Compatible" -msgstr "" +msgstr "兼容Hash Solidity" #: src/SUMMARY.md:48 msgid "Optimisations" -msgstr "" +msgstr "优化" #: src/SUMMARY.md:49 msgid "Storage Optimisations" -msgstr "" +msgstr "存储优化" #: src/SUMMARY.md:50 msgid "List" @@ -301,7 +301,7 @@ msgstr "# 存储" #: src/ch00/basics/storage.md:3 msgid "Here's the most minimal contract you can write in Cairo:" -msgstr "" +msgstr "这是您用Cairo能写的最简短的合约:" #: src/ch00/basics/storage.md:5 msgid "" @@ -371,16 +371,19 @@ msgid "" "> From the compiler's perspective, the storage variables don't exist until " "they are used." msgstr "" +"> 实际上,这两个合约的底层 sierra 程序是一样的。\n" +"> 从编译器的角度来看,存储变量在使用之前是不存在的。" #: src/ch00/basics/storage.md:32 msgid "" "You can also read about [storing custom types](./storing-custom-types.md)" msgstr "" +"您还可以阅读有关 [存储自定义类型] 的内容(./storing-custom-types.md)。" #: src/ch00/basics/storage.md:34 src/ch00/basics/variables.md:126 #: src/ch01/constant-product-amm.md:275 msgid "" -msgstr "" +msgstr "" #: src/ch00/basics/constructor.md:1 msgid "# Constructor" @@ -394,12 +397,17 @@ msgid "" "constructor function must be annotated with the `#[constructor]` attribute. " "Also, a good practice consists in naming that function `constructor`." msgstr "" +"构造函数是一种特殊类型的函数,只在部署合约时运行一次,可用于初始化合约的状" +"态。你的合约不能有一个以上的构造函数,而且构造函数必须使用 `#[constructor]` " +"属性注释。此外,一个好的做法是将该函数命名为 `constructor`。" #: src/ch00/basics/constructor.md:5 msgid "" "Here's a simple example that demonstrates how to initialize the state of a " "contract on deployment by defining logic inside a constructor." msgstr "" +"下面是一个简单的示例,演示如何通过在构造函数中定义逻辑,在部署时初始化合约的" +"状态。" #: src/ch00/basics/constructor.md:7 msgid "" @@ -423,6 +431,25 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::contract]\n" +"mod ExampleConstructor {\n" +" use starknet::ContractAddress;\n" +"\n" +" #[storage]\n" +" struct Storage {\n" +" names: LegacyMap::,\n" +" }\n" +"\n" +" // The constructor is decorated with a `#[constructor]` attribute.\n" +" // It is not inside an `impl` block.\n" +" #[constructor]\n" +" fn constructor(ref self: ContractState, name: felt252, address: " +"ContractAddress) {\n" +" self.names.write(address, name);\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/constructor.md:25 msgid "" @@ -432,6 +459,12 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/constructor/src/constructor.cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x017fd6558e67451dA583d123D77F4e2651E91502D08F8F8432355293b11e1f8F) " +"上的合约,或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/constructor/src/constructor.cairo) 中" +"尝试它。" #: src/ch00/basics/variables.md:1 msgid "# Variables" @@ -439,7 +472,7 @@ msgstr "# 变量" #: src/ch00/basics/variables.md:3 msgid "There are 3 types of variables in Cairo contracts:" -msgstr "" +msgstr "Cairo合约中有 3 种变量:" #: src/ch00/basics/variables.md:5 msgid "" @@ -453,10 +486,19 @@ msgid "" " - provides information about the blockchain\n" " - accessed anywhere, even within library functions" msgstr "" +"- 局部\n" +" - 在函数中声明\n" +" - 不存储在区块链中\n" +"- 存储\n" +" - 在合约的 [Storage](./storage.md) 中声明\n" +" - 可从一个执行过程访问到另一个执行过程\n" +"- 全局\n" +" - 提供有关区块链的信息\n" +" - 可在任何地方访问,甚至在库函数中" #: src/ch00/basics/variables.md:15 msgid "## Local Variables" -msgstr "" +msgstr "## 局部变量" #: src/ch00/basics/variables.md:17 msgid "" @@ -464,6 +506,8 @@ msgid "" "function or block of code. They are temporary and exist only for the " "duration of that particular function or block execution." msgstr "" +"局部变量在特定函数或代码块的范围内使用和访问。它们是临时的,只在特定函数或代" +"码块执行期间存在。" #: src/ch00/basics/variables.md:19 msgid "" @@ -473,10 +517,13 @@ msgid "" "a specific context. They also make the code more readable by giving names to " "intermediate values." msgstr "" +"局部变量存储在内存中,不会存储在区块链上。这就意味着在执行过程中无法访问它" +"们。局部变量可用于存储仅在特定上下文中相关的临时数据。通过为中间值命名,它们" +"还能使代码更具可读性。" #: src/ch00/basics/variables.md:21 msgid "Here's a simple example of a contract with only local variables:" -msgstr "" +msgstr "下面是一个只有局部变量的简单合约示例:" #: src/ch00/basics/variables.md:23 msgid "" @@ -511,6 +558,36 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait ILocalVariablesExample {\n" +" fn do_something(self: @TContractState, value: u32) -> u32;\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod LocalVariablesExample {\n" +" #[storage]\n" +" struct Storage {}\n" +"\n" +" #[abi(embed_v0)]\n" +" impl LocalVariablesExample of super::" +"ILocalVariablesExample {\n" +" fn do_something(self: @ContractState, value: u32) -> u32 {\n" +" // This variable is local to the current block. It can't be " +"accessed once it goes out of scope.\n" +" let increment = 10;\n" +"\n" +" {\n" +" // The scope of a code block allows for local variable " +"declaration\n" +" // We can access variables defined in higher scopes.\n" +" let sum = value + increment;\n" +" sum\n" +" }\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/variables.md:50 msgid "" @@ -520,6 +597,12 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/variables/src/local_variables.cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x015B3a10F9689BeD741Ca3C210017BC097122CeF76f3cAA191A20ff8b9b56b96) " +"上的合约,或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/variables/src/local_variables.cairo) " +"中尝试它。" #: src/ch00/basics/variables.md:52 msgid "## Storage Variables" @@ -531,22 +614,24 @@ msgid "" "accessed from one execution to another, allowing the contract to remember " "and update information over time." msgstr "" +"存储变量是存储在区块链上的持久数据。它们可以在不同的执行过程中被访问,从而使" +"合约能够保存和更新信息。" #: src/ch00/basics/variables.md:56 msgid "" "To write or update a storage variable, you need to interact with the " "contract through an external entrypoint by sending a transaction." -msgstr "" +msgstr "要写入或更新存储变量,需要通过外部入口点发送交易与合约交互。" #: src/ch00/basics/variables.md:58 msgid "" "On the other hand, you can read state variables, for free, without any " "transaction, simply by interacting with a node." -msgstr "" +msgstr "另一方面,只需与节点交互,就可以免费读取状态变量,无需发出任何交易。" #: src/ch00/basics/variables.md:60 msgid "Here's a simple example of a contract with one storage variable:" -msgstr "" +msgstr "下面是一个带有一个存储变量的简单合约示例:" #: src/ch00/basics/variables.md:62 msgid "" @@ -583,6 +668,38 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IStorageVariableExample {\n" +" fn set(ref self: TContractState, value: u32);\n" +" fn get(self: @TContractState) -> u32;\n" +"}\n" +"#[starknet::contract]\n" +"mod StorageVariablesExample {\n" +" // All storage variables are contained in a struct called Storage\n" +" // annotated with the `#[storage]` attribute\n" +" #[storage]\n" +" struct Storage {\n" +" // Storage variable holding a number\n" +" value: u32\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl StorageVariablesExample of super::" +"IStorageVariableExample {\n" +" // Write to storage variables by sending a transaction that calls an " +"external function\n" +" fn set(ref self: ContractState, value: u32) {\n" +" self.value.write(value);\n" +" }\n" +"\n" +" // Read from storage variables without sending transactions\n" +" fn get(self: @ContractState) -> u32 {\n" +" self.value.read()\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/variables.md:92 msgid "" @@ -593,10 +710,16 @@ msgid "" "blob/main/listings/ch00-getting-started/variables/src/storage_variables." "cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x06eA827B32875483709b785A7F9e846a52776Cd8D42C3fE696218c2624b0DCCa) " +"上的合约,或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/variables/src/storage_variables." +"cairo) 中尝试它。" #: src/ch00/basics/variables.md:94 msgid "## Global Variables" -msgstr "" +msgstr "## 全局变量" #: src/ch00/basics/variables.md:96 msgid "" @@ -604,12 +727,15 @@ msgid "" "blockchain and the current execution environment. They can be accessed at " "any time and from anywhere!" msgstr "" +"全局变量是预定义变量,可提供有关区块链和当前执行环境的信息。可以随时随地访问" +"它们!" #: src/ch00/basics/variables.md:98 msgid "" "In Starknet, you can access global variables by using specific functions " "contained in the starknet core libraries." msgstr "" +"在 Starknet 中,您可以通过使用 starknet 核心库中的特定函数来访问全局变量。" #: src/ch00/basics/variables.md:100 msgid "" @@ -617,6 +743,8 @@ msgid "" "caller of the current transaction, and the `get_contract_address` function " "returns the address of the current contract." msgstr "" +"例如,`get_caller_address`函数返回当前事务的调用者地址," +"`get_contract_address`函数返回当前合同的地址。" #: src/ch00/basics/variables.md:102 msgid "" @@ -645,6 +773,30 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IGlobalExample {\n" +" fn foo(ref self: TContractState);\n" +"}\n" +"#[starknet::contract]\n" +"mod GlobalExample {\n" +" // import the required functions from the starknet core library\n" +" use starknet::get_caller_address;\n" +"\n" +" #[storage]\n" +" struct Storage {}\n" +"\n" +" #[abi(embed_v0)]\n" +" impl GlobalExampleImpl of super::IGlobalExample {\n" +" fn foo(ref self: ContractState) {\n" +" // Call the get_caller_address function to get the sender " +"address\n" +" let caller = get_caller_address();\n" +" // ...\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/variables.md:125 msgid "" @@ -655,18 +807,24 @@ msgid "" "blob/main/listings/ch00-getting-started/variables/src/global_variables." "cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x05bD2F3943bd4e030f85678b55b2EC2C1be939e32388530FB20ED967B3Be433F) " +"上的合约,或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/variables/src/global_variables." +"cairo) 中尝试它。" #: src/ch00/basics/visibility-mutability.md:1 msgid "# Visibility and Mutability" -msgstr "" +msgstr "# 可见性和可变性" #: src/ch00/basics/visibility-mutability.md:3 msgid "## Visibility" -msgstr "" +msgstr "## 可见性" #: src/ch00/basics/visibility-mutability.md:5 msgid "There are two types of functions in Starknet contracts:" -msgstr "" +msgstr "Starknet合约有两种功能:" #: src/ch00/basics/visibility-mutability.md:7 msgid "" @@ -674,6 +832,8 @@ msgid "" "- Functions that are only accessible internally and can only be called by " "other functions in the contract." msgstr "" +"- 外部可访问、任何人都可调用的函数。\n" +"- 只能在内部访问的函数,只能被合约中的其他函数调用。" #: src/ch00/basics/visibility-mutability.md:10 msgid "" @@ -685,10 +845,14 @@ msgid "" "accessible functions is not annotated with any attribute, which means that " "all the functions inside this block are private by default." msgstr "" +"这些函数通常也分为两个不同的实现块。第一个`impl`块用于外部访问的函数,明确标" +"注了 `#[abi(embed_v0)]`属性。这表明该代码块中的所有函数都可以作为交易或视图函" +"数调用。第二个用于内部可访问函数的 `impl` 块没有注释任何属性,这意味着该块中" +"的所有函数默认都是私有的。" #: src/ch00/basics/visibility-mutability.md:12 msgid "## State Mutability" -msgstr "" +msgstr "## 状态可变性" #: src/ch00/basics/visibility-mutability.md:14 msgid "" @@ -699,6 +863,10 @@ msgid "" "adding it as the first parameter of the function. This can be done in two " "different ways:" msgstr "" +"无论函数是内部函数还是外部函数,它都可以修改或不修改合约的状态。当我们在智能" +"合约中声明与存储变量交互的函数时,\n" +"我们需要将 `ContractState`添加为函数的第一个参数,明确说明我们正在访问 合约的" +"状态。这有两种不同的方法:" #: src/ch00/basics/visibility-mutability.md:17 msgid "" @@ -707,6 +875,10 @@ msgid "" "- If we want our function to be read-only and not mutate the state of the " "contract, we pass it by snapshot like this: `self: @ContractState`." msgstr "" +"- 如果我们希望我们的函数能够更改合约的状态,我们可以像这样通过引用来传递它:" +"ref self:ContractState`。\n" +"- 如果我们希望我们的函数是只读的,并且不更改合约的状态,我们可以通过快照传递" +"它,如下所示:`self:@ContractState`." #: src/ch00/basics/visibility-mutability.md:20 msgid "" @@ -716,16 +888,19 @@ msgid "" "External functions, that modify the contract's state, on the other side can " "only be called by making a transaction." msgstr "" +"只读函数(也称为视图函数)可以直接调用,无需进行事务处理。你可以直接通过 RPC " +"节点与它们交互,读取合约的状态,而且可以自由调用!\n" +"而修改合约状态的外部函数则只能通过交易来调用。" #: src/ch00/basics/visibility-mutability.md:23 msgid "" "Internal functions can't be called externally, but the same principle " "applies regarding state mutability." -msgstr "" +msgstr "内部函数不能被外部调用,同样的原则也适用于状态可变性。" #: src/ch00/basics/visibility-mutability.md:25 msgid "Let's take a look at a simple example contract to see these in action:" -msgstr "" +msgstr "让我们通过一个简单的合约示例来了解这些功能:" #: src/ch00/basics/visibility-mutability.md:27 msgid "" @@ -787,6 +962,63 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IExampleContract {\n" +" fn set(ref self: TContractState, value: u32);\n" +" fn get(self: @TContractState) -> u32;\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod ExampleContract {\n" +" #[storage]\n" +" struct Storage {\n" +" value: u32\n" +" }\n" +"\n" +"\n" +" // The `abi(embed_v0)` attribute indicates that all the functions in " +"this implementation can be called externally.\n" +" // Omitting this attribute would make all the functions in this " +"implementation internal.\n" +" #[abi(embed_v0)]\n" +" impl ExampleContract of super::IExampleContract {\n" +" // The `set` function can be called externally because it is written " +"inside an implementation marked as `#[external]`.\n" +" // It can modify the contract's state as it is passed as a " +"reference.\n" +" fn set(ref self: ContractState, value: u32) {\n" +" self.value.write(value);\n" +" }\n" +"\n" +" // The `get` function can be called externally because it is written " +"inside an implementation marked as `#[external]`.\n" +" // However, it can't modify the contract's state is passed as a " +"snapshot: it is only a \"view\" function.\n" +" fn get(self: @ContractState) -> u32 {\n" +" // We can call an internal function from any functions within " +"the contract\n" +" PrivateFunctionsTrait::_read_value(self)\n" +" }\n" +" }\n" +"\n" +" // The lack of the `external` attribute indicates that all the functions " +"in this implementation can only be called internally.\n" +" // We name the trait `PrivateFunctionsTrait` to indicate that it is an " +"internal trait allowing us to call internal functions.\n" +" #[generate_trait]\n" +" impl PrivateFunctions of PrivateFunctionsTrait {\n" +" // The `_read_value` function is outside the implementation that is " +"marked as `#[abi(embed_v0)]`, so it's an _internal_ function\n" +" // and can only be called from within the contract.\n" +" // It can modify the contract's state as it is passed as a " +"reference.\n" +" fn _read_value(self: @ContractState) -> u32 {\n" +" self.value.read()\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/visibility-mutability.md:73 msgid "" @@ -796,23 +1028,29 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/visibility/src/visibility.cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x0071dE3093AB58053b0292C225aa0eED40293e7694A0042685FF6D813d39889F) " +"上的合约,或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/visibility/src/visibility.cairo) 中尝" +"试它。" #: src/ch00/basics/visibility-mutability.md:75 #: src/ch00/interacting/interacting.md:4 msgid "
Last change: 2023-10-19
" -msgstr "" +msgstr "
Last change: 2023-10-19
" #: src/ch00/basics/counter.md:1 msgid "# Simple Counter" -msgstr "" +msgstr "# 简单计数器" #: src/ch00/basics/counter.md:3 msgid "This is a simple counter contract." -msgstr "" +msgstr "这是一个简单的计数合约。" #: src/ch00/basics/counter.md:5 msgid "Here's how it works:" -msgstr "" +msgstr "这个合约是这样工作的:" #: src/ch00/basics/counter.md:7 msgid "" @@ -823,6 +1061,11 @@ msgid "" "\n" "- When a user calls 'decrement', the contract decrements the counter by 1." msgstr "" +"- 合约有一个名为 'counter'的状态变量,初始化为 0。\n" +"\n" +"- 当用户调用 'increment'时,合约会将计数器递增 1。\n" +"\n" +"- 当用户调用 'decrement'时,合约会将计数器递减 1。" #: src/ch00/basics/counter.md:13 msgid "" @@ -868,6 +1111,47 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait ISimpleCounter {\n" +" fn get_current_count(self: @TContractState) -> u128;\n" +" fn increment(ref self: TContractState);\n" +" fn decrement(ref self: TContractState);\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod SimpleCounter {\n" +" #[storage]\n" +" struct Storage {\n" +" // Counter variable\n" +" counter: u128,\n" +" }\n" +"\n" +" #[constructor]\n" +" fn constructor(ref self: ContractState, init_value: u128) {\n" +" // Store initial value\n" +" self.counter.write(init_value);\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl SimpleCounter of super::ISimpleCounter {\n" +" fn get_current_count(self: @ContractState) -> u128 {\n" +" return self.counter.read();\n" +" }\n" +"\n" +" fn increment(ref self: ContractState) {\n" +" // Store counter value + 1\n" +" let counter = self.counter.read() + 1;\n" +" self.counter.write(counter);\n" +" }\n" +" fn decrement(ref self: ContractState) {\n" +" // Store counter value - 1\n" +" let counter = self.counter.read() - 1;\n" +" self.counter.write(counter);\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/counter.md:54 msgid "" @@ -877,14 +1161,20 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/counter/src/contracts.cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x01664a69Fe701a1df7Bb0ae4A353792d0cf4E27146ee860075cbf6108b1D5718) " +"上的合约,或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/counter/src/contracts.cairo) 中尝试" +"它。" #: src/ch00/basics/counter.md:56 msgid "
Last change: 2023-11-04
" -msgstr "" +msgstr "
Last change: 2023-11-04
" #: src/ch00/basics/mappings.md:1 msgid "# Mappings" -msgstr "" +msgstr "# 映射" #: src/ch00/basics/mappings.md:3 msgid "" @@ -893,6 +1183,9 @@ msgid "" "important to note that the `LegacyMap` type can only be used inside the " "`Storage` struct of a contract and that it can't be used elsewhere." msgstr "" +"映射是一种键值数据结构,用于在智能合约中存储数据。在开罗,它们使用 " +"`LegacyMap` 类型实现。值得注意的是,`LegacyMap`类型只能在合约的 `Storage`结构" +"中使用,不能用在其他地方。" #: src/ch00/basics/mappings.md:5 msgid "" @@ -903,10 +1196,14 @@ msgid "" "Similarly, we can read the value associated with a given key by calling the " "`read()` method and passing in the relevant key." msgstr "" +"在此,我们演示如何在Cairo合约中使用 `LegacyMap` 类型,在 `ContractAddress` 类" +"型的键和 `felt252` 类型的值之间进行映射。键值类型在角括号 <> 中指定。我们通过" +"调用 `write()` 方法,传入键和值,写入映射。同样,我们可以通过调用 `read()` 方" +"法并输入相关键值来读取与给定键值相关的值。" #: src/ch00/basics/mappings.md:7 msgid "Some additional notes:" -msgstr "" +msgstr "一些补充说明:" #: src/ch00/basics/mappings.md:9 msgid "" @@ -921,6 +1218,14 @@ msgid "" "starknet.io/documentation/architecture_and_concepts/Contracts/contract-" "storage/#storage_variables)" msgstr "" +"- 也有更复杂的键值对映射,例如,我们可以使用 `LegacyMap::<(ContractAddress, " +"ContractAddress), felt252>` 在 ERC20 代币合约上创建一个代币授权许可。\n" +"\n" +"- 在映射中,键`k_1,...,k_n`处的值的地址是`h(...h(h(sn_keccak(variable_name)," +"k_1),k_2),...,k_n)`,其中 `ℎ` 是 Pedersen 哈希值,最终值取`mod2251-256`。有关" +"合约存储布局的更多信息,请参阅 [Starknet Documentation](https://docs." +"starknet.io/documentation/architecture_and_concepts/Contracts/contract-" +"storage/#storage_variables)。" #: src/ch00/basics/mappings.md:13 msgid "" @@ -958,19 +1263,58 @@ msgid "" "}\n" "```" msgstr "" - -#: src/ch00/basics/mappings.md:44 -msgid "" -"Visit contract on [Voyager](https://goerli.voyager.online/" -"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " +"```rust\n" +"use starknet::ContractAddress;\n" +"\n" +"#[starknet::interface]\n" +"trait IMapContract {\n" +" fn set(ref self: TContractState, key: ContractAddress, value: felt252);\n" +" fn get(self: @TContractState, key: ContractAddress) -> felt252;\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod MapContract {\n" +" use starknet::ContractAddress;\n" +"\n" +" #[storage]\n" +" struct Storage {\n" +" // The `LegacyMap` type is only available inside the `Storage` " +"struct.\n" +" map: LegacyMap::,\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl MapContractImpl of super::IMapContract {\n" +" fn set(ref self: ContractState, key: ContractAddress, value: " +"felt252) {\n" +" self.map.write(key, value);\n" +" }\n" +"\n" +" fn get(self: @ContractState, key: ContractAddress) -> felt252 {\n" +" self.map.read(key)\n" +" }\n" +" }\n" +"}\n" +"```" + +#: src/ch00/basics/mappings.md:44 +msgid "" +"Visit contract on [Voyager](https://goerli.voyager.online/" +"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " "or play with it in [Remix](https://remix.ethereum.org/?" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/mappings/src/mappings.cairo)." msgstr "" +"访问 [Voyager](https://goerli.voyager.online/" +"contract/0x06214AB4c23Cc545bf2221D465eB83aFb7412779AD498BD48a724B3F645E3505) " +"上的合约或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/mappings/src/mappings.cairo) 中尝试" +"它。" #: src/ch00/basics/errors.md:1 msgid "# Errors" -msgstr "" +msgstr "# 错误" #: src/ch00/basics/errors.md:3 msgid "" @@ -980,10 +1324,13 @@ msgid "" "execution is stopped and any changes made during the transaction are " "reverted." msgstr "" +"错误可用于处理智能合约执行过程中可能发生的验证和其他条件。\n" +"如果在执行智能合约调用期间抛出错误,则将停止执行,并恢复在交易期间所做的任何" +"更改。" #: src/ch00/basics/errors.md:6 msgid "To throw an error, use the `assert` or `panic` functions:" -msgstr "" +msgstr "要抛出错误,请使用 `assert` 或 `panic`函数:" #: src/ch00/basics/errors.md:8 msgid "" @@ -998,10 +1345,18 @@ msgid "" " (Use `panic_with_felt252` to be able to directly pass a felt252 as the " "error value)" msgstr "" +"- 'assert' 用于验证条件。\n" +" 如果检查失败,则会引发错误以及指定的值,通常是一条消息。\n" +" 它类似于 Solidity 中的`require`语句。\n" +"\n" +"- 'panic' 立即停止执行,并给出错误值。\n" +" 当要检查的条件复杂且存在内部错误时,应使用它。它类似于 Solidity 中的" +"`revert` 语句。\n" +" (使用`panic_with_felt252` 可以直接传递一个felt252作为错误值)" #: src/ch00/basics/errors.md:16 msgid "Here's a simple example that demonstrates the use of these functions:" -msgstr "" +msgstr "下面是一个简单的示例,演示了这些函数的用法:" #: src/ch00/basics/errors.md:18 msgid "" @@ -1034,6 +1389,34 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IErrorsExample {\n" +" fn test_assert(self: @TContractState, i: u256);\n" +" fn test_panic(self: @TContractState, i: u256);\n" +"}\n" +"#[starknet::contract]\n" +"mod ErrorsExample {\n" +" #[storage]\n" +" struct Storage {}\n" +"\n" +" #[abi(embed_v0)]\n" +" impl ErrorsExample of super::IErrorsExample {\n" +" fn test_assert(self: @ContractState, i: u256) {\n" +" // Assert used to validate a condition\n" +" // and abort execution if the condition is not met\n" +" assert(i > 0, 'i must be greater than 0');\n" +" }\n" +"\n" +" fn test_panic(self: @ContractState, i: u256) {\n" +" if (i == 0) {\n" +" // Panic used to abort execution directly\n" +" panic_with_felt252('i must not be 0');\n" +" }\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/errors.md:46 msgid "" @@ -1043,16 +1426,22 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/errors/src/simple_errors.cairo)." msgstr "" +"在 [Voyager](https://goerli.voyager.online/" +"contract/0x0022664463FF0b711CC9B549a9E87d65A0882bB1D29338C4108696B8F2216a40) " +"上访问合约或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/errors/src/simple_errors.cairo) 中尝" +"试它。" #: src/ch00/basics/errors.md:48 msgid "## Custom errors" -msgstr "" +msgstr "## 自定义错误" #: src/ch00/basics/errors.md:50 msgid "" "You can make error handling easier by defining your error codes in a " "specific module." -msgstr "" +msgstr "您可以通过在特定模块中定义错误代码来简化错误处理。" #: src/ch00/basics/errors.md:52 msgid "" @@ -1091,6 +1480,40 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"mod Errors {\n" +" const NOT_POSITIVE: felt252 = 'must be greater than 0';\n" +" const NOT_NULL: felt252 = 'must not be null';\n" +"}\n" +"\n" +"#[starknet::interface]\n" +"trait ICustomErrorsExample {\n" +" fn test_assert(self: @TContractState, i: u256);\n" +" fn test_panic(self: @TContractState, i: u256);\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod CustomErrorsExample {\n" +" use super::Errors;\n" +"\n" +" #[storage]\n" +" struct Storage {}\n" +"\n" +" #[abi(embed_v0)]\n" +" impl CustomErrorsExample of super::ICustomErrorsExample " +"{\n" +" fn test_assert(self: @ContractState, i: u256) {\n" +" assert(i > 0, Errors::NOT_POSITIVE);\n" +" }\n" +"\n" +" fn test_panic(self: @ContractState, i: u256) {\n" +" if (i == 0) {\n" +" panic_with_felt252(Errors::NOT_NULL);\n" +" }\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/errors.md:85 msgid "" @@ -1100,16 +1523,22 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/errors/src/custom_errors.cairo)." msgstr "" +"在 [Voyager](https://goerli.voyager.online/" +"contract/0x0501CD5da5B453a18515B5A20b8029bd7583DFE7a399ad9f79c284F7829e4A57) " +"上访问 contract 或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/errors/src/custom_errors.cairo) 中尝" +"试它。" #: src/ch00/basics/errors.md:87 msgid "## Vault example" -msgstr "" +msgstr "## Vault 示例" #: src/ch00/basics/errors.md:89 msgid "" "Here's another example that demonstrates the use of errors in a more complex " "contract:" -msgstr "" +msgstr "下面是另一个示例,演示了在更复杂的合约中使用错误:" #: src/ch00/basics/errors.md:91 msgid "" @@ -1160,6 +1589,52 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"mod VaultErrors {\n" +" const INSUFFICIENT_BALANCE: felt252 = 'insufficient_balance';\n" +"// you can define more errors here\n" +"}\n" +"\n" +"#[starknet::interface]\n" +"trait IVaultErrorsExample {\n" +" fn deposit(ref self: TContractState, amount: u256);\n" +" fn withdraw(ref self: TContractState, amount: u256);\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod VaultErrorsExample {\n" +" use super::VaultErrors;\n" +"\n" +" #[storage]\n" +" struct Storage {\n" +" balance: u256,\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl VaultErrorsExample of super::IVaultErrorsExample {\n" +" fn deposit(ref self: ContractState, amount: u256) {\n" +" let mut balance = self.balance.read();\n" +" balance = balance + amount;\n" +" self.balance.write(balance);\n" +" }\n" +"\n" +" fn withdraw(ref self: ContractState, amount: u256) {\n" +" let mut balance = self.balance.read();\n" +"\n" +" assert(balance >= amount, VaultErrors::INSUFFICIENT_BALANCE);\n" +"\n" +" // Or using panic:\n" +" if (balance >= amount) {\n" +" panic_with_felt252(VaultErrors::INSUFFICIENT_BALANCE);\n" +" }\n" +"\n" +" let balance = balance - amount;\n" +"\n" +" self.balance.write(balance);\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/errors.md:137 msgid "" @@ -1169,6 +1644,12 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/errors/src/vault_errors.cairo)." msgstr "" +"在 [Voyager](https://goerli.voyager.online/" +"contract/0x020C2da26F42A28Ef54ED428eF1810FE433784b055f9bF315C5d992b1579C268) " +"上访问 contract 或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/errors/src/vault_errors.cairo) 中尝" +"试它。" #: src/ch00/basics/events.md:1 msgid "# Events" @@ -1184,12 +1665,19 @@ msgid "" "later time. Events data can be indexed by adding a `#[key]` attribute to a " "field member." msgstr "" +"事件是从合约发出数据的一种方式。所有事件都必须在`Event`枚举中定义,该枚举必须" +"使用`#[event]`属性进行注释。\n" +"事件被定义为派生`#[starknet::Event]`特征的结构。该结构的字段对应于将要发出的" +"数据。可以对事件编制索引,以便在以后查询数据时轻松快速地访问。可以通过向字段" +"成员添加`#[key]` 属性来索引事件数据。" #: src/ch00/basics/events.md:6 msgid "" "Here's a simple example of a contract using events that emit an event each " "time a counter is incremented by the \"increment\" function:" msgstr "" +"下面是合约使用事件的简单示例,这些事件在每次计数器通过“increment”函数递增时发" +"出一个事件:" #: src/ch00/basics/events.md:8 msgid "" @@ -1256,6 +1744,68 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IEventCounter {\n" +" fn increment(ref self: TContractState);\n" +"}\n" +"#[starknet::contract]\n" +"mod EventCounter {\n" +" use starknet::{get_caller_address, ContractAddress};\n" +" #[storage]\n" +" struct Storage {\n" +" // Counter value\n" +" counter: u128,\n" +" }\n" +"\n" +" #[event]\n" +" #[derive(Drop, starknet::Event)]\n" +" // The event enum must be annotated with the `#[event]` attribute.\n" +" // It must also derive the `Drop` and `starknet::Event` traits.\n" +" enum Event {\n" +" CounterIncreased: CounterIncreased,\n" +" UserIncreaseCounter: UserIncreaseCounter\n" +" }\n" +"\n" +" // By deriving the `starknet::Event` trait, we indicate to the compiler " +"that\n" +" // this struct will be used when emitting events.\n" +" #[derive(Drop, starknet::Event)]\n" +" struct CounterIncreased {\n" +" amount: u128\n" +" }\n" +"\n" +" #[derive(Drop, starknet::Event)]\n" +" struct UserIncreaseCounter {\n" +" // The `#[key]` attribute indicates that this event will be " +"indexed.\n" +" #[key]\n" +" user: ContractAddress,\n" +" new_value: u128,\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl EventCounter of super::IEventCounter {\n" +" fn increment(ref self: ContractState) {\n" +" let mut counter = self.counter.read();\n" +" counter += 1;\n" +" self.counter.write(counter);\n" +" // Emit event\n" +" self.emit(Event::CounterIncreased(CounterIncreased { amount: " +"1 }));\n" +" self\n" +" .emit(\n" +" Event::UserIncreaseCounter(\n" +" UserIncreaseCounter {\n" +" user: get_caller_address(), new_value: self." +"counter.read()\n" +" }\n" +" )\n" +" );\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/events.md:66 msgid "" @@ -1265,10 +1815,15 @@ msgid "" "#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" "blob/main/listings/ch00-getting-started/events/src/counter.cairo)." msgstr "" +"在 [Voyager](https://goerli.voyager.online/" +"contract/0x022e3B59518EA04aBb5da671ea04ecC3a154400f226d2Df38eFE146741b9E2F6) " +"上访问 合约 或在 [Remix](https://remix.ethereum.org/?" +"#activate=Starknet&url=https://github.com/NethermindEth/StarknetByExample/" +"blob/main/listings/ch00-getting-started/events/src/counter.cairo) 中尝试它。" #: src/ch00/basics/storing-custom-types.md:1 msgid "# Storing Custom Types" -msgstr "" +msgstr "# 存储自定义类型" #: src/ch00/basics/storing-custom-types.md:3 msgid "" @@ -1279,6 +1834,10 @@ msgid "" "custom type. Hopefully, we can just derive this trait for our custom type - " "unless it contains arrays or dictionaries." msgstr "" +"虽然本机类型可以存储在合约的存储中,而无需任何额外的工作,但自定义类型需要更" +"多的工作。这是因为在编译时,编译器不知道如何在存储中存储自定义类型。为了解决" +"这个问题,我们需要为我们的自定义类型实现 `Store`特征。希望我们可以为我们的自" +"定义类型派生这个特征 - 除非它包含数组或字典。" #: src/ch00/basics/storing-custom-types.md:5 msgid "" @@ -1314,6 +1873,37 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IStoringCustomType {\n" +" fn set_person(ref self: TContractState, person: Person);\n" +"}\n" +"\n" +"// Deriving the starknet::Store trait\n" +"// allows us to store the `Person` struct in the contract's storage.\n" +"#[derive(Drop, Serde, Copy, starknet::Store)]\n" +"struct Person {\n" +" age: u8,\n" +" name: felt252\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod StoringCustomType {\n" +" use super::Person;\n" +"\n" +" #[storage]\n" +" struct Storage {\n" +" person: Person\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl StoringCustomType of super::IStoringCustomType {\n" +" fn set_person(ref self: ContractState, person: Person) {\n" +" self.person.write(person);\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/storing-custom-types.md:37 msgid "" @@ -1322,10 +1912,13 @@ msgid "" "blob/main/listings/ch00-getting-started/storing_custom_types/src/contract." "cairo)." msgstr "" +"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://" +"github.com/NethermindEth/StarknetByExample/blob/main/listings/ch00-getting-" +"started/storing_custom_types/src/contract.cairo) 中尝试这个合约。" #: src/ch00/basics/custom-types-in-entrypoints.md:1 msgid "# Custom types in entrypoints" -msgstr "" +msgstr "# 入口点中的自定义类型" #: src/ch00/basics/custom-types-in-entrypoints.md:3 msgid "" @@ -1336,6 +1929,11 @@ msgid "" "entrypoint, we need to be able to serialize it into an array of `felt252`.\n" "Thankfully, we can just derive the `Serde` trait for our custom type." msgstr "" +"在入口点中使用自定义类型需要我们的类型来实现`Serde`trait。这是因为在调用入口" +"点时,输入以`felt252` 数组的形式发送到入口点,我们需要能够将其反序列化为我们" +"的自定义类型。同样,当从入口点返回自定义类型时,我们需要能够将其序列化为" +"`felt252` 数组。\n" +"值得庆幸的是,我们可以为我们的自定义类型派生`Serde` 特征。" #: src/ch00/basics/custom-types-in-entrypoints.md:6 msgid "" @@ -1371,6 +1969,37 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait ISerdeCustomType {\n" +" fn person_input(ref self: TContractState, person: SerdeCustomType::" +"Person);\n" +" fn person_output(self: @TContractState) -> SerdeCustomType::Person;\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod SerdeCustomType {\n" +" #[storage]\n" +" struct Storage {}\n" +"\n" +" // Deriving the `Serde` trait allows us to use\n" +" // the Person type as an entrypoint parameter and return value\n" +" #[derive(Drop, Serde)]\n" +" struct Person {\n" +" age: u8,\n" +" name: felt252\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl SerdeCustomType of super::ISerdeCustomType {\n" +" fn person_input(ref self: ContractState, person: Person) {}\n" +"\n" +" fn person_output(self: @ContractState) -> Person {\n" +" Person { age: 10, name: 'Joe' }\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/basics/custom-types-in-entrypoints.md:37 msgid "" @@ -1379,6 +2008,9 @@ msgid "" "blob/main/listings/ch00-getting-started/custom_type_serde/src/contract." "cairo)." msgstr "" +"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://" +"github.com/NethermindEth/StarknetByExample/blob/main/listings/ch00-getting-" +"started/custom_type_serde/src/contract.cairo) 中尝试这个合约。" #: src/ch00/basics/documentation.md:1 msgid "# Documentation" @@ -1389,14 +2021,15 @@ msgid "" "It's important to take the time to document your code. It will helps " "developers and users to understand the contract and its functionalities." msgstr "" +"花时间为你的代码写文档非常重要。它将帮助开发人员和用户了解合约及其功能。" #: src/ch00/basics/documentation.md:5 msgid "In Cairo, you can add comments with `//`." -msgstr "" +msgstr "在Cairo,您可以使用“//”添加注释。" #: src/ch00/basics/documentation.md:7 msgid "### Contract Interface:" -msgstr "" +msgstr "### 合约接口:" #: src/ch00/basics/documentation.md:9 msgid "" @@ -1406,6 +2039,10 @@ msgid "" "purpose and functionality of the contract entry points. You can follow this " "template:" msgstr "" +"在智能合约中,你通常会有一个定义合约接口的trait(带有'#[starknet::" +"interface]')。\n" +"这是包含详细文档的理想场所,这些文档解释了合约入口点的用途和功能。您可以遵循" +"以下模板:" #: src/ch00/basics/documentation.md:12 msgid "" @@ -1424,6 +2061,20 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IContract {\n" +" /// High-level description of the function\n" +" ///\n" +" /// # Arguments\n" +" /// * `arg_1` - Description of the argument\n" +" /// * `arg_n` - ...\n" +" ///\n" +" /// # Returns\n" +" /// High-level description of the return value\n" +" fn do_something(ref self: TContractState, arg_1: T_arg_1) -> T_return;\n" +"}\n" +"```" #: src/ch00/basics/documentation.md:27 msgid "" @@ -1431,6 +2082,8 @@ msgid "" "function, but rather the high-level purpose and functionality of the " "contract from the perspective of a user." msgstr "" +"请记住,这不应该描述函数的实现细节,而应该从用户的角度描述合约的高级目的和功" +"能。" #: src/ch00/basics/documentation.md:29 msgid "### Implementation Details:" @@ -1440,13 +2093,13 @@ msgstr "### 实装细节:" msgid "" "When writing the logic of the contract, you can add comments to describe the " "technical implementation details of the functions." -msgstr "" +msgstr "在编写合约逻辑时,可以添加注释来描述函数的技术实现细节。" #: src/ch00/basics/documentation.md:33 msgid "" "> Avoid over-commenting: Comments should provide additional value and " "clarity." -msgstr "" +msgstr "> 避免过度注释:注释应提供额外的价值和清晰度。" #: src/ch00/interacting/interacting.md:1 msgid "# Deploy and interact with contracts" @@ -1454,7 +2107,7 @@ msgstr "# 部署合约并与合约交互" #: src/ch00/interacting/interacting.md:3 msgid "In this chapter, we will see how to deploy and interact with contracts." -msgstr "" +msgstr "在本章中,我们将了解如何部署合约并与之交互。" #: src/ch00/interacting/interfaces-traits.md:1 msgid "# Contract interfaces and Traits generation" @@ -1468,12 +2121,17 @@ msgid "" "the [Cairo Book](https://book.cairo-lang.org/ch99-01-02-a-simple-contract." "html)." msgstr "" +"合约接口定义合约的结构和行为,充当合约的公共 ABI。它们列出了合约公开的所有函" +"数签名。接口的详细说明可以参考 [Cairo之书](https://book.cairo-lang.org/" +"ch99-01-02-a-simple-contract.html)。" #: src/ch00/interacting/interfaces-traits.md:5 msgid "" "In cairo, to specify the interface you need to define a trait annotated with " "`#[starknet::interface]` and then implement that trait in the contract." msgstr "" +"在cairo中,要指定接口,您需要定义一个带有`#[starknet::interface]`注释的特征," +"然后在合约中实现该特征。" #: src/ch00/interacting/interfaces-traits.md:7 msgid "" @@ -1483,6 +2141,9 @@ msgid "" "type as a parameter. It's important to note that every function in the " "contract interface must have this `self` parameter of type `TContractState`." msgstr "" +"当函数需要访问协定状态时,它必须具有类型为`ContractState`的`self`参数。这意味" +"着接口特征中的相应函数签名也必须采用`TContractState`类型作为参数。需要注意的" +"是,合约接口中的每个函数都必须具有此类型为`TContractState`的`self`参数。" #: src/ch00/interacting/interfaces-traits.md:9 msgid "" @@ -1495,10 +2156,14 @@ msgid "" "attribute depending on whether it's an external function, a constructor or a " "l1 handler." msgstr "" +"您可以使用`#[generate_trait]`属性隐式生成特定实现块的特征。此属性会自动生成一" +"个特征,其功能与已实现块中的函数相同,将`self`参数替换为通用的" +"`TContractState`参数。但是,您需要使用`#[abi(per_item)]` 属性注释块,并且每个" +"函数都具有适当的属性,具体取决于它是外部函数、构造函数还是 l1 处理程序。" #: src/ch00/interacting/interfaces-traits.md:11 msgid "In summary, there's two ways to handle interfaces:" -msgstr "" +msgstr "总之,有两种方法可以处理接口:" #: src/ch00/interacting/interfaces-traits.md:13 msgid "" @@ -1507,10 +2172,13 @@ msgid "" "#[abi(per_item)]` attributes, and annotating each function inside the " "implementation block with the appropriate attribute." msgstr "" +"- 显示地,通过定义一个用`#[starknet::interface]`标记的特征\n" +"- 隐式地,通过将`#[generate_trait]`与`#[abi(per_item)]`属性结合使用,并使用适" +"当的属性注释实现块中的每个函数。" #: src/ch00/interacting/interfaces-traits.md:16 msgid "## Explicit interface" -msgstr "" +msgstr "## 显式接口" #: src/ch00/interacting/interfaces-traits.md:18 msgid "" @@ -1542,6 +2210,33 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IExplicitInterfaceContract {\n" +" fn get_value(self: @TContractState) -> u32;\n" +" fn set_value(ref self: TContractState, value: u32);\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod ExplicitInterfaceContract {\n" +" #[storage]\n" +" struct Storage {\n" +" value: u32\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl ExplicitInterfaceContract of super::" +"IExplicitInterfaceContract {\n" +" fn get_value(self: @ContractState) -> u32 {\n" +" self.value.read()\n" +" }\n" +"\n" +" fn set_value(ref self: ContractState, value: u32) {\n" +" self.value.write(value);\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/interacting/interfaces-traits.md:45 msgid "" @@ -1550,10 +2245,13 @@ msgid "" "blob/main/listings/ch00-getting-started/interfaces_traits/src/explicit." "cairo)." msgstr "" +"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://" +"github.com/NethermindEth/StarknetByExample/blob/main/listings/ch00-getting-" +"started/interfaces_traits/src/explicit.cairo) 中尝试这个合约。" #: src/ch00/interacting/interfaces-traits.md:47 msgid "## Implicit interface" -msgstr "" +msgstr "## 隐式接口" #: src/ch00/interacting/interfaces-traits.md:49 msgid "" @@ -1581,6 +2279,29 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::contract]\n" +"mod ImplicitInterfaceContract {\n" +" #[storage]\n" +" struct Storage {\n" +" value: u32\n" +" }\n" +"\n" +" #[abi(per_item)]\n" +" #[generate_trait]\n" +" impl ImplicitInterfaceContract of IImplicitInterfaceContract {\n" +" #[external(v0)]\n" +" fn get_value(self: @ContractState) -> u32 {\n" +" self.value.read()\n" +" }\n" +"\n" +" #[external(v0)]\n" +" fn set_value(ref self: ContractState, value: u32) {\n" +" self.value.write(value);\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/interacting/interfaces-traits.md:73 msgid "" @@ -1589,6 +2310,9 @@ msgid "" "blob/main/listings/ch00-getting-started/interfaces_traits/src/implicit." "cairo)." msgstr "" +"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://" +"github.com/NethermindEth/StarknetByExample/blob/main/listings/ch00-getting-" +"started/interfaces_traits/src/implicit.cairo) 中尝试这个合约。" #: src/ch00/interacting/interfaces-traits.md:75 msgid "" @@ -1596,10 +2320,12 @@ msgid "" "contract::{GeneratedContractInterface}`. However, the `Dispatcher` will not " "be generated automatically." msgstr "" +"> 注意:您可以使用`use contract::{GeneratedContractInterface}`导入隐式生成的" +"合约接口。但是,`Dispatcher`不会自动生成。" #: src/ch00/interacting/interfaces-traits.md:77 msgid "## Internal functions" -msgstr "" +msgstr "## 内部函数" #: src/ch00/interacting/interfaces-traits.md:79 msgid "" @@ -1607,6 +2333,9 @@ msgid "" "Since this trait is generated in the context of the contract, you can define " "pure functions as well (functions without the `self` parameter)." msgstr "" +"您还可以将`#[generate_trait]`用于内部函数。\n" +"由于此特征是在合约的上下文中生成的,因此您也可以定义纯函数(没有“self”参数的" +"函数)。" #: src/ch00/interacting/interfaces-traits.md:82 msgid "" @@ -1656,6 +2385,51 @@ msgid "" "}\n" "```" msgstr "" +"```rust\n" +"#[starknet::interface]\n" +"trait IImplicitInternalContract {\n" +" fn add(ref self: TContractState, nb: u32);\n" +" fn get_value(self: @TContractState) -> u32;\n" +" fn get_const(self: @TContractState) -> u32;\n" +"}\n" +"\n" +"#[starknet::contract]\n" +"mod ImplicitInternalContract {\n" +" #[storage]\n" +" struct Storage {\n" +" value: u32\n" +" }\n" +"\n" +" #[generate_trait]\n" +" impl InternalFunctions of InternalFunctionsTrait {\n" +" fn set_value(ref self: ContractState, value: u32) {\n" +" self.value.write(value);\n" +" }\n" +" fn get_const() -> u32 {\n" +" 42\n" +" }\n" +" }\n" +"\n" +" #[constructor]\n" +" fn constructor(ref self: ContractState) {\n" +" self.set_value(0);\n" +" }\n" +"\n" +" #[abi(embed_v0)]\n" +" impl ImplicitInternalContract of super::" +"IImplicitInternalContract {\n" +" fn add(ref self: ContractState, nb: u32) {\n" +" self.set_value(self.value.read() + nb);\n" +" }\n" +" fn get_value(self: @ContractState) -> u32 {\n" +" self.value.read()\n" +" }\n" +" fn get_const(self: @ContractState) -> u32 {\n" +" self.get_const()\n" +" }\n" +" }\n" +"}\n" +"```" #: src/ch00/interacting/interfaces-traits.md:127 msgid "" @@ -1664,10 +2438,13 @@ msgid "" "blob/main/listings/ch00-getting-started/interfaces_traits/src/" "implicit_internal.cairo)." msgstr "" +"在 [Remix](https://remix.ethereum.org/?#activate=Starknet&url=https://" +"github.com/NethermindEth/StarknetByExample/blob/main/listings/ch00-getting-" +"started/interfaces_traits/src/implicit_internal.cairo) 中尝试这个合约。" #: src/ch00/interacting/interfaces-traits.md:129 msgid "
Last change: 2023-11-26
" -msgstr "" +msgstr "" #: src/ch00/interacting/calling_other_contracts.md:1 msgid "# Calling other contracts"