From c910e9faa18d77ba480390338da680011a7e1bda Mon Sep 17 00:00:00 2001 From: Karol Marter Date: Mon, 26 Jun 2023 17:19:59 +0200 Subject: [PATCH 01/62] 1176 - Migrate from other chains --- config/sidebar.config.js | 1 + source/docs/casper/resources/migrate.md | 351 ++++++++++++++++++++++++ 2 files changed, 352 insertions(+) create mode 100644 source/docs/casper/resources/migrate.md diff --git a/config/sidebar.config.js b/config/sidebar.config.js index 8a4543ad3f..e0ba0f8c2d 100644 --- a/config/sidebar.config.js +++ b/config/sidebar.config.js @@ -232,6 +232,7 @@ module.exports = { items: ["resources/build-on-casper/index", "resources/build-on-casper/casper-open-source-software"], }, "resources/quick-start", + "resources/migrate", //"resources/sample-projects", // NEW CONTENT WILL BE HERE { type: "category", diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md new file mode 100644 index 0000000000..339fa280cd --- /dev/null +++ b/source/docs/casper/resources/migrate.md @@ -0,0 +1,351 @@ +--- +title: Migrate from other chains +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Moving from other chains to Casper{#migrate-to-casper} + +There are several blockchain projects available in different technologies. It's important to choose the right blockchain for a particular task. +The most popular blockchain projects in the market include: + +- `Ethereum` +- `Near` +- `Aptos` +- `Solana` + +We will compare them to Casper based on the following parameters: + +- Contract Lifecycle +- Variable Storage +- Public Methods +- Passing Arguments +- State Management + + +## Contract Lifecycle{#contract-lifecycle} + + + + +Casper smart contracts are written in Rust. In Casper, variables defined within the smart contract can be stored as either Named Keys or [Dictionaries](../concepts/dictionaries.md). The `call` function serves as the constructor of the smart contract on the Casper network. It automatically executes when the smart contract is deployed, setting the initial state of the contract and defining all entry points. + +It's worth noting that Casper only supports public entry points for [contracts](../developers/writing-onchain-code/simple-contract.md). Additionally, contracts can be defined as either immutable or upgradable. + + + + +Ethereum smart contracts are primarily written in Solidity, a programming language specifically designed for this purpose. These contracts comprise a collection of global variables that persist on the blockchain and define the contract's state. + +Furthermore, Ethereum smart contracts feature a constructor that allows for the specification of an initial state after deployment on the blockchain. Public functions declared within the contract can be invoked from outside the blockchain. + +In terms of immutability, Ethereum smart contracts are inherently immutable once deployed. However, there are design patterns available, such as "Proxy" or "Diamond," that facilitate versioning of contracts on the Ethereum blockchain. + +Smart contracts written in Solidity adhere to object-oriented programming principles and support features such as inheritance and libraries. + + + + + +Near smart contracts can be written in either JavaScript or Rust. Regardless of the chosen language, the Near SDK compiles the code to WebAssembly. In the Near ecosystem, smart contracts function as classes. The constructor, referred to as the "init" method, can receive attributes required for initializing the contract's initial state. + +All public methods defined within the contract serve as the contract's interface, exposing its functionalities. In the Near blockchain, there are various capabilities for versioning. Examples of how updates are handled include state migrations, state versioning, and contract self-updates. + + + + +The Aptos programming language is known as Move. Its primary concepts revolve around scripts and modules. Scripts enable developers to incorporate additional logic into transactions, while modules allow them to expand blockchain functionality or create custom smart contracts. A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs. + + + + +Solana smart contracts are primarily written in Rust. Unlike some other blockchain platforms, Solana's smart contracts are stateless and solely focus on program logic. The management of the contract state is handled at the account level. This means that there is a clear separation between the state stored within the account and the contract logic defined in the programs. + +In Solana, smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction. It is worth noting that Solana programs can be updated through the use of an authority known as the "update authority," which holds the necessary permissions for making modifications to the program. + + + + +## Variable Storage{#variable-storage} + + + + + +The variables can be stored either as Named Keys or [Dictionaries](../concepts/dictionaries.md). Additionally, local variables are available within the entry points and can be utilized to perform necessary actions or computations within the scope of each entry point. + + + + +The variables within the contract are responsible for storing the state of the contract at a specific moment in time. However, it's important to note that local variables used within the call functions are not stored in the contract's state. Instead, they are employed solely for computational purposes within those specific functions. + + + + +The variables in the contract can be stored as native types, SDK collections, or internal structures. It is recommended to use SDK collections whenever feasible, as they offer advantages over native types. Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state. + + + + +Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules. For storing important or relevant data, Aptos encourages the use of Resources. Resources serve as a specialized type for managing and storing significant data in an efficient manner. + + + + +Variables can be utilized locally within the context of a specific entry point being executed. They are limited to the scope of that entry point and not accessible outside of it. These variables can be defined as elementary types such as bool, String, int, and so on. + +In terms of storage, the actual data is stored in the Account. It is organized as a struct comprising related variables, allowing for efficient management and retrieval of the stored information. + + + + + +## Public Methods{#public-methods} + + + + +Entry points are declared within the 'call' routine. To declare a public entry point, the following format is used: + +```rust + +#[no_mangle] +pub extern "C" fn counter_inc() { + let uref: URef = runtime::get_key(COUNT_KEY) + .unwrap_or_revert_with(ApiError::MissingKey) + .into_uref() + .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant); + + storage::add(uref, 1); // Increment the count by 1. +} + +``` + +It's important to note that entry points do not inherently have input arguments in their definition. If a return value is needed, it should be declared using the following syntax: + +```rust +runtime::ret(value); +``` + +In the Casper networks, each call to an entry point is treated as a [Deploy](../concepts/deploy-and-deploy-lifecycle.md) to the network, and therefore, each call incurs a certain amount of mots (the network's native currency). + + + + +On Ethereum, public methods serve two purposes: they can be used to execute contract logic and modify the contract's state, or they can be utilized to retrieve data stored within the contract's state. + +The declaration of public methods in Ethereum follows the format: + +```bash + +function update_name(string value) public { + dapp_name = value; +} + +``` + +In cases where a public method only returns a value without modifying the state, it should be defined as follows: + +```bash + +function balanceOf(address _owner) public view returns (uint256 return_parameter) { } + +``` + +It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas. + + + + +In the Near blockchain, there are three types of public functions: + +`Init Methods`: These are used as the class constructors to initialize the state of the contract. + +`View Methods`: These functions are used to read the state of the contract variables. + +`Call Methods`: These methods can mutate the state of the contract and perform specific actions, such as calling another contract. + +The definition of public methods in Near is as follows: + +```rust + +pub fn add_message(&mut self, ...) { } + +``` + +For public methods that return variables, the definition would be: + +```rust + +pub fn get_messages(&self, from_index: Option, limit: Option) -> Vec { } + +``` + +The actual implementation of the functions may include the necessary parameters and logic based on the specific requirements of the contract. + + + + +Public functions in Aptos are similar to public methods or functions found in other blockchain networks. The definition of a public function in Aptos appears as follows: + +```rust + +public fun start_collection(account: &signer) {} + +``` + +For public functions that return variables, the definition would be as follows: + +```rust + +public fun max(a: u8, b: u8): (u8, bool) {} + +``` + +In the Aptos Blockchain, it is possible to return one or more values from a function. + + + + +In Solana, functions are defined as public entry points that act as interfaces visible to the network. The declaration of an entry point follows this format: + +```rust + +entrypoint!(process_instruction); + +``` + +The implementation of the entry point may resemble the following: + +```rust +pub fn process_instruction( + program_id: &Pubkey, + accounts: &[AccountInfo], + _instruction_data: &[u8], +) -> ProgramResult {} + +``` + +Within the entry point function, the necessary parameters are specified, such as `program_id`, which represents the program's identifier, `accounts`, an array of `AccountInfo` providing account details, and `_instruction_data`, representing the instruction data received. The function returns a `ProgramResult`, which indicates the success or failure of the instruction execution. + + + + +## Passing Arguments{#passing-arguments} + + + + + +Named arguments are passed as strings with type specifiers. To provide session arguments to the entry point during a Deploy, you can utilize the following approach: + +```bash + +casper-client put-deploy \ + --node-address http://65.21.235.219:7777 \ + --chain-name casper-test \ + --secret-key [KEY_PATH]/secret_key.pem \ + --payment-amount 2500000000 \ + --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \ + --session-entry-point "delegate" \ + --session-arg "validator:public_key='0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f'" \ + --session-arg "amount:u512='500000000000'" \ + --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'" + +``` + +In the contract, you can access the session arguments as follows: + +```bash + +let uref: URef = runtime::get_key(Key_Name) + +``` + +The `get_key` function can be used to retrieve the desired session argument by specifying its name or key. + + + + +Strongly typed function arguments, where both the input and return variables need to be explicitly defined. The compiler checks the correctness of the arguments passed to the functions during runtime. + +This means that the types of the function arguments, as well as the return types, must be explicitly specified in the function signature. The compiler ensures that the provided arguments adhere to the specified types, helping to catch type-related errors and ensure type safety. + +By enforcing strong typing, the compiler helps prevent potential runtime errors and enhances code reliability by verifying the compatibility of the passed arguments and expected return types. + + + + +Strongly typed function arguments require explicit definition of both the input and return variables. + +By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. + + + + +Strongly typed function arguments require explicit definition of both the input and return variables. + +By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. + + + + +Strongly typed function arguments require explicit definition of both the input and return variables. + +By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. + + + + +## State Management{#state-management} + + + + +Data is persisted in Named Keys and [Dictionaries](../concepts/dictionaries.md) in the context of a contract or an account. + + + + +Data is persisted in a storage represented by state variables within the smart contract. These state variables need to be strongly typed to allocate the appropriate amount of space for them in the storage. + +By using strong typing, the smart contract compiler can enforce type consistency and ensure that the allocated storage space aligns with the declared data types. This promotes code correctness and prevents potential data corruption or memory-related issues when interacting with the contract's state variables. + + + + +When creating state variables, it is advisable to use SDK Collections. SDK Collections provide convenient data structures, such as lists, maps, and sets, which can be used to organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage management and facilitates easier access and manipulation of data in the smart contract. + + + + +To facilitate efficient data management and organization, it is advisable to cluster related data into Resources. Resources are a special type of structure that represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve readability and maintainability of the code. + + + + +Data is stored in structs within the account. These structs should be serialized and deserialized using Borsh. The process involves reading the data from the account, deserializing it to obtain the values, updating the values, and then serializing the modified data to save the new values back into the account. + + + + +## Summary{#summary} + +While choosing a blockchain, there are additional aspects that need to be considered. These include consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and the availability of software development kits (SDKs). + +`Consensus mechanism` refers to the algorithm used by the blockchain network to achieve agreement on the validity and ordering of transactions. Different blockchains employ various consensus mechanisms such as Proof of Work (PoW), Proof of Stake (PoS), or Delegated Proof of Stake (DPoS). The choice of consensus mechanism impacts factors like security, scalability, and energy efficiency. + +`Tokenomics` relates to the economic model of the blockchain network and its native tokens. It involves aspects such as token distribution, inflation, utility, and governance. Understanding the tokenomics is crucial for evaluating the long-term viability and potential value of the blockchain ecosystem. + +`Cross-contract` capabilities refer to the ability of smart contracts to interact and communicate with each other within the blockchain network. This feature is essential for building complex decentralized applications (DApps) and implementing inter-contract functionality. + +`Contract upgradability` determines whether the deployed smart contracts can be modified or updated after deployment. It is important to assess the flexibility of the chosen blockchain in terms of contract maintenance, bug fixes, and incorporating new features or improvements without disrupting the existing ecosystem. + +Lastly, the availability of software `development kits (SDKs)` plays a significant role in the development process. SDKs provide tools, libraries, and documentation to simplify the creation of applications and smart contracts on the blockchain. Evaluating the maturity, community support, and compatibility of the available SDKs is crucial for developers. + +Considering these aspects helps in making an informed decision when selecting a blockchain that aligns with the specific requirements and goals of the project or application. + +Since all of these aspects are the focus of `Casper` ecosystem, it is also a perfect choice even for Enterprise grade projects. + From 34a6c12579d47b89a361ccafe5d1effdd4a35a0a Mon Sep 17 00:00:00 2001 From: ipopescu Date: Mon, 3 Jul 2023 23:39:34 +0200 Subject: [PATCH 02/62] Simplified title and introduction --- source/docs/casper/resources/migrate.md | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 339fa280cd..f7670f3db8 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -1,29 +1,22 @@ --- -title: Migrate from other chains +title: Moving to Casper from another Blockchain --- import useBaseUrl from '@docusaurus/useBaseUrl'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Moving from other chains to Casper{#migrate-to-casper} +# Moving to Casper {#moving-to-casper} -There are several blockchain projects available in different technologies. It's important to choose the right blockchain for a particular task. -The most popular blockchain projects in the market include: +This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects: -- `Ethereum` -- `Near` -- `Aptos` -- `Solana` - -We will compare them to Casper based on the following parameters: - -- Contract Lifecycle -- Variable Storage -- Public Methods -- Passing Arguments -- State Management +- [Contract Lifecycle](#contract-lifecycle) +- [Variable Storage](#variable-storage) +- [Public Methods](#public-methods) +- [Passing Arguments](#passing-arguments) +- [State Management](#state-management) +Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case. ## Contract Lifecycle{#contract-lifecycle} From 6c863084a2d519121048ab38333de752b2153b2f Mon Sep 17 00:00:00 2001 From: ipopescu Date: Mon, 3 Jul 2023 23:58:35 +0200 Subject: [PATCH 03/62] Summary update to additonal considerations --- source/docs/casper/resources/migrate.md | 31 +++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index f7670f3db8..87de705bcd 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -18,7 +18,9 @@ This page covers various considerations for moving to Casper from another blockc Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case. -## Contract Lifecycle{#contract-lifecycle} +When choosing a blockchain, it is also essential to compare consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and software development kits (SDKs) as described [here](#additional-considerations). + +## Contract Lifecycle {#contract-lifecycle} @@ -61,7 +63,7 @@ In Solana, smart contracts are commonly referred to as on-chain programs. These -## Variable Storage{#variable-storage} +## Variable Storage {#variable-storage} @@ -95,7 +97,7 @@ In terms of storage, the actual data is stored in the Account. It is organized a -## Public Methods{#public-methods} +## Public Methods {#public-methods} @@ -226,7 +228,7 @@ Within the entry point function, the necessary parameters are specified, such as -## Passing Arguments{#passing-arguments} +## Passing Arguments {#passing-arguments} @@ -292,7 +294,7 @@ By enforcing strong typing, the programming language ensures that the arguments -## State Management{#state-management} +## State Management {#state-management} @@ -324,21 +326,20 @@ Data is stored in structs within the account. These structs should be serialized -## Summary{#summary} - -While choosing a blockchain, there are additional aspects that need to be considered. These include consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and the availability of software development kits (SDKs). +## Additional Considerations {#additional-considerations} -`Consensus mechanism` refers to the algorithm used by the blockchain network to achieve agreement on the validity and ordering of transactions. Different blockchains employ various consensus mechanisms such as Proof of Work (PoW), Proof of Stake (PoS), or Delegated Proof of Stake (DPoS). The choice of consensus mechanism impacts factors like security, scalability, and energy efficiency. +When choosing a blockchain, you may also look into the network's consensus mechanism, the tokenomics or economic model, cross-contract communication, smart contract upgrades, and the available software development kits (SDKs). -`Tokenomics` relates to the economic model of the blockchain network and its native tokens. It involves aspects such as token distribution, inflation, utility, and governance. Understanding the tokenomics is crucial for evaluating the long-term viability and potential value of the blockchain ecosystem. +1. **Consensus mechanism** refers to the algorithm the blockchain network uses to achieve agreement on the validity and ordering of transactions. Different blockchains employ various consensus mechanisms such as Proof-of-Work (PoW), Proof-of-Stake (PoS), or Delegated Proof-of-Stake (DPoS). The choice of consensus mechanism impacts factors like security, scalability, and energy efficiency. -`Cross-contract` capabilities refer to the ability of smart contracts to interact and communicate with each other within the blockchain network. This feature is essential for building complex decentralized applications (DApps) and implementing inter-contract functionality. +2. **Tokenomics** relates to the economic model of the blockchain network and its native tokens, involving token distribution, inflation, utility, and governance. Understanding the tokenomics of the network is crucial for evaluating the ecosystem's long-term viability and potential value. -`Contract upgradability` determines whether the deployed smart contracts can be modified or updated after deployment. It is important to assess the flexibility of the chosen blockchain in terms of contract maintenance, bug fixes, and incorporating new features or improvements without disrupting the existing ecosystem. +3. **Cross-contract capabilities** refer to the ability of smart contracts to interact and communicate within the blockchain network. This feature is essential for building complex decentralized applications (dApps) and implementing inter-contract functionality. -Lastly, the availability of software `development kits (SDKs)` plays a significant role in the development process. SDKs provide tools, libraries, and documentation to simplify the creation of applications and smart contracts on the blockchain. Evaluating the maturity, community support, and compatibility of the available SDKs is crucial for developers. +4. **Contract upgradability** determines whether the smart contracts installed on the network can be modified or updated after installation. It is essential to assess the flexibility of the chosen blockchain in terms of contract maintenance, bug fixes, and incorporating new features or improvements without disrupting the existing ecosystem. -Considering these aspects helps in making an informed decision when selecting a blockchain that aligns with the specific requirements and goals of the project or application. +5. **SDK availability** also plays a significant role in the development process. SDKs provide tools, libraries, and documentation to simplify the creation of applications and smart contracts on the blockchain. Evaluating the maturity, community support, and compatibility of the available SDKs is crucial for developers. -Since all of these aspects are the focus of `Casper` ecosystem, it is also a perfect choice even for Enterprise grade projects. +Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals. +The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects. \ No newline at end of file From d1514e87c32dc0989437b84c286196e56ff1bba9 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:00:09 +0200 Subject: [PATCH 04/62] Shorten title in sidebar --- source/docs/casper/resources/migrate.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 87de705bcd..0b14fb5841 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -1,12 +1,12 @@ --- -title: Moving to Casper from another Blockchain +title: Moving to Casper --- import useBaseUrl from '@docusaurus/useBaseUrl'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -# Moving to Casper {#moving-to-casper} +# Moving to Casper from another Blockchain {#moving-to-casper} This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects: From 2bf2e97a906daa2e31877a3c9b93f292ecf8f036 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:00:50 +0200 Subject: [PATCH 05/62] Workaround for not having bullets --- source/docs/casper/resources/migrate.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 0b14fb5841..40e2dd9eae 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -10,11 +10,11 @@ import TabItem from '@theme/TabItem'; This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects: -- [Contract Lifecycle](#contract-lifecycle) -- [Variable Storage](#variable-storage) -- [Public Methods](#public-methods) -- [Passing Arguments](#passing-arguments) -- [State Management](#state-management) +1. [Contract Lifecycle](#contract-lifecycle) +2. [Variable Storage](#variable-storage) +3. [Public Methods](#public-methods) +4. [Passing Arguments](#passing-arguments) +5. [State Management](#state-management) Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case. From 64bdb7d59ddd5ea98247fce108bf4ef85c905abd Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:03:37 +0200 Subject: [PATCH 06/62] Remove extra space --- source/docs/casper/resources/migrate.md | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 40e2dd9eae..9c7ef2a3d1 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -105,7 +105,6 @@ In terms of storage, the actual data is stored in the Account. It is organized a Entry points are declared within the 'call' routine. To declare a public entry point, the following format is used: ```rust - #[no_mangle] pub extern "C" fn counter_inc() { let uref: URef = runtime::get_key(COUNT_KEY) @@ -115,7 +114,6 @@ pub extern "C" fn counter_inc() { storage::add(uref, 1); // Increment the count by 1. } - ``` It's important to note that entry points do not inherently have input arguments in their definition. If a return value is needed, it should be declared using the following syntax: @@ -134,19 +132,15 @@ On Ethereum, public methods serve two purposes: they can be used to execute cont The declaration of public methods in Ethereum follows the format: ```bash - function update_name(string value) public { dapp_name = value; } - ``` In cases where a public method only returns a value without modifying the state, it should be defined as follows: ```bash - function balanceOf(address _owner) public view returns (uint256 return_parameter) { } - ``` It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas. @@ -165,17 +159,13 @@ In the Near blockchain, there are three types of public functions: The definition of public methods in Near is as follows: ```rust - pub fn add_message(&mut self, ...) { } - ``` For public methods that return variables, the definition would be: ```rust - pub fn get_messages(&self, from_index: Option, limit: Option) -> Vec { } - ``` The actual implementation of the functions may include the necessary parameters and logic based on the specific requirements of the contract. @@ -186,17 +176,13 @@ The actual implementation of the functions may include the necessary parameters Public functions in Aptos are similar to public methods or functions found in other blockchain networks. The definition of a public function in Aptos appears as follows: ```rust - public fun start_collection(account: &signer) {} - ``` For public functions that return variables, the definition would be as follows: ```rust - public fun max(a: u8, b: u8): (u8, bool) {} - ``` In the Aptos Blockchain, it is possible to return one or more values from a function. @@ -207,9 +193,7 @@ In the Aptos Blockchain, it is possible to return one or more values from a func In Solana, functions are defined as public entry points that act as interfaces visible to the network. The declaration of an entry point follows this format: ```rust - entrypoint!(process_instruction); - ``` The implementation of the entry point may resemble the following: @@ -220,7 +204,6 @@ pub fn process_instruction( accounts: &[AccountInfo], _instruction_data: &[u8], ) -> ProgramResult {} - ``` Within the entry point function, the necessary parameters are specified, such as `program_id`, which represents the program's identifier, `accounts`, an array of `AccountInfo` providing account details, and `_instruction_data`, representing the instruction data received. The function returns a `ProgramResult`, which indicates the success or failure of the instruction execution. @@ -237,7 +220,6 @@ Within the entry point function, the necessary parameters are specified, such as Named arguments are passed as strings with type specifiers. To provide session arguments to the entry point during a Deploy, you can utilize the following approach: ```bash - casper-client put-deploy \ --node-address http://65.21.235.219:7777 \ --chain-name casper-test \ @@ -248,15 +230,12 @@ casper-client put-deploy \ --session-arg "validator:public_key='0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f'" \ --session-arg "amount:u512='500000000000'" \ --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'" - ``` In the contract, you can access the session arguments as follows: ```bash - let uref: URef = runtime::get_key(Key_Name) - ``` The `get_key` function can be used to retrieve the desired session argument by specifying its name or key. From 3345f800383a1d60c4fb4ebf1b6ba8746eef9b18 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:17:48 +0200 Subject: [PATCH 07/62] Updated contract lifecycle for Casper --- source/docs/casper/resources/migrate.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 9c7ef2a3d1..2d496cd6de 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -25,9 +25,13 @@ When choosing a blockchain, it is also essential to compare consensus mechanisms -Casper smart contracts are written in Rust. In Casper, variables defined within the smart contract can be stored as either Named Keys or [Dictionaries](../concepts/dictionaries.md). The `call` function serves as the constructor of the smart contract on the Casper network. It automatically executes when the smart contract is deployed, setting the initial state of the contract and defining all entry points. +Casper smart contracts are written in Rust. -It's worth noting that Casper only supports public entry points for [contracts](../developers/writing-onchain-code/simple-contract.md). Additionally, contracts can be defined as either immutable or upgradable. +Variables defined within the smart contract can be stored as either [Named Keys](../developers/json-rpc/types_chain.md#namedkey) or [Dictionaries](../concepts/dictionaries.md) as described in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). + +The `call` function serves as the main entry point of the [smart contract](../developers/writing-onchain-code/simple-contract.md). It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points. + +It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described [here](../developers/writing-onchain-code/upgrading-contracts.md). From a4d0d1d796d19d118fa3b4623adf035b8ff43d02 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:25:59 +0200 Subject: [PATCH 08/62] Updated Eth contract lifecycle --- source/docs/casper/resources/migrate.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 2d496cd6de..87a50b73bb 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -38,12 +38,11 @@ It's worth noting that Casper only supports public entry points for contracts. A Ethereum smart contracts are primarily written in Solidity, a programming language specifically designed for this purpose. These contracts comprise a collection of global variables that persist on the blockchain and define the contract's state. -Furthermore, Ethereum smart contracts feature a constructor that allows for the specification of an initial state after deployment on the blockchain. Public functions declared within the contract can be invoked from outside the blockchain. +Furthermore, Ethereum smart contracts feature a constructor that specifies an initial state after deployment on the blockchain. Public functions declared within the contract can be invoked from outside the blockchain. -In terms of immutability, Ethereum smart contracts are inherently immutable once deployed. However, there are design patterns available, such as "Proxy" or "Diamond," that facilitate versioning of contracts on the Ethereum blockchain. - -Smart contracts written in Solidity adhere to object-oriented programming principles and support features such as inheritance and libraries. +In terms of immutability, Ethereum smart contracts are inherently immutable once deployed. However, design patterns such as "Proxy" or "Diamond" facilitate versioning contracts on the Ethereum blockchain. +Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries. From abf9ae39d371ff807fbdb40ac28e795022e3e55c Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:26:17 +0200 Subject: [PATCH 09/62] Updated Near contract lifecycle --- source/docs/casper/resources/migrate.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 87a50b73bb..adbf0496b4 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -47,9 +47,13 @@ Solidity smart contracts adhere to object-oriented programming principles and su -Near smart contracts can be written in either JavaScript or Rust. Regardless of the chosen language, the Near SDK compiles the code to WebAssembly. In the Near ecosystem, smart contracts function as classes. The constructor, referred to as the "init" method, can receive attributes required for initializing the contract's initial state. +Near smart contracts can be written in JavaScript or Rust, and the Near SDK compiles the code to WebAssembly. -All public methods defined within the contract serve as the contract's interface, exposing its functionalities. In the Near blockchain, there are various capabilities for versioning. Examples of how updates are handled include state migrations, state versioning, and contract self-updates. +In the Near ecosystem, smart contracts function as classes. The constructor, referred to as the "init" method, can receive attributes required for initializing the contract's initial state. + +All public methods defined within the contract serve as its interface, exposing its functionality. + +The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates. From 79e70237bfdab1f665d1e34ee033d011a09fe8d7 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:31:41 +0200 Subject: [PATCH 10/62] Updated Solana contract lifecycle --- source/docs/casper/resources/migrate.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index adbf0496b4..db527dacac 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -58,14 +58,20 @@ The Near blockchain provides various capabilities for versioning, including stat -The Aptos programming language is known as Move. Its primary concepts revolve around scripts and modules. Scripts enable developers to incorporate additional logic into transactions, while modules allow them to expand blockchain functionality or create custom smart contracts. A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs. +The Aptos programming language is known as Move. Its primary concepts revolve around scripts and modules. Scripts enable developers to incorporate additional logic into transactions, while modules allow them to expand blockchain functionality or create custom smart contracts. + +A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs. -Solana smart contracts are primarily written in Rust. Unlike some other blockchain platforms, Solana's smart contracts are stateless and solely focus on program logic. The management of the contract state is handled at the account level. This means that there is a clear separation between the state stored within the account and the contract logic defined in the programs. +Solana smart contracts are primarily written in Rust. + +Unlike other blockchain platforms, Solana's smart contracts are stateless and solely focus on program logic. The management of the contract state is handled at the account level, separating the state stored within the account and the contract logic defined in the programs. + +Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction. -In Solana, smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction. It is worth noting that Solana programs can be updated through the use of an authority known as the "update authority," which holds the necessary permissions for making modifications to the program. +It is worth noting that Solana programs can be updated using an authority known as the "update authority," which holds the necessary permissions for making modifications to the program. From a6757619161a7e207a0d5e95b3c4fa752b40654a Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:40:21 +0200 Subject: [PATCH 11/62] Updated variable storage for other chains --- source/docs/casper/resources/migrate.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index db527dacac..73d2c56c1b 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -81,8 +81,9 @@ It is worth noting that Solana programs can be updated using an authority known +Variables can be stored as Named Keys or Dictionaries as described in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). -The variables can be stored either as Named Keys or [Dictionaries](../concepts/dictionaries.md). Additionally, local variables are available within the entry points and can be utilized to perform necessary actions or computations within the scope of each entry point. +Additionally, local variables are available within the entry points and can be utilized to perform necessary actions or computations within the scope of each entry point. @@ -92,17 +93,19 @@ The variables within the contract are responsible for storing the state of the c -The variables in the contract can be stored as native types, SDK collections, or internal structures. It is recommended to use SDK collections whenever feasible, as they offer advantages over native types. Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state. +The variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types. + +Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state. -Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules. For storing important or relevant data, Aptos encourages the use of Resources. Resources serve as a specialized type for managing and storing significant data in an efficient manner. +Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules. For storing important or relevant data, Aptos encourages using Resources, which are specialized types for managing and storing important data efficiently. -Variables can be utilized locally within the context of a specific entry point being executed. They are limited to the scope of that entry point and not accessible outside of it. These variables can be defined as elementary types such as bool, String, int, and so on. +Variables can be utilized locally within the execution context of a specific entry point. They are limited to the scope of that entry point and not accessible outside of it. These variables can be defined as elementary types such as bool, String, int, etc. In terms of storage, the actual data is stored in the Account. It is organized as a struct comprising related variables, allowing for efficient management and retrieval of the stored information. From 2f231ee8ec1334b4ac9833fe92e02fee58cb266d Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:54:36 +0200 Subject: [PATCH 12/62] Updated public methods for Casper --- source/docs/casper/resources/migrate.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 73d2c56c1b..3eef1b1ed0 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -118,27 +118,25 @@ In terms of storage, the actual data is stored in the Account. It is organized a -Entry points are declared within the 'call' routine. To declare a public entry point, the following format is used: +For Casper smart contracts, public methods are called entry points. To declare them, the following format is used: ```rust #[no_mangle] pub extern "C" fn counter_inc() { - let uref: URef = runtime::get_key(COUNT_KEY) - .unwrap_or_revert_with(ApiError::MissingKey) - .into_uref() - .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant); - storage::add(uref, 1); // Increment the count by 1. + // Entry point body } ``` -It's important to note that entry points do not inherently have input arguments in their definition. If a return value is needed, it should be declared using the following syntax: +It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the [RuntimeArgs](https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html) passed to the contract. Entry points are instantiated within the `call` entry point. + +If a return value is needed, it should be declared using the following syntax described in the [Interacting with Runtime Return Values](../resources/tutorials/advanced/return-values-tutorial.md) tutorial. ```rust runtime::ret(value); ``` -In the Casper networks, each call to an entry point is treated as a [Deploy](../concepts/deploy-and-deploy-lifecycle.md) to the network, and therefore, each call incurs a certain amount of mots (the network's native currency). +Each call to an entry point is treated as a [Deploy](../concepts/deploy-and-deploy-lifecycle.md) to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit). From d2469ced8e62d05f597136090476213728f32dd9 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 00:59:52 +0200 Subject: [PATCH 13/62] Minor updates to the rest of the public methods --- source/docs/casper/resources/migrate.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 3eef1b1ed0..82750792ed 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -164,11 +164,9 @@ It is worth noting that public view methods on Ethereum, which solely retrieve d In the Near blockchain, there are three types of public functions: -`Init Methods`: These are used as the class constructors to initialize the state of the contract. - -`View Methods`: These functions are used to read the state of the contract variables. - -`Call Methods`: These methods can mutate the state of the contract and perform specific actions, such as calling another contract. +- **Init Methods** - These are used as the class constructors to initialize the state of the contract. +- **View Methods** - These functions are used to read the state of the contract variables. +- **Call Methods** - These methods can mutate the state of the contract and perform specific actions, such as calling another contract. The definition of public methods in Near is as follows: @@ -182,7 +180,7 @@ For public methods that return variables, the definition would be: pub fn get_messages(&self, from_index: Option, limit: Option) -> Vec { } ``` -The actual implementation of the functions may include the necessary parameters and logic based on the specific requirements of the contract. +The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements. @@ -199,7 +197,7 @@ For public functions that return variables, the definition would be as follows: public fun max(a: u8, b: u8): (u8, bool) {} ``` -In the Aptos Blockchain, it is possible to return one or more values from a function. +In the Aptos blockchain, it is possible to return one or more values from a function. From bd0bbfb1a73f67f48607fc1d3b77a8fe100f8ca0 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 11:41:41 +0200 Subject: [PATCH 14/62] Updated state management for all --- source/docs/casper/resources/migrate.md | 66 ++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 82750792ed..6e636dbfa4 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -290,29 +290,83 @@ By enforcing strong typing, the programming language ensures that the arguments -Data is persisted in Named Keys and [Dictionaries](../concepts/dictionaries.md) in the context of a contract or an account. +Data persists in Named Keys and Dictionaries in a contract or an account's context. See more details in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). -Data is persisted in a storage represented by state variables within the smart contract. These state variables need to be strongly typed to allocate the appropriate amount of space for them in the storage. +Data persists in state variables within the smart contract. These state variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. -By using strong typing, the smart contract compiler can enforce type consistency and ensure that the allocated storage space aligns with the declared data types. This promotes code correctness and prevents potential data corruption or memory-related issues when interacting with the contract's state variables. + + + +SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. + + + + +Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. + + + + +Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. + + +## State Management {#state-management} + + + + +Data persists in Named Keys and Dictionaries in a contract or an account's context. See more details in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). + + + + +Data persists in state variables within the smart contract. These state variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. + + + + +SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. + + + + +Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. + + + + +Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. + + +## State Management {#state-management} + + + + +Data persists in Named Keys and Dictionaries in a contract or an account's context. See more details in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). + + + + +Data persists in state variables within the smart contract. These state variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. -When creating state variables, it is advisable to use SDK Collections. SDK Collections provide convenient data structures, such as lists, maps, and sets, which can be used to organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage management and facilitates easier access and manipulation of data in the smart contract. +SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. -To facilitate efficient data management and organization, it is advisable to cluster related data into Resources. Resources are a special type of structure that represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve readability and maintainability of the code. +Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. -Data is stored in structs within the account. These structs should be serialized and deserialized using Borsh. The process involves reading the data from the account, deserializing it to obtain the values, updating the values, and then serializing the modified data to save the new values back into the account. +Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. From 5d8e49aaad12d3f8e07653c41ccd35289be36d65 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Tue, 4 Jul 2023 12:06:05 +0200 Subject: [PATCH 15/62] Update passing arguments; fix copy/paste error --- source/docs/casper/resources/migrate.md | 75 ++----------------------- 1 file changed, 6 insertions(+), 69 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 6e636dbfa4..6f19251d64 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -250,37 +250,29 @@ In the contract, you can access the session arguments as follows: let uref: URef = runtime::get_key(Key_Name) ``` -The `get_key` function can be used to retrieve the desired session argument by specifying its name or key. +Use the `get_key` function to retrieve the desired session argument by specifying the key's name. -Strongly typed function arguments, where both the input and return variables need to be explicitly defined. The compiler checks the correctness of the arguments passed to the functions during runtime. - -This means that the types of the function arguments, as well as the return types, must be explicitly specified in the function signature. The compiler ensures that the provided arguments adhere to the specified types, helping to catch type-related errors and ensure type safety. +Ethereum uses strongly typed function arguments, and developers must explicitly define the input and return variables. The compiler checks the correctness of the arguments passed to the functions during runtime. As a result, developers must explicitly specify the argument and return types in the function signature. The compiler ensures that the provided arguments adhere to the specified types, helping to catch type-related errors and ensure type safety. By enforcing strong typing, the compiler helps prevent potential runtime errors and enhances code reliability by verifying the compatibility of the passed arguments and expected return types. -Strongly typed function arguments require explicit definition of both the input and return variables. - -By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. +Strongly typed function arguments require explicitly defining the input and return variables. By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. -Strongly typed function arguments require explicit definition of both the input and return variables. - -By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. +Like Near, Aptos requires strongly typed function arguments, thus, preventing type-related errors and promoting code correctness. -Strongly typed function arguments require explicit definition of both the input and return variables. - -By enforcing strong typing, the programming language ensures that the arguments passed to a function match the expected types, preventing type-related errors and promoting code correctness. Strong typing provides additional clarity and safety by explicitly stating the data types of the function's inputs and outputs. +Like Near and Aptos, Solana requires strongly typed function arguments, thus, preventing type-related errors and promoting code correctness. @@ -312,65 +304,10 @@ Aptos advises developers to cluster related data into Resources for efficient da Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. - -## State Management {#state-management} - - - - -Data persists in Named Keys and Dictionaries in a contract or an account's context. See more details in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). - - - - -Data persists in state variables within the smart contract. These state variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. - - - - -SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. - - - - -Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. - - - - -Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. - - -## State Management {#state-management} - - - - -Data persists in Named Keys and Dictionaries in a contract or an account's context. See more details in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). - - - - -Data persists in state variables within the smart contract. These state variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. - - - - -SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. - - - - -Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. - - - - -Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. - + ## Additional Considerations {#additional-considerations} When choosing a blockchain, you may also look into the network's consensus mechanism, the tokenomics or economic model, cross-contract communication, smart contract upgrades, and the available software development kits (SDKs). From 344d01662998eb4dd39c961678ab6a78a50a5ad7 Mon Sep 17 00:00:00 2001 From: Iulia Popescu Date: Thu, 6 Jul 2023 17:01:22 +0200 Subject: [PATCH 16/62] Review feedback Co-authored-by: Adam Stone <97986246+ACStoneCL@users.noreply.github.com> --- source/docs/casper/resources/migrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 6f19251d64..82005ca8e4 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -83,7 +83,7 @@ It is worth noting that Solana programs can be updated using an authority known Variables can be stored as Named Keys or Dictionaries as described in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). -Additionally, local variables are available within the entry points and can be utilized to perform necessary actions or computations within the scope of each entry point. +Additionally, local variables are available within the entry points and can be used to perform necessary actions or computations within the scope of each entry point. From 2496d9b7334bdf0bfbb66d029078ea54d60650c2 Mon Sep 17 00:00:00 2001 From: Iulia Popescu Date: Thu, 6 Jul 2023 17:01:41 +0200 Subject: [PATCH 17/62] Review feedback Co-authored-by: Adam Stone <97986246+ACStoneCL@users.noreply.github.com> --- source/docs/casper/resources/migrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 82005ca8e4..7b8df9875d 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -93,7 +93,7 @@ The variables within the contract are responsible for storing the state of the c -The variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types. +Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types. Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state. From 3e68492a37079f0d77ad25a1564de8784567d503 Mon Sep 17 00:00:00 2001 From: Iulia Popescu Date: Thu, 6 Jul 2023 17:01:57 +0200 Subject: [PATCH 18/62] Review feedback Co-authored-by: Adam Stone <97986246+ACStoneCL@users.noreply.github.com> --- source/docs/casper/resources/migrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 7b8df9875d..3c9d8425c1 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -292,7 +292,7 @@ Data persists in state variables within the smart contract. These state variable -SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Utilizing SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. +SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Using SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. From 3db4b082409ea1d92e6bca46147729d4e64fb73c Mon Sep 17 00:00:00 2001 From: Karol Marter Date: Sun, 23 Jul 2023 20:24:25 +0200 Subject: [PATCH 19/62] 1176 - Migrate from other chains - corrections after editing pass --- source/docs/casper/resources/migrate.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 3c9d8425c1..0f47e53269 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -10,9 +10,9 @@ import TabItem from '@theme/TabItem'; This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects: -1. [Contract Lifecycle](#contract-lifecycle) +1. [Smart Contract Platform Overview](#contract-overview) 2. [Variable Storage](#variable-storage) -3. [Public Methods](#public-methods) +3. [Contract Functions](#contract-functions) 4. [Passing Arguments](#passing-arguments) 5. [State Management](#state-management) @@ -20,7 +20,7 @@ Since other blockchain projects use different technologies, it is essential to c When choosing a blockchain, it is also essential to compare consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and software development kits (SDKs) as described [here](#additional-considerations). -## Contract Lifecycle {#contract-lifecycle} +## Contract Lifecycle {#contract-overview} @@ -47,7 +47,7 @@ Solidity smart contracts adhere to object-oriented programming principles and su -Near smart contracts can be written in JavaScript or Rust, and the Near SDK compiles the code to WebAssembly. +Near smart contracts can be written in JavaScript or Rust, and the Near SDK can pack the code with lightweight runtime. This can be compiled into a single WebAssembly file and deployed on the NEAR network. In the Near ecosystem, smart contracts function as classes. The constructor, referred to as the "init" method, can receive attributes required for initializing the contract's initial state. @@ -113,12 +113,12 @@ In terms of storage, the actual data is stored in the Account. It is organized a -## Public Methods {#public-methods} +## Contract Functions {#contract-functions} -For Casper smart contracts, public methods are called entry points. To declare them, the following format is used: +For Casper smart contracts, public functions are called entry points. To declare them, the following format is used: ```rust #[no_mangle] @@ -244,13 +244,17 @@ casper-client put-deploy \ --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'" ``` +To understand the context of this example please refer to: [Delegating with the Casper Client](../developers/cli/delegate.md). + In the contract, you can access the session arguments as follows: ```bash let uref: URef = runtime::get_key(Key_Name) ``` -Use the `get_key` function to retrieve the desired session argument by specifying the key's name. +Use the `get_key` function to retrieve the desired session argument by specifying the key's name. + +If you are uncertain, how to use the `get_key` function to obtain a specific session argument, check how to [write a basic smart contract on Casper](../developers/writing-onchain-code/simple-contract.md). From 243367b0053e021aa72e9d1d0096f127f67ed4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Mon, 24 Jul 2023 12:07:40 +0200 Subject: [PATCH 20/62] Update links to match new resources structure --- source/docs/casper/resources/migrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/migrate.md index 0f47e53269..b02b56de82 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/migrate.md @@ -130,7 +130,7 @@ pub extern "C" fn counter_inc() { It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the [RuntimeArgs](https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html) passed to the contract. Entry points are instantiated within the `call` entry point. -If a return value is needed, it should be declared using the following syntax described in the [Interacting with Runtime Return Values](../resources/tutorials/advanced/return-values-tutorial.md) tutorial. +If a return value is needed, it should be declared using the following syntax described in the [Interacting with Runtime Return Values](../resources/advanced/return-values-tutorial.md) tutorial. ```rust runtime::ret(value); From 15531d591f46933bcc188daf17d85a4042824afd Mon Sep 17 00:00:00 2001 From: Adam Stone <97986246+ACStoneCL@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:55:05 -0400 Subject: [PATCH 21/62] PublicKey Updates --- source/docs/casper/concepts/hash-types.md | 2 +- source/docs/casper/concepts/serialization-standard.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/docs/casper/concepts/hash-types.md b/source/docs/casper/concepts/hash-types.md index 4613716c11..c1b24529b8 100644 --- a/source/docs/casper/concepts/hash-types.md +++ b/source/docs/casper/concepts/hash-types.md @@ -34,7 +34,7 @@ For the sake of user convenience and compatibility, we expect the delivery of ha ## Hash and Key Explanations {#hash-and-key-explanations} -`PublicKey` is a 32 byte asymmetric public key, preceded by a one-byte prefix that tells whether the key is `ed25519` or `secp256k1`. +`PublicKey` is a 32 byte asymmetric public key, preceded by a one-byte prefix that tells whether the key is `ed25519` or `secp256k1`. There is a third type of `PublicKey` that refers to system contracts and it is a single `00`. `AccountHash` is a 32 byte hash of the `PublicKey` serving to identify user accounts. diff --git a/source/docs/casper/concepts/serialization-standard.md b/source/docs/casper/concepts/serialization-standard.md index e44c404ce1..a526046238 100644 --- a/source/docs/casper/concepts/serialization-standard.md +++ b/source/docs/casper/concepts/serialization-standard.md @@ -745,6 +745,7 @@ A `Map` serializes as a list of key-value tuples. There must be a well-defined o `PublicKey` serializes as a single byte tag representing the algorithm followed by 32 bytes of the `PublicKey` itself: +- If the `PublicKey` is a `System` key, the single tag byte is `0`. With this variant, the single byte of `0` is the entire key. - If the `PublicKey` is an `Ed25519` key, the single tag byte is `1` followed by the individual bytes of the serialized key. - If the `PublicKey` is a `Secp256k1` key, the single tag byte is a `2` followed by the individual bytes of the serialized key. From c9d822c3b8b6bbd01148bc3eef47c0f6bb159b60 Mon Sep 17 00:00:00 2001 From: Adam Stone <97986246+ACStoneCL@users.noreply.github.com> Date: Fri, 8 Sep 2023 08:12:23 -0400 Subject: [PATCH 22/62] Update source/docs/casper/concepts/hash-types.md Co-authored-by: Karan Dhareshwar <42871449+darthsiroftardis@users.noreply.github.com> --- source/docs/casper/concepts/hash-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/concepts/hash-types.md b/source/docs/casper/concepts/hash-types.md index c1b24529b8..79ee6257bf 100644 --- a/source/docs/casper/concepts/hash-types.md +++ b/source/docs/casper/concepts/hash-types.md @@ -34,7 +34,7 @@ For the sake of user convenience and compatibility, we expect the delivery of ha ## Hash and Key Explanations {#hash-and-key-explanations} -`PublicKey` is a 32 byte asymmetric public key, preceded by a one-byte prefix that tells whether the key is `ed25519` or `secp256k1`. There is a third type of `PublicKey` that refers to system contracts and it is a single `00`. +`PublicKey` is a 32 byte asymmetric public key, preceded by a one-byte prefix that tells whether the key is `ed25519` or `secp256k1`. There is a third type of `PublicKey` that refers to the system and it is a single `00`. `AccountHash` is a 32 byte hash of the `PublicKey` serving to identify user accounts. From 21491ff294dd70bfb089318b5733dece80e8c249 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Mon, 11 Sep 2023 12:14:44 +0200 Subject: [PATCH 23/62] Refresh the fast sync intro --- .../operators/becoming-a-validator/fast-sync.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/docs/casper/operators/becoming-a-validator/fast-sync.md b/source/docs/casper/operators/becoming-a-validator/fast-sync.md index 03be1b7fbf..5c5d09ed2e 100644 --- a/source/docs/casper/operators/becoming-a-validator/fast-sync.md +++ b/source/docs/casper/operators/becoming-a-validator/fast-sync.md @@ -1,18 +1,20 @@ --- -title: Fast-Sync +title: Fast Sync --- -# Introducing Fast-Sync +# Introducing Fast Sync import useBaseUrl from '@docusaurus/useBaseUrl'; -The Casper Network is a smart contract platform. It requires new nodes to download and execute each and every block to join the network. Starting from genesis (start of the Mainnet), the node executes each deploy in every block. This process continues until the node has arrived at the current state of the blockchain. This process to sync a node with the blockchain can take a very long time. +A Casper Network requires new nodes to download and execute every block to join the network. From genesis (start of the Mainnet), the node executes each deploy in every block. This process continues until the node has arrived at the current state of the blockchain. Syncing a node this way can take a very long time. -To provide an alternative and faster approach to joining a Casper network, we have introduced fast‑sync. Fast-sync does not start syncing at the genesis block; instead, the user verifies a recent block, e.g. using block explorers, and provides its hash to the node software. The network [global state](../../concepts/design/casper-design.md#global-state-head) — smart contract data, account balances and all other on-chain information — is the storage layer of the blockchain and is massive in size, so fast-sync downloads the global state of only the most recent block. The following section briefly describes the fast-sync process. +We have introduced a fast syncing process (fast sync) to provide a faster alternative to joining a Casper network. Fast sync does not start syncing at the genesis block; instead, the operator verifies a recent block and provides a [trusted hash](../setup/basic-node-configuration.md#trusted-hash-for-synchronizing) to the node software. The global state, account balances, and all other on-chain information is the storage layer of the blockchain and is massive in size, so fast sync downloads the global state of only the most recent block. The following section briefly describes the fast sync process. ## How Fast-sync Works -For fast-sync, you need to provide the trusted hash of a block on a Casper network in the config.toml file. Fast-sync uses this trusted block as part of the cryptographic verification for the later blocks. This trusted block is downloaded, as are all newer blocks up to and including the most recent block from the current era. For example, if the trusted block hash is 5 hours old, it will first download that block, then newer blocks until it arrives at one that is only a few minutes old. It then downloads the newer block's global state. Finally, it executes all blocks the network created while the download was in progress, until it is fully in sync. +For fast sync, operators must provide the trusted hash of a block in the `config.toml` file. An example can be found [here](). + +Fast sync uses this trusted block as part of the cryptographic verification for the later blocks. The node downloads the trusted block first, then newer blocks up to and including the most recent block from the current era. For example, if the trusted hash is 5 hours old, it will first download that block, then newer blocks, until it arrives at one that is only a few minutes old. It then downloads the newer block's global state. Finally, it executes all the blocks the network created while the download was in progress until it is entirely in sync. From afba7fbc28ad7a69e08c0eb1ce6e1b40a1f76a9f Mon Sep 17 00:00:00 2001 From: ipopescu Date: Mon, 11 Sep 2023 12:18:02 +0200 Subject: [PATCH 24/62] Move file to setup section; update link --- config/sidebar.config.js | 1 + .../operators/{becoming-a-validator => setup}/fast-sync.md | 4 ++-- source/docs/casper/operators/setup/install-node.md | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename source/docs/casper/operators/{becoming-a-validator => setup}/fast-sync.md (88%) diff --git a/config/sidebar.config.js b/config/sidebar.config.js index af90d00804..bb14b2191b 100644 --- a/config/sidebar.config.js +++ b/config/sidebar.config.js @@ -225,6 +225,7 @@ module.exports = { "operators/setup/basic-node-configuration", "operators/setup/node-endpoints", "operators/setup/install-node", + "operators/setup/fast-sync", "operators/setup/open-files", "operators/setup/upgrade", "operators/setup/joining", diff --git a/source/docs/casper/operators/becoming-a-validator/fast-sync.md b/source/docs/casper/operators/setup/fast-sync.md similarity index 88% rename from source/docs/casper/operators/becoming-a-validator/fast-sync.md rename to source/docs/casper/operators/setup/fast-sync.md index 5c5d09ed2e..7614eb400b 100644 --- a/source/docs/casper/operators/becoming-a-validator/fast-sync.md +++ b/source/docs/casper/operators/setup/fast-sync.md @@ -10,11 +10,11 @@ A Casper Network requires new nodes to download and execute every block to join We have introduced a fast syncing process (fast sync) to provide a faster alternative to joining a Casper network. Fast sync does not start syncing at the genesis block; instead, the operator verifies a recent block and provides a [trusted hash](../setup/basic-node-configuration.md#trusted-hash-for-synchronizing) to the node software. The global state, account balances, and all other on-chain information is the storage layer of the blockchain and is massive in size, so fast sync downloads the global state of only the most recent block. The following section briefly describes the fast sync process. -## How Fast-sync Works +## How Fast Sync Works -For fast sync, operators must provide the trusted hash of a block in the `config.toml` file. An example can be found [here](). +For fast sync, operators must provide the trusted hash of a block in the `config.toml` file. An example can be found [here](https://github.com/casper-network/casper-node/blob/f7d8228de3cb56a3fe705f5a787d3dbf03ff7998/resources/production/config-example.toml#L7). Fast sync uses this trusted block as part of the cryptographic verification for the later blocks. The node downloads the trusted block first, then newer blocks up to and including the most recent block from the current era. For example, if the trusted hash is 5 hours old, it will first download that block, then newer blocks, until it arrives at one that is only a few minutes old. It then downloads the newer block's global state. Finally, it executes all the blocks the network created while the download was in progress until it is entirely in sync. diff --git a/source/docs/casper/operators/setup/install-node.md b/source/docs/casper/operators/setup/install-node.md index 39026d495e..8e080ac82d 100644 --- a/source/docs/casper/operators/setup/install-node.md +++ b/source/docs/casper/operators/setup/install-node.md @@ -119,7 +119,7 @@ For more details, see the [Node Setup](./basic-node-configuration.md#create-fund ## Getting a Trusted Hash -In the past, we have used a lower `trusted_hash`. Connecting at the tip, we now use as high of a `trusted_hash` as possible. +In the past, we have used a lower `trusted_hash`. Connecting at the tip, we now use as high of a `trusted_hash` as possible. Find out more about [Fast Sync](./fast-sync.md). ### Node Address From aaaa26f95de3438bd3a568dd553dac28c5c2edda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Mon, 11 Sep 2023 20:11:13 +0200 Subject: [PATCH 25/62] Unify summary style to use non-bold font. All `...` are simply replaced with `...`. --- .../developers/cli/calling-contracts.md | 2 +- .../developers/cli/installing-contracts.md | 8 +-- .../developers/cli/querying-global-state.md | 8 +-- .../cli/transfers/verify-transfer.md | 4 +- .../json-rpc/json-rpc-informational.md | 52 +++++++++---------- .../developers/json-rpc/json-rpc-pos.md | 12 ++--- .../json-rpc/json-rpc-transactional.md | 8 +-- .../writing-onchain-code/best-practices.md | 2 +- .../operators/becoming-a-validator/bonding.md | 2 +- .../casper/operators/setup/node-endpoints.md | 4 +- .../resources/advanced/cross-contract.md | 4 +- .../casper/resources/advanced/list-cspr.md | 2 +- .../resources/beginner/upgrade-contract.md | 8 +-- 13 files changed, 58 insertions(+), 58 deletions(-) diff --git a/source/docs/casper/developers/cli/calling-contracts.md b/source/docs/casper/developers/cli/calling-contracts.md index 144a48843e..c8efd84544 100644 --- a/source/docs/casper/developers/cli/calling-contracts.md +++ b/source/docs/casper/developers/cli/calling-contracts.md @@ -68,7 +68,7 @@ The payment amount varies based on each deploy and network [chainspec](../../con The following sample response contains a `deploy_hash`, needed to verify the changes in global state, as described [here](./installing-contracts.md#querying-global-state).
-Sample response +Sample response ```rust { diff --git a/source/docs/casper/developers/cli/installing-contracts.md b/source/docs/casper/developers/cli/installing-contracts.md index 1f4dcf75fc..13fee67ab1 100644 --- a/source/docs/casper/developers/cli/installing-contracts.md +++ b/source/docs/casper/developers/cli/installing-contracts.md @@ -123,7 +123,7 @@ casper-client query-global-state \ Here is how your account state would look. Notice that the sample response contains several named keys, including "counter", "counter_package_name", and "version". You can use these values to query the contract state further, as shown in the next example.
-Sample account state +Sample account state ```bash { @@ -197,7 +197,7 @@ casper-client query-global-state \ Here is how the sample contract would look and would contain details such as the `contract_package_hash`, the contract `entry_points`, and the `named_keys` for the contract.
-Sample contract state +Sample contract state ```bash { @@ -257,7 +257,7 @@ casper-client query-global-state \ ```
-Sample stored value +Sample stored value ```bash { @@ -308,7 +308,7 @@ casper-client query-global-state \ Here is how the contract package details would look. The response would contain the `contract_hash`, which you would need to [call a contract by hash](./calling-contracts.md#calling-contracts-by-hash) in the next section. You would also see the `access_key` for the `ContractPackage` and the current `contract_version`.
-Sample contract package state +Sample contract package state ```bash { diff --git a/source/docs/casper/developers/cli/querying-global-state.md b/source/docs/casper/developers/cli/querying-global-state.md index d8df350da1..73f21320c7 100644 --- a/source/docs/casper/developers/cli/querying-global-state.md +++ b/source/docs/casper/developers/cli/querying-global-state.md @@ -60,7 +60,7 @@ casper-client query-global-state \ Here is how your account state would look. Notice that the sample response contains several named keys, including "counter", "counter_package_name", and "version". You can use these values to query the contract state further, as shown in the next example.
-Sample account state +Sample account state ```bash { @@ -134,7 +134,7 @@ casper-client query-global-state \ Here is how the sample contract would look and would contain details such as the `contract_package_hash`, the contract `entry_points`, and the `named_keys` for the contract.
-Sample contract state +Sample contract state ```bash { @@ -194,7 +194,7 @@ casper-client query-global-state \ ```
-Sample stored value +Sample stored value ```bash { @@ -245,7 +245,7 @@ casper-client query-global-state \ Here is how the contract package details would look. The response would contain the `contract_hash`, which you would need to [call a contract by hash](./calling-contracts.md#calling-contracts-by-hash) in the next section. You would also see the `access_key` for the `ContractPackage` and the current `contract_version`.
-Sample contract package state +Sample contract package state ```bash { diff --git a/source/docs/casper/developers/cli/transfers/verify-transfer.md b/source/docs/casper/developers/cli/transfers/verify-transfer.md index d07abe827b..7764c57b28 100644 --- a/source/docs/casper/developers/cli/transfers/verify-transfer.md +++ b/source/docs/casper/developers/cli/transfers/verify-transfer.md @@ -42,7 +42,7 @@ casper-client query-global-state \ - `key` - The base key for the query. This must be a properly formatted transfer address.
-Explore the JSON-RPC request and response generated. +Explore the JSON-RPC request and response generated. **JSON-RPC Request**: @@ -97,7 +97,7 @@ casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS] ```
-Sample output of the get-state-root-hash command +Sample output of the get-state-root-hash command ```json { diff --git a/source/docs/casper/developers/json-rpc/json-rpc-informational.md b/source/docs/casper/developers/json-rpc/json-rpc-informational.md index b802e71f10..0067492d7b 100644 --- a/source/docs/casper/developers/json-rpc/json-rpc-informational.md +++ b/source/docs/casper/developers/json-rpc/json-rpc-informational.md @@ -15,7 +15,7 @@ This method returns the JSON representation of a [Block](../../concepts/design/c
-Example chain_get_block request +Example chain_get_block request ```bash @@ -45,7 +45,7 @@ The result from `chain_get_block` depends on block availability from a given nod
-Example chain_get_block result +Example chain_get_block result ```bash @@ -128,7 +128,7 @@ This method returns all **successful** native transfers within a given [Block](.
-Example chain_get_block_transfers request +Example chain_get_block_transfers request ```bash @@ -156,7 +156,7 @@ This method returns all **successful** native transfers within a given [Block](.
-Example chain_get_block_transfers result +Example chain_get_block_transfers result ```bash @@ -195,7 +195,7 @@ This method returns the era summary at a given [Block](../../concepts/design/cas
-Example chain_get_era_summary request +Example chain_get_era_summary request ```bash @@ -223,7 +223,7 @@ This method returns the era summary at a given [Block](../../concepts/design/cas
-Example chain_get_era_summary result +Example chain_get_era_summary result ```bash @@ -326,7 +326,7 @@ This method returns a state root hash at a given [Block](../../concepts/design/c
-Example chain_get_state_root_hash request +Example chain_get_state_root_hash request ```bash @@ -354,7 +354,7 @@ This method returns a state root hash at a given [Block](../../concepts/design/c
-Example chain_get_state_root_hash result +Example chain_get_state_root_hash result ```bash @@ -377,7 +377,7 @@ This method returns raw bytes for chainspec files.
-Example info_get_chainspec request +Example info_get_chainspec request ```bash @@ -400,7 +400,7 @@ This method returns raw bytes for chainspec files.
-Example info_get_chainspec result +Example info_get_chainspec result Please note that adding a `--vv` flag will return the full chainspec bytes. @@ -434,7 +434,7 @@ This method retrieves a [Deploy](../../concepts/design/casper-design.md#executio
-Example info_get_deploy request +Example info_get_deploy request ```bash @@ -466,7 +466,7 @@ If the `execution_results` field is empty, it means that the network processed t
-Example info_get_deploy result +Example info_get_deploy result ```bash @@ -581,7 +581,7 @@ This method allows you to query for the balance of a purse using a `PurseIdentif
-Example query_balance request +Example query_balance request ```bash { @@ -618,7 +618,7 @@ This method allows you to query for the balance of a purse using a `PurseIdentif
-Example query_balance result +Example query_balance result ```bash @@ -649,7 +649,7 @@ This method allows for you to query for a value stored under certain keys in glo
-Example query_global_state request +Example query_global_state request ```bash @@ -681,7 +681,7 @@ This method allows for you to query for a value stored under certain keys in glo
-Example query_global_state result +Example query_global_state result ```bash @@ -767,7 +767,7 @@ This method returns a JSON representation of an [Account](../../concepts/design/
-Example state_get_account_info request +Example state_get_account_info request ```bash @@ -797,7 +797,7 @@ This method returns a JSON representation of an [Account](../../concepts/design/
-Example state_get_account_info result +Example state_get_account_info result ```bash @@ -843,7 +843,7 @@ For instance, one native layer-1 token of the Casper Mainnet [CSPR](../../concep |purse_uref|String|Formatted URef.|
-Example state_get_balance request +Example state_get_balance request ```bash @@ -870,7 +870,7 @@ For instance, one native layer-1 token of the Casper Mainnet [CSPR](../../concep |[merkle_proof](types_chain.md#merkle-proof)|String|The merkle proof.|
-Example state_get_balance result +Example state_get_balance result ```bash @@ -901,7 +901,7 @@ You may query a stored value directly using the dictionary address.
-Example state_get_dictionary_item request +Example state_get_dictionary_item request ```bash @@ -935,7 +935,7 @@ You may query a stored value directly using the dictionary address.
-Example state_get_dictionary_item result +Example state_get_dictionary_item result ```bash @@ -975,7 +975,7 @@ This method returns a list of peers connected to the node.
-Example info_get_peers request +Example info_get_peers request ```bash @@ -999,7 +999,7 @@ This method returns a list of peers connected to the node.
-Example info_get_peers result +Example info_get_peers result ```bash @@ -1027,7 +1027,7 @@ This method returns the current status of a node.
-Example info_get_status request +Example info_get_status request ```bash @@ -1063,7 +1063,7 @@ This method returns the current status of a node.
-Example info_get_status result +Example info_get_status result ```bash diff --git a/source/docs/casper/developers/json-rpc/json-rpc-pos.md b/source/docs/casper/developers/json-rpc/json-rpc-pos.md index dc4e58d185..946f270ceb 100644 --- a/source/docs/casper/developers/json-rpc/json-rpc-pos.md +++ b/source/docs/casper/developers/json-rpc/json-rpc-pos.md @@ -14,7 +14,7 @@ This method returns the [bids](../../concepts/economics/consensus.md#bids) and [
-Example state_get_auction_info request +Example state_get_auction_info request ```bash @@ -42,7 +42,7 @@ This method returns the [bids](../../concepts/economics/consensus.md#bids) and [
-Example state_get_auction_info result +Example state_get_auction_info result ```bash @@ -102,7 +102,7 @@ Potential change types:
-Example info_get_validator_changes request +Example info_get_validator_changes request ```bash @@ -128,7 +128,7 @@ If no changes occurred in the current era, `info_get_validator_changes` will ret
-Example info_get_validator_changes result +Example info_get_validator_changes result ```bash @@ -165,7 +165,7 @@ This method returns an EraInfo from the network. Only the last Block in an `era`
-Example chain_get_era_info_by_switch_block request +Example chain_get_era_info_by_switch_block request ```bash @@ -193,7 +193,7 @@ This method returns an EraInfo from the network. Only the last Block in an `era`
-Example chain_get_era_info_by_switch_block +Example chain_get_era_info_by_switch_block ```bash diff --git a/source/docs/casper/developers/json-rpc/json-rpc-transactional.md b/source/docs/casper/developers/json-rpc/json-rpc-transactional.md index 933a179560..7a8ef03ed5 100644 --- a/source/docs/casper/developers/json-rpc/json-rpc-transactional.md +++ b/source/docs/casper/developers/json-rpc/json-rpc-transactional.md @@ -14,7 +14,7 @@ This is the only means by which users can send their compiled Wasm (as part of a
-Example account_put_deploy request +Example account_put_deploy request ```bash @@ -91,7 +91,7 @@ The result contains the [deploy_hash](./types_chain.md#deployhash), which is the
-Example account_put_deploy result +Example account_put_deploy result ```bash @@ -121,7 +121,7 @@ The `speculative_exec` endpoint provides a method to execute a `Deploy` without
-Example speculative_exec request +Example speculative_exec request ```bash @@ -215,7 +215,7 @@ The result contains the hash of the targeted block and the results of the execut
-Example speculative_exec result +Example speculative_exec result ```bash diff --git a/source/docs/casper/developers/writing-onchain-code/best-practices.md b/source/docs/casper/developers/writing-onchain-code/best-practices.md index 0afa88d6f9..617de3bb61 100644 --- a/source/docs/casper/developers/writing-onchain-code/best-practices.md +++ b/source/docs/casper/developers/writing-onchain-code/best-practices.md @@ -9,7 +9,7 @@ When developing on Casper, a policy of efficient data usage will ensure the lowe When creating smart contracts, including an explicit initialization entry point allows the contract to self-initialize without a subsequent Deploy of session code. This entry point creates the internal structure of the contract and cannot be called after the initial deploy. Below is an example of a self-initalizing entry point that can be used within the `call` function.
-Example Self-initialization Entry Point +Example Self-initialization Entry Point ```rust diff --git a/source/docs/casper/operators/becoming-a-validator/bonding.md b/source/docs/casper/operators/becoming-a-validator/bonding.md index 1786faeaea..88e95f7c06 100644 --- a/source/docs/casper/operators/becoming-a-validator/bonding.md +++ b/source/docs/casper/operators/becoming-a-validator/bonding.md @@ -140,7 +140,7 @@ casper-client get-auction-info --node-address http:// ```
-Example auction info response +Example auction info response ```bash { diff --git a/source/docs/casper/operators/setup/node-endpoints.md b/source/docs/casper/operators/setup/node-endpoints.md index 9a3dbe7179..fdf149a3f3 100644 --- a/source/docs/casper/operators/setup/node-endpoints.md +++ b/source/docs/casper/operators/setup/node-endpoints.md @@ -74,7 +74,7 @@ curl -s http://:8888/status | jq ```
-Sample response +Sample response ```json { @@ -134,7 +134,7 @@ curl -s http://:8888/status | jq -r '.api_version, .last_added_blo ```
-Sample response +Sample response ```json "1.4.15" diff --git a/source/docs/casper/resources/advanced/cross-contract.md b/source/docs/casper/resources/advanced/cross-contract.md index 4ae1272c2e..45a8908919 100644 --- a/source/docs/casper/resources/advanced/cross-contract.md +++ b/source/docs/casper/resources/advanced/cross-contract.md @@ -674,7 +674,7 @@ Query the state of Casper network using the account hash: If we check the account's named keys, we can see all of the account's deployed contracts:
-Account's named keys +Account's named keys ```bash { @@ -843,7 +843,7 @@ casper-client get-deploy \ After the deploy finishes successfully, you should see a similar outcome to the following:
-Deploy details +Deploy details ```bash { diff --git a/source/docs/casper/resources/advanced/list-cspr.md b/source/docs/casper/resources/advanced/list-cspr.md index 9104a48267..a534a6576a 100644 --- a/source/docs/casper/resources/advanced/list-cspr.md +++ b/source/docs/casper/resources/advanced/list-cspr.md @@ -37,7 +37,7 @@ Casper supports native two-party transfers as well as bulk transfers using custo You can accomplish a native transfer by sending a native transfer deploy, without any Wasm. Included below is an example of this type of deploy. The included `payment` field describes how we are paying for the deploy, in this case a native transfer, while the `session` field describes the actual transfer.
-Native Transfer Deploy +Native Transfer Deploy ```json diff --git a/source/docs/casper/resources/beginner/upgrade-contract.md b/source/docs/casper/resources/beginner/upgrade-contract.md index 724fb52b7a..3a1a4d40ac 100644 --- a/source/docs/casper/resources/beginner/upgrade-contract.md +++ b/source/docs/casper/resources/beginner/upgrade-contract.md @@ -141,7 +141,7 @@ For the simple example counter above, here are the [corresponding tests](https:/ You could store the latest version of the contract package under a NamedKey, as shown [here](https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107). Then, you can query the NamedKey to check the latest version of the contract package.
-Example test function +Example test function ```rust // Verify the contract version is now 2. @@ -186,7 +186,7 @@ casper-client query-global-state \ ```
-Example output +Example output ```rust { @@ -248,7 +248,7 @@ casper-client query-global-state \ --key [ACCOUNT_HASH] -q "version" ```
-Example output +Example output ```rust { @@ -278,7 +278,7 @@ casper-client query-global-state \ --key [ACCOUNT_HASH] -q "counter_package_name" ```
-Example output +Example output ```rust { From 37e4bb42ba4b97d2f6eb97fee80701155d854b04 Mon Sep 17 00:00:00 2001 From: Karol Marter Date: Tue, 12 Sep 2023 23:20:32 +0200 Subject: [PATCH 26/62] 1176 - Migrate from other chains - addressed comments --- .../{migrate.md => moving-to-casper.md} | 57 +++++++------------ 1 file changed, 20 insertions(+), 37 deletions(-) rename source/docs/casper/resources/{migrate.md => moving-to-casper.md} (91%) diff --git a/source/docs/casper/resources/migrate.md b/source/docs/casper/resources/moving-to-casper.md similarity index 91% rename from source/docs/casper/resources/migrate.md rename to source/docs/casper/resources/moving-to-casper.md index b02b56de82..985ae54999 100644 --- a/source/docs/casper/resources/migrate.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -11,16 +11,15 @@ import TabItem from '@theme/TabItem'; This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects: 1. [Smart Contract Platform Overview](#contract-overview) -2. [Variable Storage](#variable-storage) +2. [Variable Storage and State Management](#variable-storage) 3. [Contract Functions](#contract-functions) 4. [Passing Arguments](#passing-arguments) -5. [State Management](#state-management) Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case. When choosing a blockchain, it is also essential to compare consensus mechanisms, tokenomics, cross-contract capabilities, contract upgradability, and software development kits (SDKs) as described [here](#additional-considerations). -## Contract Lifecycle {#contract-overview} +## Smart Contract Platform {#contract-overview} @@ -53,7 +52,7 @@ In the Near ecosystem, smart contracts function as classes. The constructor, ref All public methods defined within the contract serve as its interface, exposing its functionality. -The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates. +Near smart contracts are immutable but the state can change as transactions are executed. Contracts can be also upgradable through the deployment of new versions of the contract. The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates. @@ -62,6 +61,12 @@ The Aptos programming language is known as Move. Its primary concepts revolve ar A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs. +Smart Contract in the Aptos blockchain is called a Module. It is always connected with an account address. The modules have to be compiled to be able to call functions in the module. + +The public methods defined within the Module are treated as the interface of this Module and can be invoked from outside the blockchain. + +The Move code can be upgraded and will be changed under an account address, which does not change. The upgrade is only accepted if the code is backwards compatible. + @@ -76,7 +81,7 @@ It is worth noting that Solana programs can be updated using an authority known -## Variable Storage {#variable-storage} +## Variable Storage and State Management {#variable-storage} @@ -90,6 +95,8 @@ Additionally, local variables are available within the entry points and can be u The variables within the contract are responsible for storing the state of the contract at a specific moment in time. However, it's important to note that local variables used within the call functions are not stored in the contract's state. Instead, they are employed solely for computational purposes within those specific functions. +State variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. + @@ -97,17 +104,23 @@ Variables in the contract can be stored as native types, SDK collections, or int Additionally, there is a distinction between class attributes and local variables. Class attributes represent the state of the contract, while local variables are specific to the invocation of a function and have no impact on the contract's overall state. +SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Using SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. + -Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules. For storing important or relevant data, Aptos encourages using Resources, which are specialized types for managing and storing important data efficiently. +Aptos employs primitive types, such as integers, booleans, and addresses, to represent variables. These elementary types can be combined to create structures, but it's important to note that struct definitions are only permitted within Modules. + +Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. + +Aptos blockchain introduces a tree-shaped persistent global storage which allows read and write operations. Global storage consists of trees originating from and account address. Variables can be utilized locally within the execution context of a specific entry point. They are limited to the scope of that entry point and not accessible outside of it. These variables can be defined as elementary types such as bool, String, int, etc. -In terms of storage, the actual data is stored in the Account. It is organized as a struct comprising related variables, allowing for efficient management and retrieval of the stored information. +Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. @@ -281,36 +294,6 @@ Like Near and Aptos, Solana requires strongly typed function arguments, thus, pr -## State Management {#state-management} - - - - -Data persists in Named Keys and Dictionaries in a contract or an account's context. See more details in [Reading and Writing Data to the Blockchain](../concepts/design/reading-and-writing-to-the-blockchain.md). - - - - -Data persists in state variables within the smart contract. These state variables must be strongly typed so that the smart contract compiler can enforce type consistency and ensure the storage space aligns with the declared data types. Strong typing promotes code correctness and prevents potential data corruption or memory-related issues related to the contract's state variables. - - - - -SDK Collections are typical when creating state variables because they provide convenient data structures such as lists, maps, and sets. These data structures can organize and manage complex data within the contract's storage. Using SDK Collections ensures efficient storage and facilitates easier access and data management in the smart contract. - - - - -Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. - - - - -Data persists in structs within the account. The Binary Object Representation Serializer for Hashing (Borsh) facilitates the serialization and deserialization of these structs. The process involves reading the data from the account, deserializing it to obtain the values it contains, updating the values, and then serializing the modified data to save the new values back into the account. - - - - ## Additional Considerations {#additional-considerations} From 78faea0633f792e2785180965d5d1542f608e2e2 Mon Sep 17 00:00:00 2001 From: Karol Marter Date: Tue, 12 Sep 2023 23:31:56 +0200 Subject: [PATCH 27/62] 1176 - Migrate from other chains - change sidebar config --- config/sidebar.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/sidebar.config.js b/config/sidebar.config.js index 47f2d559a5..13be03759e 100644 --- a/config/sidebar.config.js +++ b/config/sidebar.config.js @@ -263,7 +263,7 @@ module.exports = { "resources/build-on-casper", "resources/casper-open-source-software", "resources/quick-start", - "resources/migrate", + "resources/moving-to-casper", //"resources/sample-projects", // NEW CONTENT WILL BE HERE { type: "category", From da6d482ea69770f04699ab46c387246b21de66a9 Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:06:45 +0200 Subject: [PATCH 28/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index 985ae54999..4f6dcd18a7 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -52,7 +52,7 @@ In the Near ecosystem, smart contracts function as classes. The constructor, ref All public methods defined within the contract serve as its interface, exposing its functionality. -Near smart contracts are immutable but the state can change as transactions are executed. Contracts can be also upgradable through the deployment of new versions of the contract. The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates. +Near smart contracts are immutable, but their state can change as transactions are executed. Contracts can also be upgraded by deploying new versions of the contract. The Near blockchain provides various capabilities for versioning, including state migrations, state versioning, and contract self-updates. From 88b0af01021dd766d48c362e482e4a5b81baf001 Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:06:55 +0200 Subject: [PATCH 29/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index 4f6dcd18a7..c6a3a33688 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -61,11 +61,11 @@ The Aptos programming language is known as Move. Its primary concepts revolve ar A distinctive feature of Move is the concept of Resources, which are specialized structures representing assets. This design allows resources to be managed similarly to other data types in Aptos, such as vectors or structs. -Smart Contract in the Aptos blockchain is called a Module. It is always connected with an account address. The modules have to be compiled to be able to call functions in the module. +A smart contract in the Aptos blockchain is called a Module. It is always connected with an account address. The modules have to be compiled to call functions in the Module. -The public methods defined within the Module are treated as the interface of this Module and can be invoked from outside the blockchain. +The Module's public methods are its interface and can be invoked from code outside the blockchain. -The Move code can be upgraded and will be changed under an account address, which does not change. The upgrade is only accepted if the code is backwards compatible. +Module code can be upgraded and changed under the account address, which does not change. The upgrade is only accepted if the code is backward compatible. From 39e1266b0544977a3ff2f4899947973bce5e9c06 Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:07 +0200 Subject: [PATCH 30/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index c6a3a33688..e1a9248611 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -113,7 +113,7 @@ Aptos employs primitive types, such as integers, booleans, and addresses, to rep Aptos advises developers to cluster related data into Resources for efficient data management and organization. Resources represent assets or specific data entities on the blockchain. By grouping data into Resources, you can maintain logical coherence and improve the readability and maintainability of the code. -Aptos blockchain introduces a tree-shaped persistent global storage which allows read and write operations. Global storage consists of trees originating from and account address. +The Aptos blockchain introduces a tree-shaped persistent global storage that allows read and write operations. Global storage consists of trees originating from an account address. From 012de4b104645982c1395d42e6cb28326dcbdf30 Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:14 +0200 Subject: [PATCH 31/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index e1a9248611..7fa6dd65d5 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -143,7 +143,7 @@ pub extern "C" fn counter_inc() { It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the [RuntimeArgs](https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html) passed to the contract. Entry points are instantiated within the `call` entry point. -If a return value is needed, it should be declared using the following syntax described in the [Interacting with Runtime Return Values](../resources/advanced/return-values-tutorial.md) tutorial. +If a return value is needed, it should be declared using the syntax described in the [Interacting with Runtime Return Values](../resources/advanced/return-values-tutorial.md) tutorial. ```rust runtime::ret(value); From 83576c5677063e70be15614e646e5ff7fd8830ef Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:28 +0200 Subject: [PATCH 32/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index 7fa6dd65d5..e4acc21847 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -257,7 +257,7 @@ casper-client put-deploy \ --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'" ``` -To understand the context of this example please refer to: [Delegating with the Casper Client](../developers/cli/delegate.md). +To understand the context of this example, refer to: [Delegating with the Casper Client](../developers/cli/delegate.md). In the contract, you can access the session arguments as follows: From 71d4e7695a6e7c3bdab5f40c382dcadcfd18fc3d Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:36 +0200 Subject: [PATCH 33/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index e4acc21847..792bf15272 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -267,7 +267,7 @@ let uref: URef = runtime::get_key(Key_Name) Use the `get_key` function to retrieve the desired session argument by specifying the key's name. -If you are uncertain, how to use the `get_key` function to obtain a specific session argument, check how to [write a basic smart contract on Casper](../developers/writing-onchain-code/simple-contract.md). +If you are uncertain how to use the `get_key` function to obtain a specific session argument, check how to [write a basic smart contract on Casper](../developers/writing-onchain-code/simple-contract.md). From e9599ef28717e8bc05e02e00f424c15afaa905dd Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:43 +0200 Subject: [PATCH 34/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index 792bf15272..02264d5239 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -284,7 +284,7 @@ Strongly typed function arguments require explicitly defining the input and retu -Like Near, Aptos requires strongly typed function arguments, thus, preventing type-related errors and promoting code correctness. +Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness. From b1de2280ec88dd29fb9462e2b5b0db0381b66fab Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:52 +0200 Subject: [PATCH 35/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index 02264d5239..dd55213067 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -289,7 +289,7 @@ Like Near, Aptos requires strongly typed function arguments, thus preventing typ -Like Near and Aptos, Solana requires strongly typed function arguments, thus, preventing type-related errors and promoting code correctness. +Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness. From 6615cbc6004f3febe6e5409ca5ffcae1fb450914 Mon Sep 17 00:00:00 2001 From: KMCreatesWorlds <78648740+KMCreatesWorlds@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:07:58 +0200 Subject: [PATCH 36/62] Update source/docs/casper/resources/moving-to-casper.md Co-authored-by: Iulia Popescu --- source/docs/casper/resources/moving-to-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/moving-to-casper.md b/source/docs/casper/resources/moving-to-casper.md index dd55213067..b68bcfad50 100644 --- a/source/docs/casper/resources/moving-to-casper.md +++ b/source/docs/casper/resources/moving-to-casper.md @@ -1,5 +1,5 @@ --- -title: Moving to Casper +title: Move to Casper --- import useBaseUrl from '@docusaurus/useBaseUrl'; From 17383812c4aa76fe3631a91509daa470235ed5a1 Mon Sep 17 00:00:00 2001 From: Karol Marter Date: Fri, 15 Sep 2023 12:13:19 +0200 Subject: [PATCH 37/62] 1176 - Migrate from other chains - sidebar/table --- config/sidebar.config.js | 2 +- source/docs/casper/resources/index.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/sidebar.config.js b/config/sidebar.config.js index 771a37f91f..f2510c460d 100644 --- a/config/sidebar.config.js +++ b/config/sidebar.config.js @@ -279,9 +279,9 @@ module.exports = { resources: [ "resources/index", "resources/build-on-casper", + "resources/moving-to-casper", "resources/casper-open-source-software", "resources/quick-start", - "resources/moving-to-casper", //"resources/sample-projects", // NEW CONTENT WILL BE HERE { type: "category", diff --git a/source/docs/casper/resources/index.md b/source/docs/casper/resources/index.md index ba80e7f8f6..020bfefecb 100644 --- a/source/docs/casper/resources/index.md +++ b/source/docs/casper/resources/index.md @@ -10,6 +10,8 @@ | [Developer tools](./build-on-casper.md#development-tools) | Available development tools | | [Ecosystem Projects](./casper-open-source-software.md) | Explore some open-source code available in the Casper ecosystem | +## Move to Casper + ## Tutorials | Topic | Description | From 9e299b9ecce181494ca36c955377f66368795128 Mon Sep 17 00:00:00 2001 From: Karol Marter Date: Fri, 15 Sep 2023 12:25:35 +0200 Subject: [PATCH 38/62] 1176 - Migrate from other chains - table correction --- source/docs/casper/resources/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/docs/casper/resources/index.md b/source/docs/casper/resources/index.md index 020bfefecb..08ff288d08 100644 --- a/source/docs/casper/resources/index.md +++ b/source/docs/casper/resources/index.md @@ -12,6 +12,10 @@ ## Move to Casper +| Topic | Description | +| ----------------------------------------------------------- | ---------------------------------------------------------------- | +| [Move to Casper](./moving-to-casper.md) | Learn how to start working with Casper, having previous knowledge of other blockchains | + ## Tutorials | Topic | Description | From e9901b71ea73e4b356c62e9fed3b9af666627be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Killian=20Hasco=C3=ABt?= Date: Mon, 18 Sep 2023 04:30:56 +0000 Subject: [PATCH 39/62] Remove flask suffix to Metamask --- source/docs/casper/resources/build-on-casper.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/build-on-casper.md b/source/docs/casper/resources/build-on-casper.md index c2a7aff0fd..afcebc98ae 100644 --- a/source/docs/casper/resources/build-on-casper.md +++ b/source/docs/casper/resources/build-on-casper.md @@ -24,7 +24,7 @@ The Casper Ecosystem is growing every day through the addition of new dApps and - [Ledger](https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true) - [Tor.us](https://casper.tor.us) - [Casper Wallet](https://www.casperwallet.io) -- [Metamask Flask](https://metamask.io/flask/) with [Casper Snap](https://github.com/casper-ecosystem/casper-manager) +- [Metamask](https://metamask.io/) with [Casper Snap](https://github.com/casper-ecosystem/casper-manager) ### Block Explorers - [cspr.live](https://cspr.live) From 55155f681062563e0ab7948834a98450145d2211 Mon Sep 17 00:00:00 2001 From: liam Date: Tue, 19 Sep 2023 10:11:16 +0700 Subject: [PATCH 40/62] Update source/docs/casper/resources/casper-open-source-software.md --- source/docs/casper/resources/casper-open-source-software.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/docs/casper/resources/casper-open-source-software.md b/source/docs/casper/resources/casper-open-source-software.md index bc663d89f7..70bacc5ec8 100644 --- a/source/docs/casper/resources/casper-open-source-software.md +++ b/source/docs/casper/resources/casper-open-source-software.md @@ -62,3 +62,5 @@ Name | Description | Author | Language | License | Last Update Date | Type [ServicesDAO](https://github.com/EKON-YAZILIM/ServicesDAO) | The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR. | Ekon Yazilim | HTML-CSS-C# | MIT license | 2022-09-13 | DAO [Uniswap DemoApp](https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp) | Uniswap UI + Contracts | Rengo Labs | JavaScript | GPL-3.0 license | 2022-09-15 | DeFi [Verified Impact NFT](https://github.com/AdelElMessiry/Verified-Impact-NFTs) | An NFT platform dedicated to impact causes with verification of the beneficiaries | AlphaFin | JavaScript-Rust | MIT license | 2022-07-08 | NFT +[UseWallet](https://usewallet.casperdash.io) | useWallet is a collection of React Hooks containing everything you need to start working with Casper Network | CasperDash | Typescript-React | MIT license | 2023-09-19 | dApp library +[Faucet](https://faucet.casperdash.io) | A faucet is a casper tool that drips testnet tokens to anyone that requests them for free | CasperDash | Typescript-React | MIT license | 2023-09-19 | Tools From 45c5ad5efbbd6647397c3c393e972d070d563a04 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Wed, 20 Sep 2023 19:14:35 +0200 Subject: [PATCH 41/62] Replace state_get_balance with query_balance --- .../cli/transfers/verify-transfer.md | 102 ++++++---- .../json-rpc/json-rpc-informational.md | 61 +----- .../developers/json-rpc/minimal-compliance.md | 4 +- .../resources/beginner/querying-network.md | 175 +++++++++++++----- 4 files changed, 193 insertions(+), 149 deletions(-) diff --git a/source/docs/casper/developers/cli/transfers/verify-transfer.md b/source/docs/casper/developers/cli/transfers/verify-transfer.md index 7764c57b28..29e54d7cac 100644 --- a/source/docs/casper/developers/cli/transfers/verify-transfer.md +++ b/source/docs/casper/developers/cli/transfers/verify-transfer.md @@ -105,7 +105,7 @@ casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS] "jsonrpc": "2.0", "result": { "api_version": "1.4.13", - "state_root_hash": "a1f11692c5adc0e8b0a3f83e34d5831593a39ba03c8be73a0ebf7e9d9aadd76b" + "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" } } ``` @@ -250,18 +250,22 @@ casper-client query-global-state \
-## Get Purse Balance {#get-purse-balance} +## Query Purse Balance {#get-purse-balance} -All accounts on a Casper network have a purse associated with the Casper system mint, which we call the _main purse_. The balance associated with a given purse is recorded in global state, and the value can be queried using the `URef` associated with the purse. +All accounts on a Casper network have a purse associated with the Casper system mint, which we call the _main purse_. The balance associated with a given purse is recorded in global state, and the value can be queried using the `query-balance` command and the purse identifier, which can be a public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef can be used. For full details, run the following help command: + +```bash +casper-client query-balance --help +``` Now that we have the source purse address, we can verify its balance using the `get-balance` command: ```bash -casper-client get-balance \ +casper-client query-balance \ --id 6 \ --node-address http://:7777 \ --state-root-hash \ ---purse-uref +--purse-identifier ``` **Request fields:** @@ -269,22 +273,37 @@ casper-client get-balance \ - `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned - `node-address` - An IP address of a node on the network - `state-root-hash` - Hex-encoded hash of the state root -- `purse-uref` - The URef under which the purse is stored, following the format "uref-". +- `purse-identifier` - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef. + +The `-v` option generates verbose output, printing the RPC request and response generated. Let's explore an example below. + +**Query Source Account Example:** + +```bash +casper-client query-balance -v --id 6 \ +--node-address http://:7777 \ +--state-root-hash cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3 \ +--purse-identifier account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5 +```
-Explore the JSON-RPC request and response generated. +Explore the sample JSON-RPC request and response generated. **JSON-RPC Request**: ```json { - "id": 6, - "jsonrpc": "2.0", - "method": "state_get_balance", - "params": { - "purse_uref": "uref-6f4026262a505d5e1b0e03b1e3b7ab74a927f8f2868120cf1463813c19acb71e-007", - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + "jsonrpc": "2.0", + "method": "query_balance", + "params": { + "state_identifier": { + "StateRootHash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + }, + "purse_identifier": { + "main_purse_under_account_hash": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5" } + }, + "id": 6 } ``` @@ -292,42 +311,54 @@ casper-client get-balance \ ```json { - "id": 6, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "balance_value": "5000000000", - "merkle_proof": "2502 chars" - } + "jsonrpc": "2.0", + "result": { + "api_version": "1.5.2", + "balance": "164000000000" + }, + "id": 6 } ```
-Similarly, we have the address of the target purse, so we can get its balance. +Similarly, we have the public key of the target purse, so we can get its balance. ```bash casper-client get-balance \ --id 7 \ --node-address http://:7777 \ --state-root-hash \ ---purse-uref +--purse-identifier +``` + +**Target Account Example:** + +```bash +casper-client query-balance -v --id 7 \ +--node-address http://:7777 \ +--state-root-hash cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3 \ +--purse-identifier account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668 ```
-Explore the JSON-RPC request and response generated. +Explore the sample JSON-RPC request and response generated. **JSON-RPC Request**: ```json { - "id": 7, - "jsonrpc": "2.0", - "method": "state_get_balance", - "params": { - "purse_uref": "uref-6f4026262a505d5e1b0e03b1e3b7ab74a927f8f2868120cf1463813c19acb71e-007", - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + "jsonrpc": "2.0", + "method": "query_balance", + "params": { + "state_identifier": { + "StateRootHash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + }, + "purse_identifier": { + "main_purse_under_account_hash": "account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668" } + }, + "id": 7 } ``` @@ -335,13 +366,12 @@ casper-client get-balance \ ```json { - "id": 7, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "balance_value": "5000000000", - "merkle_proof": "2502 chars" - } + "jsonrpc": "2.0", + "result": { + "api_version": "1.5.2", + "balance": "5000000000" + }, + "id": 7 } ``` diff --git a/source/docs/casper/developers/json-rpc/json-rpc-informational.md b/source/docs/casper/developers/json-rpc/json-rpc-informational.md index 0067492d7b..aff285b77a 100644 --- a/source/docs/casper/developers/json-rpc/json-rpc-informational.md +++ b/source/docs/casper/developers/json-rpc/json-rpc-informational.md @@ -639,7 +639,7 @@ This method allows you to query for the balance of a purse using a `PurseIdentif This method allows for you to query for a value stored under certain keys in global state. You may query using either a [Block hash](../../concepts/design/casper-design.md#block_hash) or state root hash. -* Note: Querying a purse's balance requires the use of `state_get_balance` or `query_balance`, rather than any iteration of `query_global_state`. +* Note: Querying a purse's balance requires the use of `query_balance`, rather than any iteration of `query_global_state`. |Parameter|Type|Description| |---------|----|-----------| @@ -829,65 +829,6 @@ This method returns a JSON representation of an [Account](../../concepts/design/
-## state_get_balance {#state-get-balance} - -This method returns a purse's balance from a network. The request takes in the formatted representation of a purse URef as a parameter. - -To query for the balance of an Account, you must provide the formatted representation of the Account's main purse URef, which can be obtained from the [`state_get_account_info`](#stategetaccountinfo-state-get-account-info) response. The response contains the balance of a purse in motes. - -For instance, one native layer-1 token of the Casper Mainnet [CSPR](../../concepts/glossary/C.md#cspr) is comprised of 1,000,000,000 motes. On a different Casper network, the representation of token-to-motes may differ. - -|Parameter|Type|Description| -|---------|----|-----------| -|[state_root_hash](types_chain.md#digest)|String|The hash of state root.| -|purse_uref|String|Formatted URef.| - -
-Example state_get_balance request - -```bash - -{ - "id": 1, - "jsonrpc": "2.0", - "method": "state_get_balance", - "params": [ - "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007", - "0808080808080808080808080808080808080808080808080808080808080808" - ] -} - -``` - -
- -### `state_get_balance_result` - -|Parameter|Type|Description| -|---------|----|-----------| -|api_version|String|The RPC API version.| -|[balance_value](types_chain.md#u512)|String|The balance value in motes.| -|[merkle_proof](types_chain.md#merkle-proof)|String|The merkle proof.| - -
-Example state_get_balance result - -```bash - -{ - "id": 1, - "jsonrpc": "2.0", - "result": { - "api_version": "1.4.13", - "balance_value": "123456", - "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3" - } -} - -``` - -
- ## state_get_dictionary_item {#state-get-dictionary-item} This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a `dictionary_identifier`. The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key. diff --git a/source/docs/casper/developers/json-rpc/minimal-compliance.md b/source/docs/casper/developers/json-rpc/minimal-compliance.md index c411f3dec6..681b578f50 100644 --- a/source/docs/casper/developers/json-rpc/minimal-compliance.md +++ b/source/docs/casper/developers/json-rpc/minimal-compliance.md @@ -8,11 +8,11 @@ The methods included in this document represent the most basic, fundamental endp * [`account_put_deploy`](./json-rpc-transactional.md#account-put-deploy) - This method allows users to send their compiled Wasm (as part of a Deploy) to a node on a Casper network. Deploys represent the only means by which a user can perform computation on the platform, without which their interaction with a Casper network will be entirely passive. -* [`chain_get_state_root_hash`](./json-rpc-informational.md#chain-get-state-root-hash) - The state root hash is one of the several [global state identifiers](./types_chain.md#globalstateidentifier) used to query the network state after deployments, and the only way to do so in the context of `state_get_balance` and `state_get_dictionary_item`. A minimal SDK requires both dependent methods. +* [`chain_get_state_root_hash`](./json-rpc-informational.md#chain-get-state-root-hash) - The state root hash is one of the several [global state identifiers](./types_chain.md#globalstateidentifier) used to query the network state after sending deploys. * [`state_get_account_info`](./json-rpc-informational.md#state-get-account-info) - This method returns a JSON representation of an Account from the network. `state_get_account_info` is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse. -* [`state_get_balance`](./json-rpc-informational.md#state-get-balance) - This method returns a purse's balance from a network. This is the only method to return a purse's balance in a human-readable format. +* [`query_balance`](./json-rpc-informational.md#query-balance) - This method returns a purse's balance from a network. This is the only method to return a purse's balance in a human-readable format. The deprecated method `state_get_balance` should not be used. * [`state_get_dictionary_item`](./json-rpc-informational.md#state-get-dictionary-item) - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state. diff --git a/source/docs/casper/resources/beginner/querying-network.md b/source/docs/casper/resources/beginner/querying-network.md index 60bb9e88e7..e8b2b5e8f6 100644 --- a/source/docs/casper/resources/beginner/querying-network.md +++ b/source/docs/casper/resources/beginner/querying-network.md @@ -87,21 +87,33 @@ casper-client query-global-state \ - `"result"."stored_value"."Account"."main_purse"` - the address of the main purse containing the sender's tokens. This purse is the source of the tokens transferred in this example +**Example Account Query with Verbose Output:** + +```bash +casper-client query-global-state -v \ + --id 4 \ + --node-address https://rpc.testnet.casperlabs.io/ \ + --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \ + --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 +``` +
-Explore the JSON-RPC request and response generated. +Explore the sample JSON-RPC request and response generated. **JSON-RPC Request**: ```json { - "id": 4, - "jsonrpc": "2.0", - "method": "state_get_item", - "params": { - "key": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "path": [], - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" - } + "jsonrpc": "2.0", + "method": "query_global_state", + "params": { + "state_identifier": { + "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2" + }, + "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "path": [] + }, + "id": 4 } ``` @@ -109,42 +121,88 @@ casper-client query-global-state \ ```json { - "id": 4, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "merkle_proof": "2228 chars", - "stored_value": { - "Account": { - "account_hash": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "action_thresholds": { - "deployment": 1, - "key_management": 1 - }, - "associated_keys": [ - { - "account_hash": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "weight": 1 - } - ], - "main_purse": "uref-9e90f4bbd8f581816e305eb7ea2250ca84c96e43e8735e6aca133e7563c6f527-007", - "named_keys": [] - } + "jsonrpc": "2.0", + "id": 4, + "result": { + "api_version": "1.5.2", + "block_header": null, + "stored_value": { + "Account": { + "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "named_keys": [ + { + "name": "counter", + "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e" + }, + { + "name": "counter_access_uref", + "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007" + }, + { + "name": "counter_package_name", + "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b" + }, + { + "name": "my-key-name", + "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007" + }, + { + "name": "version", + "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007" + } + ], + "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007", + "associated_keys": [ + { + "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34", + "weight": 1 + }, + { + "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "weight": 3 + }, + { + "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4", + "weight": 1 + }, + { + "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5", + "weight": 1 + }, + { + "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "weight": 1 + }, + { + "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a", + "weight": 1 + } + ], + "action_thresholds": { + "deployment": 2, + "key_management": 3 } - } + } + }, + "merkle_proof": "[32054 hex chars]" + } } ```
-You can use the URef of the `main_purse` to query the account balance. The balance returned is in motes (the unit that makes up the Casper token). +To query the account balance, use the `query-balance` command and the purse identifier, which can be a public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef can be used. The balance returned is in motes (the unit that makes up the Casper token). For full details, run the following help command: ```bash -casper-client get-balance \ - --id 6 \ - --node-address http://:7777 \ - --state-root-hash \ - --purse-uref +casper-client query-balance --help +``` + +```bash +casper-client query-balance \ +--id 6 \ +--node-address http://:7777 \ +--state-root-hash \ +--purse-identifier ``` **Request fields:** @@ -152,7 +210,19 @@ casper-client get-balance \ - `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned - `node-address` - An IP address of a node on the network - `state-root-hash` - Hex-encoded hash of the state root -- `purse-uref` - The URef under which the purse is stored. This must be a properly formatted URef "uref-\-" +- `purse-identifier` - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef. + +The `-v` option generates verbose output, printing the RPC request and response generated. Let's explore an example below. + +**Example Balance Query with Verbose Output:** + +```bash +casper-client query-balance -v \ + --id 6 \ + --node-address https://rpc.testnet.casperlabs.io/ \ + --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \ + --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 +```
Explore the JSON-RPC request and response generated. @@ -161,13 +231,17 @@ casper-client get-balance \ ```json { - "id": 6, - "jsonrpc": "2.0", - "method": "state_get_balance", - "params": { - "purse_uref": "uref-6f4026262a505d5e1b0e03b1e3b7ab74a927f8f2868120cf1463813c19acb71e-007", - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + "jsonrpc": "2.0", + "method": "query_balance", + "params": { + "state_identifier": { + "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2" + }, + "purse_identifier": { + "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986" } + }, + "id": 6 } ``` @@ -175,13 +249,12 @@ casper-client get-balance \ ```json { - "id": 6, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "balance_value": "5000000000", - "merkle_proof": "2502 chars" - } + "jsonrpc": "2.0", + "result": { + "api_version": "1.5.2", + "balance": "164000000000" + }, + "id": 6 } ``` From 871b6ddb72bb0bcbb85e21cce28f2c28d471dc52 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Thu, 21 Sep 2023 21:19:14 +0200 Subject: [PATCH 42/62] Move state_get_balance to a note --- .../docs/casper/developers/json-rpc/minimal-compliance.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/docs/casper/developers/json-rpc/minimal-compliance.md b/source/docs/casper/developers/json-rpc/minimal-compliance.md index 681b578f50..2e6fbae77d 100644 --- a/source/docs/casper/developers/json-rpc/minimal-compliance.md +++ b/source/docs/casper/developers/json-rpc/minimal-compliance.md @@ -12,10 +12,16 @@ The methods included in this document represent the most basic, fundamental endp * [`state_get_account_info`](./json-rpc-informational.md#state-get-account-info) - This method returns a JSON representation of an Account from the network. `state_get_account_info` is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse. -* [`query_balance`](./json-rpc-informational.md#query-balance) - This method returns a purse's balance from a network. This is the only method to return a purse's balance in a human-readable format. The deprecated method `state_get_balance` should not be used. +* [`query_balance`](./json-rpc-informational.md#query-balance) - This method returns a purse's balance from a network. This is the only method to return a purse's balance in a human-readable format. * [`state_get_dictionary_item`](./json-rpc-informational.md#state-get-dictionary-item) - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state. * [`query_global_state`](./json-rpc-informational.md#query-global-state) - This method allows for querying values stored under certain keys in global state. Aside from purse balances, this is the main means of recovering stored data from a Casper network. +:::note + +The deprecated method `state_get_balance` should not be used. + +::: + In addition to these methods, a minimally compliant Casper SDK must account for the [types](./types_chain.md) associated with each method. Each method above links to the expanded information available within the larger JSON RPC method pages, which includes the necessary associated types. From 2050e46a36cd2762eb3e9275f91d6363a505a405 Mon Sep 17 00:00:00 2001 From: Iulia Popescu Date: Mon, 25 Sep 2023 12:19:58 +0200 Subject: [PATCH 43/62] Edited explanation --- source/docs/casper/resources/casper-open-source-software.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/casper-open-source-software.md b/source/docs/casper/resources/casper-open-source-software.md index 70bacc5ec8..6daec7e7ae 100644 --- a/source/docs/casper/resources/casper-open-source-software.md +++ b/source/docs/casper/resources/casper-open-source-software.md @@ -63,4 +63,4 @@ Name | Description | Author | Language | License | Last Update Date | Type [Uniswap DemoApp](https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp) | Uniswap UI + Contracts | Rengo Labs | JavaScript | GPL-3.0 license | 2022-09-15 | DeFi [Verified Impact NFT](https://github.com/AdelElMessiry/Verified-Impact-NFTs) | An NFT platform dedicated to impact causes with verification of the beneficiaries | AlphaFin | JavaScript-Rust | MIT license | 2022-07-08 | NFT [UseWallet](https://usewallet.casperdash.io) | useWallet is a collection of React Hooks containing everything you need to start working with Casper Network | CasperDash | Typescript-React | MIT license | 2023-09-19 | dApp library -[Faucet](https://faucet.casperdash.io) | A faucet is a casper tool that drips testnet tokens to anyone that requests them for free | CasperDash | Typescript-React | MIT license | 2023-09-19 | Tools +[Testnet Faucet](https://faucet.casperdash.io) | A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free | CasperDash | Typescript-React | MIT license | 2023-09-19 | Tools From 8888829546ccc2d66ef59fe0c1a38c76e400cbcf Mon Sep 17 00:00:00 2001 From: Iulia Popescu Date: Mon, 25 Sep 2023 12:20:06 +0200 Subject: [PATCH 44/62] Edited explanation --- source/docs/casper/resources/casper-open-source-software.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/resources/casper-open-source-software.md b/source/docs/casper/resources/casper-open-source-software.md index 6daec7e7ae..c12ac235f7 100644 --- a/source/docs/casper/resources/casper-open-source-software.md +++ b/source/docs/casper/resources/casper-open-source-software.md @@ -62,5 +62,5 @@ Name | Description | Author | Language | License | Last Update Date | Type [ServicesDAO](https://github.com/EKON-YAZILIM/ServicesDAO) | The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR. | Ekon Yazilim | HTML-CSS-C# | MIT license | 2022-09-13 | DAO [Uniswap DemoApp](https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp) | Uniswap UI + Contracts | Rengo Labs | JavaScript | GPL-3.0 license | 2022-09-15 | DeFi [Verified Impact NFT](https://github.com/AdelElMessiry/Verified-Impact-NFTs) | An NFT platform dedicated to impact causes with verification of the beneficiaries | AlphaFin | JavaScript-Rust | MIT license | 2022-07-08 | NFT -[UseWallet](https://usewallet.casperdash.io) | useWallet is a collection of React Hooks containing everything you need to start working with Casper Network | CasperDash | Typescript-React | MIT license | 2023-09-19 | dApp library +[UseWallet](https://usewallet.casperdash.io) | useWallet is a collection of React Hooks containing everything you need to start working with a Casper network | CasperDash | Typescript-React | MIT license | 2023-09-19 | dApp library [Testnet Faucet](https://faucet.casperdash.io) | A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free | CasperDash | Typescript-React | MIT license | 2023-09-19 | Tools From de32e58ef87e7c1fb72ca34a12189125d9a8a85c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20Bro=C5=84ski?= Date: Tue, 26 Sep 2023 14:08:28 +0200 Subject: [PATCH 45/62] Restore font styles for headings and menu items --- src/assets/scss/_global.scss | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/assets/scss/_global.scss b/src/assets/scss/_global.scss index 8670bd44b4..4b88d958cd 100644 --- a/src/assets/scss/_global.scss +++ b/src/assets/scss/_global.scss @@ -236,3 +236,51 @@ html { font-size: 26px; } } + +// Fix for low readability. +// See: https://github.com/casper-network/docs/issues/1287. +// +.main-wrapper { + font: var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base); + + h1, h2, h3, h4, h5, h6 { + font-family: var(--ifm-heading-font-family); + font-weight: var(--ifm-heading-font-weight); + line-height: var(--ifm-heading-line-height); + } + + h1 { + font-size: var(--ifm-h1-font-size) + } + + h2 { + font-size: var(--ifm-h2-font-size) + } + + h3 { + font-size: var(--ifm-h3-font-size) + } + + h4 { + font-size: var(--ifm-h4-font-size) + } + + h5 { + font-size: var(--ifm-h5-font-size) + } + + h6 { + font-size: var(--ifm-h6-font-size) + } + + .menu__list { + .menu__link { + font-size: inherit !important; + } + + .menu__link--sublist { + letter-spacing: inherit !important; + font-size: inherit !important; + } + } +} From b7fdbc77708d062ecdf638771d31f471c1589cc8 Mon Sep 17 00:00:00 2001 From: Jacek Malec <145967538+jacek-casper@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:45:34 +0100 Subject: [PATCH 46/62] Update account_put_deploy example to work with current casper-node --- .../json-rpc/json-rpc-transactional.md | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/source/docs/casper/developers/json-rpc/json-rpc-transactional.md b/source/docs/casper/developers/json-rpc/json-rpc-transactional.md index 7a8ef03ed5..03bb8a7229 100644 --- a/source/docs/casper/developers/json-rpc/json-rpc-transactional.md +++ b/source/docs/casper/developers/json-rpc/json-rpc-transactional.md @@ -26,20 +26,20 @@ This is the only means by which users can send their compiled Wasm (as part of a { "approvals": [ { - "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007", - "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c" + "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5", + "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100" } ], - "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa", + "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888", "header": { - "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c", - "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50", - "chain_name": "casper-example", + "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5", + "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00", + "chain_name": "casper-net-1", "dependencies": [ "0101010101010101010101010101010101010101010101010101010101010101" ], "gas_price": 1, - "timestamp": "2020-11-17T00:39:24.072Z", + "timestamp": "2023-09-26T14:07:10.024Z", "ttl": "1h" }, "payment": { @@ -48,9 +48,8 @@ This is the only means by which users can send their compiled Wasm (as part of a [ "amount", { - "bytes": "e8030000", - "cl_type": "I32", - "parsed": 1000 + "bytes": "0400f90295", + "cl_type": "U512" } ] ], @@ -64,9 +63,15 @@ This is the only means by which users can send their compiled Wasm (as part of a [ "amount", { - "bytes": "e8030000", - "cl_type": "I32", - "parsed": 1000 + "cl_type": "U512", + "bytes": "0400f90295" + } + ], + [ + "target", + { + "cl_type": "URef", + "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07" } ] ] From 6b9727ef35b1734c32135e1450bc1e9976754648 Mon Sep 17 00:00:00 2001 From: Jacek Malec <145967538+jacek-casper@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:53:47 +0100 Subject: [PATCH 47/62] Fix a typo that breaks MD rendering in casper-design.md --- source/docs/casper/concepts/design/casper-design.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/docs/casper/concepts/design/casper-design.md b/source/docs/casper/concepts/design/casper-design.md index 7eafd949f0..2b42fe1d82 100644 --- a/source/docs/casper/concepts/design/casper-design.md +++ b/source/docs/casper/concepts/design/casper-design.md @@ -259,7 +259,7 @@ The Casper *mint* is a system contract that manages the balance of *motes* withi The `AccessRights` of the URefs permissions model determines what actions can be performed when using a `URef` associated with a purse. -As all URef`s are unforgeable, the only way to interact with a purse is for a `URef` with appropriate `AccessRights` to be validly given to the current context. +As all `URef`s are unforgeable, the only way to interact with a purse is for a `URef` with appropriate `AccessRights` to be validly given to the current context. The basic global state options map onto more standard monetary operations according to the table below: From 3a4c792f84608ec3052517a5cfbfc8be989a9e1d Mon Sep 17 00:00:00 2001 From: ipopescu Date: Fri, 6 Oct 2023 15:29:19 +0300 Subject: [PATCH 48/62] Initial content --- .../contract-hash-vs-package-hash.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md diff --git a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md new file mode 100644 index 0000000000..543bb0d749 --- /dev/null +++ b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md @@ -0,0 +1,94 @@ + +--- +title: Contract Hash vs. Package Hash +--- + +# Calling Contracts by Contract Hash vs. Package Hash + +This page describes the advantages and disadvantages of using `contract_hash` vs. `contract_package_hash` when calling a contract. + +When should a contract store or call a contract hash rather than a contract package hash? There are cases to use either `contract_package_hash` or `contract_hash` or both. There's no right or wrong option; like with most things, it depends on what you are trying to do. + +A given contract might: +- Not need either hash for its use case +- Want to identify specific versions of contracts within the same package and thus use a `contract_hash` +- Not need specific contract versions and allow or block all versions in the same package, thus using the `contract_package_hash` +- Need specific contract versions within the same package, and thus use both `contract_hash` and `contract_package_hash` + +A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide: +- will I allow, block, or track contract callers loosely at the package level? +- will I allow, block, or track contract callers specifically at the contract level? + +Or a more fine-grained variation would be: +- will I allow or block at the package level but track by both package and contract hash? +- will I allow other combinations of these basic concepts? + +Such a contract is responsible for documenting its choices and what it requires of its callers. It is essential to keep in mind the difference between the behavior of the host, which in this case is the Casper network execution engine (the host), as exposed by the [Casper External FFI](https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/), versus use cases and interactions between two or more ecosystem entities such as accounts and contracts. + +The execution engine doesn't know how a contract such as CEP-18 is trying to manage its internal data or its exposed functionality. The contract is responsible for creating and managing a sub-ledger of resource management, access control, etc. + +## The Casper Call Stack + +When identifying who called a contract or initiated a call chain, the execution engine offers the FFI method [casper_load_call_stack](https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/fn.casper_load_call_stack.html), which provides a stack of one or more entries of this kind: + +```rust +/// Represents the origin of a sub-call. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum CallStackElement { + /// Session + Session { + /// The account hash of the caller + account_hash: AccountHash, + }, + /// Effectively an EntryPointType::Session - stored access to a session. + StoredSession { + /// The account hash of the caller + account_hash: AccountHash, + /// The contract package hash + contract_package_hash: ContractPackageHash, + /// The contract hash + contract_hash: ContractHash, + }, + /// contract + StoredContract { + /// The contract package hash + contract_package_hash: ContractPackageHash, + /// The contract hash + contract_hash: ContractHash, + }, +} +``` + +You can find the source code [here](https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs). + +After retrieving the required information, the contract must manage its internal logic and data storage, actions that are entirely opaque to the execution engine (the host). + +Learn more about [Call Stacks](../../concepts/callstack.md) and how Casper manages the calling of a contract. + +## Recommendations + +Consider the following questions when designing the contract and choosing whether to store and use the contract hash or contract package hash. This section summarizes each case's recommendations, advantages, and disadvantages. + +Will you allow only accounts to use the contract? If so, what kind of accounts are you considering? +- Any accounts? +- Specific accounts? +- Exactly one specific account? + +Will you allow only contracts to use it? If so, what kind of contracts? +- Any version of any contract? +- Specific contract versions? +- Specific versions of specific packages? +- Any versions of specific packages? + +Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be: +- Any accounts and contracts? +- Specific accounts and specific contract versions? +- Specific accounts and specific versions of specific packages? +- Specific accounts and any versions of specific packages? + +## Further Reading + +| Topic | Description | +| ----- | ----------- | +| [Cross Contract Communication](./cross-contract.md) | Variations of cross-contract communication for more complex scenarios | +| [Interacting with Runtime Return Values](./return-values-tutorial.md) | Contract code returning a value to the immediate caller via `runtime::ret()` | \ No newline at end of file From 6c0a6a32511b33866d00b65b574614a73f39d024 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Fri, 6 Oct 2023 16:16:42 +0300 Subject: [PATCH 49/62] Cleanup index page; remove duplicate links --- .../developers/writing-onchain-code/index.md | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/source/docs/casper/developers/writing-onchain-code/index.md b/source/docs/casper/developers/writing-onchain-code/index.md index bb9576a52b..04157a8e5f 100644 --- a/source/docs/casper/developers/writing-onchain-code/index.md +++ b/source/docs/casper/developers/writing-onchain-code/index.md @@ -14,32 +14,38 @@ This section shows you how to write session code and smart contracts in Rust and | Title | Description | | ------------------------------------------- | ------------------------------- | |[Getting Started with Rust](./getting-started.md)| An introduction to using Rust with the Casper Platform| -|[Best Practices for Casper Smart Contract Authors](./best-practices.md)| An outline of best practices when developing smart contracts on a Casper network| +|[Getting Started with AssemblyScript](./assembly-script.md) | An introduction to using AssemblyScript with the Casper Platform | |[Writing a Basic Smart Contract in Rust](./simple-contract.md) | An example of a smart contract built in Rust| |[Unit Testing Smart Contracts](./testing-contracts.md) | Steps to test contract code using the unit testing framework| +|[Upgrading and Maintaining Smart Contracts](./upgrading-contracts.md)| An introduction to versioning smart contracts| +|[Calling Contracts](./calling-contracts.md) | | |[Smart Contracts and Session Code](./contract-vs-session.md) | Understand what session code is and when you would use it over contract code | |[Writing Session Code](./writing-session-code.md) | An introduction to writing session code| |[Unit Testing Session Code](./testing-session-code.md) | Steps to test session code using the unit testing framework| +|[Calling Contracts by Contract Hash vs. Package Hash](./contract-hash-vs-package-hash.md)| Advantages and disadvantages of using `contract_hash` vs. `contract_package_hash` when calling a contract| +|[Best Practices for Casper Smart Contract Authors](./best-practices.md)| An outline of best practices when developing smart contracts on a Casper network| + +## Interacting with Contracts on the Blockchain + +Additionally, the section on [Interacting with the Blockchain](../cli/index.md) covers installing and calling contracts using the Casper command-line client written in Rust. + |[Installing Smart Contracts and Querying Global State](../cli/installing-contracts.md)| A guide on installing smart contracts and querying global state | |[Calling Smart Contracts with the Rust Client](../cli/calling-contracts.md)| Steps to call a smart contract with the Rust command-line client| -|[Upgrading and Maintaining Smart Contracts](./upgrading-contracts.md)| An introduction to versioning smart contracts| |[Reading and Writing to Dictionaries](../../concepts/dictionaries.md)| Information on Dictionaries and how to read and write to them on the Casper Platform.| |[Execution Error Codes](../cli/execution-error-codes.md)|Possible error codes when writing smart contracts.| -|[Getting Started with AssemblyScript](./assembly-script.md) | An introduction to using AssemblyScript with the Casper Platform | -Additionally, the following tutorials outline some aspects of writing smart contracts on a Casper network. +## Tutorials + +The following tutorials outline some aspects of writing smart contracts on a Casper network. | Title | Description | | ----------------------------------------------------------- | ---------------------------------------------------------------- | |[Getting Started Video](../../resources/beginner/getting-started-tutorial.md) | Step-by-step video tutorial for setting up the Casper development environment | -|[NFTs on Casper with the CEP-78 NFT Standard](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md) | Implementing the Casper CEP-78 NFT standard | -|[A Counter on an NCTL Network](../../resources/beginner/counter/index.md) | An example contract that maintains a counter variable on a local Casper Network with NCTL | |[A Counter on the Testnet](../../resources/beginner/counter-testnet/index.md) | An example contract that maintains a counter variable on the Casper Testnet | +|[Smart Contract Upgrades](../../resources/beginner/upgrade-contract.md) | Learn how to upgrade smart contracts | +|[NFTs on Casper with the CEP-78 NFT Standard](https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md) | Implementing the Casper CEP-78 NFT standard | |[Fungible Tokens on Casper](https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md) | Implement the Casper Fungible Token standard | |[Interacting with Runtime Return Values](../../resources/advanced/return-values-tutorial.md)| Learning how to return a value using contract code | |[Working with Authorization Keys](../../resources/advanced/list-auth-keys-tutorial.md)| Retrieving and using the authorization keys associated with a deploy | |[Safely Transfer Tokens to a Contract](../../resources/advanced/transfer-token-to-contract.md) | How to handle tokens via a contract | -|[Smart Contract Upgrades](../../resources/beginner/upgrade-contract.md) | Learn how to upgrade smart contracts | -|[Interacting with Runtime Return Values](../../resources/advanced/return-values-tutorial.md)| Learning how to return a value using contract code | -|[Safely Transfer Tokens to a Contract](../../resources/advanced/transfer-token-to-contract.md) | How to handle tokens via a contract | -|[Smart Contract Upgrades](../../resources/beginner/upgrade-contract.md) | Learn how to upgrade smart contracts | + From 7896879b34d0f121f2b6f21a4df9022c3a92f0cf Mon Sep 17 00:00:00 2001 From: ipopescu Date: Fri, 6 Oct 2023 16:18:17 +0300 Subject: [PATCH 50/62] Add page in sidebar; fix table --- config/sidebar.config.js | 1 + .../writing-onchain-code/contract-hash-vs-package-hash.md | 4 ++-- source/docs/casper/developers/writing-onchain-code/index.md | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config/sidebar.config.js b/config/sidebar.config.js index f2510c460d..498dde3d6f 100644 --- a/config/sidebar.config.js +++ b/config/sidebar.config.js @@ -110,6 +110,7 @@ module.exports = { "developers/writing-onchain-code/contract-vs-session", "developers/writing-onchain-code/writing-session-code", "developers/writing-onchain-code/testing-session-code", + "developers/writing-onchain-code/contract-hash-vs-package-hash", "developers/writing-onchain-code/best-practices", ], }, diff --git a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md index 543bb0d749..a5b375dd22 100644 --- a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md +++ b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md @@ -90,5 +90,5 @@ Will you allow both accounts and contracts to use it? If so, will these accounts | Topic | Description | | ----- | ----------- | -| [Cross Contract Communication](./cross-contract.md) | Variations of cross-contract communication for more complex scenarios | -| [Interacting with Runtime Return Values](./return-values-tutorial.md) | Contract code returning a value to the immediate caller via `runtime::ret()` | \ No newline at end of file +| [Cross Contract Communication](../../resources/advanced/cross-contract.md) | Variations of cross-contract communication for more complex scenarios | +| [Interacting with Runtime Return Values](../../resources/advanced/return-values-tutorial.md) | Contract code returning a value to the immediate caller via `runtime::ret()` | \ No newline at end of file diff --git a/source/docs/casper/developers/writing-onchain-code/index.md b/source/docs/casper/developers/writing-onchain-code/index.md index 04157a8e5f..e0d7330053 100644 --- a/source/docs/casper/developers/writing-onchain-code/index.md +++ b/source/docs/casper/developers/writing-onchain-code/index.md @@ -29,6 +29,8 @@ This section shows you how to write session code and smart contracts in Rust and Additionally, the section on [Interacting with the Blockchain](../cli/index.md) covers installing and calling contracts using the Casper command-line client written in Rust. +| Title | Description | +| ----------------------------------------------------------- | ---------------------------------------------------------------- | |[Installing Smart Contracts and Querying Global State](../cli/installing-contracts.md)| A guide on installing smart contracts and querying global state | |[Calling Smart Contracts with the Rust Client](../cli/calling-contracts.md)| Steps to call a smart contract with the Rust command-line client| |[Reading and Writing to Dictionaries](../../concepts/dictionaries.md)| Information on Dictionaries and how to read and write to them on the Casper Platform.| From 73c397aa5e121866a52b97e9a854176b4f6a37ba Mon Sep 17 00:00:00 2001 From: ipopescu Date: Fri, 6 Oct 2023 17:57:54 +0300 Subject: [PATCH 51/62] Minor edits --- .../contract-hash-vs-package-hash.md | 10 +++++----- .../casper/developers/writing-onchain-code/index.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md index a5b375dd22..7ba5dd87b5 100644 --- a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md +++ b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md @@ -3,7 +3,7 @@ title: Contract Hash vs. Package Hash --- -# Calling Contracts by Contract Hash vs. Package Hash +# Using Contract Hash vs. Package Hash This page describes the advantages and disadvantages of using `contract_hash` vs. `contract_package_hash` when calling a contract. @@ -16,12 +16,12 @@ A given contract might: - Need specific contract versions within the same package, and thus use both `contract_hash` and `contract_package_hash` A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide: -- will I allow, block, or track contract callers loosely at the package level? -- will I allow, block, or track contract callers specifically at the contract level? +- Will the contract allow, block, or track contract callers loosely at the package level? +- Will the contract allow, block, or track contract callers specifically at the contract level? Or a more fine-grained variation would be: -- will I allow or block at the package level but track by both package and contract hash? -- will I allow other combinations of these basic concepts? +- Will the contract allow or block at the package level but track by both package and contract hash? +- Will the contract allow other combinations of these basic concepts? Such a contract is responsible for documenting its choices and what it requires of its callers. It is essential to keep in mind the difference between the behavior of the host, which in this case is the Casper network execution engine (the host), as exposed by the [Casper External FFI](https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/), versus use cases and interactions between two or more ecosystem entities such as accounts and contracts. diff --git a/source/docs/casper/developers/writing-onchain-code/index.md b/source/docs/casper/developers/writing-onchain-code/index.md index e0d7330053..96580532a3 100644 --- a/source/docs/casper/developers/writing-onchain-code/index.md +++ b/source/docs/casper/developers/writing-onchain-code/index.md @@ -22,7 +22,7 @@ This section shows you how to write session code and smart contracts in Rust and |[Smart Contracts and Session Code](./contract-vs-session.md) | Understand what session code is and when you would use it over contract code | |[Writing Session Code](./writing-session-code.md) | An introduction to writing session code| |[Unit Testing Session Code](./testing-session-code.md) | Steps to test session code using the unit testing framework| -|[Calling Contracts by Contract Hash vs. Package Hash](./contract-hash-vs-package-hash.md)| Advantages and disadvantages of using `contract_hash` vs. `contract_package_hash` when calling a contract| +|[Using Contract Hash vs. Package Hash](./contract-hash-vs-package-hash.md)| Advantages and disadvantages of using `contract_hash` vs. `contract_package_hash` when calling a contract| |[Best Practices for Casper Smart Contract Authors](./best-practices.md)| An outline of best practices when developing smart contracts on a Casper network| ## Interacting with Contracts on the Blockchain From 4f8fa82f763fd416f506e2a78b1aef57b6f66e56 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Sun, 8 Oct 2023 16:54:03 +0300 Subject: [PATCH 52/62] Additional content --- .../contract-hash-vs-package-hash.md | 78 ++++++++++-------- .../upgrading-contracts.md | 2 + .../image/package-representation-extended.png | Bin 0 -> 85337 bytes 3 files changed, 47 insertions(+), 33 deletions(-) create mode 100644 static/image/package-representation-extended.png diff --git a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md index 7ba5dd87b5..8850caa307 100644 --- a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md +++ b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md @@ -1,29 +1,33 @@ - --- title: Contract Hash vs. Package Hash --- -# Using Contract Hash vs. Package Hash +import useBaseUrl from '@docusaurus/useBaseUrl'; + +# Using the Contract Hash vs. the Package Hash -This page describes the advantages and disadvantages of using `contract_hash` vs. `contract_package_hash` when calling a contract. +This page describes the circumstances of using the [contract hash](https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html) vs. the [contract package hash](https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html) when calling a contract or allowing, blocking, or tracking calls from other contracts. As noted in [Upgrading and Maintaining Smart Contracts](./upgrading-contracts.md#the-contract-package), the contract package contains various contract versions. The contract hash is a BLAKE2b hash of a contract, and the contract package hash (package hash for short) is the BLAKE2b hash of a contract package. -When should a contract store or call a contract hash rather than a contract package hash? There are cases to use either `contract_package_hash` or `contract_hash` or both. There's no right or wrong option; like with most things, it depends on what you are trying to do. +

package-representation

-A given contract might: -- Not need either hash for its use case -- Want to identify specific versions of contracts within the same package and thus use a `contract_hash` -- Not need specific contract versions and allow or block all versions in the same package, thus using the `contract_package_hash` -- Need specific contract versions within the same package, and thus use both `contract_hash` and `contract_package_hash` +Depending on what a contract needs to accomplish, it may save and manage the contract hash, package hash, or both. Like with most things, this behavior depends on what the contract needs to do. A given contract might: + +- Want to identify specific versions of contracts within the same package and thus use a contract hash +- Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash +- Need specific contract versions within the same package, and thus use both contract hash and contract package hash +- Not need either hash for this use case A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide: + - Will the contract allow, block, or track contract callers loosely at the package level? - Will the contract allow, block, or track contract callers specifically at the contract level? Or a more fine-grained variation would be: -- Will the contract allow or block at the package level but track by both package and contract hash? + +- Will the contract allow or block callers at the package level but track by both package and contract hash? - Will the contract allow other combinations of these basic concepts? -Such a contract is responsible for documenting its choices and what it requires of its callers. It is essential to keep in mind the difference between the behavior of the host, which in this case is the Casper network execution engine (the host), as exposed by the [Casper External FFI](https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/), versus use cases and interactions between two or more ecosystem entities such as accounts and contracts. +Each contract is responsible for documenting its choices and what it requires of its callers. It is essential to keep in mind the difference between the behavior of the Casper execution engine (the host), as exposed by the [Casper External FFI](https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/), versus use cases and interactions between two or more ecosystem entities such as accounts and contracts. The execution engine doesn't know how a contract such as CEP-18 is trying to manage its internal data or its exposed functionality. The contract is responsible for creating and managing a sub-ledger of resource management, access control, etc. @@ -61,34 +65,42 @@ pub enum CallStackElement { You can find the source code [here](https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs). -After retrieving the required information, the contract must manage its internal logic and data storage, actions that are entirely opaque to the execution engine (the host). +After retrieving the required information, the contract must manage its internal logic and data storage, actions entirely opaque to the execution engine. -Learn more about [Call Stacks](../../concepts/callstack.md) and how Casper manages the calling of a contract. +Learn more about [Call Stacks](../../concepts/callstack.md) and how Casper manages the calling of a contract. ## Recommendations -Consider the following questions when designing the contract and choosing whether to store and use the contract hash or contract package hash. This section summarizes each case's recommendations, advantages, and disadvantages. +Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash. + +1. Will you allow only accounts to use the contract? If so, what kind of accounts are you considering? + + |Answer|Recommendation| + |----|-----------| + | Specific accounts | Use the account hashes to identify and track specific accounts | + | Exactly one specific account | Use the account hash of a specific account | + | Any accounts | No need to track by account hash | + +2. Will you allow only contracts to use it? If so, what kind of contracts? -Will you allow only accounts to use the contract? If so, what kind of accounts are you considering? -- Any accounts? -- Specific accounts? -- Exactly one specific account? + |Answer|Recommendation| + |----|-----------| + | Specific contract versions| Use the contract hash of each contract version | + | Specific versions of specific packages| Use the contract hash and the package hash to identify each version | + | Any versions of specific packages| Use the package hash to identify each contract package | + | Any version of any contract| No need to track by contract hash or package hash | -Will you allow only contracts to use it? If so, what kind of contracts? -- Any version of any contract? -- Specific contract versions? -- Specific versions of specific packages? -- Any versions of specific packages? +3. Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be: -Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be: -- Any accounts and contracts? -- Specific accounts and specific contract versions? -- Specific accounts and specific versions of specific packages? -- Specific accounts and any versions of specific packages? + |Answer|Recommendation| + |----|-----------| + | Specific accounts and specific contract versions | Use the account hash for each account and the contract hash for each contract version | + | Specific accounts and specific versions of specific packages | Use the account hash for each account and the contract hash and the package hash to identify each version | + | Specific accounts and any versions of specific packages | Use the account hash of each account and the package hash of each contract package | + | Any accounts and contracts | No need to track by account hash or contract hash | -## Further Reading +## What's Next? -| Topic | Description | -| ----- | ----------- | -| [Cross Contract Communication](../../resources/advanced/cross-contract.md) | Variations of cross-contract communication for more complex scenarios | -| [Interacting with Runtime Return Values](../../resources/advanced/return-values-tutorial.md) | Contract code returning a value to the immediate caller via `runtime::ret()` | \ No newline at end of file +- [Best Practices for Casper Smart Contract Authors](./best-practices.md) - An outline of best practices when developing smart contracts on a Casper network +- [Cross-Contract Communication](../../resources/advanced/cross-contract.md) - Variations of cross-contract communication for more complex scenarios +- [Interacting with Runtime Return Values](../../resources/advanced/return-values-tutorial.md) - Contract code returning a value to the immediate caller via `runtime::ret()` diff --git a/source/docs/casper/developers/writing-onchain-code/upgrading-contracts.md b/source/docs/casper/developers/writing-onchain-code/upgrading-contracts.md index 55b061a29e..799a47ffe0 100644 --- a/source/docs/casper/developers/writing-onchain-code/upgrading-contracts.md +++ b/source/docs/casper/developers/writing-onchain-code/upgrading-contracts.md @@ -9,6 +9,8 @@ Our smart contract packaging tools enable you to: - Version your contracts and deprecate old versions - Set permissions around who can perform contract upgrades +## The Contract Package + When you upgrade a contract, you add a new contract version in a contract package. The versioning process is additive rather than an in-place replacement of an existing contract. The original version of the contract is still there, and you can enable certain versions for specific clients. You can also disable a contract version if needed.

package-representation

diff --git a/static/image/package-representation-extended.png b/static/image/package-representation-extended.png new file mode 100644 index 0000000000000000000000000000000000000000..a2dae97568153d8fa3c26b585564fa591a4bc2f0 GIT binary patch literal 85337 zcmeEtWk6M1*DfH+Mv1*ax;H7c=`LxIRvJMXq(j&=2-1yoNeChx5>nFLNJw{g_g$QG z-gD0VuJ5n=^IqIr7Hh7#V$M0nc*ZlH6{Msfh5nfEF#-Ytx{S2A3IYOhGy($R1n3d4 z2N$=w3;_X6##~HHNk&YJT*=zKT18^P@$PY?0ULo%#?qXvG~N5;?FO+1?Ye6$Rl(&$)^w1%f!)m#Rc%I@LuP zFj40lZ}5v)9;vXNk328J@>RLIf`|j15k+zi;AO-J71|kTs;vV)0>7##oMJ$&SO|`t zV3b1%0mRlQa0DY=LQd--29JqHTg(x6e}TRNDa;f<-$5Cb_Z4IO>XFH9`pWs7N@Owq zp*|*&JXMI?t5viuCw?2P3aknpsK$;^=OvwN_~`!j;?b)EBC%=uk0met;eLmx ztYS4FzYP7&=~4z!nP3{df)`r&(O(FzWRucAm3HJcUxPl+5*o0(C`X$xl4^ixvy;do zVsL4w@|Rl6?Ol{nH{tsR;0HY9Pm6dST57%_?0mQwJ{zZd{$d6j11|E&-Wy!~mP3qk z_>~~mxf~MpJZ7Muh>!rY_)i9838gz1jeO7V?=4krqTY&=!jbF{10P-NSBY}UvTZZr zTtDJm^n$OoXdLOkJiU3@;h%&bCdt~`GfYrM- zOY7Z!$H@6BHI?15^|7T>nHhCDMz!4tZ+3aUmo)tloU#eqHN3KFtlKY9jLzK7&Iljp zASYZWNqLt-g{U!a@D2u0vg?^5p!9_7=y zAV;7d^kL{m)<7Vd2OZg==>8x>_GJM-Tzt+Zjq>tMtc0yl&kr;fB1VLjPgsm779!{q zph|C&H{25_T0it{kx~%xns96%On)fPB@#gKm}kNl0sHw4LLM2s*MK?&K3NPuC-;%Y z$MU6uZb;Ka`$~f!vJqWiqLbz@nyx(l^jM% zNy08aS#l7{OVVcXt~*vBGl|7#{xlQ({=`aB@e|$P{ie(Ck z2ajW)fg`Z_gCc@%sIa>HmPH?vx5dD-MOApsNzCy!@Hgo5l8@60Br2(DV_Lchj8JPn z>PXDW2+20cddiZ1T36Yo^ZW=8_GXJI3oVNsmaLK6$U##&`GPTu@Rp4;{=2u9yj5me z&TLl0*zj=K*x^sYV(PJ^V%5TL>RTyeVuhF-9!czBV#(q!2jhk-N5V&T2X#j_9Nk=5 z1bua-^<-^6rDqF&Y8*E)ix^&g`=nyceEco9h2Brk46&io5&bQ>p=U#R!;{4hnz`!n znHI%8Ln|BoKMQ{fX1l$p(u>I8mW1gRi`WFsD%2mj4jju|o?hx-BHggvFkRA~kg>D) zqx-hZvo{!88mE{z5`oc)(W)QSJc@l(i_V93iFShCL6}2`OEgAE%DQb}Am>ICpE#h? zKHX8*b!}#3-O7bU$i(%Q?fcu~ez>1qN$Fs9Gd$t|eJO&5F@_~ZAO?qqiRMh+?xpF- zK@PhdcS0K14v9WXvlp_Lcw3+cr6;FYUrHZVpGl$>Ypv0kjkP|hJ~OADspoLr_XeMe(Xgw?7(tf9buEDR7s}ZlY zSK44B_U)jwt5VZy#CpWk!koy0f2wlmRGmLKH6pdsx^PCb*7+3U)co|xj`nssFFwC5 zi7YW8$u93Oi7#<3{}{inGnDUwXN9-W`TJrhpBrCDibX1{_7k%%vqAg`b1Ee&rH7QP zXw9d9j9V2WbTu2K^VIAK?al&UC{4N?x+nE4M*;nSDyPvhYZJ4YiGHQ`Ce&v3U{VU#OAR0_SQUg829Z%_5{%8cT(T}VEO2!T<)?WFPo|ppv0*K}QRE%9XNNGD*=h;il^NO2$H{=}_MkK!}*D%CB`J|C7_OAIj;VnT&o*x?F=2Ty=SUDDdrYWr2RnXozbu5v4` z`05qq*BWIamD=3?0&BaO+LQMu>fFdSX1~lDO6`|Aiu?e~C`3RIGH3 zjTV}E9bc5{CvQ}CTcuaMsC3?up0@kiRGXonJK1j>W|oy%YC4|%THPsN*V@Y7>Q`Mr zO|Cs`B7frQN-p|ULB4%zS%vUt)x!6=7CyQ|UDT3XtaI?uP)dEp~NxdW-F z!VZUwSKFlyh-(<>XZ&94?*~4_h3MiX!(4Rv&O_E-t5v&xH;;YeV_Z z)fIJ~)H|*6on5vO*>UsP(BeUF_Dl=`-nj z>BW0vp%|||9u<&*2@{lcbv$FeJ2;wKZuHn>b`$kdIT<}PZ(%<(4RC9AE4mgsINMzt zUVBi#;<|FKTS2xO?QGE4zdu2YKx>#P<#*6(_-pxz&&bR8J4a%%)9k)y4 zlJ7u3IoXJi5J|#8&~e^n`N&!&Y)Eex9TyEl)`cx?lg_)z-^BF6{#$;8V@Cvh_4y0^ z%*(V~EO8HRRf_%el1t_hTdlcc+E znF;F-z_XYb4O}SRqmO==PR`H&xNK?~(AF<;M&J>8?a}z^F=Q5<>mmIRx?z+1e%Lip z^SYPKvI9L7$SvT;8ZsvG@(A?6HVEM%A{N2}U<(oWhk!_k@bHgq1O!<`qQAFQ5b6Fp z1_=Qnz#IYjuVb`;-}gU}z!&KK*KedxNdGwkIr`Is|7;^p+#kA{uF44fLba9FbO6#E z>iaLEj0)900s>OH`6~@a4S6{}LmMk*eIpwKV`jLO?R_r<0XQG9X=UuFPY$=Tw07Ww z3qt=mf)Cif-wlJ3|8a<;g&cg3=9Vq`i$$!oxZtP%a zZ*J>oZevY;e_nk9n|F?aQ0V=I{{H#%J{`?X{<)I1!(WdDJRt181;)zE0{dMzW4QT$ z>2}}pXSY9|>(9#x+@Fk3Q^nZ9#`4|$Z3(e*a0vWyiT`cyKR5VikAFI-TAMoxvHjKM zf9(FBy)^!5|JQZ?z4w3iP_#EU28Qy_JNxS*|K9hnYtwfYWb_D0PKDW|23t5u9rXd0t-gyu>kDv#V7Q57mq&x z0YL;oM*R6JIO29HYTfIRi^h0**>4qJGNtoMe`We7y?iMut*R8HiN+csL8WZiry~A- zOb#tilPVkQJ$O{^=k%w-(u!b}yW69JQ^Ce}&SRwgyjRn1{(Dy!({BBfEx+7^-L$r9 zXU|@j-Gzxm<)UA9PD+VynObcQlQKxJIP%=o{pkyToysz{@Nz)aQRug1n3 zFaO)Q1(19nq0@h6S&^oHnDrR)+o|_Cr6s4xyBR1ASNi>FWGR65r=j%Xzi79q|@O;{O=``}P0nDbOz4^hNZy#vuOb231=6 z?VUpb<7^^QF5=ifWN4mZR6VDf_kFug8om7Q zn}5XtrdKKWjgRH`wg=q3U$(u=SB~E|n`z&h=IQ9>kN@&?I!JnqRXnjYNPmo|46@Mm zzS!Ajez6JZA+ba6Lc{GzaqS0OEjovqvst%+`lEjS-4R7$`PbI7E^F`R&fB@C1&(@S zzN4|vx*y4(RW;u9-CWJxg)?(cS(ab0#c3Fza$jwiOU3I$uMRJ_ifbc;F6rJ8n3U+% zyPkCGtdiZG2e@7BR5|p#|M~t2^ZIIvL;vXE{Oy>w%}U(2Ubddb+Sv9$W(YH3 z^6SL*ll}vb!!Fub^HSLKz_syY?OwxHabbZ&=jAqbN1~IWgPiRm{zw}7$Cmo4?XsRj z)jvlaSju3E$k#`~1)pT@X94)ULDqHMpyoDc1zi!`h(Fz!sw$qcuHDHzvRXXe7?}y< zo?Rz$;bOX|>88)G_IZHveI;H`h&R7ykAJUjWai!Y>xP3#;3<8DjOI zr`rDJ9B&4Is>Io}!@y^z#oThe4iaabRW`5dC9;`nyQOKe+x>vv6|OmVhpL}y+82^u zzuto=4Lic$eM~gYk_@vCG&YwsOmct&4`~`q87PfH=3b(0U9&PAd<&^8K`4gy!t@}uh{0r??#W}+W!Rbdtmh)}C1rMddi8mfLRTzV-=q&0_ z#(JJ=fxX&831YfPSbZHP8oll+`YtwJ=E&Kp>$(`PvW37Js;BHaNM^Jw3S(=g3#(=~ za}-iHhyAKx?h8+DCmvyvZm*_$-Hw)laf)kJ2?qq_&7O;EnWny*7P{Jw(ZXP_?uRvA z+jASXhxV>i&Uw0Vn+<;IHLk|6ZoF}VEgCcN7Z4PpM? z`9#*-n1Wu{w&|gHIp^!Y%#<$;@EUx#SYU+T8y=k`0OME{v}Av8)hIw>( zY-!J3HljY8YdEXlyU17&zCB<1NS#8al1kBg6slYlr(@qWN-;;!7OdY)pexv;;SXt_ z^}4$$XtNJ+HC@rIcdfCioTRB@OemXSG^FA>4aw*&57l1>zQdEVvu=B-yu_FHj)6Cr zcoK0}jcmss)3;8dLb1MNQ85m&yw!)r+*#6%^rfpCzr^ z^{j|t+=CHk-l`{wqSP4Da7BRPA9qUuZ{ zA$Ry|>9X3{O?oYckpGf{RA3{b%Ir9Dy<`0A1b@1QzyBW;0bDyFNL}LhClKL>m|Yr8 z+0-5QC-c~4*4~^>&Gf(;w@rEz7H)6P8n3E_46dXLssSH+o}J<%!!Whcx}hQdiOvU4 z7v5A49PVj{m5nQ7sa0XgMEi$V`uozr#-Jv0lA5&Z&B^!-;9X{7)pZF3DHVk-vX=%z zhYTbE<93>LF^%Wm3@*%4gsdYYP2&NUcM#w@p&wAg-p`YTjiKE^2b@O|8UOkA+}&-J zp*vU-eZ;LHOrZ!v;y+gNX$8dbIg-O^TcfInxz-3nB894Nu(x)nGMWGG`e??+^N6Tw zSeAhr&%A4H{I&CI<8>YX=O&bTy7FWwGqx)Fx#=aFIRV{q8q3C(0$iGt&jup*!F`<3p`qT4% znnV(j0dK^9*2_Lnt!-2PQxJ%a4eP?U2NBkQD?ZNHap>nYO-z2N`R^%z2;zv1Ai1@MSILjX8QvX1C|2w*m$w9tl5CQD`7*OCVe*JoSyErmg@YSeL!Gj;V1M@7-U9_ zm^Me|zVAZ@qNs_jSxcMpILX(0=iUu0FhqL*z6qX;zQlMQbS;g~8@;b`d6a&)jj{+o zXv2Fw*WfYpn4w^PHOZnVv(17RV(WF$qc`0MAQ4Szr8T2BkN?iwMfiMjAkjqtL}2bJ zM?oiC?&n=gITlpxU1;-aLFcYEj((lWcIhHKV{(#r*$c)F?%0`1h{(qu0c4)*r0{t}ZmVA$X8`D|y^oPYD+%WSFmXYQ z*|O>59CuuX=om#wsKk$>K|rW-2`o+Zr@t%~sO~(1sN?o|xlI!@Q2(As93*)PDv#@f zj&hJt2dSH-F>Qz^1?_Moh1m47+>}LiiYjo;(>NfQib_Pb#^|5{v8s#=no8PVrn9w6I1?I*3P1@CcW975K2WLb<`+Mke2cR8` z##aEkL6?*MIG-5#51#()Ux*&ZFhiQKMGg|6?ggXUVW0ZTW;l~?2#ma z3ARm#`~mEco-jtb&ZzPGZbj-a1P=&!+z*euR6*2M6*%FQop53rJk@u#c- z*$Yx6?>;&YDaOh0q{kWuRcfyKVJm!*GfnR+s$LB4J_gpsxT0h=9}sD-of_|M_G-hp zesw~S!0fIbn0)KxbMs=$6s0bWo;U7$%(}?;(31anP|U+vu+r0#P;^w+ZD$31M(2Cj zsVy+G#ODS1?!3K^{$zg{eRHsuc#3EM~3UG3HmK?&{ZK&~wTn9df(^_7jJ z2PXQCG@@DIysP+R!9V(KchHD=2JaU75=@Elbi?aSXf~yYSNU|TzWuC|mc_aQoF6&i zVk9sJfJYjYLO?`~fC@yynIp)AXZsRZvmyhHv{yZ(P(ZqNel_eMsb3B~V?(+BILbhg z9ptyp?0Fu^P==wantSMHlUT75ltCNC9rp7cL{W6N zqQOw=Xj!Ir4lFn38XMit7Xl1JY5`m5y({gXC^dY&ejxU6qWiIWd)wUf^`t+6s4vri z6QtxGt2qO4W(t~@4uqzRDYw1)muu|4v%G$6w`R7Kbw-m*5yHEV(D0Qeb0^AS;~^=AHNyZBr~PZUvt5$DEm0UZI-$MQYo|$L-4bbr z_>Hi6>6()gqno#uo1=NUwj4uGm7^?#R?$ZTm)c&KoEOxqUx@TD_p$X0UV2a#|0`fKNzm3@t7Gc&9-AN(l19G~-6X*MSvV(bM=zxBbb z;B_M|>uDbDd+-EU@dS+vj1-wQ)RxE9lC{o+5i#52k|4+{fY@G|0upqMkP+yY@Zs#K zF2Ly5U92YWW(1HPW~~A>R8oD!3_6q0k5wyi+D-=?nL0U9&OmwMwB4io#uvX8FPG!(w{5pSsrQnZu!$F%}X)S~ZA|G~MHN?+;Pm0L!rR5yHI= zL)*n5L;P|-NQ$I*h)EcF*J}F8Q=Kt`stFF{|4zmLbfYBflLL-68%)IMGd1cNKa`P( z+2_S(H`7r_;Thu2ZaFl2wR9pPjVrkleJJa;Hkl_zwh{>WaP8w=k znSOhm8$OMDLhQEk=CL~kG1xE}ol6H#%{R;cD=M^EW)!__Vh1Qiigk*-y?c0l9N(7UP`r=#(V4>V<7G!-;w zC!y^9>rkj2Z2p~iLJC2crl`f)l#Q@3Dn-avY({(Ei~hKufTs|-L53GYK}#Q6%W2*3 zXkV<6yhjkHRoqLQ&GP$Y-#8NW{`?xiQJ0aU6YSnBn&LLC2D4L+;2{FTfsf0T$J+k^ zfA`cOj}PprUIpt5sH4gF1rFV@m+gxQ5R zI3+YtC8*SXB)@OBFoO%n>eE1nCQS7r1P-Os&jQ?8^e(#9>66KkF$SKo+w)SlJxva9 zencT*vd=bvliW_L1A4|n#QFB)lPr&={E&0d?Vb)=J6QW7_ysVV7Xz;#8o$2@60(U{cqfcS7xdn@&@F9Sf}V9%Qo66DOD z$;R8;=@Hlg&BPi&vcIL+T`CQfg7vhADxmMK#VGJ~IX{m2k?awOs#to$`EL@5T!CEo zDi}5unMbp(u>hav7+(L}THb-yWDGdds`Md6SM~!*))osIn(PU8p|eR-vZ{W*Ex(xW z?zyI%97lYQbAMjm+^0!+&@XWx6q(&#o`&LvytJ$o<0dKn91e zcT!l6*9nfuQu!sFF)xgw^@9o1WZ?ma%pD^vxbKOW2b}BVAnO}%N+VB}*)Ey>mAWW} zibModQZvLz(EGJvFf}}#<*5FdOo4^NDj8U|+yGZvc2a9LjURXQC5UB$IU}Rr4n_-p2Z5KfSs9vRqt@0b+QIA~PR2zmgQ+iT_fLDg z;OJr;ITbXt*DF1!knl+pu)HdMjajEDDcB>&C`SEe0t)yylBZ! zs)#&=_kTR74|txG&?9J^5mFGKPP)cFuptl%Y}3 zlMXSu-VeCi4=}YJ<&z8WGgLuHLmiQa2n_Ts7mlbHlTAr@Q3wQlbj(8MWja&-%|d>1 zMG|DD^4PJ^+bSE^MCGn!)L6pwcjL~&l4+?9jGE`Jz|(VQRh5Q5GlM)2ZRc;sRa>=- zIino_qaBJrV0d7YA)rrp%$Q~0IP1DKxtW)acA%hglvX0oJ;R}HY1qhkP_?tfP+Yed zkW)2h?2tVzSxyyz$D7v+-U|+tX4E@9@b3ubUR(@;S=Yv1b_vZhN$wT_p@-+_D0)eo zplb!dy9DF4&Nj(~187KaVJz#9MxFG2GSHMBz6gXx^aqU70DY(1+C<4CkKm8N8w&7& zPwsSAzdsl6W{=ZfmbCwRa4nMJ`OaiFJ7Gxkxf#g-zi4fZ$$>W`l%u12q+*Qb2d81G z%R-bbN%!CUXc_8pb>v5P{Q&fy?bpRt%t(=%DpVyKrHaU~I;URW2Lm4~qOyXyk_eSu zBwA%xeS%07?FrNLk8wu~Lo}MnIy(32W(~U^4-n~ty6Tj=c216M#Ot7vEy#P!hG0@t z%Nti-6_e_)GEFQM`_)8Kr^$DO>Qu!v3-7+E?H%}MD&h+zR*{8nC(uv>Pht}& zQ0_JrS6(N7s-3=pY}Sh{ijR#7rYAZmcri!Rw_%P1Pxw{t(~spxg0)J!$2z501W9|h zY_U`?SMQAxl-YhFv4-w~aG(GkAR0hvE{SR9lg0`X1=aePaf3H@CJ0T>>;m~UqxC9VZf93D0_5BH?p!P66!Fed_lz#*%jY*%rLTP+sUs^c0$x=}fH*#j`jnK}LohH~g=O zm7zIz@d#%!ib7|Oq)7q5GT^=2H}bgL$o0UlUeSNCOFfRB@e}@NgtY|$6e#MFG1g^& z-seVYBf*CXj{~@h;p=-YsInTfZS}%e>M`#f$T`GiR6>2MwUYdkshW0*B#Gaj^#)9c z*<%XSVoXWRW?SFlak>FXD#Ou|t>VT86{`9Olb@@?s7J`k`ts#!>wTF9ifr5W(0Yf( zy&6H^p6U@T*{gM**n;(dG-^#t74ESLRv*x#Q5&Z%9nk-UEe!&y>3pHt;dh~iRH_3kSd}y`^Xd7 zKrQ%5P8hO!yUsAb z5+9JL^iB3$r_odUT-8}gRNA{flvNuj{pve`dAN=e8lqx?2;C2mS0Z}c&=jiV}(}$`20KI9HRR!kw*fHmcyjW%OaffKF58f z@+e;Yo-q_}l2L{Ao>tfB8^_~(NagUU#E8TvY|y?n)zgp8XTF$12~!lUffma&1{F%; z*=2%a;G~1l`?Tuj=;U{)El0n!st2e<6YWgcZqhvz8pH1bLQ^W4%{zzhfZ zRnkzE`qHL4Mh{p-PftP{yH2nODa-vTr|o-c0C3i$DEs8)DJ^1h|LY`bbNjZGbfBu@k0w$bOm+>3BgGqRDw?s1-0_S^5WA12b(YN@xl3BazjhC_aY2JHL8iGs7KL@e*#si4k0O0{rv?8_8QE8LyA<%`6qq0KVGo}pc9Q5tDE&Em5dro zc4N|)1dzI##iyVJ%692?+h%johjLHbipd7Orq#1+!-++Gr9(hcsLGTW5NtH;(r(+O ziA(cL!st6ddX?dx9W_s@qDjrYhGG%X5?Dql(Tn4iM`MDe&s&j?@dx7?ESx$*5p zL`fKuO3L_wuYK>vxL^$RBpJ~8l>C%HAg6Vy7J!(srC=w`Gv|8Luxql zP;$Un*M@4#6G*|s>tOLZ_Nc=3%KFnlJ!so>B_>4%jos3zoxn6(&D)AV{G;uc1HJ1- zJg$6gVZ$1dx060b6IkfyjE2V~{Zerd3<)}K0wg)LG6TsY)Oy`s_O3BS&$xHn`ZWM8 ztX(1XD=s78X7~l{Te>w+SlnC87zPr}f+0o*l;cL&afKcbvtH9sGE+jy0Xa=Fja=$HNFH4L%Uu#O)j zC40*%xY0ysT`1#y6lm6RbOn?y5A@$?UUb7N$)QmpR`Wl6JYQ8Z9^~+UnUC#l7<73q z^sV5gsT>#aNfd!{h~fCRX%f>sx5}nknv1$c=P~{-Zl`kEf7SVY+97m36glR8RP@Pk zN=?WQx=otztRN`kaTM%n|6D}TvhwjHtTbE^iSQ|IbO;yuO zWudEX_gCs53e?rlkEA4TPvBadVBqID>anVtSyd1?Xth;Y;ipjOy4K1V{PF&tFbR7j zQ={4Lfg211!DN~$03WtK0kCoElbpNUhdfbFxy_f~G!e15>`=!qaj$hBYTBhjgp%WG zL!yYi4r9_^)e&?pmCboxwFUpIc#0$tLa_b@U|-6w7rJoWFtVS1?vj^7C?>WqNOj%J z6Z*)+-~~Aw3T7x;mkh;UXgjD=TH6)a2Cg@5^?f6!;X#P0Y}&#JhetV648_ zNV9##L06CrU}bGq6A1*)p8OroJ0Wl-j!)s(R%h8BLAKYT3FcPQG{$Kpp~vUYLCq@l zXD|*h2#Ou=RCHA&Kt(Z3|8hP2$yC^R(l|beD+~p+G7a3S=M7MZnFhGF7TS3e4nF#B zj>oXtZ8q3wDR=<{lsxl5vbOVegGz72i7kP0_o-mLx}L|kJ9ItKCh#Nh{Jz{gKKO9` zg#BvA#*0XPcRJ9p%F3P@(h)9rsxikR%GeqbM!F7=EOSrHoMtsqU?Gr2AxIZo`q-4VbqlGKb=on;#+fdpZ7tT1}Ypk z?r9GI+6cZ#-zcaA>t2$Z$z_(Nm_ut%WiR8^JElE#ca^FF_B~l(zO` zw{~y$zS6fhltP1LR{$4s@EFN!D=iH#_=Y-|C=N0l?tF>wUrM{SRrMD|R>6j-ax*BS zR?Hb2+1eBd#;&@!Ih&iKtwY0%T#nb*O|>PRGk*hx;^fWWQ!1X-ZawMmQRIi0s2J1B zY-(2Gtc!KFD@GK6x^Geb_G20Oiz#4&EO4X0h+wNpE*jH!;CD$}gb=)k)DLcltb8N{ zsDUL+7#nu92A*R_)I0cOepb7&0{YWv4 zyg*#IP%D~#g3?p0Aj-#3r)z*m3T4tt^ba7^FDu&w4G#LhVeNHD(KwWeuy2gLTvIsBOvX{C#3o*d?&T0K!j9d0F{TeCWr^xSxStNyCjSIyayeWK?c9v7s{mc&Hm*_Wf~;ySh=r5ONK>RWFmMM zV%r*n8bR@htn+f|cEByb)C$ul#Y%ba2T_tKc}MdRw|Srp+%(FJIAZpN>FVGTL1G)V zrvJa=o+1|A3+W^)leTr?6Jk&phwA|f8vgv<<}-#$W)#^899^bkOd)uw=$jb zpE-LApEA%|5YA%4pDUZUU%ii{C5-#{VqJ}`%T`S@Ea|KXh3s6srFu3-@o_u{;oJ#f zZu+cAcwR8-;Joj8nLNdSdCcJPzGzz5; zsBsJo+3wG_CQyqhb8-F8p49NO5I(G$b9NaHu84N~ zC}s4pCq0WRfrIfJ{W!YTeqXz_d=a|V?lB|TY+r4>vr!U7HTbmWi)9`6#&w?5MCpz# zdc(<>cKDELdFW1*DU9aYs1Pr?!y(KR;{2FJ5ld)aVu@9^gc1~ zAs^ljnI%^mObz8F*EJIAzvNdwYUCoMZ&e13Bn)wQ!*lSWgNgm(AU;s!VZUtX*4xBY z3h&5J6hw6SP}`3c`<<(kTVublQDq9>HFQsF`%&^e!OwddHM3hj!L>drB9OV{)9zfa zD_v@J+{z)E404f_%Pfnf{d&6jvu910vWkR++Oe}U>0Um$DlGL&?2pXC=MZ&Xajqbn;c0Q$)@q9a-heEz3WCIi?K%<*(OX|VD+$htgL%j0FbNQVTlMd zvBxSG>`%8~bM)=sQfyoPR8>FG&GSpHjDf$8XOg+-A`0lhZYJc7+OCONKHTh$B0De= zwH1BUl7&-j{&!u}8^l3`C{WVFf+}OI^ojtuI49&smd~_w-1JA=%AqW&+_*M-6jJyb zW1)+bUu{n^?UgQ}NHfyjB?FDuD=?voL>+0r=v-8qI7QH2)_uJy;%nfC)KWN;IE-DnO;eK2RI3g`D&rAq_q7 zIhAQgKOjI#FNg<6WkZH50c8d}0yX(Q4ZixS2#f(eXpjhyR^9Zhl_s+p2iF3kGY_Fp z6}t4hs&$sqvVDRtJWJUQu~bWY1k31VWq_(}oUpE>oX36>3Q5|>`!s~{s)cVRaI6`%ns1Q%$glL<8cXuU3f8tV8jbCDSJpaW(|G-sObp#xA9JGnw`kqEvdy@1$i$fyNg;P`%i(Dyul zmP1#XDyqH3KkAtbbE*lPBI=cEX&bHsk#%*(fK>b5vIv^_R#lHE zs-L3rTfhT-l=L>LkD-ybuXj5;rKC||X~yz0uLMHCcR*r6X;qoy%#IkH?r@90!Dhak zpxlr^6`OVyHjYNh8Cud|78{D3WCHR7`2cBn8J;reWYb9O%^OEPNfHua&pO5Su!L6W zVi`(-$kvs6_1DeiiG#Lf=?BafCPVRBfT*wKLQ095_~MNf{dOtu+h4K57qEpf9>rfh zG*FQNN?sS14}=^;L5VdC9Q~br_CU?}dlaRVWB^evcX}jY^W<{SsLq-VP{O|##u#iW zbYWBC$XE4?Oy7&lX6`}feR%wWfVB(0@VNxUJ$ImkXx_coRjpVrs_#?h0~bKi0oTWX z6(>+|ESyNJ&jTKFTWkh^IpGtTNn?G;>#dQ0fj*$#DJeoK^UZEVi%I$okhw5bkEfRR z`1KPzPuqFY$u>*kyIuq8fbwLUhKuV?88~7Bc!Kwp)|xamF6UVdbowoj?+XEt;G3Z? zhZ8bYVEYsE5qa(tU6WM&ZWBg>be%0f3+uXrc3qKrfQE60lk?^pJlX=>Y)`8DVVCa5 zDWe#9cj)d!S<;vX@^SB`(Acl&Ke?tOaHN#VQOc8@Ab{o$LS8SF;#gE1gCo_+nXUVK zaRf3M(WcnU?Zmv>=1+&;Kvroin2~@LMt7N)n`Xb)c-KH#$JB?bWBVNDbiFPmd}x3I zjb>Cp;DS>xP|ILh<1c9vuVg$r+gc!!{7HLXrDCt2_+Jnih*Fu&+^v-li(L+p($FShw-t_K{uaMB7|>w^66mk zg`Z*u`;1qBP&BFA`^0kjd34A))}iORXim+n=)5e~LvlDYajTPj8WJ}O(c>XTJ>$*h{C<*WSppe=EwWmNl zgJIXS&JV4&r!-L3W?eyDY0G4m?*K_ahmD-oxZ<)%4rMKyJ{k~C*TkhT2xM`gFaSy{ zwP#4O452KXJYZ`zh6ktm0AM|;nU;Q~@ZRe54iG;l8<)#bs^c^h&C2X+IM2LW8RCBO zO#W|CAYF`zR(;7YD{1MkaS3sF_nK%d&^%()iIgFig=dt@w>Tg213*J`xwDkoRJqN* zQ`-ka3=96^gFsof@WC%ojE+cbAeUebJdlW^rqNVb-p?2AE*&U)LYN6k<9eB^(8n0O zQYLv}Xk6!%=5eYCsAVd8%i>-;X;vK%zc6KPkrU^{I?p9Ylb*ZTb!Hd48y-W?T~clR zfw-BHS?TxxdZO56f5_`zvWtw1$>@7#@8~G> z#(?~I9gf7o2b3lbnhg|HM$JvU1F=F6RY&0zn*DU*?+48^u)D>X2{a8s^QgdWz+5m% z>)>F-kx+-{3S`J3-^O*PLS)Q)-n#A}gLC%TnwLVr4Z_z8m_nmWtEuAnWcs#1vY&d7 zi>4)std_;lQ18T!V>tZ*(wT8N#uR7U_-|Fu2J)+NMbj+a`yG+8ZyGLE9j?1l3_n%@ zOc*nt0S<)_T!Rr%7K^H~ArdzENw5-5eSG%PT|;w>M%qsSgUbGJ{zG=VJ#OLU8U-or z`+BDJfZ&;xMP!~fehPLt_(gISqenCJWDm3KO%OBJ| z0~DKSoq^H0ED<~8IsuT7+sV&p~fp!hM3&OJSU1Zrz`DBux&a`1Lzyf__?27E$j3?jLv&@m=BIueJh zQvO(uRpmGiu`lbUFH_X)cx6PIRkKsQ6kaqgrw>8|Hw8N2{RogFO;t$XgWhd4_~RoKrE;x{I7Xv3M~Q&nwHv$Y>or`_}vRTI#`C5dG)2uB=_~{tR<%I0kl@j2p zV--7lznGW{$_7$U!AV)(c<+g4uzwDmP=Wb9#M2oJ=)XDd5bkFT_IOU$&DMRnq3E^g z@X(m4!=W%xq;g!>twuu^%0OiDF?QvfQP0>_S0y-_2PP2VGDh*ZJ=CGs%=#X6VYY}W zX*u+98vbwMmt`#JeBsri1dUHtAF^BRHcfp|{pzz9oLybSdNv^#@fM%=;&ol~05xs( z+zRk!Lh)M))TpB$4=|5i*vrDNTCo)!rHJjst+P-O&07N@yMXNdgo4G~7|Vdwa-w9K z^seHBNKmjYym>FxR-QAdu-k?SY55aWlidKRCK6=zA|IK2kX*n9P^VjOe2zbD8N@@s z`x^gv>Urowv2Ip@%W7iotO5NN_f#zkD|%@t^KS6JskcE>Dv1DXKnNm5d*z_i_;@Fhcz5DLq2`_Z~#rZQe zBcj`qBc!2DYmx%OhY>ik_q6|VQT9o_e zShYjaT=>!LX;tG1sdT9ZeDArM15Zw?~73IxOq`TgIBe|ZWW?q(?7hKF}*1t5^>EZagG zpOVG{?;sovc=}~!-|Ja-XPoEWVG8VfE4Iq>aPp#Rs=rr>j{7H%=LiN+tYp+qiM^N) z-BW}gBBUVf=x#LCb(vOnlV00+J?uGa`-YjDw@bf4GZ2|27SN8)NH^aycXfdL;71*JQ5OnE zaVUc&vT0uSf(Hu5%R+~=3!lYNkT2rEIR6AHXyiTcH8j*J117W|i$pmM8#RQ7CZKF<#YIc(UZbf52WW4YH3U|dhu z*iL=jVW2n;qZt2OKf)>*`h!38!HQqxiipLL4=Fwq%+kV3=j{TyDO{YsQ)W2*x;1kJ zghayj#pEDpHms}@YJHCwG_IFp6ip@(aGvvV?khF>;;`C%z)}0+`o>@L@opq)-Cpxq z35gSXJ&INO@w2}Ij`9856eu$EMxY1Bix7Va8*9Ndwqx93Ixm1;B}PYd#m)=dSAWr# zcDVk*q*Kq82!bV@q-A4Ru)Tz#_?*s+N^DB5_fx<(tt&vxxr!aSc&RA%Y~%GyE0=G~ ziqe{FXoX{C8hZdK{iUE`F__`I7^YywA^+(Ii%q=7^AC!ZeeTga(J1EMeySaXINZzt z+TB>yN%bY&#Dw!QKmhs5kIH1Ic18|oUGnuyRJ2P?B*b0CW(%`(nlKCQUc1ba zk}HBg0@L%0zJCQ0w>A@0ukfPjCTs%bIO3Nw`A&YL%a?x_v;G%RX8{yt|Gj+)Vd-6v zTDp;t6a1!L8Tj6M7moEL6k;CIz&LMTxVPh09MGH3H9wZhSK+{8Yf;OpPGpn4P2h@@5|m#*rI>b_EhB?R5r*@ z{N$GRW57-S6!>6v?AtbZl!v?n`t-dU`=709y=}s)gI%CDO(~H0h&;;-S+2jPkX3=> zggaJ4%$w?c|6ZRzt1-eHIuMhs;^Q~~wN^4Yi?-U(jXJ1ikm!AnM=SShbX#4)flOc= zpvFBE`oK2FwwtEVvEvWUHa@w$A#2V30Bxr>c=C78eds5E0kMLhce2Pm0Mj>Vm`WFi zUJOBpQ-f&jD<|oir^~dcG5`j<{8P)6TB|?Um&mA32Z!jnMhriW==3X?>qdW$RrMM1(|O9xnP0u)bwwHXPWl}Yq(Yj89cG|=U}a;yC+xr z_a~XZj`RHQfnAxbFu0*sVyC>G560v|UiYzBYizt8rh5`tFFMK$EqHVkvG*bipcPu}>pc-or3D9bH!cMdp>3N$8#j9-<-N{Pd#$9Cc+IEW-y5rHva zs71q-m$h!N(0cy&`0F_d8+hf1myQA!`o$QWBxtj-1P_ zhb3R);1Mj8jqt2}1PuCCkaRGvTA$VfhGeonA*`jet|Ors2ld z3P4Av(N|hPn&1V;8_Mg0TGP@XD?6VocP?;uR#&_24k`+1fKu&|q(}=$Zi=&Ds-#yncTBRh_J;^w+=<4^qE)0hJ)coq&Fs4a@c`F7vqY0 z5>#cuGCwP1*>$P@8}OMdlAi-u#1-xf-JnTV-t<f@C`vku+uzpfKgS)+#LLMthvQm#2&bl46qbWOYMDephf*&^zzbZZK^rPvs z2-v>kyRVTXzny8>I*#BYh$V|#8!Ej1A*S_?3V(fE!Ogj^f z4&nbjHrT%sm3?G*-7mH@7Wv2Ur^f1$kscs{B81ZV5NNN(y{n0-EuI1|c#gK*@10WX z%5S2FVe(+lgYUwnXqHhcB{hRwz3c)SbMLbptEYLT=_%=>xFVd3{BaeDMCwQxHe}hN zZrE?beUIMYvmEB1Q&9iqRf&;5Iy!{#nJVY3)jbcF-wQ26Hg||!lEUX|ZMw{991)^E z8hIYTSW!+O{EPUOT2uTs-GJ1ph0Ye)k(k(@)pSH#JiS!okgahGWI|!5l)hA4Bwsh( z(wx&n)w1`POh{r657x9h$J0tSZ-r!RVG4Q5jRRw9P$B)H#dpebpX?b{6EYr{Qx@G& z&m}Eq0>GDpzKMOGHj4Rty5@mAj^ah4gPJnmm;fF)WFI$lFv%_EoPmi9AXmz3Z8$q) z?0>jgc;g;;yo}&W*l*AN7wO+Y;C^6op&)0G!`Aff=Q66_IKyAZ;difeKD*o)moU(w z+oPd;$@V1X&4Xf7bDE&lsRtYd5&B7EL$(g=l(R>a73@g>w@uO#wC8L-SlCf4O+zQ) zZl;W2PZAvSyu+VepaNo9A4ooKgecp=DOXXbTe%A{Ur`DVyuK=^?v%u<-GN(|JytGT zcz56K6M(7i_Wr4I56Xn_CQ9%@Scu4y=&jX3-9QUs>fZ7a7#C(LggeVymuQq`vTP+5UrgWB9qG#6c-#`@kq*xUju)qVUVN`}kibbEPo<2fOq7N&m%lqqv zVib1Aa~55M{Q~+%u9~KGuh$cEjCvRX6cH)oXS3i>$cYNs4tHgYC)WA6FFiw7ZjtA8 z%PG1Dg*BvEv)ZXIuuPfqU*RxcwrvLV$+xHTHuCL3IbV=526>~R_{1xo#e{tOx6X2e zC9xTmiC%)NM%>BdcoQNV?^e6Y7k?pPo50dJF-z==DXU^yHu;{o9Q{|AV+99N1jx*4+qz}C=R?5{?>-XMvKF%ri z(JV0+gUTxNwRY?_Xez6{1$?Pj7bQo`(CwH4QxIbAVPYGi{1Rw50v+{x)_V#}v*=~7 zqNksO7Y}@he*)efW7mtMN2+GrtNH4>?OxA+-w+ZE5r8XiibtNCho0%qm5vzP&(y+| zO9+1Tl~DdbsjDKI{ZQ-Kda@*6`}E8RqHjcWMLqKrDD#buPWrP|9U4-y7lL1|+D7Nv zUVNI#wnv@{OedT!cp{!-8<4RM@jfjS$o;Qbc~00wK~h-{`j@^*fy=AIp_}v^ueX?3 z813ds_a$p+SDs108A|Tp+V8@=F^fDf&p;tcpLYP&<(!Zdcv*Y#zuu=>mGzbChah|= z4$kOy@0mx@f$=jjkGMSzEcVJA+EJtFsdq;!^)duLQOezLHP58d8DjLhy^0z})SsKq zc~@lF?4LMr<*$5Y&$dii3B`_}2M+&kNp^Y5?AApUDJw-_LdBpIW0O?)9v6GRHn!dY z2Vfb8ka0?Rs!TC{{ymUtVEOS$T16tpE$El)Pz+JeAwmJcfyiLAHkUm#_Anv=;GSP9 zvUs=$!Q1afDgBYO2kz{q3>fKQ9fH+65#qQX)DK2Vd=nM#g8Vh9#@h%2_bHuH)B0af zTY91l{=XacpJ))i2@%<+%6#h0;w2Dn7u5PNBK2Mv3UkO1aKtX*v!PbByOhmy5-}b4 zi{me4XEG;V#kugf;oX)(73KiWl+5%NRcHF84=N2^3-Pd$Lk3RIyvw~%n*wL&fY*Ie%_ z6G<(?_434Fvh=oTUe!9n7;R)4SbCI&L(8YgoV<+=56gWB?q1JwxN62G+HF3z*ap9N zqA!J@7?(^7$%oE$EwT>P+CsQ6~NMD3Cz%ZRBc@Q zykjp-2F}aUGPTmI{TRd@8r@HJrpY~pNWASAnF5xl0V2!9{Ehz-42nT5rL)4sRb1g9 zb|EA4VrOxhAtmKM)F=(NuRh6S^r8q3rDz_7FC>t!@7AQU?kJe&S&DG_?Blb=PuzlT zVQGKa@A&^C6}C>Af#V}=Q1M=qNJtXC2!bTh7oTql4vH?n zsn+w1W6~6y9Wtk3P|SkZ+;s6qH=5GT92+;HOi88s@+#WG)V=()r+D?pXHV#7@fIRQ zHL7$vTf%f)AqxDGsTp`><*(`Iy6;%~lFh71p`05{Y!wvDd~M~<=6QpK&4oc*q%rgK2fUd-QPYtC+ftU}5&KHII&Qs0mg*tQ30Ex_)6-=hB{UH5T5FSplth?vib(>eROBd|0>ntB-_T9D2ucR1_G_+u?%~0g{pF9B8F3w(s|N0ghHBVRjy} zbNb|~$30oSJ`fV5O7J&L8)BZxBUw+mON2S9#fj($*|rgH#YnQ^9LUzj7-nt0E4d#F z^E8CF^#<$--1;MVBOHv5d8+-A+4n^{&=2MgGMVg}Vh*b&?3JaIi?&zK!2GL8Jgkmi zLwaRWeHq_*x-&^r(s`s#1*`b4)6t96Knm$vv_lg9HBSL29EAYU4xwaxA#vJBvF6tzcDeLf525%; zuT5UAE>dmjl|;I;`6r=oz_OqT$0v$J45Z z=P+1_*WnQnrH5foyzGxWmFq}sa$G@y>dIi8^T&4?M`xPH{}U>LVic;BUS-REi<@e( zc;7e2=H3ncF(wbBZTMywvY()`Vcvb)jih0#E*7iO!8{S%N-G%(Vp@z(N;|o7JhQ&U zNf&dedXsENe{p?JFDW-`c?kJJ_kAHLeQGG{PLS*>PPT+bQMKtA4>Kvyu4tE=L3u1~ zl8#J0q6?Yrp+ruc=Yo$>Ur;Ir4#3SzK>`P}4vRW~v)jtE4F|57Mi zxNy~FOXfmyR1K&%(CYLVwu<#7+}info?GTU1!yc&pLJH3G>*HYAO=?X*}izHYdcqU z@x~FCmx055n42UKKu8PSyGQxkf2TP1_a;b{wcBHcF8TK1IO(JarAF8dBwkSz8svx) zg%KZEl(e>VBr)4)R_TCn=hY32-Z7aL*~rt|=gV6T5_u`XLnI!+rQ3Ia=O$98`-wfT9B&+SVXv-HA#8^G$C&lmcY z;-^B)w;>8@8y2i6jE-cF_F>Cl?+p6w?4mjow@_xw@y@rn4E)MkD#wUv5$2a|YWJ4z zbv--EZ4Z0Z_^63QAR*={eCK^QtygvN*-sx#(9wgpmoRm;?-7mTBx2$yVnmWS$A@nG zq9#W*q&vqyY+q>H`P4dZ3p0k_iSvWIWAD#DfQTC4T;LrePa4x!F`v0|DZYODPK+&> znTASx$cmbqQA~EuSTmZKj^OSPhp?IVag9Nl@i@o7^n4H`!vYr5Z?R04S2H zbgk#QK8uc>NvEg5Ba45?<=LriN6=jJ z-&6e`5Fc%bU^oQBG^gYy*tj_VW7wYCCt3n0Ce8u-s_VwdO9h+E`E-+i!}`NdG3$f-1_&u<4og#>X>w3obZA=hNAwHI#1z-S~jB? zf}|%Cojs-r=9bvvexZem&J~86bN(jh4*@K)7Cuyh=M4IQFtD?@-LnTsPaS~Av!oY% zoVEa%Vfjj{S210HF?HN$>_!La`1AV*|Lkycw@ZN2f$~_f^V}0|Y>t|WMs#Jm3es+Y zL;;gj!WOa`T3>Yb2sM0Tr==gE+m{F;JOAWX>y6xU53ga;ryQ)5?bc&&~V&~zWai1Hn_U-*G&wPPYOB? z2N*&?p1W$V8V_&MCw?uWeu+Zw1@a8nM!)|+uCiUdDWiSUpG%GS99pN;glm9BmUmAg6S6 z1K(TIzf4y&%SvX9Nkee3c%$$uPw0G zhu4;|C0+h=8h7@S0J!sog7HlO7K!AFLPin8zKIC*#IcH zmtH*^e%CY+CHO;$5rpKpfivJdGAct*;0c4RyTmqHikS~}$xIkpShZMiQ=(sUs-%))M3AI;&IS!2O7b=H zCICjcFb9gsAx3C^Vyx&e6{<4R-{;lIw4u1eP+H5Vp+YoXYaoL0ct@jQQ!-f`mf=#z zMK;Z=<(2ZgfQ#5Xjsc@Pz{Hk-8L5J45C1edW~hx(p)Z}$uUE}o&mR$maU*kEf-u!p z_8+i&Y~cZT)?`2J#P1!xeS}a$Y+;|#=n4e2fqxO@6av-kr`ypfrFbB-N(Ni*ID$^6 zAo#3eOqzzHtgBxcWG^zeF8~WUTzIKJqme!KY*FKKB`&0#991E<>h6T(Gvu+W3m33P znjDjIP7>qgPUWe}(oODLbk=yV+z2&#G7;jsv>K#@{EwT-<$G=e6WEP}xW10W6z>&f z&E@|5kaAnV7hs}p z{h56Ea zI~7D0I4C%y#yW~Q)@bnUfvS)1&RUyV(E zjz6&NL9r{(V@a*q=6;pqXc>6?Iml(rME}U~;>aecooyl$CAQRe`_Q1=TDysOVU5fA z7|8Va5s4LcEtYeSjS-Wz5pOwovV)p-{=WI<^m)!LCS$+Xten%8U#~SkN3SfGhCB!o^cVb|2^b7*AFt@hh+;EA^onL>BC*a=r)JnPE>3!` zkOYNuDv+!dygpJE800!XeG_O$Ipc(hL==9Fs|Q5$$u*qGM+lVdx~%IoPnjW`td>~3 zb9E5rlZo2nlWGk-#(nxf33O`|#j1fSN@cSQ949H1azjOd{+r&jS2g$tO>o|XXsExH zK^IViu`2ZDLMU8ev+CiX=h-Cjn}_e=Y30YaQj?~r^DaaoF3Py#ydWZ0@uIgNDdum} z<&?}RE5r5EIK6&wAkLw*l(hB^BHH9w=W)NU@s`|imD0&7V}5!CW$j*xN@o-!oHW~x zgXRlBQHPebR*_HD1tTQBkzPdo7dn~efpjFxnlXaYUy(%>3l;nV(<@DV8e~tLhc(H zJ0Le>!sDMnq+XReRmh0ox2)~xirwbEnh5<6glR}Aw&00tYT)E7PoMVt*DRdEs<4US zyxxfIrixeb&ezYY@X@4WU`8Vo4fNCF0U+-MBz9Xo@@@}bdyflhz=zm-c>`=O#~vQI z9W7h+v+pHSYBa$dke|XI8}lF~*Q|Q_MVX?iwNw&;Y z{8@;#o9LAy9aY>{_+vl;KCGdm0W-e5(P8H3wTTsJ_JfWzAR%d5h3^j=7#$CoM56J} z#b;cN*eh4rVg^}Z3D7H|Z{3Y)%f`YlEce_HV0NYhZj>o6??<02<@38Oj6L|~bDhZjsG zQWFg;O>x-A>Ck<3S$FR|(yFNbH+VZEBB_lbq_0vQJ{ycKd$26Fmg& z-=4b2B8K9u$q~?$i`o%z=Vp6Vb)4DHTEN40x2$;ozd@fK9uD7wq!y{rE94itmyx+n z;x(=dfRaihS5U3C$uE#dK#E6Hc7MRbJm{-y8W)44M3L^u3w^tI(cZw-0H}R^LZP6N zW2ETUG~@b5HkE!aPs?luMC~? z>*c7WMn)c2=@E2p0`p%W;?m=pRxH(Eu494BS)!ZJ=#FiSYIPm+rcR7GK_ZrnelQ?g23KkMF_EIz=Bx~S?4m29j~5)bk= zIMq+XJebe9q6&nGMZb~So#UNzN{P54&wk8L%13!zA5e9p7)$6@2;+1~Uq;5>xiA7s za1abD4|X^Rc3$xHQHVajEv4rn?pWj2C_GQRVhTJ0EfN4_W?3i!6e~%4VMaGh|L!c9 z>qO`d+NFSFZFMm=7ho?XE*!pqinmg6f)kQ*)$Cbn$>8DOe!G1p7!%!3+8R=8`}4%bB*o^KaJf$SAzQR{U@=9AkE=115Lpy&+l@y9>SW%K%)hy790 z5tJPmN#K|nI94A*ToH|{{HxGWOHDL2$4mBd;xsO8V92F_C71Kd;fKT>Bj8{ zYuu}4dAfPA{ijD{gA+XG-}-57c6DS=jl#4I_UVAIzH&7br`TLA*KhV<8Z&d*3wq4+ z1DQ*s4VZDqe*Lyqvtu3ht-f3FOaFhxO^f{Sc;=)^bv#aY0Zxjf1ma{bzQ!fbuFn1b zaY{w>k0np2sL@Lo7iW5ArW3UD{f$bs^o%48t86BKt9nHyG#7;zNZ{hmiYTL(twlkd zqpc04UW(igJlbfoyYhp2b~q5<5Fk7^R>?!SeK)W`U zHN~)XbP)@b1%}*%y1fO?l!JJLuy~iTV?s%l``qb)`KxRX0PwHqcqCU(qDPpCl~MAX zmkGpe=Uv2p%YM~6W(ibr+-cp*kn0xSH@M5Q9UnkCk26T7Dxdk2vCjr#BF9b5T`p!Z7l#846>-Yv*ej_OuS6iXBfUeb~+*Zm?OiG98P`V7N}cKK5)x$ zLpL$L1o=m#l5(3-sqT7MH`D-9*p{UAfq{_&#$t7wrGGu1 zJ5Ou$LplVAqv$<4#jz9mTrT%uzC&&+2-8c4ex1thJs$ zDcUu}9P~CEl;LFe7iv5;;h1bu$CF5<-X4HPwpj0GjKH?jey}@$%SiGc!@jyq4Q*Tfe#{(@aS`;*|%)7NM+owdJBD z>#^(Tw1JM8%ed=)Ln2$y6Qmggogwl4&c4`+$5r0pA9jJ10FpJFHNx$J%Um$qo+0I% z<7K-?&x2CGv^+l__NCWP3ZR&bUlEg`15ZK-z&v2`pKTBsTMZtPZ4p<;MudVbrwf8( zf(+vZQZLZ0F|QHqIcS^sW&f3{hvpk7A)ce9%aOS;EAMnTq~|o1*Ll84Ftu(dT+fn0 zM2YTZ8dvKkT;vEOFFoAXkL97UgYLW5=wkH)dD4dR-Do4k@7S*%0eOkb-tyh4Zsf(Z zY}5FHEs99-d3;>s_txmc9c2mK19R8uT?V`z{2dm3K3|wm2EKNbmm+k` zMU{#2{ucldkz97m9tlW zCEPP5OLVfxUgr-=G9NWI)R{Y+eb0f7QIWD{N8P+vyek1H#8lnDQUrl$Nkmm3Xey54 zIQgK;tts7e3rKjbv|K`ZPrcVl5VLHJBeK-wZeyiO+sF6j9@pC8@+0t$iSgNSjpHFA zbL+_#Mi66JTzBn|caCDGStZ!wF92~Mwg_`dQA|8d@2Q?$v6?^^ajQo*ygme5Kek}{ z$Nio5HdQJqie!%~DOe07U;m5k4=-^^ zuEbKQ;JAlp(WbnltRK9{Sf%aa5}O;-aNiA5yV=qm66Iu|J=GV=BZF>I|ox zg=A={HEce<-k@`>TT@ixHQ5bP4Hg#C-Mfoln;X|B=cPSUYzwCp0PCV{UuUX5;Ta8x zRtuL@U3k%IU&5x1;emx}Axoofv%Qi@KHx?mVCm?A_4{Av%lTkG0LiWaN#twuV$}W&BY%1tC0xsMPq9uaXPmvPQ7au{%Dt#of&)?pmyNIY@ zV~W`liBWq}+<|mrb6PcDNHQ4>e0}-=fV4Dpe*8-wWom?L;63?#Lc?vNV{~UIel|me zBWL>2jz_-|J3lJX`aYld33_!)x4$A^Lra&rqD2t*vtl@qxWtzXJCbCBP2DQTu_asZ zk_YGRa1At~Mr4ykk9bb~QiU&-qF}DDT4{APcrKA3_YUg#$90NJM4Yn(^5AP_oWt=& znONk3fLrcbA;MmsAD@B(E&R&gjQPvB<}m!ZV1TAiyG7W#W5l59jxAMo|FeE<#K8fH zQb5nLZ#I939t+Cvx6c@&)tCV!=Vals`TBqz;|EA z9ZQ6Yjnw&{b4`kL+*_bIB}8OSmGUnWQf4)#(p?lDRVCR^EUCyILpUJ=RdR!eT%D2V z&GnxsVb^nBj5(kqO$oq;l;YlNPH@)POVcgTl<>28JjEQoQ1a8DGR;_O{j%|_k3-n$ z!}bAr6L@YxG~a{?Cy>*4P*W2Sy8+pf6QoD4Ho6IqMqS7{8dZ6hb5FBBIWljLt#tVM zGKH2hdDx6O1|v=GVTzxhe2dHhd#^Inci*e%&^bP%_qtrMr|~_Ea3@(suSe!p1@;>0 zwE8h!{AB=|D>^0jTq_TDz+0~(o%}?lTflCEyFrC-|4z@W%bkIwI$Fv;XZm?Tj6djw znaMRzN5% zd5GMwSnagG$pgAqvj+3U8(HqqKS8W#W9|dkM$pwO^fk5YF17jep7&Vu^QyKjctd+-K)4EsikDHG4(*8S)hPv!u#%|hBU z90(UsTu5biu?LbOC%u_sv$nkGp;>XIfn;-Dg(Y8XRo4@I2i~D2i6*<6e#GnX^>O!T z61lSa4MTy^%B#&04sg(0z1Q~_Mwj68=pKFk_9q!c;T`v`!@9sBaHUKwDl{@?TULfQ z(c^hq=F@%DlECl6%cM)0QKWTDB!03D)&n%!y_6u2F%JfEm;jHuiFYV-WCs13Cd4~x zo4MFr))v;0h%7)^%hewPcN&Z?nV}YItQ(I!@jHzT*kTy0tSeIrYifC zEUP*36iIP}iI2->-X>+^CNB>+r?)5NL_!7a%5GfIhL)JpPB+PGn%>#?>$(YTgb0H+ zjdy&odfXH!3PtzyHJ~JY5UXAPxAYt0RN#tO5r;4CKuRMqPACFaW;XIPe%8fGjfb__ z-;8$Y>BoYSW=9kd#QYQWn=W^bpV}TvEG5e@Ag*LT@ z?wn;wzHfoJw3o?4X>)o_qEcbXeGp1nXYW|N!5kjW`cBxMIN#9(%Vlbv(w}O9(khrq zm981ia^nQsr4h<_?vKNGsiJae8nLu(jdAq6B0|c2Hk$H zdudN!iun*H}-9K}k<&BbmzA{#{D;DXM>nF*moODq<)w^#oMz`>GHH12bYAar_ zMXo6BHjH81USM&7EJvH!@PW{kb>Aqv<-47Ly@--|(S2U%w>X8XbVE`RB2VHyGU(xf zfE^oEU&>?r6!y)WPOa$>(%Pb`5Z(+fwwwY&%A8}E!j%f@YifZp%=6oWRf<&Jl@QBG zm}W!OuKmO(lj`H1A912|oi#(vnOL3G9H%lctDgtpQU1BstTTv9)RKrjw{twMp&+X@ z{2o=nGHM?kE8X6Q+!z0ZC$^m9^cw>+ZQgqhLqF!KIQ_R7%#XPxq|EmW)u4Yj3~-c& z=svM9VdCK<1>8>@{lRyryv` zX0l$K|3~iZh>*Q>p?5Ka(j>7TJJ{o6SL}u*OhC>=Z#sl*GbL{8*XFI*7xdn&wh+=0 zJ){?N+6W?d%Bl{WP*k5x}nal1>ZjVfyKI}j= z-gx98G~uZ=eo)#iIAwgB>(~sado~hWn7is9K}aP#97vYB@H^k6Kw(#E@HlOH1n5ET z*?_l+bsMVihs+;t1h45o+C~?*D6!qOl+@m#$f@54sY=W+%r?N+>;_#o#YcIV1C#vv zd1BNC0$)Iq>r&HFVp+Zf+N4{`+(Fw7LV_yu>!1&7%wJ}0Lgql(!f-8iql5yLI5o}~ z04vSuyrmNorH6Ph8_~}a$?8vmb)V_$Ye;EN-=69VULqK-cWbXWxThhu=j@})RfJQ< z`KYO_iP8Ch{Mdo*4mBht(AphHKcZ%fe->T$_A!=yHl>`pBIh(1Any{KZ7v1=xkz96 zy^K`U;?zlD@z6%fm-#s)Sqx~^HM@I&f8B)?2bhQ7g>xVQ#QB{m%YJF@(DO~JncPmd z&jzkjAAhTI(5%8-Z${0^YIeZt0T}=~{xjT9e9f(z9j{iErX`?7H+8df#fGLNOrN8P z*WGW;cIq_&i%O*^1gM+4$=KqTWstIK$#*1n=%KQcE_asnw(F$GmD>IUeU< zfTcLsq(6S$d_rF+gQhBr8Xm4lWGGPZDq=>NqlJQ^0TXCz}&YTuAYJ!x=!LDout6fE*GI}rrW-*lq-5nLgaeo z&v<_XxXaG911`zn1*R{HHL@K$?M{_}0s@lNjAyA{SsM+>zkdc)ZG7%1(F@P`(%oW%VR@rAZO8d+36hA+ml>sE4}9uRoXj=jQ?|QOT7Dvvi0ZH7ML5T_vMB7G$83BEnzG zBX`)snu%Xb!J)McaAQxA?3@fXu9vDDP$4|buoDW+d7P21J3tCq&vV8cPC7r&J_`iA zr6x|^DZku|l@v%k0K@ihi0;}qYKtSQQ5ZpzaIXyQJ}2~>`BNY!%>;VjR#hKEi*CsF zYza($G<-iPM=T~MmuPg@o=4zLH^Vf@yI18FCw@(qApKtddoFcP%)()}`|d)0D2+Qf z5v>xpHI&Z5kMZ?`vi77q0Xa*|2b18r?uSHYcm$+72Kc9v7*mNfJWLSm8GOI<9zVYP z?$tusLY$9;Zc+cuHnahC&3`+KGVqJ}SLb7pK9IdSG&xOJ@v%>+U{_Jl_qzcAj`kp^ zvbTV~zF|m2QPksz?a+$d0I(0lE36agO{*HcKaK{#Ya;c&LMQP|NTRFo2{83t^-x?d z6Zr9^D~t=qF3=bkpw$*E6I>zo^+go<(WEhnuQb5)VO4SLz}EEUF}z410RJ+EBUw5r zO$GZ99b*G5;qP)GG<#>JJw<|P>j>Ev-x&$)q3mCtiwf6HmB_XKLtk^gVJ<`hy#6( zGGuhzZnadRmRb%naM&h#NSRJ5BKSipJb6Hl_+RhnbuesFvBp*6){h~ zxWNfxJJCZ0N8l20GF(W-WJ9`0+!ZZ^cbFh;`ygDQ{NO8zwbRCwc<+)Zx5}{=aqV%{ zZ?|d3#Cy({b4*36B6E$MLLV9%=BWSM$2m?~n$`Iwm$4I?6r1%Kxyq5gA@z?f_C#er04wQPz54aN>sP z&gCc19X?ZZ$GR=nsA3C{TXnMTH=8p6X0!6|gnUg1Hs`>Om`uo+;Ul%@+>Ha?n|x;X zV_xZ0Vc4IG&`iWb0#8jDx#t7hfUo37ktEFb7l)@|KDAZLj*sh-Yu|||#(p;khK71S zHG27Pkj5)~FY3Y11%271)H-P43%|sfx-=e!0~96Iw}XstP%IuL~iM&mWmg#D*sKI zWru$mmkKNA2a4WAatdbHkDY>{<485;j%#i#1qKPV1q@Ctw8He{g#@B2bVxl`%jpM$ zqj=r;y7X?hD1Q&jq=XRl4iaVb9!CanY1wKj6?vd5NO6d_0wx)?MYNtK-J&M30U`|< zVnyW`y3t@HtZKhwUk=FprNcUaxF9+N!no`d*@`5~? z7QG2my0u0>cAWDJ$WN`|ui-+qc;UAcKK(SD9v~<_r<@B+(;R&odeuWKY3@}fkc3(fWPSslcc3oxf<*aVAG*r+9V+=kays>^y%nlJ$p<(eD$GY z4|0m@Mz1rsM9lmaOGf+8D)eWQlsh*y)n4bkn7aw70ICrXjm zsdh9N=2FQaFr%i7fGhOzM>xOBN>=+=7<0~OM>Ei@`im@*bVa6_SRHlNO@ByWOIRy& z)W-@3M<$=s!kJd!!R*;}Rw{4ctUW-Sx`5Etd+2I!lJC%vEsDfPchy{l(*B4?q(F8l zO7M8sN+VPN(Pvhn$&vEqtT|~?rEY`KOOAk?aYxpmGR!NP{a$))vIn~tM+s}>^9PYr zBmM>cKXbgtKI;=$!;yq+x7Zxm^Vurd6ppYlkl9@eQ3@%1UThwmz|t91mn|QE%_8oS z#v&^jC~(jWUMm1b=6oVx7l(d|>TNPm5W0Qa-qy$+rIH+IF%`%5cNAFeqj!APyjF#;rjR%k z5kMLk?}C_FN?pBcpSM{yr+4_sVHV{XOjJ|tjeB7edLJs5!np&*>0KD4TlahS}2QM1*;jCgG z6m^7bB|t2Fd=-mt@{<<+0DX(Efxe!vUZ{QwYYKKGW~e#gm9HY3v2*X^u+Q}`e}5LP z`%na-`~9-u35aSWM_S39b)DBP$V#!Qrr_HdQ#90$G+jLp^}#Q!M(lha*!9tjJbwPg z(kR31q1r02zzhST_%M%pC!vk6)=*v4K_PO^_?Vl&eG{hrd#?gmMOCJgwHF?l`grWk z1X%TVgEEU297RSD!HOn`vd^Rh;p0XqunM!{Z^)r3dS1*cTnzIRxeF{-<&t zOtK2{mpqX27{KA~dLq{7_UWT>wqmxT!7S^j$QTN0>7UiyPxFuyUH!`12_m(T$?UI@ zhGkJLvUsoMo*|_RlIQnn&NF}L^HeNf`z6JYl)f>{s8v$w+toHB$;U6pe+%BX^zAa* zI?}uQ5a(;r`-q5dCe*Q174&`|k^Crn8tr49{C)qAY8o_?Nt9)ggW9CGLtbfv}e)J(gyu^ zbpFUBa3XV)y`-4 zcDa{dI&4@;s^6MdrelV;4ytHg+}@bg(mUuqENowKBmxLtMQv}?E5e8%AAq?bDY3*vbbmr zR5+$yw8wTH+|MD>>xO?Lo9JP_%Y&4f@ z?6um6pcfnFTq1xOSvahH#IO1omESGq;wHM0zTM`KrOgMv^!ZLMwUK60GI7h0JiWlH z@mp>IEx%&(U3Kv7PdBTAB&jprR>{*piUASc-mm#q% zRX@RYTk*NNu%$7pQEMxyEOiY1Cy5ND0WEJsJ3TyKj||!#|5=BED9^CVC8B_N`$Bp% z4%(3v#m`R-uXTpv+>}EpQ%E93WvD)i7V;xXggF|w8MpPfb=G#9q}D!4Pd5E+C;EMx z@Y85x_l3gCwkIe0Klfw%lpZokMJkT2fjh@vi1&)^ zH_QfOdrr_9sNyk)RK-lnx0X~lgTM2s*hi1XZWG#*&VO$kyB=!Jh?gs}qEdUeJo#C* z=MM`mI<+H*8?U}MoJ}|R6Q+0Z|l~4_4nvqN+$;y2ZmFEXwr%r7CZZ=tWvoq@6&sCKbAK<{|;$v zxN}$3N}H)8Gs3W1MirZUAe8gQQ}-+{XVOMK;j?W^*Ydkic?vvD2mN^m<*rlA-em`c z-lIUr=w-iGjq#KS{WRsyqI5Zb1Qj7MyDM(OuYX=9aL;;-KgP+HF2LYXPWnB!1qDyAaRSkM5yqr-~sp7fBuS{UH?F6J&664 z4Zi)~|GsyZ%?sfFE2y7gN4ut+7&Y4MHUimZDM)~q;7Ev5e5VHk*2q-#C~Ji2`{)wI zHzuTk7wZ1|zrdGYHu&sKf;{zi#br;H5aM8YdO?XmosG0 z^N~9$%lA{0kJ$=^iIJm`6Y#+JUfsX&zbpXT#}Cyf-kCVo`)GYek8U1gLAyqklZt<6?n);Z8C^9T*nfEk)cr#vQFx&DrFC?ot*~5&@Ka0!LJfoXWh;5~5 zT)1m~+bUy^&E#Dp+92cA8(+m~2QJz63<8hFkdG~j>(raTdB3?1NwhfpzoAimuRYdf zDZEeqyZX%Fy0IO=f}d&P_zZwqESQY@VzYA6)ZBnDLo=$!z8iwua-a;}WjAn45RuUEzr?5dFG=nIaY;KiE(9Q!sqBtXbzP~yLX)kqf6qP{%bbl-0v z2w0n5dHpqtf@a>*SKAwyThQF>P;_H@XUWTR2CU8VAXYU88psMQte*3Y$^5Y_O>8C} zGr6ORJaA^a*%a=p3T`k@Io&~8XNb%TP^$mo(2#l~2`qXZSJyTs%ew!_gtmQQnJN^3 zcC=AL&96?m4U7Koud{-4?}G5t#SJHnK8XGEf*kMQ=xhMFJ64v!Qj2e$f=RKIYgx6y zj`iIH40nJ{c2C(j-v~CnAu))53M`M9xU*;2TK)gHddq;Qy7hfn5h(#Fm3pLy4(S1; zyQDj%kwF*)1O!AH0bwZV?vj=+r9%mk?ixy3`d#DWIluFNKRNy9gy)%k#q zB1b8Wj_XC2J8JnwybbsX)UaJ8B7RzvNCGmp`ZT1b)rv3m0>c&I)dif9KZa~IM9HI% z0!VOLtb&#zkn3=6n0OUP{o}Dn%ipbyg>KD+CIPHOi64#QqjtNQzIaT^JeVKF(WOpqzdB1}mal&0pICL}=0j@zz6!?Gc?*!cRX zv4^>Lqj{&jfd>21nbqifJ-4#=E;vzXwQRTOL662Vcj;;_zSDoqYjkX1R5l@#qxi$*X==^?^IqC2 z-+~v@-=QDL|L+5nBFs=0T6lXW%=L$UK1$Xq3?P0>D;N$~6rwKnZm##fqJ&3ETCdM# zT3MN&p4JbmDEc#|zo|U=OgRI@6KQ&K3|=kui)Z+vr=1Ph~jRFI8 zfz_w>v}K3R^uOJFJ;#ep9u)Iit1UhK`;ZgGsY7zCmU!jp{+uNrC$Ug$m9GEwA{W-Mbnw`gS|Op6#O=V=0iyQ%QF7X$5I{j`l**LAGVhm(jG7>Y>W#{$SmG6hSL9 zwJde2;@@IyZ)yMKdvogh2=yvP6=7QPux=@8RGi>Mb?ue{Ip3IPKd&fl**E-m!J^hJ ziA+GP3@7SkfPayaqjij#93T=%P^3f}%w9kRHJJe}nl;_aw+s*$!1SFH)siQHR|4GM zgyZxv!+JFpW=-+sZ`AEg5fX?_kr+(1*t~32+`d8CrU?Sw%ov==#F?Jn)hftzj0I?0FaZzQ0;-z+!6;iIGR-#BtKP=ZJ@qm)z@>2TES$c99 zO8}vwQ%M92qnK~Ph==gK$}~!xjE(*|YWSDTuP|Q@w|sfQ$MW{11~I+vA@3=d|?u!!{;!Ks_5+YQBl1oPRM0P zkIWgMI+?CF)2|C1V~$c^900No2XLlz<2Lq#o-zzqI}ykDq}^n1@zF>?-4eb6FF zxTwh$Qa7K{0j0W2Gv-KnilC7sk^w2rzk%r~o!UQMr%e`Cozw`Hw_jTSe(W#Twk;Nn zuR!bG2ecPb;Eej_g&ZU@OEW;lij6te=jLMm5h^BEfce=&plvdWX<8po#C|{WlZ0&z z*+|BF`Ewvql+Y(xTTMpWsi*;yMpRaI&g;Yru>*K^L^7$enjcMnbxp4c@c(!ORD*O_ zqb+>}X>zB+H91!bVR3Ahv^AkQy)aoTT6OrNXrRU;P($?kJO{ooXN}Aiqc%vw)h}w| zpv6}B5%^$4r8!C*2GPGloeCXI$Xb^xn%O8TaM7(u(7smj2s%=l?zQ5#@4s3qDlSvZ zv7*Ra7kZcO=}FT%CEuZ5#}N7G?<&U%zXJ;9Ew!G=G#XOS>`z9RIEnl(6p_Yr!H4YWO1k=3iFq@s^&(d7dBr6{ z2#$osSu-^Aj1+#_(6H=cwpFL2Mx|=u-Ke%onb00 zW-R-3EKnN)Yv_aT#^(BtlhGEkAF=LfI+_wcuC?1@tuK*i)ud6F+VlDK-t;odX*XHf z*Vy}b{5{axURg$39vs zToRW~cWQg{-gm^`D{cCNfI7NvB(3u2;(BWY1jr!y1H}3&N)e<~2%AewLDG+jSTIyF zC+)OpUFLHi_r!~=_I@0+kY%vvia!HVVhm29%2_a1mK#aO`t{o!{QtR=TtYy*&fO2W z`Fn5RfS1n!tBQM-Ct6&$Ah}82b@5q8>PkVhA$G+VyI3h}txQKAlBEJSYOZX83_-*V zR{a}5prx;Qu4&5_s6layui zz&P?5WH8DDv%>a!))Fwgc(Ic(6zqobO!*3EjOk^eW&9ni|5FT|OD#~vi&Wp_r_=ge zAErM7hS;wwz>$}$D`xezDKURWk%fJh^@3*=_i zz#EAU2uxv9=`XSgk3x%8hd~IrjT(ubxP(Vb!@fjVZ4}lve5%mUHjMnZ{n?PFT=jPR zwEyplK7;8nQy^QB7cgAUMvwkHKSFtgLvNhHe0cS>`z|4saj`Qhv^jj8y_Q$rd0|Ly z(oB#7yShC$lixB+aeQ#1OmTHoRzC1=>dJrOFNuPIiRWup4~rXR zqZ%C_gc#EIJo3d&PK>HzQD+`a(Mj7R)MW>C0=|Sz&=+$T4leq=zW3jSW{rl1(iAmt zSp6n-f2SCTnHO^Ye!l*9VMx%4`_Wjc6!d{<*G0ao;B$%O5B*xM*oUUt8niXvgrY>^@y%^ESkQnruI(5>eKYPm-L;_-`n1I#F)lf*@ZO>X$8P-gPZ!Jpr6YX+^hP0*e3J z<>HbVb_narUmzdX|ML9e@0X3He*0Q7#ZdPeN5*Qjm1NKO6hqmjHWheDAr001$-KeNkCumbzo9AzVrerjN)6LkJh zB~D6(mMKq8b>h78_a+|`X0RZMEp+H}yF~W9AD9@UOv);Jo8!Md^py z$zK5q84)rET$h@hy!r9WqGg6XhFrpc%xv~gct895njZ$mAzZaqO?PAt|6UFwQhe0q zbtPsPr9zAhTkW4X51u$bR!`>hyZJ!e>g+4W#Csx zHbxF4R^AKD@i~8h;X)3P!<1;t-}^=FoJ~LR@TB~1j}U{u0p%$4mMbEK1(-&_o!jp| zq7NKF#oMe%WuV_8c5^899;GJT>o;p2{7+ay^R`tWchCc5-s79oo9p?h^VsCbZ^)wH zO2KWIQXZ@3yQQ*U)K=J6FOoAgf@b(&R)z0RJZcgNAUj(uN*Bl><9Y{I4U-9Ij94)q z>qW8Vqr?JSy_&dOfwLdCR23O13T<5J(OsJhD0y6bz}m% zdS>B3SmXgHvtJrmqgo~BYEw)pyCBt8HFt$!eyW^#VRD$XVkrPS1@oA^2U`Kinn@t3 zlF)ITR4Z|A*-eH0&64QxOAyXVY2=7lP>F$^Oj#cMjhM|)N{-0cgzwcv*Pzd7<9zOT z^JCAA%r4la_*dHMiWf5FJi{V9g_cP;RlX+ATOz6}&=!EXz_R33(suo@x1-_)N1<2p zrVGkla2kUBk~N_jMCq5ayGbv~6mS~z0uHg5i_#XZYu=As3q+}}|8krs_;yHEFv{z}G&PW2Vu)`PfmHelj%8JoWf ztTJ3IUPMs?7bZn#RFnZi^sZCo&dbc#;^x)|;!n_jm6-%!yLBG)$)1S!3^gwkFii(pI|@d`!`la%UZz zjO@QpgY6#Hs|Z)muhb+8&9o1u|1O=QfLj`CKu$-M{w;k2D!jZ0UBGHRyWBX>DPJ`T zY%kC6?@hF}fe~&fy|{z=z!({$VRPWJTC&rtRaHcYm)aVsWa3n;SfmWY*m2aU7pIkL z-16&M_54~-sE)3_&#*bX4_0Z?|4zy`}E^bQ1 zZ|P)6@Y}Ck1j7Tr+oanZ>YQsQk6$c>*3UO!@(kaxsB+M0uL*A`fzw;4gHuD?U2*toN_2TSe{U4YsQvRdxhMhf9PouSAhW&9#3O%bz zp+Fp_WT6t?2r*NIIyKjO0`Z5=7$`JAP9^d4Nm&9~QX_w$X)L3WtqyE2YRGwwv>bPp zB#D{(qU1xkPVXoRpN5(TUEwu6?c}&Gx;qq-d?0nEgTW+=Kl^^m_jTW8lV@ zM?Am$FJjcLz)8*>u{tvxJ!7(~JDRwWR=Ca_l0)`7Q#$V7R!td}(-?{@Bu!~$g?6`X zr*1wigkdH8OM_&ntR1B;3l zTFtTqP(sm?lLYuGRms+E#xIj$wfeN=0Z3N{1l6lXp3URY^lRR6{ohuJM~En@!~l}$ z60s8b#blJN#XacS%;;7)e00l3>_Y$CW3eN!P;47yd0#2!eg#Q$jqeDIwp;-77SYV` zSOOn?B^(Zdz8M$L3^xd z?Z`3ZDxrP}x;^g~GUG@`fqYep?G_IsvP_$TRCY2Z8IQ+*zd1hm%0 z#X+|4VWKQKmc>WI;BLv_=c3#)sykTuzm+yEJdDPYFYIqq$`G)tFO3lMh=i z(~0V8L+&2>wQ?QEZaI#5zFIx!^xg%YUf=V;9F(wnZ$zJ`shGtW<7z-$N}M0ZW@>PS3q!MeFNkODz56SMXM`)*6#yeVa-P|H3(r9 z@9LhmO3bi=cI(hDGFQZW;b5%QgR-*rbV?Ff5Q$U?^uG2%c@xz@gXN-6zTlIsN$U=> z1|*&-v}OvqLdyBN{hlXMxE!<`N5U;Nn-{)7cX8@Qx`0krbItW9?mJUfv3SOMg)xVt zR#+PApO`b7+y?b44d%35h-ktC{MC=C$>|FnxhF^^Wr<#3?=8v%^4d$msl&=a#UA^y zg*~yUq2Ar~xK6#!e5_llz#Ej3&lGdsIC!7Ey@Sv6!^mYYr|U^o`LiTJF6Lh#pQC?J z#3gsC;Gx^{E0B|ZWX{KULQ8b$m3Qk#)_Vw650F6hZP0PCJvR6;Eyimmr{#2}ZwNt% z+?z=#-;$Id)r3LkjQ}JX z%;-<^tOXihre(3PLlWtcsAsk$RR5lN--OXp?%wYxt({_tX4ASySuX?+>RfY2Vwk_A zG+R-4wE5i&)=Z{j*%tQT<$HkUz#R#FK%%Xg9M)L@ zwKJ|ah$29KU!_dIq#t)Xql*6WgjY(}z3f0VgdJTWxt-ACTU@nXDuFo6IvLfai6($e zJHx$t>uU!2r>ha@L)nL;x%`@(9zIC8!>VUT(W7I$8vLw+LENL%bPhvMjUW&Z;k)BI z#_84~jXiBhpKH0_eIHza1~Q{$Ug-^s@7D*q%3)GPQWFyeDzvsMT|lEdY3zv#O-a3p zJm)DI&Hd$qmu20b=V#Yju6AB>%FtpTdreQz>AWhv-Y}2}>#KV1Dvdt_SlrPhc0PZq z;eG0FIj__yhM5;H99Uv3?7E*^?U!7PB(zkMgj!Ns;M(KT=1f(+#YwZ@#1#82K^s?n z3ffW64Q^Qr%_f78@J^mwvpb^mPj{UFiBN!;*ez%DV9@Jv_T`!&BXIZ0bI1xB zWsSSFyyUg$onmOjkLm7sAma+7bX2TP&!5uj>BU{DgwV5eKt{U>Dz!9s#d@}_CIha$ z*M;X3-?l+7XVyg%u(milX82z6iJqQ={?*gMbn3Ma(6x`!SkFkvsX+Q|mV*`Btu?+c z2SF%jysjOjCssv?3#)4Bo76t@Mrzs_@$awBi}ie!$)vv@Tal`uTBNYpn09Bh-5Ti; z_N{jFn^zY8pF(ed7QKKUh@jNvC{r_>w5^+sMe`gu$PYz)ob=o(9i?u&&c<==|D-wM z#ImZw?Ipv`P*OTXV2brAMIbckb_LI$6E9)EJC`nMpEK3lpLxxYddi zXKU;e5*O5yMdWrFVgrHhhk20~#irFa4qVOWw)SO-{1jrgZ_ERao_MA2fJU_H>B^<= zM57ON@HZgl6w{FaE5A{zc4gj!Pwv)ts79To7!ecsYZN8)70e$A*#hsA< zQe$Rw^xU@9B2J>Ves?CJH~YY58i_gZ@dbB$x#mQZcenFR?1w?9d74-{n6lU_(6I(eMZ4{V)GIEfo)Q!WD;0mi~8jMXFE5923d za<~%Ir{uJsRRVK{NCG642hHx;Y)=q66i+Lk4W5Yty>dtqh^Je5P7|S=o|kQzsHFGa z>9e)#(3z?Os~D&+gt(+OVB=TcN{m;f4c2jflN;<*7khzOmduJWF0n-^Q8pK{qUtCr zO;kDhp4hI@p6XMPjY(;wCrz@~bzRGG=}|eQV~0`IEGSGiq3gayGC4&y!FMS{?m$b^ zD0BuTpU10s!SZp_kIiXvQeLStNJdCHl-B%Ed>wlVyTJ8TG|c&A^8h!te_!^UT8+kw zwqj)_mE0@X@y0pclf}!;V5bqEFxk_G>k6Msa;{c|_~W3qC|Q?vxk(eJ!7z~S2lknfrflDgA=cwT|c%|9Q{ceQjsIt z#AZ%zwoK53`di?wdkT1aKpt9 z@k9+{LSr`=>U6|hlNByB@Zg{qp=*9@F;YxkfgGB;rtVHM=qJ|D(3$yzyy!K*ds)920A=lm|Wd*H6^y!tOVb^u(N8 zYY>WSWhEwA9j@(_*3fB+J?&3FmXn@h&QH-06yqx7K$?X!5{jRa!*V~otd@t+=j3st#HBeuO5aVdCI^;2Q8+NweCY$jH$ z*pzeKu5zcKaag$)cN#OA_rcin^uKMnG{Ovxs2&}BqC40{e*8R#GI$c1(y6@o@UAwj zM25OZ^y*dpP5aryfvj`*E8INLH%Sb*^?=Cc5QX#X3*;vX^^_uI!i=TcId^o~4GQ$v zcRVGsop($zih-H93Z zquZ=^i}DYpX|kwn1taStjq! zKlcPDVLb`6e(4tVv=Mvbu5Unn108-5`rYTLR#{mMVh7Hk?qGhTZbGJ_A42P`XEJ!>1@&c*bDwN4_oH7Z*5@Q-q2wQ+L zWJg)+ANc2byb?c@rYgfE)f)I?0m1&Gv z>(9_>*P)(_EpmVax}p~EwW$4h47rh`2>r6?q~f$jz`aZwQcNY6I3g|27F@n7ig>bk zRKPiYi_tUoG}s8FcfL6aCm>>c!%mgn$xNc6cLXR% zi7DDc406{NR2O>1RjU6;TLr$!z=!V=GMuw^>tZF^L|JIYJOPjq}&E=-Y}M(pqEHb-&;|;wFmfCyzf4c}&sc&6_7il0 ztGS}go&+HmZijJuFRPwX7T>kV?N?VT?hJ?$yqM0mMji zI?=t`4l~)lI8uj~zo#Zz;?FtWRf}Bv^#_AGw&NIG%p3pvd-;KYcni{tO=2wRpidgX z2hXvlELUqB%7RV8k>w7}ySj5Wdg&lv&@7B`;ljE{Ye&E&OZK-to{HtPfV+m5Hz?R= zN1KvKsS$nei5b6IHiGL@#zAyH&HbZ8x6U`~Go;^eT(VWUH^fQEUQa-$kq%~7KR&v= zXnV1st&$=*AS5^GCti-_q+#sq@i37)d$8azfYccwsI#ng{F!kjg{LQ{!As8ZjvVD} z7=JRk-Om+y(OqS)^)HS2R@otBwb0=C%Qb-*sZBjCO3DEiXy>E^gc`}S_>L>e1sghQ z3CxsUo-1tN!h^DnAOy?`fas3=%^V6U_>LJBiCY+QD;Z3D=jfa7-{}WMu;UW+ z!wQLkjffgQdhJDKFI^7JyU3!d2zhd?1AyU{f(n$w$G***R&itBIfSDliy7VQf zQrzJ0CwrRLEjx!G?@x%`^`Hn?W!iN;d)?ghY*pk~!*Q11pB8aFKW^Y2`f@Dbd%xI(xlt6!QT`0i@UyiR7u=wdeV~;fmXvbN z?Uxk}by*W(xGbZbvq|<*reMxzvYi9t!5kY5+F)9G;l&=zMJHSdzh6ak(U)an{SmQ) zH49KpzSZ8H*m6Aj+kC;6Q`)#9og%|4p?%ic#p=oH%tX-|^~$t`m`zcSR`*sVil#Cu zq_bWJ+4R#io!wlPnRMONLC^lSFDdUfNj){=8h)@xVm*Sc^+2JFd0saZdZ9tOnsYW4 z7+wwAZLNPZj27BeSaBqfcS9Ffl$U~PH`~F7UhWE)Sy?{Gc3@f8&EA$>ii=aR>r}Xw zVC%07SQrcrC!EKJFtN$YKKpB3|B=lp+~rntDb{SB%lNMx-$1AdU=@<&Ts4-|Ui zra^1QBruTKyf~OV1C~FL4mwZE(X>i~Z#O539Oo8HIaCdfn6;q#9FJ}=(K@Buj=y5( zCRIriPPo)m$W1LJ%0xH=O6FDfP zlN%$y5AStxo=Zb0s>_RTisGN`1biHrV6yrFtgJ6dLpFQ_tI0r3hFr>Ao`soKJTK3?f?Hgob`;{RzcDU;ofOuNku?{XlS^o)!s ze`xO{SG(t)gSf5W5meW3#dR$Z#p_=@gwcv*6Oc?ZE`O|P9EclLb>V>VNr+W%mJtj@ zF(Ted(4loXTrYinuW9m;vP{#R?TS)g$&a25({6f&U}8tCU~lC+*ZXbqEad^5$c6*x zI2Ipj8Op0StED{wIeeW#_JNSe1s^y7yW ziu;HItur?CZtP1$?im+X6~)-VAf(8U6$y*YGsjA%m=YZVm;2Iv>h9W7Gf~^FVGR&v zjPGlCm6-caHEK%czJKtfdBkjgz=v#r-wd(j!kgJVslN<{)#3J9WJSJ9hQ^E70`+UY z?m7bhU(n?)2OZy>x0J`ymZI0MJjxq=m2(}z4C!voPsV?vkeL}4X{!wttvo4iK5hvRM-#7G;rR+w34c$xH9N>XHWL)3eCDlTbiIe)NrW2}X2#USqQ zxNbXpo}y3NO+R4W`h>{El(I4>)N`; zaae=f4r|LR?t*P3i@nTFuy*&@JSq*<#KQQhyZc`~q#utZ9tNhYzUry_PU4wwRIXgj z>wV%i`qFj2IA*Is`R9toYpStRnAKV7BbV~H*LB+&(0QvD4Ikp_HrK1-epV{%&ahUP z7&lD2WQ59R?J_g|8tg7^5q5(hrsVsOKE^kVCXG4>I7eSVfLE#y{lM7O&wlg(cUPlN zW)c(T#FI$^2W&fmGZ|AvNqqP&zFRWR8W7Q~q0x+rSHr>^8U7lQE)z{HLDUi@bj5`^ z3;Z?;AvrBSPQpu8+`)qGp*mIn0wc zZn1i^N@^>Nfl1Pf)}QCe`o7BUp?0J{M2eP-#BDX?^<=+Eyi7-Y6(It|iAuWS%t#9c5f>3FB4Uk>?czKqOs*+^PQ z86y<+Cl?f0d`jFBY+U23yLaCz%ccnS&XsHrE=FXKSo+?fciKblA+_zSjo$dAis|*$ zvl^Av`Mz{7b^X}7z2mB_+O4$Me)xy}FyUd5K5a{cSGX4sV@tTzT={Nuc<9BFB^C$| zL087*u5732wL*AAN;C;W{$Ez*MTd=8*F4CwsrjFFHZx^~OB}5uk3mm21Jo401UCs6 z(FY|a6H2BPa6|I8F%wkB^9tnV-6N?=qkn9Sgp4% zdB`t_4!Vt$@#-3Xp$q9)P94xA>o7c=75JjwkHOE$iS(_q-{gZrH^fzsxED67l9YBF z^OOdf{Rj(d+u1rYg$gQTeu*F%&_6QtLc6DwQ%Cu3u~YF9+j+QV9lTr}HiXq^Ge&<= zuLmAwjFi;}*JnI&!6!9@3RB_IEbALR7YXx$m><8w=nw?dShrW?lGTmK#@wMOodNwm zn{lo9PfXtUz2j@u1qnhmi)EC@o3seQF=IU%w*_8(+TM&QY7NH(b0^5IIfP_>#iNs~ysPc%md5p31^tbOR|ew<+XS zQdwNn&8ychz0#EPd^+1ks@~dTmsw4o7}T_`tkZ-f31&|FqZX48i#s0Md&^P#nC3B&{&>{KzsX zX|z75?Vs|R{r!rC6u^}Jr(n;dX~X7vy=?iK20DPjU&wrE9mtz0jL@TH#$Azx+Ab^< zRE^sdL;?szY!5xYt2H+D4yQFape2yn#`M|&YvV;n#}TVH!R9#s z$Ms)0n>-oo+jKH=u=*h_`4syJ=hX4&Uf1b}bKwa#ZjRQ0x9h{Jr+Is@(WB{%R`-@- z?4()usM8)D*$16ZlI=}1vND-^u68@Au77DrYn)vwucgpNMvYGr)T;0k?`DUL_KHqNepFt8*;xSiEtkI@}ftUfcwslc}jjWow(RMtG>y^1{VXRtg- z`VqIxmhj>^zTXi5*t)-K;!h(Yx1m*;LO=cdDVLCR?20BNC)YXRKj_FjY&6QpIM_Vi za{st$X=uk{_O05Vry)DqW{{!)ypmka+h8=OB}(xo5k?aH@|L2uxix3-npXeO6$+t* zkwH|YfmGHRG6r}T(^|rB`See6C6|7^B6~nYJIeQi|NWe{s#vQ_6!U#!PD!a`Wn0?( zPH#WS{sGs-0%l^N<~Ox3Ij8wxF{kTXLq|^7i|vW>lF~`DzQbN~qpw&DTHT-Z(z zs9p*+>26)`y0q z7(~$D$=Jy9nQQe{&|LQtX~#z&c^oc9JjiR%v=?&m<0v!pBacJ-Z{w{K_R{l9XDsMT=U2=Kb~_;10fQ< zCeW#Rkt)9t_^K*PkALFfxSZ}ss^cY8o5HPX=VJcmIv1=CqeWyQb@a>&CK~1!t7rFKpb#l;ZjPt&D8SxmmL7@pk6O%et}QT&!bZ;U zf2s*f*)oNDRSj6>%GP-A->eX3)H=;ejPaaK0MFs(4C#%ykcssI+<;TdY0$xd#K#ZM z_cF$)_+Cv8`}`PXQItP(*e!)+!aN!`&&!4r1{F0DOPG93ua!5oYa6z{x+3rrl~cbc zysSDL7W3`!bAKjIKS)o35r6Jv!aY~@)1_%BoOLEfWI0fG^}(&cwn58m2iD|uCEX#h z>CSCnW2)5HfuXO(*H>B&NLa*u&>{wfx>cSmW!L-WV~U^Vfi?x`57Rx7No|zA}}5Z7B?TXBx8yH`$)$bT9MZ+ejX9 zv6nnC1VbtbG!X<}p(QH#LZ*fa z=~P#9^`-K!8)g1s$Z)8#32kqb9qjb>={~3Trjp%d)=tQc(7;0uqmKtua2Zxb}yTx-f14;y_1GNV>vyn4UPZ9#t!dgn(K#c zufLX{KlV4-rucV)&82}Z$dB=$=l++s`pi{Ru3hysJaXSix#+9~cU9n94cr*}sqG0- zl&<_e37vU`Ll~5luqrpi5AuOTtFj>-B}op-+(B&J(^|juc_^L}J!S%Zb#G7CbO`B% zRo3u97YxG}%&nbE_yO-lHTRv6YqV8lr-Xf<_Nse87*`rUW1kz+>aCHh$z?pAPBWXB zV^H0DC;JX#!xG@+PGebcKWQkPe-jf-FpU+9BF1=ascL9QOOTAQg9FV@!+An<@1qci zT-wJAWBeIZu7=jj`!g>DEdcgbSK}~B0I0{j!^evN!`e&$Q67q4xE5TmfsBdgs!GfS@IE-ITp9qm%z+d89euf-M~CXaDL=%eJ) zYKHkeB76W67s9P?Y)plf#bUC11NSFOelje6nsO-ur~2K7DH?SUcxF7GZz8D{*A44( zCHXuF5c;jJ_BL=fho*s7X4RYR%h`8#?}eGN_rekf(KuA3UzSgwG#HDnG0pkQli%%g z4*we}?SkLle!@uXXNJ*7-TgMdw_e~g*EgP@(HCvh&$zeMlY{_hTPAhzi0n0Ocu|)` zlz@Vyf$O?FjdtIeB7u@NywE_E^M>M=GYON{IiD(ZaO-=@%~ioO%KI#D0vqfI@*@0^ z!ada-lBEVV-cspYN|Dk;lI9unyiBhgnG2$xU~FQQAs1Ra!zFG$uw{w%vPjZv5Etf) z!AXArOYoeugGh7=*Hp}ic4emFtJrr~e(b}PF?-TJLRYvF;a{A+8$akz4mM-&v(G=% zX%`HpRK>waFJ3e1!~U`_twR&CVlyI_vS-v{!5Y)4XHvQi6spJz8^%~NB(FZ^^pS{Q zIhE591s7VS&<_KDF{L zpwP)HWSHX^4vTj4-d=o+c8J2c7Fu>=6*TkyZL-2O? zjA-4e>eG@!a{jBtuzn%m+KnTl(Tde|{Wtxvkhn$DDUo-uKPgUof1vmQH`k*jYcrTQ z(|4|e93dsc*_YpLC<5Rck~q8Cf9Rcf4)-dknlz?KJur0=O2YVb&X@nQP4x7bItmi( z-fBpPC+I%pA2)p@fb>&lqk#~TQ`)s^Uu4WjOT$@f3J(YxQPX+E$Xhzq%upax+?ej7 z5iNg?ul-Imre9VgVx+`2Vf_B?*N&G2++)I;42YSV#qcKQy?l;XMht8}BYx(01=$Y| zBH5g0IDu|YDD{X>-;*!*OZsUlhce?j1MW3Equ!!_BI`)q{?GkdpZUfjWtzm=ZZDB=Kb*XcGcBg!8@Rm=gx-nR9cO}#`wATt^{aU z(V@Ij1vJzV#%3#xGYJQz7`J5xwYtQ`q}tXl6_AduhETR*jCsnXAZ523iRY!DiOxJQ zcmjQ-J$DKwZaq|t$BrV}3BSX4NXC5#!>|5g&AWnb(b^6XL0j8{+nZOK zDJk#lBmGC-qK8^OWGCjae#=ZPyZMQ{#O0Qta)%83wMnX?f093)IbhYf;QBO>)7!2pEf9@d%ZZDcS>y0;-`L27aX;Cu~ zU{g-?vedw#`*UJw@^bXSUfE63DLpCg(P`3C*AAkiVkzYnW&(Rpvgl*oyS#A~7+!{n zreP<;Cq?Pfu6O3IO9?ubM8yjn#z<3@9{LNPk7qd@@N7a@d5#y(~=$NY~L0CM2>Z8Et<+WcvUC(9&XNNHoZd-Vd& z^M}IQ-GD*j5Rn} z=7+O)846|pff|t)X0-j6^v4AwSO|fOLkB|=8~0j-p%7Q7o}g6DcS;xh`b2{v1wI|0 zj}h4|T)&oHJ0~d=;>E8-^!k?`>_Znx{;^)d{V^b3?815G*SGp*Ju&cBa5PfN_kp#9 z@i)s9GJgj};V@yv9Or_lBW-+4hEO40m&Vww@}V*I9(C7;Q@oKv30oxT?{nm{NHfsH zP5KoiBcx~+R$Gv1TQf8sM^L1iw3+d{Ss~@wmxPbypIxY1)1EiGzzKGCowXi!@UY)E z0a7(q{pK-JO`bHB+j6rj_3cR=(bYSjI`Nh4X%?*^%wraF2!iy=`Z@R<Fy5M675r74w1xBdSN3P8`LL9}=Wz zwA5gWJR$u72e`Q9nzy!aJ3MY9g-v!AYkjjEvud_QlZDAa$T;Lygsn$Bt_W}9uWO$fG z8{udI-V7lo&v!v#SmbYI2hIAS8T3;|{OSaoJL^NIiaX`~!CD;oJ5?9|Wc4)< z_djuYOuM(+zs&C{O^;~2>C)XKrwA~{cY(tuWaiZAX$sA7 zmCWVN##zgN2u!)_h81d;+%!J&3eLSNl0rw1!yTAZ8L_gRJ2&c0F_Ckf-fKxp?YQ`s zlsx#rwZVcvb&IjS^-1~N2j>;kh;s?fe-(So9@27+hUUCc?D@^$K=03w<(Mq+WQ%3} zZtjP6^NBVQDvNJ>^b05~m}2FWwhi0`|FgbYRn~IRVa5}^AN|WYnuD9II-T6as)=Kk zSY%(Kdqt|cmz^41QdeIQ;*US@Y$Fs1ky+4?8L(t@s3lfVx#IW_$K+!omYRY(;#i4Z z#&&u@M=_r|uvQ zm_w=A{Jm1!27zs|UaB(tJNYDBg9_N+HsLd@s033$@KH$O?3Nlb{ysW%XC~yxRF&oo z5~ZMnWzU@xajDotrdk&8VVR4_IaIs%tGO-q21F`Sy$owHd-tPCsA%$(h+%62u1Q)6 z3Wmn~CWD7I3c4p}xzc>P~Oj%*;{(Pm2uMH2r_^_kIE2tW0ay1wJ07)lCAv#ieMA1Wrj20-e( zH*AQcq68tGLI1cz)lDgLX8@qjamq9y%Gc>fuKS)v223dYQmF7#MpWxLMiv$Fph*&0 z_it%1Dj*C^JnI^sU5YgmM1B59KGY|E&M2c{jQDNz!rV;qC$L@lP%RYCRpE0mx&miB zj1)(_S59pnGZk~-KE2J_)4LT&eSA}}RpMCo=r~Vlen<9}y32a1J0w`;x#CcTbX*U8?_0Tgp`<)#J!lz`rlzBOcyIK| zl9szrfvnV#=h+DnU?+Ui+;o!$UD)b!8UdI2U@3-cQ9L^Vj81%0c1y%Tob52mpv;=@KH8r zOh_OQN$-y9e{T>*OW1qWcIST1C-s2ToP{yto{7YiV!N>`>i7Lc=JOsA*%mCFnF47y$!3F9n7%y`Cr^aWnOQ)R?d<2&ZW4T~iT~v(aYp zT#pW9GwIQTs-TMN#66tfw#IOyP1*sbhAFsZ`{Y4aPojG1+u$7Oh9ZjRdF-)x zw^`;N0Wat78cF<`*tomnhNLEj_>BGGhPB>RgZxVU7KW?#lxq!6S95@4&-{vyk#qQt z9c<+BM~&M-|J^uMWPX>ITXhkj_Iz)){TDqQMS@M~subrkR#dN1BFS)x(=MT11^71% z-JjpzBIT`yIt=U+k`Wo20=lK0{z`)r?G6Dl5B5Ry+!h|joJ4Rxo7+{^#~IF^5UD3A zN*#vOIUK?Ng3b-GQ2Cw{ZceTtVVf$V2@ATE2nYT3U$S~LK%+uhF2q(4^(joO~~%O+ws|Z0Uw3=9O}K)@!L2QLvb6yoYOX z^_iSSmXxk(7TuS*0$3%vi|GkdwWWCL1?(uevAh0H8pJ^c^rI#{t+S2)#E$_r^nfU5 z!Q{tkSdl0d4d%@nHGwePA&8`TEDO~yjg1mO{|FT%5bA=iDgR(*8%w^!5`akvnYhPo zIaVJtmaI86DT8x$lrN^D%KbniRo&bOu=SahKS*(w|9@niWmr^w+wK)d7*bMN7#LEd zC6%tBI~0&EX&7mc7^J%yxr|vess0>UPPE1B!Z%9e2UV5;A}Sw;vw(J}eKrvf=goUe=sZpMyG`f(dwQ5ITPcEY^X}q{(J=BD;#Fk|EfOQwFo5`AQo#Rhr`P~& zcH$bj=ZtON01;OfN}D{t*K0$$%OH)y5?4N862AL+h|e#;?@>JBYT_MX8GKsKk%f$y zEZtWDtTsIj-!0DOLg*cSuq$4m&B)&7|esjLbg7xJ$_XE*Sr9Vhj zMS^5!(&A`P(36d;>GY|etd{n{qszWA-sf;r{f~0Y*l?02X^pA1U${zA{u+S}fI2!$ zI0E&9c2VWg-H<}==i#4-6soXsa+nK}q*XU8wz{yO$_4)8zJl|;sRoc$AM-ZV49a6+t4J7ivt+99cr%e3mh)}lP1P5Uo? zP#zdef>t;)JQm6qt}Ijygm65r@Qvfu7F%`Aevj%2mmdVGVNBtyD{0>Wxk$4pDYb4P zaZhj@m8|BrtKTFXD9NZ09LSOzC4nOW39naqX%%3~=)dgPSF17IXm~q&We_0WPR~37 zNF#fm8FEWxzu>`3M;nQ=@D9i99qk(hz;KcI)3D0wpj!lj%*b;YVQVP}QZ_2hROjt4T5pLz z%ZLC~^VvP^5x<@gFZxIWd7UC~3wW(1BvHcQ-vQY_pa+Bo?V(3t%lY7#X1R3Ip+eS^ znhv4#TbfxN>aAH-HQw(90WFd10+wuP`qqRXYdbVY9KfZ`Eh${fb~=aj0I6hFUyJ{U z?Dk!1|H1B5k!^W!f3bnm=7a3XcYB__qT>T^3wBQ%DZz}>fAyOy0EE{`2huUs_~yM8 z#v8+v;gi_Yf5Q<86J`cL{H*-!wZ=bS0V^;@AO5!ytxF^zOoDBVt|2wg>77{90N{G+ z+VAMDJj^G_U(tF~aFLd(Fq3e(%1MfkLRhvT2huLjakW$sIh8*C3y`L&b{mnTTdZ?8 zIteY2a%bAtz!o2mX%r~P#3;Y!i{OLE0s<6=`q^Sn0O>VfZ@^;>xN*qGITnWFQUD?ngDoYw@dln*36&?jW;6`>Qb&ong9vrzA*kQ4a7puK zG(<~iNjc3M|1^bsM}-oqI}y}7Q>p?erm4zN!WHSfG1Bak1yp5r7!(H|N}*}Vj>*-n zlganNkf3F?KHgzKQ*6^kgsY5@*b^S>>F z3^d2TS-^kta5qV> zV1-}HfuHGK!MAcU)qIvIo*gaSSTRED(QZ%it zfbVIUppcmfurfHAfMsegQ}%jL5mA!$=EaNT_fJ4-FV~(Y*5aS9 zi(zd055vjmuDuK^P&(Vhz@XQ^myi)SjPPSa6vFZU%T;U`*rb!N2_A5T5EFM<$Yf!3 zIw9SL-|M7J!Wu|4ZR1o;s$NcfF^5nS^3iCnMS%uxPhQarfKKZ4o#6C z{`IOrz_buhqWNh;VCpLKs~Hu1-MD1qK$Z5Def_Lecoe0!SXt9*onI;tH31rH8Q=P{ zo#Ozn64ng>Br#uT@BV=56Tnfkktt~YcgveHaI-S7xkB-eIAnq0(!c9L3G#MHVgSsS zcPz<{O}QGShs_l8L{m-yDbqAb;^f&y9Ra99T{v(EAa9TX?2IUqlN5_D!;>$6366)? zDDKiXI?L_6WehGwOd0Iv17#V3vT_s(FCgNvsT6nW>;8n@0_F}BO2DXX0t-+zHYH7e zYpl}pTW@LuhyuW{LBc5GDIx7D_jJ6!^S39T3%j>3>=I$6&z<`1BGByc7YGe;s&`wN zU`zc9!TUzk-}lL=w%7f6I4gStb^e1%0{Tk#0nlDF#=4N)Ka0Fw6HKoSU6IoS?<~{f zcoZa+@`d2b8&O0y^Cn^HhEM|)RUZI=mYf7tplY;y1h8dgJax7iK%BQd2SqaR&%7s9 zpOE2Mzc|C^?ZWZaW(60B6kO!0=9?T+dNC)l{SF`^tSP2527*i2lr&;8glUEJCTs#g znb2nigscf^E0Fs44OLV%u`}KCcn(J_Y8o5XmL($Z}ohUhb`h;CHahlS4MGpMx{tu`|!sH{G z&Zz&a;M2b=5XK;pEOQd{Q{s*Dn{||=)nxkqWA^(N3Hy)3BZcD&1WwlNt<6HaF3(nD zr*(rxwtyw02obK=*mDW_NzcpS##N}kVrrqFN^d+AA55QDSd)uM9F^bWC3OX%Nnw)i zQFy`G&-aWFrUIK@&R1i^Ei;2oe%I>>On=>XP8PxTj>POE3?VbLDk9~+3*=$u*k41k z{1uiFeM!CjxPMea*Q8u=x?~s{AN3|THW7kR~R4Z-55dF zU@aRmHsIH1ibzAT$MRE%ctb~*D`Q2X5L76#51z6j0`LT9mXnl;BE>& z>1QZ!EeHK@$GRz9B@hkPg4c(x7ovoU9zgm8`i}bT8!c_iSEl;(YjmB#FlU}U7`nzR zRo1`6raduWm69<{-XmEL;UTI#^gvHCD;6qiWt}vlVGL{^Mz79~NE*YUC{KhDb+1ET zJlKN&uq|P#+`h=KZ~p<8K7hC1#e!D$7D)w}hKxNu`S>4%jY$)PyHsZmsJb{>3!wfM zG}_aMC|KePw`ll62zkR_V5Nt2+qkm3El`Dr>~s-5!s>|Me&Ru58S#;O*o8K|@ChlS zRMDrQ2)lG;sv?pc9a`crt#Nw#A0OZNqho+it|@M-Oopm+)``O6+D_?FL{y;^m3$PM zv>L}??1C6cyOI?e5pvfMoA$ zzHDTK09gWXn*-h|9B4oyX^h~&>tY;DLYR)s%I&{fX)6kiIy?U@Gyl)=&;gFhR2UeA zux@a`iX9LF<%HP5Q||#JxSFsT^)jcnRDl4&dq98HcM4^R_7)WGLCI?%N(nicJ;oZ6 z$h`X9K{&*CY-1LEqVW1BWCT*S6vMu>*m_kHA7i$VSza6IU+LyviQ^m+DVI-lPlPj6w!cc7i=hm&}8 zT^gORvEvlr!?0)K@U%(b+fITLOpM-CGnl(S`TflORDnbx-_geEPp~;QAE=)rUtXXB z{#sA&kA*kQ#fyXixa6Ej`qPa1qvt0{prv6-rk_Hcd#=}|asF4UbmRbL@wMi!^}X!{ zq7;;}q%4f=f4CkXj8$nMhd(f-lmB=60bo5_jPqq5M4>6Dis!xnBLlhSsrhx1(lXRg zEJ0rDiN1H%59>*}Cy>R7M?SyfNj0V3aI_d(3pdNNk{zy{dmxa%mcx+5%;lf+E^435*;a%Z;|M}5Ml2c0r{Qr z@w;mOvC(Zp+86S6@&C$md)@(SaJ5S;=0Ef+Y)~9K@r$;DXeVVw9M#gbW_YLtF>gxO zr+NUPwHET-L3D60L|Egz8Gwi>g}$zr0tpyHhkulos7I*d zG|mCIVXXkEplBtd8MWI8zyH02!_b%TL8V;g-(5xl!Jv_p334thhiI_A#9Y6lsqV~5 zL`!plj(iZWri2R)iD8pZobc+fEfdIDyeH*&7zbm_IdTZiFl{xg6}U}}_DOr*-O&e- zASeM^ln1E}U=!^5u@%6uB}kPzJ{9SHaHzyeBZVFQ8DRYv{vlwD9iykJ8oqdEs0Ie2 z>MtLjrY8F{o|5GcesL3ysqdg`6+iD+i})Hz&T{`HNqVS+>ovsu_}T?g18F^e4Fmyc zm#{>f@D+s|c?EzOogv*%yKy1iqoXo@2?Tc47x1fpD{APxhY1*AWe+5x`}gsgWA9ii zE2Q|c=)5$Kewx4+7Dtif!dqq`H+VaGCsva45Gj@VjP4}o>lyW94|`b5W@iANj-oD$%SQ; z{U!urxsqa;+H_TaUT-^-SDWI`|Yc?AC>xttQb!kF@m!Xrtjjz;+Z z23SQvmB!Zg*~&jB4Mrf0p`C4wW&ubA)n*g5!a^uQAp%0kKIj08SA5((c*-`b_5krI zI95m3fGJ+1%UN?9wIm9qcxOCJ4oV}36Q5|%@*DxsE@9zCGz5`hz=UmW5T#SVkDU=u zjGo0Iu>y1FIimEQ?nrp*hb#4w4I%;|BR#V1N!tpD5dFac3Jc{#2v3L>j>;tFd0da_ z1s7mz3@vI0X%zbF}5p@^F_+2I^X`law)hW zeLnf9?<=P?ySfyd3HHwDgADyTxs)n~6O_1l4v#W8WEQCNYI%}r+R}t36&ylh%q3D*Z-OCjUK& zfbtq44pM!%w6MPq8e?w+#{YU3L*@}fW7h9?OG_cKsQ zkm5GDrZc}5LsSLz7%QEEp=7a{o8$5o7pP$)nNqlH?VL@&^267b`zWFMnLj|L2v652 z0k;KjTXBqdUd$fgo$EP>eek70(SjZ_$hq2e4+`N?GRmg_s>6!naYUVnJ~n=J?(ih+hZ6Sp!cx~qrFP91)kqKxB|1D| z;jK^{PySXClIJ|ZX;hfL{Z_p$l^1Nxlxzh6K zr$oQO*>vE1N{01EiZ{+(Y$Y5{#VQwlW-GRmN@l&(ZjtFo;t}BzyE&lRHG$)~ITho@S(uCyn;xe=uk_eVH$wpfwf+O*Q#wu|EbF8gpB`g<|A?Yl|97dOpD6(N zQj>K4)gJ#o5x?9Wo?sILAi<5q7dRiJ7BrNMd=I|9e@D^;|I4Ys4ma2N zEJ>)?iGcu%EOt_rS!P7#D^`^ORX|3z&K_9?NL;BW8qk@P_M#;-N;ASPCPQAKSRhL2 zxvZDm&i&V3H9v^$L_dRjKey~SkeC*#I7Iy~*HOa6n-M5(9*c=<{09drM!3|BQxL!8 z1r)%QmK_yBi<3W8ipedndMH(XOAe->tkXy>~w~bGmLQWb;pAXNXG0|ay{fl!_vq-IqYe;Jd2}8V`R}9~q;Vd`i zt6@b~KnY0~*_3>F_-DAR71@Q!q(CR%;^w!~;sFARS*Jixjcu4PbXQGRfK)MR#t`u8 zn|NMwnqdCTlIZSo4;ntFH8D@#Qr7#~(Rk(Q zByUojT|%GmW90P})jx&N(ZD-X1XB-6n(dI$TX8becd#MAEW=6OQZ>{oYyGE)u<$X! z;Y@ekoJ7ZQLO)QinM6VYeWeZwU6v}k@p!TCN=_ZF(%m+kO(pzKyX`GMu#I6b>Gyg)_U^%E6$iIhO)E(=w$`$t<1Agk>t>q|cbr=p(FQt6r zNYYusCffecQGy{*aMP9-Bu`mV=CA7nk?c$pas*eQjf(12xfw7Zri6&xS?4bN3En>i z1Y@fT410u6)0GRGB+s`U zhL@vC>P1ctsmT&97~-Jxo4JC3fP#k2n|1p*P~)`2P!Ku~1pS%X77xU)oGZK)bEMh( z&QAvPT3zkK+ui0X_DK0nPrwa({ZmYB$Y=KO(6bX)F0)D7NOCUDH$YyWbUV=UMu1|R zf3a4mU}7FZ%fAuq*w)Gv`>3`-l34)LXm3kx(yHF+YU4v`D zB_PLYy(ui+&H(5Qf(jHQL!H}su|t2A^Tm|CIj8*&rmL8pqU?+shy67ke(_an;lXU< zpC7MTc;$%yxDW<4a%!79OH`gCvnH>6&gZ>C11(T}X&R?r49V>TE5Ho#jzHtxy=85& zd{2S1yM$Zz+7X@Lzs5MSyI#3{10qDCr7#Q$yd5zVZ&Z!GNjVsagWsHzhcMIxcJ5Zz z4lDZ2JwGa-yS90OU43mcaXXEM!XY-xxBh}Y`AP!bW9fBSwp<5GyFOz|);r|?)32*z z9J4)}u+8_&BT~F?zL(=S_q@a3tzGOh5^?cwA03b8?l317d84TWB8sp{gWUgXI>S8{ zwUQK~ACk6#Gn8;oqWkzdIA)l6(BCqgECWc9qs$A}GeW-3wKaa=Y-FM6#_Adn)W^S<4AmknzsN8K})<} zi=RxE!rBc5z4%L2316uwHZ(u6N7p@{CLFn}Ew1``Gtxg8M+0vQWd@#-)xQC1IfeIe ze{%7~JCG@#Dot1K4+2Qr&)gMNZNAI6uN3^g`|~{?+yMyDiWZd52n)VtJONO7Tbo~$ z36sO2BNVHt&)%>)2~Nz}^OnD^j@|m+!+XQG^$e(o&wFc5{zpM;0j7@+(MY$IcTS6T zVqnH=2=Ph_muH1BKhd_MS=LbCR-}!gO$OH~sG7XEA8XeyfZ~|M7ykRUNEuj3oMU3u z^PqN$oY6A*>W7?aWW3nlf3QDD>i*%-7>Ad%EHm6TYn55_jI))x4mjtlAiW{G*p|}l zPbra=ysW>?0RkWlRa*>XyU$$-c<8SPOt+p*mi=+1MQVA)nW#J`3xCPS%eQJIehmP1 zTS&u02tN%h0A(-$P+!Kh3%Iv==^m3zAESY3#9fz9(BW`Tutegxtb;PU21jkV6q}!L z*A0Dr^cX99ruN809gOefS+u{*Q=<`+$;bbkQYPuL?TY$V3q$p|qQtHiJuSl_uJl5L zssPy3mO&_lKKe%-yHs`vQlT?CO;Uf2vd7hrkQ`IrU(bVY8?bd)=_AuYh1>y{?K{N% zXiw>)QAv0?AAxPv=Z|722EMi7*k`(MX1vi{eFnW=Nn~`SgexbZXCFm>S-hXhiQMn4 zU{njbuPZwaRL#Nn&+AIH2;TtZLiz1nL)sHbKSeRejEv^dkU{{ ziB5$v+d)_J(yf4Z0W60J?-!H*>G`pO)uAw(A-0D-a*}4c6~hOcHd^Otev1J8Ta)!c zLczCXD!H#^`RImdp=yGAMnoa3j1fa_m{Z;x7ycY-wjcP-{Zk_F*aaN`q zm!ZI3n>&nAf9^w>!=HmMM}64e#UkFjq=^;8_K`7Skuv~dL)Blg-i$NHOcqg+>q1gN zz!64D5wUwI+c$4c3OsU>V~Q4Wr*c$Sxq+H$;1%J|{;lu>6BW11pF& zP5)Bcjc!SM{ZipE857HN-80s&C6^I@`e7Tbd;=fXe2uWesuxa_oY7UvH62 z5!}Mgwt9xyA$2xsL_9$IW(Km3kMfXsHd` zWwGw{_s^}#t>glcXG0s5^sy8q>@5I5y7)5f@@)_>_#N zpp|aYiwa%?_>JZv zAeB~a1a)xVElJZ|sB7L=$1HuR)q=lUStHW{} zq%T-mzK8wcpmJOmIac*8muG-c>t)X!9mmA4_4=CB50aAE#(dy<}hCy5+2! z#hdiP6{J7FORJyNG|j5orV)_#)7ib1ik$aJe|@hy0H~#qd!3a2oDR7G?y6y7;yu7B zL&-vMfs^d`R2&uh>BM^?b0O)6?oG=s-(OVP*9ZRl!7>q3?+IXA^jG9n*&gZYnTnU& zsL^j8yC*DJ?wTTMDfaT+sY6~h?cG>n`+?dc_1kWv`Wf~-lqLzm7{G||XTcvf1uO5J z{9bp~q+&+_6uc_c^}PX*?0KyNZ+sFN*ZTFL^)*qvRp;P&Aa2JXjW@+D%h4iCU#KsQnu^c}6)Eb;x|pT6%m5Ib=kdDzGn zpgV6oJkgLrCNtg;7rXj5-Q-pxX1291hS;Jb!5@}1@~EN`B|(Aj|CbC(1jq{(oup~9gJobn`I@)QscJpbN38OF8j z(a8`W>98SEjJG`L_Q_6bM1e3c&Z~+;Ol#eae8-n4=pfpB~tP$?i9J&?_wcFKGwQ4 zdO2DB;~rKbDbkCpffjfX;hwL`KaPt(Q4eX}P46lF{6FlKbozDUR~U_{|WM#7G3 zJ^m*8*Qj+C?&>2@_$u|i=A*1V!-%BH@9;Q>suZKsws0!AJXojKRJia73E9+j^aDUl zsE-8fwnzr(EFlqq=_uTsbHj)DS)zL{NB6rwb^yJH)|WJg~Nm>cWc= z{({-=YBPBfYsfW?fk34C8nz6YZ2DoHSH&RRP{Ba)h-HXZ@5AEZ!3GCJPbdQ{8Y7=o zV6@=h6j02+bfu$`w%jZBry4a~dl6vw$v$k>G_gPI6ri$+mH8hFpK?HX6L{$spCXjs zJaBe$yNVavyW$iA_FG(d=t`zaj+SzP)V}Bc=b@A3Qmq9)`7dV$v zcpXEv-`(z?Yg#kEDYa>-!TwTQ1<#RrL@$nXQ>2&SbyYEgm#d!^`p@OW&YkQEhm#i2 zORf!N3UbAV^cikayQIxU{|;e0v76_E1B4-UEwA(8 z^Tg8S4Es0-M-jPmpXu=(`!-XZWh#;tlRv5WSO?6|@zx%bn*$#L zV!&ho*O=dVub#1|mE-Aoh;-Y%Z1wP3^l2MWc3lL%(Ps9MFkrowy?Fk7qzm44zL`V! z!P+y+OAXkAo__5r)Iqj}qRzhKc+rckTmaefV1`NJ#dUQ1x>nAG_R?htT`x_bF@_jh z?pNzkd8%H}T^XFakG}`5@^Ts8+iw|G(yIOKyU>5=%W!EMH)ld`8+YMfkAcI=4Z<+| z>8hcFqwTEc#C}t%=Yg9{!#)i9`s+i`u_OCZ5grF;T!YDK4ENB}U(U;ugCmJ^A(LOD1j$Sc zAZ72qiqY`AR=Yh`TU}JSB`RI{=?r9a-REU*-G&+NB*buu+9VVO;5N#!cKAX zXI@Q~A~C@bN8%ny5xy6>c(e)QEda;q;tS~=81S1Hj=D!4QTS!6xL+Q@%YB9gG;D}H zdnm1CKG?mDlfdu2BPov~DT`qOG^Ha)CIVVMUI7J+n&lq|dKQ)K!$s*JWl;2)5tB`y z@H)B*VNPH6at>MFlGuxOdEvQClhCh=^HR`N+qwu@4VHKi$c3Y#Yb)0?6oT4&vZ!*w zygI{h)^o$KblG~^!X;3rmecERNoDYb-@0h@IBC!ILUkGDoS4Z=8sij$@6RWn7iBGu z|HG2|^Dbt~lz%I*Hgex$n3Lubx66{VeRnVrH8hNGbO*@Uy>E%7$H$NJ77>wxyGvR; zxx&OA%tu6$<=fp~8Oc%F+NBK|%TzMU`AL(W-%}$9CGjw*_$49jvbWG?x!g)`jkytc zk!!z^zUD<)n5JYYE<=$RvQM*s(K+Ke0ee_?)3^tYic=|+|9*VwRRTh?{*L4qQ*4Hl zBcb%)IkHP>IEL&X7as%gNA)pfl`1fJjFkBSLp6amRCu@4WNa|46Cano0lru#G;wjO zzncS?5B4hhJ$>7`%{Og5y*{*eX6#<^F&gR7p9}P|-BvuZB?u@XTfVaUkZWebT>2#) z9ENIDB<>b9TQYj$3A1zj=(z9j*BqN)$$1MyW^n6~>%G=*Nck-m058(;=Zmu#G_237 zg-XWk`96cEM%J(jve|tuVXB+)rtDryyvl0t@e0UpPL_KHt z`S-ZHBOXtwTy}i7N5qzwNsQ(GT+azEVuyjEzj^B{nyd0Qc9F-iCO-P>f!y*LOKB2$ zinP`z_n778E{}8*9>id=-L2h~F>!Z=mB9Kpn&QpXS+(E=f4&6F7OX4Z`=sg;fozQJ zvZQ`O&KfW|Y!8=4up(KIuXO1#p~+Hb62J4V`U5isZ+3h`{sbvi=eJ+J8~Uc=NOEJ~ zffN;VSWKju70ZMrx31@rJ>Df7Anh9)REI2=3jYjwk?7(4)zx^-{_-v#d5ciZtL>WI zhC5aPBw+Iv;Wvl42jkYqW>g+K2CsPI^>3TICQ;U!!t_27!+vE@b+#(qjq;<5)5(W@ zd@x}-AA`P!4C=sK7!U=XwJ3}z#Ucf5v*AE${xucb)lJpGE=V2|rbRNJRFu^ErED){ zd^6UX%HW}e@1&oTkYJ%by}y#8ibr|Q%XwY)CEtLfObp)-*!Cq-nBc|5CaI+e3G(YH z^)nUvu7(^k4-9XWwr~*b*-(Bs9imvlHktH&J+-DwZe|)4#A$3vL=O ze6nMW@d1>D3aTKP6N5aC9ifLExwyh~#s21>HI z9mzT*jba~KtgyBCO87P}mf(B36$W|)DfG+q`6e-a-UyvYfo0ZtFYQ-K z96WTuE=ygaO2-A6&y*NCmqhOPX8l?XIWhj&YRf1I4f2F14_vj(`>HNQ#=sjBN5nRz zvQ)LTib|=X%&)-<)gQ{5NhF{)FWzfcJHqFX-@ojfIC7Zh=X9I~D!zhW8gLbt*r(Tz zEWz2U`)d++KD@M=KW46|ZhZ$|7d13myh{5GFQ(}=70KRb`IeU`wJ1}TFyIky56g&3 z#_4!bBbSMDP3Gb|0Zo<~ZO%mC<^Qa2y3*FLdhyaZeb4FXS&xt6WwskhAU#g+(^(|I zh@MbebXIkEu~@$zbqdGeS3$rTMw2k`ikR2u>!CKiP8K*dyg?Kl?m?~=9_zC(i-}}j z6so@B?^beDW+_!X8q^kw5y9q6&`4}8@cr-$i_Ma)$nv0%wVL0>Tt*T{Mc}-p@B0a?x=j6=z|FKS^v>I7P^93+pF7 zOR;!xeQ7z@hHBMv2k{&3yL2e8b8u;wVhgwssnJK_B?B(I?+YRad<{svRKI@y0ojyE zd76Dn+-}yUfo(-${>RM-mJH|ho*7BQ&sQIVz7FI-Fe#;U!#9O0V^pU;88^oUbiJ?{ z*K+u-HLohd|ENdme){hqyEjTFPW8e%Gd^|KQQavxS)!Xm4&$%S86|V7#l7Da zs4X1E_+JC{dIuItmZ`=5aeq`jlVmhdv=n?}GwhXQ9(@Npy$CeZpU@f2VGvViXHq{@ z{c`T-A7K)&=OenzeTskJFJXS+Md$jeY;oNli5ry`-eb3rHl^eA6r7=1AvFW$wzq+W z{cW*^(tpn)7>7hCo(Dz0X1>~8&AP^Y_WM?)G^5R7sxq(~mYMeZ0d0FAHy$OXU;@>C z5eBdvQ>b$Cm8#(Ez2gEYtn^AjN&$->&Mu34Cy%;K+rRRVce^V`>kR0!y~iaZ42rNg zUecz;Xygz0P#lktk)s^q6lT`4UjOa!%?5XkQh!RLJFX1VyXWy&;X?06W!Wsh7Fm+( zO_VZX<%8~nS|?azyevP9IJK%wO_v9FBv@)>wN1438{2;4Rs6=ls=|~-Pk8(5PPPeg zx}e3!!#Bg?L@~8%yfFSy0&j|$S}n27YO;kTD*d@fn@X~_>Z|xRJpeh4 zZGR}*C(fI1!`^>@3}`z%+4&=|`E9S~2<6g!NYPT2XwD|CdQkD$@N(3B=XdRh|JOQV z!OdSLqS3kfr~V~s1i&ehXfEFH@b59ArT;b;$9Cpt7SwzlNDZUOv&+&Y;S-u#jB>vr zcfPW+HpkM-%*ooog-Nb66-l=)3*VD~E;}Ch6aH!oX>~uul@g1Lw5^X+RoKD}#Fb=M zZgIrn8{47TyPWj^-88)Rp3>1n*xeU;#e5lU{#NmR!5nwfL~f9P_NRV-#$R8n`vmk! zC34;UA=1@Uxwaz1qB>V40T(6sj9CX+xdpe{<$>kZm@g_esfOj@MHBR@^Or0lEfb2T z$$G|=_eg-*Y+1bTn>k7wn41Q?n=@*7$=QmwuXOL-DI3Y=zqRnS$ZXO$YXR0``e%zF zLT-jpc`dG1YTt*mWml`1c$b0KU2h*AGs@IH@&C51__@B(@q9i_wRX&I*(2atQPOi= zBh|7kD!~nr{=y2*-Zm^2Alh~Q<6nc0c1baQK3Q{gDPy}!mSjACl4b8{&!WOaA(kE~ z%Z_DePb^f9JLr7yEzHp!n8*+O;(YyQMJlb>u`qW+@9xlNuvnqLva9uO90`bV=oXNA zM%&(K?<1f@m*jV1c#@6F$gTq?2WVxtUE){LxqJo~L_dq@Mr7w? zqG$D@n59WL$4?uDs$N>xzl(g1Vd(_ev6uy@or9%FjB+Gfa&TW}(D7dJkO7q&IO19c zk;xq7UaGR>P6+(5AKMPSdpF3WsIxx)eK)P!ZZ2QBwvo7G(dmN;{u+yM?yadEGrAb2 zFsZL`12@{77Gp&c#J!@lq5*4+bd=M~M4l>=(1&pz9Ll-y*&0ii+1JxmJ7;`0FSOsg z4;wCu4{1L+%CAvA7Z%8}&`2CIDRs?cJ=uy0IKo%o+eZdYaHqm7EK# z%5v~nm2`ujzvR3OH;x@MuUN!O$RUG79XxJk1T`tY_lQl|)sdJxm!MjB4 z@Df=x0)=pB^%$;lt*kI_UzB{V>8y~Px4ncwOUwaxel;Z z9}4#2Pz-T`ed7_@I5FDO>5AK57EY?t5CT)Ddhjnj7asG%uPeV%hMrS8Z1DlClTe8v z@taj~Ot~Yf*GH_w=C>CgZkqx_7DIi{&h1KO%L?XIYxsX1x4kHKWlEHgsgphxzpNFH zY$Nlk*N6LvVmI;R>$8J|`z~x=Z^*kfpbZue90o7L)qKqqudPly6LOi}kk+V7_%92l zuf_zR&3d0rCzN$NF<)O3{<81`6K-^*HGE_{e3h;9O$7%7>411^LA4d*RgqPww-`D5 z3XsP*oxNWv?!jh35~AJxgs6vV&{lulUO!?MQLfitZZR+uE}V8**nxCOnq?FwYw}B= z$ubz6KV~0-t6Jj+R#jgvd63^6ry=FWzU$~pDw4`YM6vJo5wjLZ4alBoKQ_FhmDjYEptQp1A-5f*0FuLQM*>4^E|aV^SeRro z3^p?2v_Mxo1~4)i9<4S_c#Rf06ChGC|RL8|N zH&1QR`OB#TShvvjoH5;aN^{`hJUTrZlp?XHNjw`CBy%(=#Cc}$36xN*xrJcrX*{)>3ZrcOgiaIP<8({aW;N^l&JC2k?>_Pfi1F zPpNq~`(7}B<&V5;@`T^1_vvi@Fz-Ixvd5Cefzn&1$sZL%m=eXdrozMHGLxEWb)|L!u}d zPGC!sQfd#bzFd(xT@t&kJ+6oR*0Z#{@Yz(*1tw7xWM6hEW;KMKZdMDfvJbWyH;lw} z6%j1jg3figM`D1TpZNlFFAsn!@~Pl)w4B?^VIxrRkJfKAJ{E@>F3LkAeP`_VnZUYn z@B15rR@3l`+pg!@9IhUXapCuRv+o7mUcRoS9e>v1St-gDby7Rt=eFfnbaQ{=^|Ns& zvdiN4g#2cceUp{ZVm5u?3S7(t6~%ULvf(+E&00r?fQx3wXMZ{q7OiUzS+4|~TR-qw zJPJCTvKrEANf%UsH{MMNN(J?Ui=Sp;HIy9)1{?`O?)x^HYVckHompD+$#TD5{})|C z>qB9zEMTy>diJr(hQXsvlB%q7gQzXP7VkBr_VeLP-Y(Is&lBg~bt)}}Re^=Zs3v=K zEO+<*cUD-1(6D*i_gPv~R!#p+}-;31Z70`dR>#8*d zah5t_6KQ^LY*Xa0)ESFIC&?7V_tUhn?5oAl6}`_pf6j(E#ahans>k;C(#hOQhm15i z?Ul&;;d^@PL(h(_Pwd(#gu=o`3al$d{aHHeebG!;VSD zF_5*eUNgvJGtu*Vuz2#o@0YYo8_zY`>-C->BN%go%q-*a*gLx5=juW^W6y-ST4rvp z_?Qoy$y25{IEU*jNG7l><{J~e%F{K9R{a^~X7)~rC-Z_GswB^{pc7$BBRN<7Io-ce zzJ9-^!|aWN`bk^qKw+*Q*1x6pwswrGJg7kmZSH%K4&OsNMwkbfKHHpO@d>}9W5g%C zv2AsZ-bgJAn>v6i)7H~mm|9Dwd@i*y7B3qKmG69i!WAKBl`i>#o z>Np_6sJs#CjFRtY^)s=+bj2F`VxRTsKuRzv)yUQz?QRR}B zyKCF2*@^favQNs6wF%0!r^teMEFc6LhbP zQ1uhW&ttDvfx7!=*@=?fr>R6ctj8XQdI2YTJm2Du$RuenmO*utv(fYqD3gv)6KhO_ zdPDnZeqBZDN3$G>ZWi!QHRuE;JNBYT<;XbWLc^w0 z3G>0G6t6&U<`cyuv1k4K`MyA-D~5I{kw@WU>JqmKQdm$!nB`mWTkLe+ti9dP8~g@UZ{8^1DWCK$BcG!aY*M;C={y8H`@&`$ z&{ng@%zU97lo&Edy;*sSs>8X#y}s$zKXqrK!_2fU-9!hzb45ecGiH6PE27AYX9aGa z{w(LTYoY^B@p{R6i396VVEcfp-T<1+Mm@dkQ{CVp!``c}udZaT98`{69O)GX4>d^) zF!a$XSd;W?*567PU&{9V%5kA^5vP))q7kHGEM`LS_=2ku8G4TvH{bF2Ui!9B^y(*^ zu{K0Bz-u{1ocyEVjCvUZUpNO{ibi?i`rh7mH_rVA&yAIY0dS65fa-Bqhls9{9jfOI z5!Adzi=F#ePC0&C9+plWc!8u+%6hW8(z~)%S2E-UK`6vWUx%E!)F@oVOQzWir&r zM)n87_-@QF&V-~xOjIvMJM8xI_7O9PhAlqANCyppONrhV z2Jl9urNl7BJjR&@Tkz@N3k`$Yi*FLs_6GSz@X%PB^CPnRi<8~aCcK+;LHf1UBQZli zjd^O-Fgbx+Zs|+=-|t6C@$@bRpJ5n}_e1j2pMi{Bg_He!-P}z?q&1{sDf-88%SQOy|~H#hI#)ONI1Cx zzrVe3N#xauu~>-{PX@zLtQ3j55@dq8 z-M)l%B}TXpIa9e498feIrY5pgm?kSJfR+BrB4+=xqs?yFu!A+PY~(ZQ_12!TL%<7v z!ACx({Rhf-g3aCf6POM>qL>wnI`@P-gfgr-4I4i4e@jC4I6V*K!AQ4YCYprKHE4tH zxI8~X7iFCZ${srY98G$9KeM4xa$>q^!_IKk8A)PaP5yZm(3(A28%aDKNZPV z$1hf3-|v&%29@ae) zuQkKoM#LZ;#&?VRyw5z@%$aH1_zP52nnh^GqJJ~@h8ZEp&?#vK(_aqMhwBo)X7@1p;`>}?+1kzqj3=1%r z7i+&K9yDMPLo~X{C)DP0vre~(Tazo~F`2CTxo!9Q{P^HEO9mhDetyy)EiMl1m;|F< zvG%w{uAr=|6z5$Nx`Qt&Z-}>L#NBEBPkUb;4`uuP&opX6MZ`$9$X=FgQH&)KV~H%; z_a$o$B4jB$k&>MVS+ZxDY*_|n-z9t5cd|y`>$W^k&*%5~{rCO;_xNL8%#8cK?(4eF zIq!3>bKa*uB}SyYZ{phr_10@A?Bc{nUUC|TT&hS$+Wi`>T0EryZ@*p7*eh&2oKn3K zS($D3Yh|#Ommr~!E{?*zpwlUA!_H==aH(`IM|CFp!?H`-s-v*pc2oM=X2wsJ+1D)j z)oa6`^&@4i-y=45(J+%8-TmOz9uZ0Hh*xQ6^)r4dT2+CS>YD`Uypq0rJ|Yr723E<5 z#^|4D;oF*`-Iweb)SZQE1x*0}q zltcJh@LTDm2JY2q&zO+=R~)Y?loEZJx~Upk|6uuR^SsQfn?4fEcxp4x+1+T*Jzx*I zK=iFK<$;j}CH*@MVOm6z65CwiQu+N1KPPN#qcGhtBYUuF;+8MfD-kcYSSRzOFYBwj zRJIJ}w-WvtMWDvCyE1Zfd>41z921x^ne_w6b4z6sxQ0m7ERdq3~{1Y*aJp70a7&2>J4 zYa*J9jiP6UWkY_G%i}z%E}w?`Y-Zm}4Z#y6L?~TNtd>ex2eovwl;dL<=mdMR~`QuelU;uLO8_9U~41Io? z2Bnvs@%hj^WZO5HqHz@gh{DJs!WJ; z6+Iu1@Id@#zAuYEpqoWEskrBGXS1b~$(r-hyjV1AaPiuMo%)XoDH}hlU+9zmmM*oU z9bqQ;eaGh;>*JF7-(33ijf~=uuY&TFWkN|4H=l2iH(aCHzIBoN4ms@T~$!+?k5E{DHF zR=if-#Cn_+e+xO-Jnz;(@)_UIbgVgvuRgIjKQ9(x8b;MkE_E?5aE?q^?b3alq=W=c z+_ntGSw_D0WjhO|vY8b-+y-Ex@OM**dy<<=|pU@Z?eq5Kq09vnjL70U_RKgZ#bH2PQ`PKF$aYlCmh!;4M2(Gn+aS-EC+J*r`{2PIBvEq4syys8p5)PudBlX8>KtlWeqR#3EsNe~ zvr*#<`H-7^JOkQs3bAY5QxGdoXf@Q*0Oz3yS5nms4orlCwA$zR^HO-ZHiNO*M}tGk ztRNxiP97PG*X;c+EBvzLrOJB^Nyu7+VYdSkSIKkZd#I$Ll3!RoRL)(mJa8NR)_g|V zx2N^`s=Sqebi|pcE4wW=vb(=X@E9Ydm`P{r8Z1*J!nwTkuJfLynU%lw4IVZX8{HI- z=S%coD?E#!`-JRYwZ+OyEy3w}>1#|N9rmvjt>|8GxTJyizLr(MjDq(zb z{-wADQ9~_ZS|L-;gV|(l2jj)y&}Lnjukw?F@Hg8!9Sugt(wFZQvS#U)V~hML#hInwFmCeN z4wWH=l53Vz^@;n{;F%4E7yYCPxU;r(5ESi&p?et+XE;t@Z?J;FLrVX-2PZyLg`zjY z_2+}xXv>jRjq2!gevKm!FDV2&o4%AiykOtHWWeR$DN2z2okA_M!xj5 z5VN@*&=1`qc+&LVb1D4ydulf>JZ$3e)Yq#NiJORISd!6Gl#Adzsjlm6(j=NxnRY#M zKIOG;z$Y$ghjBNDPslarIMXNaxFJw(Rpi(+n0W)|7>afP^~OFB&!v4W*7akD8QJE= z&VbX6ir1HG`{235=rf(zpbkcHjU%}UQUn`x^PB7IgAE!k?J=PU>frU}j!i+?p(Awt z+zxIhNWar_uNEZia>jyu&%A5rqD+i&YX#h}{^fc)I#2o_r?A zvq-fv)&!+zwt%tv{FZdIA>|#R z!zZ^hrS1pojbTMSdGMkp* zjxABmcSWM-GWB*XH9k68KkEHBbZ&=%z2)1u|60mV$fFZ*`UvXR#~Mr>sP1;(eWUpU zitkReCeR)4uRN7ppEtzU&6wDwYW^7_U#^==2c!|@7HWDb`*#H|%yGad$QH|KGaL+! znHk0HZ+ZtJahj`~iN2rh@5b^f+J{s=N#(vYxsis8mn=rdhe+_3Wn=~L7*?~+3Zp*ZSX zf+Y!!XTcD~U$asMV$e8_$({YU9C>6d3~q`n5887wZHgq#26br=Pf=|}`0Y$I-cwT> zs8j8@j1iv$BdT*Tzm7ty7IhZAHboMZY6CaF^F|g)rM|{ixLC1+Yx!`J{ZvwD^G%A5 z`Ql+(_r2AG-u2O1Y&)rtrVL=2AO?wRW=-)kPFJhNky}xR`heRN49CYd0ekb{4J(p9 z%gpzNde`~V42_GaZOeFokh|2(c8i(cmOk+f{%R_13J{t-PtN@Lu@R{$46j76^JIJj zv{7{4{1{_2^BHk)0-t8f1T)>evgTV040`D!*O~M*Sn?N;XOIMK3AfYtMUGr&Z4uV83JAFt0vYVtpvXsX(70ojJ8 zx9zQdiX{8uolPFq0krp{fcz{N|5}g#bc)wbmS%zBst8Qas+At5m*PPE(;`S)W5zGu zO?sr`NW6Z6xtg(dy$R{3#AEpE9YLxeEW0y;CsHlQHIbcZio;XHK5JAGxzV-PLY=excS-XWyjhJUf$5Q4*7yyb z{ED#U5Ybx$vI@_ZnrrLRtN!}PPR{UK9#*{3j1$j1*chiZ4|b1IqAoxa<-s}orV>Ms zI?)1E=UMT-YTb({F1xgT!ib*jHPyF=`89~8cFv$w8z}BIN9~W2rA0Crd5@e-t_VxP zG%)zqGMfO^9(77eMX<+-6YM5W%6Ew)J^QU_JZOnS?QKiD<8a42uEm{6 zDf+cw!J_mak#3X3e5{r~NFGW^`b$Ez9ybo)eHBhF56b{Y@ zq9MZX2w)#Sx`EACFV8))K`)7Fbrcg00xK^R@puV@(8asZ`T_R1d z4%NJ;Cn0z$)=Ihqa8~u5j6SlKdp!sxUDQlHwB)ly_j{Rc6f}Th%jOhMP5Aw5auk$B z5CO9;HD~8CROVdg%+e{fE$TAjd7>KB!4C>q(!}}q5`=R1gWAX%K*>%E($bL)-;%IoJ{jXN}>Gq&(heFJ&m$@*2LKJ^Oo4QatX*UhH1(=JTrQf zQ@&1!xzaMeHr)w2dvBAIf@Fpp0iIRB%((?vd1j^`2;2yqnCVo@kRk-1d?Y-YUICH_ zA+_AqQx{{N;XO5(AtZrcL_(te6e?~yu55#yPVIxw0YKzZ=M&Z}iSiNk>3Oe3Negg$ zWVz&zSZ0IpHzaVa0#md;H8N@*cx#$G+z~ymtWy_RgfFuA8SC>k%Fow}Z6}KbB(MI^ z8h!V;)UWlxdFays%a3DL*th&hZ#*hlIAK}1*zrO(A&%w}^O+)$eN{JM12@<}~go61{eZBk052rD5#p~+!eHk&~&i7d3G(G z1@#bpv=IM+!5G<4J}r=R>>!fT2S6pyxtPNC!pmGh1#6e=ZOo#(C$jDx#K}62{g<>Iy6^Htu6@zl%P)cF zha)CJsW4s2x9XUUpw^9fHREG2oKP4sTXZ+X#C!_$jFL6~Ea3u}2+!TAA6tu)d?Mp* z<0FV`c5pm=0;NP-VAHmx=T96MVE_j(MGEUJAc+~bRKDoO1<_vR4ZppkQVg~G9$omj z7@{d|%yL;Hm!9Nl((e=-3gNEQ-^qX<$QSgO;U)RT{{BpYtl5~cM&2HDXj&6Qb+t)i zW}?MT^9XTZV1wlksD)_-We%TFn6wY5k7`Y`I1oXl)N{3eG?!Oz=`FbS8ngA|b$$Eb z&}#fftwPz!DNHg+mZ54<;1w+Ex_?)pJZ~5>Yyl$Q653tsj4}Nid!jstfjU@GI@Cv= z*$8gTHmGX6kgAwK3n^5))n>sHFp(4qv);A1wK^_$o>)wW>?qgSLdSMT5yj(Gg6wZ3b{;`_)uc z{#yBxv-usg#^X}!)7!xImK$OfebhblI{-H>#Vw2osFSM!6kw!R%GWyj`uQ2({kY^1 zfTo{UC>EQ*AJf4Tr}jtjR!Vs1Qk zB);g7DXTN@yIuX3yacki=I&dcdF~8@LWvl~_0mIostOd;UG85h(5mat!T59x%{Krl zuw8?Uhd>$lKWem7wK*bmOR~zRy&qzd&c#f3ECIMlDHuOK1?Z^)X&gF91<~Id6fV}J zXJ_5}z|jZUFXLA zCd}YT$h+_FA&`T>D%d|QIme+^J7MpToWCq8ZOrIVTM0~Q>1=ZC-QMQP162qNg8?PL zwR4aA<_~O@{#is*BoCti8&uY82;fkn-mfvrI{wFF{w&q`CSMFa{3_1~jd)bOvx5gB zPc7`j)b#F5^D|G=? zfD#CKiy%ur;7P>}z9%43&t)HN?I$yH+=W(}{(!d~CHU@s*EytJC8sH@|w)@pkq z6ArjxLc0q`E{#6qk>VyNJ|4L^zA!DDQWHQGJVb&Vw8jNdd3tn!iZ@z_v4|VEcu3=X zHmx&G9)SmeBe2?*K+|+r327cq!Ep{$q96TPDj7b9$DpxUO_}p*HQ*pKVOj7V+9#eA8f;5sR$DTV}y6jt@ z`XZvUC=2Y^w-!A1Ivx4Zrp9jA51g@BgSzc}1#7iI$NJ24O#T_ov_f6T$cM(bA>_7wfa8j=J2&2!gjzn>%i*LZMXSWpB9-@`gj4xX*F=^ zwf0%iZd9)ua+n960UAf1IUrykR`sFo0neyyO5Qlq>Q)69L8ke`>W#h4@lg<^JH?@% zofYRx2|2d8z|(pvw&^Wq9=ljg#6`?mko^nz`|d&@_%qgEhsJ-(694F;HlTCB|BbD7 z7Xeg+HE(=r?+MDqw&dA0^Y`+#6hI(w+zlXn%UIjxvAR(}B}NFLRC`e`ep}aZ>Kc)u z<&fMT5n2?J24f&_M)y1uaB&w1pn`sa>8&0By*j@BSgM}s&K%FDbz5u4ZH0gkNL6KO zb?GR8rY9j9>}b=#*+QU~d@mREB?-~t=L7mPE>0+Xt5uvWbcPI4u|CgTzcYTw+3`BC z)&JB?9(b?vfT0$=;z=*1f_JezDqs(A<&#CT#~TwuW_$Ybhvy)2u2cdpT%)3R<8G{3 zCtC0nhz{6}*{#%3xr;1Abmdu(Kt!P&UGTw_WZ4vUnbX(WiXA-6!%YZtq-u^iDl^z< z<)n^~(4p$0-AWAW0+3Sgc9eS3o8ww9R&_XD=UzGQ8IkI>bL`CZHY{gEX9Q{eUj;iGwue93q~vhdc1UN<>gqE(lT%WZDO7F zer*NUAB#elJS^+gT*e0>AKPCS^bX97eiyX=w@F9Vp?C-x2|bDU4{SOK`5UjVYVS&T zZ97*q6tq;RM1AR%JM%X=CoDKzDOUO4t8AAQnHY2zDopRjSsA4PF=U^wNwqdEABd=X zps|tqgDKPIa^P-X5vOQDvm1b|i{{r{)drTU%(@8-Iz%VJoWEuX>!>}*(W3Qa0vENS zOK7abZt3mLs5`9VAO zbUkT*bVTEI4C#6?Rl$}O6Z*Yp>d^*TnjxKDhPyfuk_ws=!H@5j12^4uhp{hb#3 z;P$WHz0;HX5Gt|>raBbkb2}$ngglJzd1h1x z@)7U&3C@(j^#=gl&%4KArEwhpMJgU;{i#`1LAV>QDcu83zW0;^b*xUrw}w^UEs^!n zbN8tt=QA6DIpDO@<|hc(I9@NQ;t^<)`}-@*_5zWWk;*5(s#}A0>(k|mqFcs=8AN-z zXp6!RspE0rUvk|XUi)g~iCTZ6Sf?52{ob+--U~)Q`(fAAYpv(PHT(4Opg=zQLh`Rn z5y4!}Z(9qPJ4^J57Kc`Z9T5xIpbdJmG)FrDW!h7<;w`ngrxf#$RRNI=9S`DQg?ut$ z`^2Pyi1d!e2a#srv}F;~gWEz(U|#3|Dv03<8G_==C2im{-zsgb2vwFZ7ptm7nMCd< zJ;Nhh7|cz(sHmT&mC~7r8ko$}wbtaZ{vwk@hO!{aPIVrjJ(*ZY;P^G-(=7ZZ)}f5d z%96;#Azz_MGBN#fUsq$k(9p-}p++;|=Lg%qhE?eawIi~)$NJ8ZojwFE(4WX+04nS| zx1|4zsV@X5CAeqL@%|CmJcKKdb+-pF;Jjd*?Oy=)?`ukfFky%Jylt`C-`_v_?f>L< z`kn1xwGZx=NahI{k?{W5gRtJ=eWm5Wko@ND1fk>wbFw~g5Pj_T5l%eN3aBgkokiNU zlmAW0+yoHyCdGbI{(pY_9bmx+q=y0Kzx50B8-zB_X~zB)KK&bCv4(=#`+U>&uVdOj zK2jp*4plX_Px^m#Rw5W8Jsaink-PfGKP94+0b&cQ^Z(D`LEk9_EBx<+{k1m#uGl}e z*1ucvA2Rc=jQy!r{#73ToDIT%mB+uz<6i^)r%<4j^*hJ9?B%sVc1g*I7ZGk*VfZK= z;ZM!VeGbliLFOw6u)uyVfJk|IZh7`m4ET@hale3pz9qX)i+ApF<#3Vd1`r*FagPw> z{+~z}{2iI|+d6Z{4?|vmI)8(t+@W1Gw_g93Q4p5{Ec9l$&L;66+jt)vw9x>RH)xMx o`*YL>sG+J2Lc9OlxAXjcY%Ux#{v=yC4-fpv-c*pvmeBY5A1fzxhX4Qo literal 0 HcmV?d00001 From bea53f818f2cb7ff91e7cbe483f6a36936f4b464 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Mon, 9 Oct 2023 10:17:27 +0300 Subject: [PATCH 53/62] Minor improvements --- .../contract-hash-vs-package-hash.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md index 8850caa307..99e43584ab 100644 --- a/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md +++ b/source/docs/casper/developers/writing-onchain-code/contract-hash-vs-package-hash.md @@ -6,11 +6,11 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; # Using the Contract Hash vs. the Package Hash -This page describes the circumstances of using the [contract hash](https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html) vs. the [contract package hash](https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html) when calling a contract or allowing, blocking, or tracking calls from other contracts. As noted in [Upgrading and Maintaining Smart Contracts](./upgrading-contracts.md#the-contract-package), the contract package contains various contract versions. The contract hash is a BLAKE2b hash of a contract, and the contract package hash (package hash for short) is the BLAKE2b hash of a contract package. +This page describes the possibilities of using the [contract hash](https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html) vs. the [contract package hash](https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html) (package hash for short) when calling a contract or managing calls from other contracts. Contracts can allow, block, or track calls from other contracts. As noted in [Upgrading and Maintaining Smart Contracts](./upgrading-contracts.md#the-contract-package), the contract package contains various contract versions. The contract hash is a BLAKE2b hash of a contract, and the contract package hash is the BLAKE2b hash of a contract package.

package-representation

-Depending on what a contract needs to accomplish, it may save and manage the contract hash, package hash, or both. Like with most things, this behavior depends on what the contract needs to do. A given contract might: +Depending on what a contract needs to accomplish, it may save and manage the contract hash, package hash, or both. This behavior depends on what the contract needs to do, so a given contract might: - Want to identify specific versions of contracts within the same package and thus use a contract hash - Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash @@ -77,27 +77,27 @@ Consider the following questions when designing the contract and choosing whethe |Answer|Recommendation| |----|-----------| - | Specific accounts | Use the account hashes to identify and track specific accounts | - | Exactly one specific account | Use the account hash of a specific account | - | Any accounts | No need to track by account hash | + | Specific accounts | Use the account hash to identify and track each account. | + | Exactly one specific account | Use the account hash of a specific account to identify it. | + | Any accounts | There is no need to track the accounts by account hash. | 2. Will you allow only contracts to use it? If so, what kind of contracts? |Answer|Recommendation| |----|-----------| - | Specific contract versions| Use the contract hash of each contract version | - | Specific versions of specific packages| Use the contract hash and the package hash to identify each version | - | Any versions of specific packages| Use the package hash to identify each contract package | - | Any version of any contract| No need to track by contract hash or package hash | + | Specific contract versions| Use the contract hash to identify each contract version. | + | Specific contract versions of specific packages| Use the contract hash and the package hash to identify each contract version. | + | Any contract versions of specific packages| Use only the package hash to identify each contract package. | + | Any contract version of any contract| There is no need to track by contract or package hash. | 3. Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be: |Answer|Recommendation| |----|-----------| - | Specific accounts and specific contract versions | Use the account hash for each account and the contract hash for each contract version | - | Specific accounts and specific versions of specific packages | Use the account hash for each account and the contract hash and the package hash to identify each version | - | Specific accounts and any versions of specific packages | Use the account hash of each account and the package hash of each contract package | - | Any accounts and contracts | No need to track by account hash or contract hash | + | Specific accounts and contract versions | Use the account hash to track each account and the contract hash to identify each contract version. | + | Specific accounts and specific versions of specific packages | Use the account hash to identify each account and the contract hash and package hash to identify each contract version. | + | Specific accounts and any versions of specific packages | Use the account hash to identify each account and the package hash to identify each contract package. | + | Any accounts and contracts | There is no need to track by account hash or contract hash. | ## What's Next? From d26ea64fb014864f2f296763f434856df60d8d62 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Wed, 11 Oct 2023 16:48:45 +0200 Subject: [PATCH 54/62] Add verification commands --- .../advanced/multi-sig/multi-sig-workflow.md | 159 ++++++++++++++++-- 1 file changed, 145 insertions(+), 14 deletions(-) diff --git a/source/docs/casper/resources/advanced/multi-sig/multi-sig-workflow.md b/source/docs/casper/resources/advanced/multi-sig/multi-sig-workflow.md index 63f551810b..e09859fbfd 100644 --- a/source/docs/casper/resources/advanced/multi-sig/multi-sig-workflow.md +++ b/source/docs/casper/resources/advanced/multi-sig/multi-sig-workflow.md @@ -8,11 +8,7 @@ The purpose of this tutorial is to provide an example of how to integrate key ma :::warning -The session code provided in this tutorial should not be used in a production environment. - -Incorrect account configurations could render accounts defunct and unusable, thus losing access to all the corresponding CSPR tokens. - -Test any changes to an account in a test environment like Testnet before performing changes in a live environment like Mainnet. +Understanding the multi-sig feature and trying it out on Testnet before using it on Mainnet is essential. Incorrect account configurations could render accounts unusable, and you could lose access to all the corresponding CSPR tokens. ::: @@ -46,17 +42,29 @@ The [multi-sig GitHub repository](https://github.com/casper-ecosystem/tutorials- git clone https://github.com/casper-ecosystem/tutorials-example-wasm/ && cd multi-sig ``` +If you take a look at the repository structure and open the `contracts` folder, you will see session code with different functionality: + +- `add_account.wasm` - adds an associated account with a specified weight +- `update_associated_keys.wasm` - updates a key’s weight +- `update_thresholds.wasm` - updates the account's action thresholds for deployment and account management +- `remove_account.wasm` - removes an associated account from the primary account + ### Step 2: Build the sample Wasm provided Prepare your environment, build and test the session code provided with the following commands: ```bash rustup update -make clean make prepare make test ``` +- `rustup update` - checks and updates your Rust installation +- `make prepare` - sets the Wasm target +- `make test` - builds and verifies the session code + +Note that in the test folder there is a `contract.wasm` that is needed for the tests to pass. If you run `make clean` that file will be deleted. + ### Step 3: Increase the primary key's weight to set thresholds This workflow starts by increasing the weight of the primary key from 1 to 3. To make account updates, a key's weight must equal or exceed the `key_management` threshold. In a later step, you will add the associated accounts that will participate in signing deploys. @@ -75,10 +83,27 @@ casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \ --payment-amount 500000000 \ --secret-key $PATH/secret_key.pem \ --session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \ ---session-arg "associated_key:key='account-hash-'" \ +--session-arg "associated_key:key='account-hash-'" \ --session-arg "new_weight:u8='3'" ``` +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` + The primary key in this account should now have weight 3.
@@ -127,7 +152,24 @@ casper-client put-deploy \ --session-arg "key_management_threshold:u8='3'" ``` -The account's action thresholds would look like this: +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` + +The account's action thresholds should look like this: ```json "action_thresholds": { @@ -184,6 +226,12 @@ casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \ --session-arg "weight:u8='1'" ``` +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + ```bash casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \ --chain-name "casper-test" \ @@ -194,8 +242,24 @@ casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \ --session-arg "weight:u8='1'" ``` -Now, the account has one primary key with weight 3, and two associated accounts, each with weight 1. +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` +Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1.
Account details @@ -258,7 +322,24 @@ casper-client put-deploy --chain-name casper-test \ --session-arg "message:string='Hello, World'" ``` -The `hello_world.wasm` will run and add a named key to the account. +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` + +The `hello_world.wasm` should have run and added a named key to the account. ```json "named_keys": [ @@ -273,9 +354,9 @@ The `hello_world.wasm` will run and add a named key to the account. Given the multi-signature scheme set up in this example, two associated keys need to sign to send a deploy from one of the associated keys. This example uses the following commands to sign a deploy with multiple keys and send it to the network: -1. `make-deploy` - creates and signs a deploy, saving the output to a file -2. `sign-deploy` - adds additional signatures for a multi-signature deploy -3. `send-deploy` - sends the deploy to the network +- `make-deploy` - creates and signs a deploy, saving the output to a file +- `sign-deploy` - adds additional signatures for a multi-signature deploy +- `send-deploy` - sends the deploy to the network Similar to step 6, this example uses Wasm (`contract.wasm`), which adds a named key to the account. The deploy originates from the primary account, specified with the `--session-account` argument. The deploy needs two signatures to meet the `deployment` weight equal to 2. Once both associated keys sign the deploy, either can send it to the network. @@ -306,8 +387,24 @@ The deploy can be sent to the network using the `send-deploy` command: casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures ``` -The `hello_world.wasm` will run and add a named key to the account. +Verify that the deploy ran successfully. +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` + +The `hello_world.wasm` should have run and added a named key to the account. ## Removing a Compromised Key @@ -333,6 +430,23 @@ casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \ --session-arg "weight:u8='1'" ``` +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` +
Account details @@ -390,6 +504,23 @@ casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \ --session-arg "remove_key:key='account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" ``` +Verify that the deploy ran successfully. + +```bash +casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ +``` + +Retrieve the latest state root hash and check the primary account details. + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/ + +casper-client query-global-state \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash \ +--key account-hash- +``` + The resulting account should not contain the associated key that was just removed.
From 1084c24f3d4030b64c06d3b958d30556d0eb5189 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Wed, 11 Oct 2023 23:33:07 +0200 Subject: [PATCH 55/62] Initial commit --- .../cli/transfers/direct-token-transfer.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md index 09cff009f9..9f12b033d6 100644 --- a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md +++ b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md @@ -6,9 +6,9 @@ This workflow assumes: 1. You meet the [prerequisites](../../prerequisites.md) 2. You are using the Casper command-line client -3. You have a target *public key* hex the path to the source *secret key* -4. You have a valid *node-address* -5. You must be able to sign a deploy for the source account +3. You have a target *public key* +4. You have a valid *node address* +5. You must be able to sign a deploy for the source account using the source *secret key* ## Transfer {#transfer} @@ -44,16 +44,16 @@ casper-client transfer \ - `chain-name` - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain - - The _chain-name_ for testnet is **casper-test** - - The _chain-name_ for mainnet is **casper** + - The _chain-name_ for Testnet is **casper-test** + - The _chain-name_ for Mainnet is **casper** -- `target-account` - Hex-encoded public key of the account from which the main purse will be used as the target +- `target-account` - Hex-encoded public key of the account that will receive the funds in its main purse - `payment-amount` - The payment for the transfer in motes. The payment amount varies based on each deploy and network [chainspec](../../../concepts/glossary/C.md#chainspec). For Testnet node version [1.5.1](https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml), you can specify 10^8 motes **Important response fields:** -- `"result"."deploy_hash"` - the address of the executed transfer, needed to look up additional information about the transfer +- `"result"."deploy_hash"` - The address of the deploy, needed to look up additional information about the transfer **Note**: Save the returned _deploy_hash_ from the output to query information about the transfer deploy later. @@ -163,7 +163,7 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- **Important response fields:** - `"result"."execution_results"[0]."transfers[0]"` - the address of the executed transfer that the source account initiated. We will use it to look up additional information about the transfer -- `"result"."execution_results"[0]."block_hash"` - contains the block hash of the block that included our transfer. We will require the _state_root_hash_ of this block to look up information about the accounts and their purse balances +- `"result"."execution_results"[0]."block_hash"` - contains the block hash of the block that included the transfer. We will require the _state_root_hash_ of this block to look up information about the accounts and their purse balances **Note**: Transfer addresses use a `transfer-` string prefix. From face7937728e8ee1487cbcce44f955e7772fa520 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Thu, 12 Oct 2023 19:31:37 +0200 Subject: [PATCH 56/62] New examples in direct-token-transfer.md --- .../cli/transfers/direct-token-transfer.md | 371 ++++++++++-------- 1 file changed, 215 insertions(+), 156 deletions(-) diff --git a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md index 9f12b033d6..833161e22c 100644 --- a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md +++ b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md @@ -20,14 +20,14 @@ For transfers of at least 2.5 CSPR (2,500,000,000 Motes) from a single sender to ```bash casper-client transfer \ ---id 1 \ ---transfer-id 123456789012345 \ ---node-address http://:7777 \ ---amount \ ---secret-key .pem \ ---chain-name casper \ ---target-account \ ---payment-amount +--id \ +--transfer-id \ +--node-address [NODE_SERVER_ADDRESS] \ +--amount [AMOUNT_TO_TRANSFER] \ +--secret-key [KEY_PATH]/secret_key.pem \ +--chain-name [CHAIN_NAME] \ +--target-account [PUBLIC_KEY_HEX] \ +--payment-amount [PAYMENT_AMOUNT_IN_MOTES] ``` **Request fields:** @@ -64,78 +64,76 @@ casper-client transfer \ ```json { - "id": 1, - "jsonrpc": "2.0", - "method": "account_put_deploy", - "params": { - "deploy": { - "approvals": [ - { - "signature": "130 chars", - "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150" - } + "jsonrpc": "2.0", + "method": "account_put_deploy", + "params": { + "deploy": { + "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c", + "header": { + "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "timestamp": "2023-10-12T14:59:40.760Z", + "ttl": "30m", + "gas_price": 1, + "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d", + "dependencies": [], + "chain_name": "casper-test" + }, + "payment": { + "ModuleBytes": { + "module_bytes": "", + "args": [ + [ + "amount", + { + "cl_type": "U512", + "bytes": "0400e1f505", + "parsed": "100000000" + } + ] + ] + } + }, + "session": { + "Transfer": { + "args": [ + [ + "amount", + { + "cl_type": "U512", + "bytes": "0500f2052a01", + "parsed": "5000000000" + } ], - "hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713", - "header": { - "account": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150", - "body_hash": "da35b095640a403324306c59ac6f18a446dfcc28faf753ce58b96b635587dd8e", - "chain_name": "casper-net-1", - "dependencies": [], - "gas_price": 1, - "timestamp": "2021-04-20T18:04:40.333Z", - "ttl": "1h" - }, - "payment": { - "ModuleBytes": { - "args": [ - [ - "amount", - { - "bytes": "021027", - "cl_type": "U512", - "parsed": "10000" - } - ] - ], - "module_bytes": "" - } - }, - "session": { - "Transfer": { - "args": [ - [ - "amount", - { - "bytes": "0400f90295", - "cl_type": "U512", - "parsed": "2500000000" - } - ], - [ - "target", - { - "bytes": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668", - "cl_type": { - "ByteArray": 32 - }, - "parsed": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668" - } - ], - [ - "id", - { - "bytes": "00", - "cl_type": { - "Option": "U64" - }, - "parsed": null - } - ] - ] - } - } + [ + "target", + { + "cl_type": "PublicKey", + "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986", + "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986" + } + ], + [ + "id", + { + "cl_type": { + "Option": "U64" + }, + "bytes": "014767a90000000000", + "parsed": 11102023 + } + ] + ] + } + }, + "approvals": [ + { + "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305" } + ] } + }, + "id": 3 } ``` @@ -143,12 +141,12 @@ casper-client transfer \ ```json { - "id": 1, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "deploy_hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713" - } + "jsonrpc": "2.0", + "id": 3, + "result": { + "api_version": "1.5.3", + "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c" + } } ``` @@ -174,12 +172,13 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- ```json { - "id": 2, - "jsonrpc": "2.0", - "method": "info_get_deploy", - "params": { - "deploy_hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713" - } + "jsonrpc": "2.0", + "method": "info_get_deploy", + "params": { + "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c", + "finalized_approvals": false + }, + "id": -3447643973713335073 } ``` @@ -187,40 +186,33 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- ```json { - "id": 6054990863558097019, "jsonrpc": "2.0", "result": { - "api_version": "1.4.6", + "api_version": "1.5.3", "deploy": { - "approvals": [ - { - "signature": "01c8c1704a2c921988cd546fe85d249f27bc9da198e8c2f79d91e19a40e015e59a099723b5540c20c57a1ebffef2e4d2e333d9e52f1f27fef9d6b9a4ec5080b40a", - "signer": "01ea8ff63a2b3bcf42c3e8e057959d864043fb989082ddc54464ef9a2ea7338ba0" - } - ], - "hash": "d5862af0c7d06df6cb265c2dee9a014ce570a8db75eb0689f14d819c632c305d", + "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c", "header": { - "account": "01ea8ff63a2b3bcf42c3e8e057959d864043fb989082ddc54464ef9a2ea7338ba0", - "body_hash": "9ccc49a951b9b783bbb20746007e221e8326fbbb48f002aaa40d664abf35995d", - "chain_name": "casper-test", - "dependencies": [], + "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "timestamp": "2023-10-12T14:59:40.760Z", + "ttl": "30m", "gas_price": 1, - "timestamp": "2022-07-05T22:39:20.190Z", - "ttl": "30m" + "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d", + "dependencies": [], + "chain_name": "casper-test" }, "payment": { "ModuleBytes": { + "module_bytes": "", "args": [ [ "amount", { - "bytes": "0400e1f505", "cl_type": "U512", + "bytes": "0400e1f505", "parsed": "100000000" } ] - ], - "module_bytes": "" + ] } }, "session": { @@ -229,48 +221,61 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- [ "amount", { - "bytes": "0400f90295", "cl_type": "U512", - "parsed": "2500000000" + "bytes": "0500f2052a01", + "parsed": "5000000000" } ], [ "target", { - "bytes": "0203343d88a5dd8a67ab8c9d572c50c7f4604960d78f8a41ea48b98d3dcec6316834", "cl_type": "PublicKey", - "parsed": "0203343d88a5dd8a67ab8c9d572c50c7f4604960d78f8a41ea48b98d3dcec6316834" + "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986", + "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986" } ], [ "id", { - "bytes": "01e6c6720000000000", "cl_type": { "Option": "U64" }, - "parsed": 7522022 + "bytes": "014767a90000000000", + "parsed": 11102023 } ] ] } - } + }, + "approvals": [ + { + "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305" + } + ] }, "execution_results": [ { - "block_hash": "b357fc78f105e43be66f268bb8d7308f357fe37e0e55d92d26f8e255c9292529", + "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b", "result": { "Success": { - "cost": "100000000", "effect": { "operations": [], "transforms": [ { - "key": "account-hash-aff4921ce6f73072a914f04e7327a946b72ec4562a7d99f107e9411d1592c3f6", + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", "transform": "Identity" }, { - "key": "account-hash-aff4921ce6f73072a914f04e7327a946b72ec4562a7d99f107e9411d1592c3f6", + "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "transform": "Identity" + }, + { + "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", "transform": "Identity" }, { @@ -281,6 +286,14 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5", "transform": "Identity" }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, { "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", "transform": "Identity" @@ -290,7 +303,11 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "transform": "Identity" }, { - "key": "balance-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4", + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", "transform": "Identity" }, { @@ -298,12 +315,12 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "transform": "Identity" }, { - "key": "balance-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4", + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", "transform": { "WriteCLValue": { - "bytes": "0500a7d0dd2c", "cl_type": "U512", - "parsed": "192700000000" + "bytes": "06621c3e660301", + "parsed": "1114111876194" } } }, @@ -314,11 +331,19 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- } }, { - "key": "account-hash-aff4921ce6f73072a914f04e7327a946b72ec4562a7d99f107e9411d1592c3f6", + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", "transform": "Identity" }, { - "key": "account-hash-aff4921ce6f73072a914f04e7327a946b72ec4562a7d99f107e9411d1592c3f6", + "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "transform": "Identity" + }, + { + "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "transform": "Identity" + }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", "transform": "Identity" }, { @@ -329,6 +354,14 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5", "transform": "Identity" }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, { "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", "transform": "Identity" @@ -338,7 +371,11 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "transform": "Identity" }, { - "key": "balance-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4", + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", "transform": "Identity" }, { @@ -346,12 +383,12 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "transform": "Identity" }, { - "key": "balance-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4", + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", "transform": { "WriteCLValue": { - "bytes": "0500a7d0dd2c", "cl_type": "U512", - "parsed": "192700000000" + "bytes": "06621c3e660301", + "parsed": "1114111876194" } } }, @@ -365,60 +402,68 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", "transform": "Identity" }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, { "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e", "transform": "Identity" }, { - "key": "balance-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4", + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, + { + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", "transform": "Identity" }, { - "key": "balance-be85882962304905286b2b4d3602f7f287095536ef4ce3e9a5360930c729ec2c", + "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c", "transform": "Identity" }, { - "key": "balance-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4", + "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1", "transform": { "WriteCLValue": { - "bytes": "0500aecd482c", "cl_type": "U512", - "parsed": "190200000000" + "bytes": "06622a383c0201", + "parsed": "1109111876194" } } }, { - "key": "balance-be85882962304905286b2b4d3602f7f287095536ef4ce3e9a5360930c729ec2c", + "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c", "transform": { - "AddUInt512": "2500000000" + "AddUInt512": "5000000000" } }, { - "key": "transfer-86760957e94a46839bcd03bee35c9db6b8a906e6fbfe87e69e93383df3d41b2a", + "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405", "transform": { "WriteTransfer": { - "amount": "2500000000", - "deploy_hash": "d5862af0c7d06df6cb265c2dee9a014ce570a8db75eb0689f14d819c632c305d", - "from": "account-hash-9aed70924116013bdd5517109bea97678d9cff449640457a8a4ed3e561d864d4", + "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c", + "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007", + "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004", + "amount": "5000000000", "gas": "0", - "id": 7522022, - "source": "uref-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4-007", - "target": "uref-be85882962304905286b2b4d3602f7f287095536ef4ce3e9a5360930c729ec2c-004", - "to": "account-hash-aff4921ce6f73072a914f04e7327a946b72ec4562a7d99f107e9411d1592c3f6" + "id": 11102023 } } }, { - "key": "deploy-d5862af0c7d06df6cb265c2dee9a014ce570a8db75eb0689f14d819c632c305d", + "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c", "transform": { "WriteDeployInfo": { - "deploy_hash": "d5862af0c7d06df6cb265c2dee9a014ce570a8db75eb0689f14d819c632c305d", - "from": "account-hash-9aed70924116013bdd5517109bea97678d9cff449640457a8a4ed3e561d864d4", - "gas": "100000000", - "source": "uref-20c3a137051eaa98efa048fd8f888ed4b342bcc1c8166f475e25b6a627d669a4-007", + "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c", "transfers": [ - "transfer-86760957e94a46839bcd03bee35c9db6b8a906e6fbfe87e69e93383df3d41b2a" - ] + "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405" + ], + "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007", + "gas": "100000000" } } }, @@ -426,10 +471,18 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", "transform": "Identity" }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, { "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5", "transform": "Identity" }, + { + "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401", + "transform": "Identity" + }, { "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", "transform": "Identity" @@ -446,26 +499,30 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e", "transform": "Identity" }, + { + "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7", + "transform": "Identity" + }, { "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", "transform": "Identity" }, { - "key": "balance-874289dbe721508e8d2893efd86364ea1ca67a6a2456825259efd6db8efb427c", + "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537", "transform": "Identity" }, { "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6", "transform": { "WriteCLValue": { - "bytes": "00", "cl_type": "U512", + "bytes": "00", "parsed": "0" } } }, { - "key": "balance-874289dbe721508e8d2893efd86364ea1ca67a6a2456825259efd6db8efb427c", + "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537", "transform": { "AddUInt512": "100000000" } @@ -473,13 +530,15 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- ] }, "transfers": [ - "transfer-86760957e94a46839bcd03bee35c9db6b8a906e6fbfe87e69e93383df3d41b2a" - ] + "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405" + ], + "cost": "100000000" } } } ] - } + }, + "id": -3447643973713335073 } ``` From 4ea99168afc3aed7af3c7d5d983c6a105415d88a Mon Sep 17 00:00:00 2001 From: ipopescu Date: Thu, 12 Oct 2023 20:45:23 +0200 Subject: [PATCH 57/62] Additional updates in direct-token-transfer.md --- .../cli/transfers/direct-token-transfer.md | 59 +++++++++++++++---- 1 file changed, 49 insertions(+), 10 deletions(-) diff --git a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md index 833161e22c..bc26431792 100644 --- a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md +++ b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md @@ -2,22 +2,22 @@ This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network. +## Prerequisites + This workflow assumes: -1. You meet the [prerequisites](../../prerequisites.md) +1. You meet the general [development prerequisites](../../prerequisites.md) 2. You are using the Casper command-line client 3. You have a target *public key* 4. You have a valid *node address* 5. You must be able to sign a deploy for the source account using the source *secret key* -## Transfer {#transfer} +## Direct Transfer Example {#transfer} -The `transfer` command allows you to move CSPR from one account's purse to another as denominated in [Motes](../../../concepts/design/casper-design.md#tokens-divisibility). A _Mote_ is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes. +The following `transfer` command allows you to move CSPR from one account's purse to another as denominated in [Motes](../../../concepts/design/casper-design.md#tokens-divisibility). A _Mote_ is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes. For transfers of at least 2.5 CSPR (2,500,000,000 Motes) from a single sender to a single recipient on a Casper network, the most efficient option is to use the direct transfer capability. -**Direct transfer example**: - ```bash casper-client transfer \ --id \ @@ -26,7 +26,7 @@ casper-client transfer \ --amount [AMOUNT_TO_TRANSFER] \ --secret-key [KEY_PATH]/secret_key.pem \ --chain-name [CHAIN_NAME] \ ---target-account [PUBLIC_KEY_HEX] \ +--target-account [TARGET_PUBLIC_KEY_HEX] \ --payment-amount [PAYMENT_AMOUNT_IN_MOTES] ``` @@ -55,7 +55,25 @@ casper-client transfer \ - `"result"."deploy_hash"` - The address of the deploy, needed to look up additional information about the transfer -**Note**: Save the returned _deploy_hash_ from the output to query information about the transfer deploy later. +:::note + +Save the returned _deploy_hash_ from the output to query information about the transfer deploy later. + +::: + +**Example Transfer:** + +```bash +casper-client transfer -v \ +--id 3 \ +--transfer-id 11102023 \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--amount 5000000000 \ +--secret-key ~/KEYS/secret_key.pem \ +--chain-name casper-test \ +--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \ +--payment-amount 100000000 +```
Explore the JSON-RPC request and response generated. @@ -152,18 +170,33 @@ casper-client transfer \
-### Deploy Status {#deploy-status} +## Verifying the Deploy {#verify-deploy} A transfer on a Casper network is only executed after it has been included in a finalized block. -Refer to the Section on [querying deploys](../../../resources/beginner/querying-network.md#querying-deploys) within the network to check the execution status of the transfer. +```bash +casper-client get-deploy +--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH] +``` **Important response fields:** - `"result"."execution_results"[0]."transfers[0]"` - the address of the executed transfer that the source account initiated. We will use it to look up additional information about the transfer - `"result"."execution_results"[0]."block_hash"` - contains the block hash of the block that included the transfer. We will require the _state_root_hash_ of this block to look up information about the accounts and their purse balances -**Note**: Transfer addresses use a `transfer-` string prefix. +:::note + +Transfer addresses use a `transfer-` string prefix. + +::: + +**Example Query:** + +```bash +casper-client get-deploy +--node-address https://rpc.testnet.casperlabs.io +1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c +```
Explore the JSON-RPC request and response generated. @@ -543,3 +576,9 @@ Refer to the Section on [querying deploys](../../../resources/beginner/querying- ```
+ +Refer to the Section on [querying deploys](../../../resources/beginner/querying-network.md#querying-deploys) for more information. + +## Verifying the Transfer + +In addition to verifying the deploy, you also need to [verify the transfer details](./verify-transfer.md). The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly. \ No newline at end of file From a21e3c61cc7acff0718185fadde1bf5e88c3fc60 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Thu, 12 Oct 2023 20:45:44 +0200 Subject: [PATCH 58/62] Updated verify-transfer.md --- .../cli/transfers/verify-transfer.md | 374 ++++++++++-------- .../image/transfers/transfer-hash-example.png | Bin 0 -> 155044 bytes 2 files changed, 205 insertions(+), 169 deletions(-) create mode 100644 static/image/transfers/transfer-hash-example.png diff --git a/source/docs/casper/developers/cli/transfers/verify-transfer.md b/source/docs/casper/developers/cli/transfers/verify-transfer.md index 29e54d7cac..674ce1e6c1 100644 --- a/source/docs/casper/developers/cli/transfers/verify-transfer.md +++ b/source/docs/casper/developers/cli/transfers/verify-transfer.md @@ -6,40 +6,91 @@ Before verifying a transfer, make sure you have: 1. Initiated a [Direct Transfer](./direct-token-transfer.md) or [Multi-sig Deploy Transfer](./multisig-deploy-transfer.md) 2. The *deploy_hash* of the transfer you want to verify -3. The *public key* hex for the source and target accounts +3. The *public key* of the source and target accounts -## Query Transfer Details {#query-transfer-details} +## Query the State Root Hash -A transfer is a part of a deploy - in a Casper network, deploys can contain multiple transfers. Execution of the deploy includes writing information about each individual transfer to global state. A unique hash known as the `transfer-address` identifies each transfer. The `transfer-address` consists of a formatted string with a `transfer-` prefix. +The state root hash is an identifier of the current network state. It gives a snapshot of the blockchain state at a moment in time. You can use the state root hash to query the network state after sending a deploy. -First, we will use the *deploy_hash* to identify the corresponding transfer: +```bash +casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS] +``` + +**Example Query:** + +```bash +casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io +``` + +
+Sample output of the get-state-root-hash command + +```json +{ + "jsonrpc": "2.0", + "id": 6458079936180872466, + "result": { + "api_version": "1.5.3", + "state_root_hash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1" + } +} +``` +
+ +:::note + +After sending deploys to the network, you must get the new state root hash to see the changes reflected. Otherwise, you will be looking at events in the past. + +::: + +## Query the Transfer Details {#query-transfer-details} + +A transfer is executed as part of a deploy. In a Casper network, deploys can contain multiple transfers. Execution of the deploy includes writing information about each individual transfer to global state. A unique hash known as the `transfer-address` identifies each transfer. The `transfer-address` consists of a formatted string with a `transfer-` prefix. + +

+Image showing a transfer hash +

+ +First, use the `get-deploy` command and the *deploy_hash* to identify the corresponding transfer: ```bash casper-client get-deploy \ ---node-address http://:7777 \ +--node-address [NODE_SERVER_ADDRESS] \ [DEPLOY_HASH] ``` **Important response fields:** -- `"result"."execution_results"."result"."Success"."transfers"` - List of transfers contained in a successful deploy. +- `"result"."execution_results"."result"."Success"."transfers"` - List of transfers contained in a successful deploy -After we have obtained the `transfer-` identifier, we can query transfer details. +After obtaining the transfer identifier, query the transfer details. ```bash casper-client query-global-state \ ---id 8 \ ---node-address http://:7777 \ ---state-root-hash \ ---key transfer- +--id [ID] \ +--node-address [NODE_SERVER_ADDRESS] \ +--state-root-hash [STATE_ROOT_HASH] \ +--key [TRANSFER_HASH] ``` **Request fields:** -- `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned. -- `node-address` - An IP address of a node on the network. -- `state-root-hash` - The hex-encoded hash of the state root. -- `key` - The base key for the query. This must be a properly formatted transfer address. +- `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned +- `node-address` - An IP address of a node on the network +- `state-root-hash` - The hex-encoded hash of the state root +- `key` - The base key for the query. This must be a properly formatted transfer address with a `transfer-` prefix, i.e., `transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb` + +The `-v` option generates verbose output, printing the RPC request and response generated. Let's explore an example below. + +**Example Query:** + +```bash +casper-client query-global-state -v \ +--id 3 \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \ +--key transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb +```
Explore the JSON-RPC request and response generated. @@ -48,14 +99,16 @@ casper-client query-global-state \ ```json { - "id": 8, - "jsonrpc": "2.0", - "method": "state_get_item", - "params": { - "key": "transfer-8d81f4a1411d9481aed9c68cd700c39d870757b0236987bb6b7c2a7d72049c0e", - "path": [], - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" - } + "jsonrpc": "2.0", + "method": "query_global_state", + "params": { + "state_identifier": { + "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1" + }, + "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb", + "path": [] + }, + "id": 3 } ``` @@ -63,70 +116,42 @@ casper-client query-global-state \ ```json { - "id": 8, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "merkle_proof": "924 chars", - "stored_value": { - "Transfer": { - "amount": "2500000000", - "deploy_hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713", - "from": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "gas": "0", - "id": null, - "source": "uref-9e90f4bbd8f581816e305eb7ea2250ca84c96e43e8735e6aca133e7563c6f527-007", - "target": "uref-6f4026262a505d5e1b0e03b1e3b7ab74a927f8f2868120cf1463813c19acb71e-004", - "to": "account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668" - } - } - } -} -``` - -
- -The query responds with more information about the transfer we conducted: its deploy hash, the account which executed the transfer, the source and target purses, and the target account. We can verify that our transfer processed successfully using this additional information. - -## The State Root Hash - -The state root hash is an identifier of the current network state. It gives a snapshot of the blockchain state at a moment in time. You can use the state root hash to query the network state after deployments. - -``` -casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS] -``` - -
-Sample output of the get-state-root-hash command - -```json -{ - "id": -550641580167406055, "jsonrpc": "2.0", "result": { - "api_version": "1.4.13", - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" - } + "api_version": "1.5.3", + "block_header": null, + "stored_value": { + "Transfer": { + "deploy_hash": "4eedbb5cf4a571748cf7ae9c2f17777364a01f80f79f3633a0cec32b7e8cf2e3", + "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007", + "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004", + "amount": "5000000000", + "gas": "0", + "id": 11102023 + } + }, + "merkle_proof": "[42526 hex chars]" + }, + "id": 3 } ``` -
- -:::note -After any deploys to the network, you must get the new state root hash to see the new changes reflected. Otherwise, you will be looking at events in the past. +
-::: +The query responds with more information about the transfer: its deploy hash, the account which executed the transfer, the source and target purses, and the target account. You can verify that the transfer processed successfully using this additional information. -## Query Account State {#query-account-state} +## Query the Account State {#query-account-state} -Here, we will query for information about the _Source_ account, using the `state-root-hash` of the block containing the transfer: +Next, query for information about the _Source_ account, using the `state-root-hash` of the block containing the transfer: ```bash casper-client query-global-state \ ---id 4 \ ---node-address http://:7777 \ ---state-root-hash \ ---key +--id [ID] \ +--node-address [NODE_SERVER_ADDRESS] \ +--state-root-hash [STATE_ROOT_HASH] \ +--key [SOURCE_PUBLIC_KEY] ``` **Request fields:** @@ -134,12 +159,22 @@ casper-client query-global-state \ - `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned - `node-address` - An IP address of a node on the network - `state-root-hash` - Hex-encoded hash of the network state -- `key` - The base key for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash, or deploy-info hash. +- `key` - The base key for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash, or deploy-info hash **Important response fields:** - `"result"."stored_value"."Account"."main_purse"` - the address of the main purse containing the sender's tokens. In this example, this purse is the source of the tokens transferred +**Source Example Query:** + +```bash +casper-client query-global-state -v \ +--id 4 \ +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \ +--key 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf +``` +
Explore the JSON-RPC request and response generated. @@ -147,14 +182,16 @@ casper-client query-global-state \ ```json { - "id": 4, - "jsonrpc": "2.0", - "method": "state_get_item", - "params": { - "key": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "path": [], - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" - } + "jsonrpc": "2.0", + "method": "query_global_state", + "params": { + "state_identifier": { + "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1" + }, + "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "path": [] + }, + "id": 4 } ``` @@ -162,42 +199,45 @@ casper-client query-global-state \ ```json { - "id": 4, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "merkle_proof": "2228 chars", - "stored_value": { - "Account": { - "account_hash": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "action_thresholds": { - "deployment": 1, - "key_management": 1 - }, - "associated_keys": [ - { - "account_hash": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5", - "weight": 1 - } - ], - "main_purse": "uref-9e90f4bbd8f581816e305eb7ea2250ca84c96e43e8735e6aca133e7563c6f527-007", - "named_keys": [] - } + "jsonrpc": "2.0", + "result": { + "api_version": "1.5.3", + "block_header": null, + "stored_value": { + "Account": { + "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "named_keys": [...], + "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007", + "associated_keys": [ + { + "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655", + "weight": 1 + } + ], + "action_thresholds": { + "deployment": 1, + "key_management": 1 } - } + } + }, + "merkle_proof": "[31406 hex chars]" + }, + "id": 4 } ```
-We can repeat the same step to query information about the _Target_ account: +**Target Example Query:** + +Repeat the same step to query information about the _Target_ account: ```bash -casper-client query-global-state \ +casper-client query-global-state -v \ --id 5 \ ---node-address http://:7777 \ ---state-root-hash \ ---key +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \ +--key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 ```
@@ -207,14 +247,16 @@ casper-client query-global-state \ ```json { - "id": 5, - "jsonrpc": "2.0", - "method": "state_get_item", - "params": { - "key": "account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668", - "path": [], - "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" - } + "jsonrpc": "2.0", + "method": "query_global_state", + "params": { + "state_identifier": { + "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1" + }, + "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "path": [] + }, + "id": 5 } ``` @@ -222,50 +264,46 @@ casper-client query-global-state \ ```json { - "id": 5, - "jsonrpc": "2.0", - "result": { - "api_version": "1.0.0", - "merkle_proof": "2228 chars", - "stored_value": { - "Account": { - "account_hash": "account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668", - "action_thresholds": { - "deployment": 1, - "key_management": 1 - }, - "associated_keys": [ - { - "account_hash": "account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668", - "weight": 1 - } - ], - "main_purse": "uref-6f4026262a505d5e1b0e03b1e3b7ab74a927f8f2868120cf1463813c19acb71e-007", - "named_keys": [] - } + "jsonrpc": "2.0", + "result": { + "api_version": "1.5.3", + "block_header": null, + "stored_value": { + "Account": { + "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7", + "named_keys": [...], + "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007", + "associated_keys": [...], + "action_thresholds": { + "deployment": 2, + "key_management": 3 } - } + } + }, + "merkle_proof": "[32060 hex chars]" + }, + "id": 5 } ```
-## Query Purse Balance {#get-purse-balance} +## Query the Purse Balance {#get-purse-balance} -All accounts on a Casper network have a purse associated with the Casper system mint, which we call the _main purse_. The balance associated with a given purse is recorded in global state, and the value can be queried using the `query-balance` command and the purse identifier, which can be a public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef can be used. For full details, run the following help command: +All accounts on a Casper network have a purse associated with the Casper system mint, which is the _main purse_. The balance associated with a given purse is recorded in global state, and the value can be queried using the `query-balance` command and the purse identifier, which can be a public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef can be used. For full details, run the following help command: ```bash casper-client query-balance --help ``` -Now that we have the source purse address, we can verify its balance using the `get-balance` command: +Verify the source purse balance using the `query-balance` command: ```bash casper-client query-balance \ --id 6 \ ---node-address http://:7777 \ ---state-root-hash \ ---purse-identifier +--node-address [NODE_SERVER_ADDRESS] \ +--state-root-hash [STATE_ROOT_HAHS] \ +--purse-identifier [SOURCE_PUBLIC_KEY_HEX] ``` **Request fields:** @@ -273,17 +311,15 @@ casper-client query-balance \ - `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned - `node-address` - An IP address of a node on the network - `state-root-hash` - Hex-encoded hash of the state root -- `purse-identifier` - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef. - -The `-v` option generates verbose output, printing the RPC request and response generated. Let's explore an example below. +- `purse-identifier` - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef **Query Source Account Example:** ```bash casper-client query-balance -v --id 6 \ ---node-address http://:7777 \ ---state-root-hash cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3 \ ---purse-identifier account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5 +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \ +--purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655 ```
@@ -297,10 +333,10 @@ casper-client query-balance -v --id 6 \ "method": "query_balance", "params": { "state_identifier": { - "StateRootHash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1" }, "purse_identifier": { - "main_purse_under_account_hash": "account-hash-b0049301811f23aab30260da66927f96bfae7b99a66eb2727da23bf1427a38f5" + "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655" } }, "id": 6 @@ -313,8 +349,8 @@ casper-client query-balance -v --id 6 \ { "jsonrpc": "2.0", "result": { - "api_version": "1.5.2", - "balance": "164000000000" + "api_version": "1.5.3", + "balance": "1109111876194" }, "id": 6 } @@ -322,23 +358,23 @@ casper-client query-balance -v --id 6 \
-Similarly, we have the public key of the target purse, so we can get its balance. +Similarly, query the balance of the target purse. ```bash casper-client get-balance \ --id 7 \ ---node-address http://:7777 \ ---state-root-hash \ ---purse-identifier +--node-address [NODE_SERVER_ADDRESS] \ +--state-root-hash [STATE_ROOT_HAHS] \ +--purse-identifier [TARGET_PUBLIC_KEY_HEX] ``` **Target Account Example:** ```bash casper-client query-balance -v --id 7 \ ---node-address http://:7777 \ ---state-root-hash cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3 \ ---purse-identifier account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668 +--node-address https://rpc.testnet.casperlabs.io/ \ +--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \ +--purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7 ```
@@ -352,10 +388,10 @@ casper-client query-balance -v --id 7 \ "method": "query_balance", "params": { "state_identifier": { - "StateRootHash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3" + "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1" }, "purse_identifier": { - "main_purse_under_account_hash": "account-hash-8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668" + "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7" } }, "id": 7 @@ -368,8 +404,8 @@ casper-client query-balance -v --id 7 \ { "jsonrpc": "2.0", "result": { - "api_version": "1.5.2", - "balance": "5000000000" + "api_version": "1.5.3", + "balance": "46200000000" }, "id": 7 } diff --git a/static/image/transfers/transfer-hash-example.png b/static/image/transfers/transfer-hash-example.png new file mode 100644 index 0000000000000000000000000000000000000000..e9e0d82f504db514de4bf203f04d06797fbf76ae GIT binary patch literal 155044 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�B!FCTAXI+QK^ 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 Vx7bBPAs2ujIVq**`OjXy{a;9KnezYu literal 0 HcmV?d00001 From 52171884e5d3d1f2d2e27edfde803c62437581c4 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Thu, 12 Oct 2023 20:49:34 +0200 Subject: [PATCH 59/62] Minor updates --- .../developers/cli/transfers/direct-token-transfer.md | 6 ------ .../docs/casper/developers/cli/transfers/verify-transfer.md | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md index bc26431792..5247f64a02 100644 --- a/source/docs/casper/developers/cli/transfers/direct-token-transfer.md +++ b/source/docs/casper/developers/cli/transfers/direct-token-transfer.md @@ -33,22 +33,16 @@ casper-client transfer \ **Request fields:** - `id` - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned - - `transfer-id` -<64-BIT INTEGER> The `transfer-id` is a memo field, providing additional information about the recipient, which is necessary when transferring tokens to some recipients. For example, if depositing tokens into an account's purse where off-chain management keeps track of individual sub-balances, it is necessary to provide a memo ID uniquely identifying the actual recipient. If this is not necessary for a given recipient, you may pass `0` or some `u64` value that is meaningful to you - - `node-address` - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint \[default:\] - - `amount` -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 `Motes`) - - `secret-key` - Path to secret key file - - `chain-name` - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain - The _chain-name_ for Testnet is **casper-test** - The _chain-name_ for Mainnet is **casper** - `target-account` - Hex-encoded public key of the account that will receive the funds in its main purse - - `payment-amount` - The payment for the transfer in motes. The payment amount varies based on each deploy and network [chainspec](../../../concepts/glossary/C.md#chainspec). For Testnet node version [1.5.1](https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml), you can specify 10^8 motes **Important response fields:** diff --git a/source/docs/casper/developers/cli/transfers/verify-transfer.md b/source/docs/casper/developers/cli/transfers/verify-transfer.md index 674ce1e6c1..7b7216c8aa 100644 --- a/source/docs/casper/developers/cli/transfers/verify-transfer.md +++ b/source/docs/casper/developers/cli/transfers/verify-transfer.md @@ -165,7 +165,7 @@ casper-client query-global-state \ - `"result"."stored_value"."Account"."main_purse"` - the address of the main purse containing the sender's tokens. In this example, this purse is the source of the tokens transferred -**Source Example Query:** +**Source Account Query:** ```bash casper-client query-global-state -v \ @@ -228,7 +228,7 @@ casper-client query-global-state -v \
-**Target Example Query:** +**Target Account Query:** Repeat the same step to query information about the _Target_ account: From 168a29938d29a8ede3526d2b37e18ab23b35a749 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Thu, 12 Oct 2023 21:20:38 +0200 Subject: [PATCH 60/62] Updated multisig-deploy-transfer.md --- .../cli/transfers/multisig-deploy-transfer.md | 111 +++++++++++------- 1 file changed, 69 insertions(+), 42 deletions(-) diff --git a/source/docs/casper/developers/cli/transfers/multisig-deploy-transfer.md b/source/docs/casper/developers/cli/transfers/multisig-deploy-transfer.md index 130dbb354a..ad4a11a592 100644 --- a/source/docs/casper/developers/cli/transfers/multisig-deploy-transfer.md +++ b/source/docs/casper/developers/cli/transfers/multisig-deploy-transfer.md @@ -1,8 +1,10 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; -# Transferring Tokens using a Multi-sig Deploy +# Transferring Tokens using a Multi-Sig Deploy -This topic explores using a deploy file to transfer Casper tokens (CSPR) between purses on a Casper network. This method of transferring tokens is recommended when you want to implement multi-signature deploys. The `make-transfer` command allows you to create a transfer Deploy and save the output to a file. You can then have the Deploy signed by other parties using the `sign-deploy` command and send it to the network for execution using the `send-deploy` command. +This page presents a method of transferring tokens via a deploy file using multiple signatures. This method is recommended when implementing multi-signature transfers between purses on a Casper network. + +The `make-transfer` command allows you to create a transfer and save the output to a file. You can then have the transfer signed by other parties using the `sign-deploy` command and send it to the network for execution using the `send-deploy` command. ## Prerequisites @@ -16,15 +18,15 @@ You must ensure the following prerequisites are met. 3. Get the path of the source account's _secret key_ file 4. Get the target account's _public key_ in hex format -## Token Transfer Workflow with the Casper Client {#token-transfer-workflow} +## Token Transfer Workflow {#token-transfer-workflow} The high-level flow to transfer tokens using the Casper CLI client and a deploy file is described in the following steps: 1. The `make-transfer` command creates and signs a transfer, saving the output to a file -2. The `sign-transfer` command adds additional signatures for a multi-signature transfer +2. The `sign-deploy` command adds additional signatures for a multi-signature transfer 3. The `send-deploy` command sends the deploy containing the transfer to the network -Deployment flow +Deployment flow ### Creating the transfer {#creating-the-transfer} @@ -35,7 +37,7 @@ casper-client make-transfer --amount 2500000000 \ --secret-key [PATH]/secret_key.pem \ --chain-name casper-test \ --target-account [PUBLIC_KEY_HEX] \ ---transfer-id 3 \ +--transfer-id [ID] \ --payment-amount 100000000 \ --output transfer.deploy ``` @@ -51,20 +53,32 @@ The following table explains the parameters used in the `make-transfer` command. | transfer-id | A user-defined identifier permanently associated with the transfer | | payment-amount | The payment for the transfer in motes. The payment amount varies based on the deploy and network [chainspec](../../../concepts/glossary/C.md#chainspec). For Testnet node version [1.5.1](https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml), wasmless transfers cost 10^8 motes | -In the output, you will see a section named **approvals**. This is where a signature from the source account is added to the Deploy. +In the output, you will see a section named **approvals**. This is where a signature from the source account is added to the deploy. + +**Example:** + +```bash +casper-client make-transfer --amount 2500000000 \ +--secret-key ~/KEYS/multi-sig/keys/default_secret_key.pem \ +--chain-name casper-test \ +--target-account 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf \ +--transfer-id 1 \ +--payment-amount 100000000 \ +--output transfer.deploy +```
Sample output of the make-transfer command ```json { - "hash": "0e17da4c7b6d12984910aa25e397fc85db53e5cd896776d47494cb4a5f2083f1", + "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b", "header": { - "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", - "timestamp": "2023-01-05T11:30:05.269Z", + "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986", + "timestamp": "2023-10-12T19:14:22.080Z", "ttl": "30m", "gas_price": 1, - "body_hash": "5d7d30965d503dba0459d5e6b3a0c923059f89e6a7179f76aec0fda1263b7819", + "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c", "dependencies": [], "chain_name": "casper-test" }, @@ -76,8 +90,8 @@ In the output, you will see a section named **approvals**. This is where a signa "amount", { "cl_type": "U512", - "bytes": "021027", - "parsed": "10000" + "bytes": "0400e1f505", + "parsed": "100000000" } ] ] @@ -98,8 +112,8 @@ In the output, you will see a section named **approvals**. This is where a signa "target", { "cl_type": "PublicKey", - "bytes": "01f48f5b095518be188286d896921d33e97f9729f5945237d5ff6cf7b077aabf1f", - "parsed": "01f48f5b095518be188286d896921d33e97f9729f5945237d5ff6cf7b077aabf1f" + "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf" } ], [ @@ -108,8 +122,8 @@ In the output, you will see a section named **approvals**. This is where a signa "cl_type": { "Option": "U64" }, - "bytes": "013930000000000000", - "parsed": 3 + "bytes": "010100000000000000", + "parsed": 1 } ] ] @@ -117,8 +131,8 @@ In the output, you will see a section named **approvals**. This is where a signa }, "approvals": [ { - "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", - "signature": "016853b69b98434f236ac2eacb053b244f5853f0ec2a1d86b8f8a35601353cebe160f3c57606be9f289da34b7ccd5b7285751d1e6edc9cc76a84c14fb286272702" + "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986", + "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e" } ] } @@ -143,6 +157,15 @@ casper-client sign-deploy \ | secret-key | The path of the secret key file used to sign the deploy | | output | The path of the output file used to save the deploy with multiple signatures | +**Example:** + +```bash +casper-client sign-deploy \ +--input transfer.deploy \ +--secret-key ~/KEYS/multi-sig/keys/user_1_secret_key.pem \ +--output transfer2.deploy +``` + Towards the end of the following output, you can observe that there is an **approvals** section, which has two signatures, one from the account initiating the transfer and the second from the account used to sign the deploy.
@@ -150,13 +173,13 @@ Towards the end of the following output, you can observe that there is an **appr ```json { - "hash": "959ba7154a58bf3a9ec555b38fb2c96dba81523b49f9a086630d0cf44d74cacc", + "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b", "header": { - "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", - "timestamp": "2023-01-05T11:42:23.311Z", + "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986", + "timestamp": "2023-10-12T19:14:22.080Z", "ttl": "30m", "gas_price": 1, - "body_hash": "5d7d30965d503dba0459d5e6b3a0c923059f89e6a7179f76aec0fda1263b7819", + "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c", "dependencies": [], "chain_name": "casper-test" }, @@ -168,8 +191,8 @@ Towards the end of the following output, you can observe that there is an **appr "amount", { "cl_type": "U512", - "bytes": "021027", - "parsed": "10000" + "bytes": "0400e1f505", + "parsed": "100000000" } ] ] @@ -190,8 +213,8 @@ Towards the end of the following output, you can observe that there is an **appr "target", { "cl_type": "PublicKey", - "bytes": "01f48f5b095518be188286d896921d33e97f9729f5945237d5ff6cf7b077aabf1f", - "parsed": "01f48f5b095518be188286d896921d33e97f9729f5945237d5ff6cf7b077aabf1f" + "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", + "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf" } ], [ @@ -200,8 +223,8 @@ Towards the end of the following output, you can observe that there is an **appr "cl_type": { "Option": "U64" }, - "bytes": "013930000000000000", - "parsed": 3 + "bytes": "010100000000000000", + "parsed": 1 } ] ] @@ -210,11 +233,11 @@ Towards the end of the following output, you can observe that there is an **appr "approvals": [ { "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986", - "signature": "014c2dc520a1d7f2b7cc18fe704899dd158c02448a4c575bc5214bad3384cb4fff6e32ece196768a8d21b5644c96850fea8b980bd2f6c1fe3c717c1c45a6b75508" + "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e" }, { - "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf", - "signature": "0107b684e395879fed81d8387b0b4422301c1e4fcbd76672cf3fb7ab2ea8a2ef1429622a999fbbb56bcb79d871bfaeeb107415d67c78a57e8f67987e7f4368980c" + "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51", + "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803" } ] } @@ -224,12 +247,12 @@ Towards the end of the following output, you can observe that there is an **appr ### Sending the deploy {#sending-the-deploy} -The next step is to send the deploy for processing on the network. As described in the [Prerequisites](#prerequisites) section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node `http://65.21.235.219` from the Testnet; replace this with an active node before using the command. Port `7777` is the RPC endpoint for interacting with the Casper client. +The next step is to send the deploy for processing on the network. As described in the [Prerequisites](#prerequisites) section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node `https://rpc.testnet.casperlabs.io/` from the Testnet. ```bash casper-client send-deploy \ --input transfer2.deploy \ ---node-address http://65.21.235.219:7777 +--node-address https://rpc.testnet.casperlabs.io/ ``` | Parameter | Description | @@ -244,18 +267,22 @@ Make a note of the *deploy_hash* from the `send-deploy` command output to verify ```json { - "id": 261147078494867680, - "jsonrpc": "2.0", - "result": { - "api_version": "1.3.4", - "deploy_hash": "87912f9ea859159dcf2f0554751ba0bce8b1df41f4b4339bc6de370d7734bdae" - } + "jsonrpc": "2.0", + "id": -818883417884028030, + "result": { + "api_version": "1.5.3", + "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b" + } } ```
-If you encounter an account authorization error, you must set up the source account to allow multi-signature deploys using session code. The [Two-Party Multi-Signature Deploys](../../../resources/advanced/two-party-multi-sig.md) workflow is an example of how to accomplish this. +:::note + +If you encounter an account authorization error, you **must set up the source account to allow multi-signature deploys** using session code. The [Two-Party Multi-Signature Deploys](../../../resources/advanced/two-party-multi-sig.md) workflow is an example of how to accomplish this. + +:::
Example of an account authorization error @@ -270,7 +297,7 @@ If you encounter an account authorization error, you must set up the source acco
-## Verifying the Transfer {#verifying-the-transfer} +### Verifying the transfer {#verifying-the-transfer} To verify the transfer status, see [Verifying a Transfer](./verify-transfer.md). From 71ec971976babf9fd105bc285913bda4ec023a22 Mon Sep 17 00:00:00 2001 From: ipopescu Date: Fri, 13 Oct 2023 13:08:42 +0200 Subject: [PATCH 61/62] Updated steps for moving a node --- .../operators/maintenance/moving-node.md | 90 +++++++++++-------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/source/docs/casper/operators/maintenance/moving-node.md b/source/docs/casper/operators/maintenance/moving-node.md index ce53bd355d..ff9f12ded7 100644 --- a/source/docs/casper/operators/maintenance/moving-node.md +++ b/source/docs/casper/operators/maintenance/moving-node.md @@ -6,68 +6,82 @@ title: Move a Node This guide is for active validators who want to move their node to another machine. +:::note + +Starting with node version 1.5, operators need to move the unit files at the database level. This step allows moving the node with nearly zero rewards loss. + +::: + ## Swapping Keys with a Hot Backup This method limits downtime and enables a smooth transition from the old to the new node. It keeps the node in sync with the tip of the chain. 1. Once a node is running (`current_node`), create a second node (`backup_node`) on another machine. These two nodes will run in parallel. -2. When the `backup_node` is up to date, stop both nodes. -3. Swap their associated keys. -4. Restart the `backup_node`. +2. When the `backup_node` is up to date, stop the `current_node`. +3. Move the unit files at the DB level using `rsync`. This step allows moving the node with nearly zero rewards loss. +4. Stop the `backup_node`. +5. Swap keys on the `backup_node`, now the new validator. +6. Restart the `backup_node`. +7. Swap keys on the `current_node`, now the new backup. +8. Restart the `current_node`. ### Preparation for swapping -Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset. +1. Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset. -Bond the `backup_node` and wait until rewards are issued. +2. Bond the `backup_node` and wait until rewards are issued. -To swap keys: +3. Prepare to swap keys by following these steps: -1. Create the following folder structure on both nodes under the `/etc/casper/validator_keys/` directory. -2. Create subdirectories for the `current_node` and `backup_node`. -3. Copy each node's keyset under the corresponding directories. + - Create the following folder structure on both nodes under the `/etc/casper/validator_keys/` directory. + - Create subdirectories for the `current_node` and `backup_node`. + - Copy each node's keyset under the corresponding directories. ```bash -/etc/casper/validator_keys/ -├── public_key.pem -├── public_key_hex -├── secret_key.pem -├── current_node -│ ├── public_key.pem -│ ├── public_key_hex -│ └── secret_key.pem -└── backup_node -| ├── public_key.pem -| ├── public_key_hex -| └── secret_key.pem + /etc/casper/validator_keys/ + ├── public_key.pem + ├── public_key_hex + ├── secret_key.pem + ├── current_node + │ ├── public_key.pem + │ ├── public_key_hex + │ └── secret_key.pem + └── backup_node + | ├── public_key.pem + | ├── public_key_hex + | └── secret_key.pem ``` This setup allows key swapping by running the `sudo -u casper cp * ../` command, as shown below. ### Swapping the nodes -On the `current_node`, run these commands: +1. When the `backup_node` is up to date, stop the `current_node`. -```bash -sudo systemctl stop casper-node-launcher -cd /etc/casper/validator_keys/backup_node -sudo -u casper cp * ../ -``` +2. On the `backup_node` (the future validator), use `rsync` to move the unit files from the `current_node`, located in `/var/lib/casper/casper-node/[NETWORK_NAME]/unit_files`. -On the `backup_node` (the future validator), run these commands: +3. On the `backup_node`, run these commands to stop the node, swap keys, and restart the node: -```bash -sudo systemctl stop casper-node-launcher -cd /etc/casper/validator_keys/current_node -sudo -u casper cp * ../ -sudo systemctl start casper-node-launcher -``` + ```bash + sudo systemctl stop casper-node-launcher + cd /etc/casper/validator_keys/current_node + sudo -u casper cp * ../ + sudo systemctl start casper-node-launcher + ``` -Restart the original validator node (`current_node`), which is now the new backup: +4. On the `current_node`, run these commands to stop the node and swap keys: -```bash -sudo systemctl start casper-node-launcher -``` + ```bash + sudo systemctl stop casper-node-launcher + cd /etc/casper/validator_keys/backup_node + sudo -u casper cp * ../ + ``` + +5. Restart the original validator node (`current_node`), which is now the new backup: + + ```bash + sudo systemctl start casper-node-launcher + ``` ### Understanding rewards impact From 6b3d9b82fbc7030aa152df2bf19dd2b7231db06a Mon Sep 17 00:00:00 2001 From: andrzej-casper <121791569+andrzej-casper@users.noreply.github.com> Date: Tue, 26 Sep 2023 15:16:07 +0200 Subject: [PATCH 62/62] Limit CI/CD push trigger to `dev` branch only. --- .github/workflows/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8f3f00d727..5dbeb1a5a8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,8 @@ env: on: push: - branches: "*" + branches: + - dev pull_request: types: [ opened, reopened, synchronize ]